Gnuplot 3D: Как подчеркнуть значения z вдоль линии постоянного значения x (или y)?

У меня есть 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. Для обоих в массиве нет значений.

Читайте о минимальном воспроизводимом примере. Я рекомендую вам включить наименьший набор данных, которые читатели смогут использовать для иллюстрации вашей проблемы. Удачи.

shellter 25.03.2024 16:58

как уже упоминал Шелтер, дайте минимальный набор данных и иллюстративный график. Ваши данные представлены в неоднородной сетке или вообще не имеют сетки? Итак, вы говорите об интерполяции желаемых значений x или y?

theozh 25.03.2024 20:17

Я обновил вопрос примером

Martin_from_K 26.03.2024 10:42
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот три предложения только по 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

Результат:

Большое спасибо за этот очень обширный ответ. Это очень ясно и полностью отвечает моим потребностям.

Martin_from_K 19.04.2024 08:30

Другие вопросы по теме