我使用命令有一个 3D 表面
使用 1:2:3 和线条调色板绘制 '-' 非均匀矩阵
我知道我可以用轮廓强调某些 z 值级别。但我想用 x 和 y 值来做到这一点。即,以不同颜色或其他线宽绘制具有相同 x(或 y)值的所有 (x,y,z) 线。如果可能的话,我不想从数据中提取值并绘制新曲线,尤其是精确的 x 和 y 值可能不在数据中。
多谢。
更新:来源和图片
我通过管道从 C++ 程序控制 gnuplot。以下是相应的控制命令:
fprintf (gnuplotPipe, "set terminal windows\n");
fprintf (gnuplotPipe, "set hidden3d\n");
fprintf (gnuplotPipe, "set title '3D Surface'\n");
fprintf (gnuplotPipe, "set zrange [0:100]\n");
fprintf (gnuplotPipe, "set xyplane at 0\n");
fprintf (gnuplotPipe, "unset key\n"); // hide the key
fprintf (gnuplotPipe, "splot '-' nonuniform matrix using 1:2:3 with lines\n");
fprintf (gnuplotPipe, "\n");
之后我发送这个数组,它是一个 gnuplot 非统一矩阵:
constexpr int32_t surface [y_size + 1][x_size + 1] = {
{ 20, 0, 216, 431, 647, 862, 1078, 1293, 1509, 1724, 1940, 2155, 2371, 2586, 2802, 3017, 3233, 3448, 3664, 3879, 4095},
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
{ 0, 89, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89},
{ 216, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89},
{ 431, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89},
{ 647, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89, 88, 88, 88, 87, 87, 87, 87, 86, 86, 87},
{ 862, 90, 90, 90, 90, 90, 89, 89, 88, 88, 87, 86, 85, 85, 84, 84, 83, 83, 82, 82, 82},
{1078, 90, 90, 90, 90, 89, 89, 88, 87, 86, 84, 83, 81, 80, 79, 78, 77, 76, 76, 76, 76},
{1293, 90, 90, 90, 90, 89, 88, 87, 85, 83, 81, 79, 76, 74, 72, 70, 68, 67, 67, 67, 67},
{1509, 90, 90, 89, 89, 88, 87, 85, 83, 81, 77, 74, 70, 66, 63, 61, 59, 58, 58, 59, 60},
{1724, 90, 90, 90, 89, 88, 86, 84, 82, 78, 74, 70, 65, 60, 56, 51, 47, 45, 47, 50, 54},
{1940, 89, 89, 89, 89, 87, 86, 83, 80, 76, 71, 66, 61, 56, 49, 38, 17, 24, 39, 47, 52},
{2155, 89, 89, 89, 89, 87, 85, 83, 79, 75, 70, 65, 60, 55, 48, 41, 38, 42, 48, 52, 56},
{2371, 89, 89, 89, 88, 87, 85, 82, 79, 74, 70, 65, 60, 56, 53, 51, 51, 53, 56, 58, 61},
{2586, 89, 89, 89, 88, 87, 85, 82, 79, 75, 70, 66, 63, 60, 58, 58, 58, 59, 61, 63, 65},
{2802, 89, 89, 89, 88, 86, 84, 82, 79, 75, 71, 68, 65, 63, 62, 62, 63, 64, 65, 67, 68},
{3017, 89, 89, 89, 88, 86, 84, 82, 79, 76, 73, 70, 68, 67, 66, 66, 67, 68, 69, 70, 72},
{3233, 89, 89, 89, 88, 86, 84, 82, 80, 77, 74, 72, 70, 69, 69, 69, 70, 71, 72, 73, 74},
{3448, 89, 89, 89, 88, 86, 85, 83, 80, 78, 76, 74, 73, 72, 72, 72, 73, 74, 74, 76, 76},
{3664, 89, 89, 88, 88, 86, 85, 83, 81, 79, 77, 75, 75, 74, 74, 74, 75, 76, 77, 77, 78},
{3879, 89, 89, 89, 88, 86, 85, 83, 81, 80, 78, 77, 76, 76, 76, 76, 77, 78, 78, 79, 80},
{4095, 89, 89, 88, 88, 86, 85, 83, 82, 80, 79, 78, 78, 78, 78, 78, 78, 79, 80, 80, 81},
};
我得到了这张照片:
我想在表面上画一条 x = 2000 的线和一条 y = 2000 的线。对于这两条线,数组中都没有值。
这是我想到的三个gnuplot建议。也许有更聪明、更简单的方法可以在 gnuplot 中实现这一点。要测试前两个变体,只需交换最后一个脚本中用
#-------
括起来的部分即可。仅用于说明目的,拍摄了xm=2700
和ym=2250
。
数据:
SO78220177.dat
20, 0, 216, 431, 647, 862, 1078, 1293, 1509, 1724, 1940, 2155, 2371, 2586, 2802, 3017, 3233, 3448, 3664, 3879, 4095
0, 89, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89
216, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89
431, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89
647, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89, 88, 88, 88, 87, 87, 87, 87, 86, 86, 87
862, 90, 90, 90, 90, 90, 89, 89, 88, 88, 87, 86, 85, 85, 84, 84, 83, 83, 82, 82, 82
1078, 90, 90, 90, 90, 89, 89, 88, 87, 86, 84, 83, 81, 80, 79, 78, 77, 76, 76, 76, 76
1293, 90, 90, 90, 90, 89, 88, 87, 85, 83, 81, 79, 76, 74, 72, 70, 68, 67, 67, 67, 67
1509, 90, 90, 89, 89, 88, 87, 85, 83, 81, 77, 74, 70, 66, 63, 61, 59, 58, 58, 59, 60
1724, 90, 90, 90, 89, 88, 86, 84, 82, 78, 74, 70, 65, 60, 56, 51, 47, 45, 47, 50, 54
1940, 89, 89, 89, 89, 87, 86, 83, 80, 76, 71, 66, 61, 56, 49, 38, 17, 24, 39, 47, 52
2155, 89, 89, 89, 89, 87, 85, 83, 79, 75, 70, 65, 60, 55, 48, 41, 38, 42, 48, 52, 56
2371, 89, 89, 89, 88, 87, 85, 82, 79, 74, 70, 65, 60, 56, 53, 51, 51, 53, 56, 58, 61
2586, 89, 89, 89, 88, 87, 85, 82, 79, 75, 70, 66, 63, 60, 58, 58, 58, 59, 61, 63, 65
2802, 89, 89, 89, 88, 86, 84, 82, 79, 75, 71, 68, 65, 63, 62, 62, 63, 64, 65, 67, 68
3017, 89, 89, 89, 88, 86, 84, 82, 79, 76, 73, 70, 68, 67, 66, 66, 67, 68, 69, 70, 72
3233, 89, 89, 89, 88, 86, 84, 82, 80, 77, 74, 72, 70, 69, 69, 69, 70, 71, 72, 73, 74
3448, 89, 89, 89, 88, 86, 85, 83, 80, 78, 76, 74, 73, 72, 72, 72, 73, 74, 74, 76, 76
3664, 89, 89, 88, 88, 86, 85, 83, 81, 79, 77, 75, 75, 74, 74, 74, 75, 76, 77, 77, 78
3879, 89, 89, 89, 88, 86, 85, 83, 81, 80, 78, 77, 76, 76, 76, 76, 77, 78, 78, 79, 80
4095, 89, 89, 88, 88, 86, 85, 83, 82, 80, 79, 78, 78, 78, 78, 78, 78, 79, 80, 80, 81
#-------
set title "closest lines"
dxmin = dymin = NaN
stats FILE matrix every :::0::0 u (dx=abs($3-xm), dxmin!=dxmin || dx<dxmin ? (dxmin=dx,col=$1-1) : 0) nooutput
stats FILE matrix every ::0::0 u (dy=abs($3-ym), dymin!=dymin || dy<dymin ? (dymin=dy,row=$2-1) : 0) nooutput
splot FILE nonuniform matrix using 1:2:3 w lines, \
'' nonuniform matrix every ::col::col u 1:2:3 w l lw 3 lc "red", \
'' nonuniform matrix every :::row::row u 1:2:3 w l lw 3 lc "blue"
#-------
结果:
set hidden3d
,这些线条从顶部和底部部分可见(就像缝合的线)。这可能是因为数字四舍五入的缘故。#-------
set title "linear interpolated lines"
stats FILE matrix u (N=$1, M=$2) nooutput # get MxN matrix size: M=rows, N=cols,
array X[N]
array Y[M]
x1 = y1 = NaN
stats FILE matrix every ::1:0::0 u (X[$1]=$3, x0=x1, x1=$3, sgn(x0-xm) != sgn(x1-xm) ? (x0m=x0,x1m=x1,col=$1-1) : 0) nooutput
stats FILE matrix every ::0:1:0 u (Y[$2]=$3, y0=y1, y1=$3, sgn(y0-ym) != sgn(y1-ym) ? (y0m=y0,y1m=y1,row=$2-1) : 0) nooutput
yzi(col) = (column(col+1)-column(col))*(x1m-x0m)/(xm-x0m) + column(col)
array XZ[2*N]
stats FILE matrix every ::1:row::row+1 u (XZ[($2-row)*N + $1]=$3) nooutput
do for [i=1:N] { XZ[i] = (XZ[i+N] - XZ[i])/(y1m-y0m)*(ym-y0m) + XZ[i] }
splot FILE nonuniform matrix u 1:2:3 w lines, \
'' every ::1 u (xm):1:(yzi(col)) w l lw 3 lc "red", \
XZ every ::::M-1 u (Y[$0+1]):(ym):2 w l lw 3 lc "blue"
#-------
结果:
脚本:
### highlight/insert line at constant x or/and y
reset session
FILE = "SO78220177.dat"
set hidden3d
set zrange [0:100]
set xyplane at 0
set xtics 1000
set ytics 1000
set grid x,y
set view 45,60
unset key
xm = 2700
ym = 2250
#-------
set title "linear interpolated and inserted lines"
stats FILE matrix u (N=$1, M=$2) nooutput # get MxN matrix size: M=rows, N=cols,
array X[N]
array Y[M]
x1 = y1 = NaN
stats FILE matrix every ::1:0::0 u (X[$1]=$3, x0=x1, x1=$3, sgn(x0-xm) != sgn(x1-xm) ? (x0m=x0,x1m=x1,col=$1) : 0) nooutput
stats FILE matrix every ::0:1:0 u (Y[$2]=$3, y0=y1, y1=$3, sgn(y0-ym) != sgn(y1-ym) ? (y0m=y0,y1m=y1,row=$2) : 0) nooutput
array XYZ[(M+2)*(N+2)]
i = 0
stats FILE matrix u (i=i+1, $1==col?i=i+1:0, $2==row && $1==0 ? i=i+N+2:0, XYZ[i]=$3) nooutput
XYZ[col+1] = xm
XYZ[row*(N+2)+1] = ym
do for [m=1:M+1] {
XYZ[m*(N+2)+col+1] = (x0=XYZ[m*(N+2)+col], m==row ? 0 : (XYZ[m*(N+2)+col+2] - x0)/(x1m-x0m)*(xm-x0m) + x0)
}
do for [n=1:N+1] {
XYZ[row*(N+2)+n+1] = (y0=XYZ[(row-1)*(N+2)+n+1], (XYZ[(row+1)*(N+2)+n+1] - y0)/(y1m-y0m)*(ym-y0m) + y0)
}
set print $MatrixNew
do for [m=0:M+1] {
line = ''
do for [n=0:N+1] {
line = line.sprintf(" %g",XYZ[m*(N+2)+n+1])
}
print line
}
set print
splot $MatrixNew nonuniform matrix u 1:2:3 w lines, \
'' nonuniform matrix every ::col-1::col-1 u 1:2:3 w l lw 3 lc "red", \
'' nonuniform matrix every :::row-1::row-1 u 1:2:3 w l lw 3 lc "blue"
#-------
### end of script
结果: