У меня есть 3D-поверхность с помощью команды
постройте неравномерную матрицу '-', используя 1:2:3 с палитрой линий
Я знаю, что могу подчеркнуть определенные уровни значений z с помощью контура. Но я хочу сделать это со значениями x и y. Т.е. у вас есть линия всех (x,y,z) с одинаковым значением x (или y-), нанесенная другим цветом или другой шириной линии. Если это возможно, я не хочу извлекать значения из данных и строить новую кривую, особенно точное значение x и y может отсутствовать в данных.
Большое спасибо.
Обновление: источник и изображение
Я управляю gnuplot из программы на C++ через канал. Вот соответствующие команды управления:
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. Для обоих в массиве нет значений.
как уже упоминал Шелтер, дайте минимальный набор данных и иллюстративный график. Ваши данные представлены в неоднородной сетке или вообще не имеют сетки? Итак, вы говорите об интерполяции желаемых значений x или y?
Я обновил вопрос примером
Вот три предложения только по 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
Результат:
Большое спасибо за этот очень обширный ответ. Это очень ясно и полностью отвечает моим потребностям.
Читайте о минимальном воспроизводимом примере. Я рекомендую вам включить наименьший набор данных, которые читатели смогут использовать для иллюстрации вашей проблемы. Удачи.