gnuplot 3D:如何沿着恒定的 x(或 y)值线强调 z 值?

问题描述 投票:0回答:1

我使用命令有一个 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
1个回答
0
投票

这是我想到的三个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
  1. 取最近的 x 和 y 线。这是最简单的,但很可能不是您想要的。
#-------
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"
#-------

结果:

  1. 在两条相邻的 x 和 y 线之间进行线性插值。然而,这显然会产生一些意想不到的输出。由于
    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"
#-------

结果:

  1. 在两条相邻的 x 和 y 线之间进行线性插值,但将这些值插入到新矩阵中。这会产生最大的努力,但可能是您感兴趣的结果。

脚本:

### 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

结果:

© www.soinside.com 2019 - 2024. All rights reserved.