Gnuplot заполнил кривые палитрой

Я пытался изменить стиль заливки для параметра fillcurves в gnuplot, чтобы цвет заливки представлял разницу между двумя кривыми на двухмерном графике. Я думаю об этом как о расширении опции «заполненные кривые сверху / снизу», где вместо двух цветов, представляющих сверху или снизу, есть цветовой диапазон или палитра.

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

http://i.stack.imgur.com/RLlpU.png

Я попытался сделать это, добавив четвертый столбец к команде using, т.е.

plot 'data.txt' using 1:2:3:($3-$2) with filledcurves fs palette

но filledcurves, похоже, не принимает четвертый столбец ... Я также подумал о том, чтобы попробовать переменную rgb, но это тоже не работает.


person atstack    schedule 22.11.2012    source источник
comment
Похоже, это задание на запрос функции (sourceforge.net/tracker/?group_id=2055&atid= 352055); Я не думаю, что gnuplot изначально может делать то, что вы хотите. Пока это не будет реализовано, вы можете подумать о том, чтобы просто нарисовать разницу между спектрами горячего и холодного состояний в виде отдельной линии на вашем графике. (Это может лучше воспроизводиться в печати и быть немного более понятным для дальтоников.)   -  person andyras    schedule 22.11.2012
comment
Я не думал об этом достаточно, но вы могли бы достичь чего-то подобного с помощью комбинации set view map, splot и _3 _...   -  person mgilson    schedule 23.11.2012
comment
Похоже, это то, что вы ищете. gnuplot-tricks.blogspot.com/2009/08/   -  person Sunhwan Jo    schedule 11.12.2012


Ответы (6)


Я играю с патчем для gnuplot, позволяющим использовать linecolor rgb variable для закрашенных кривых. Тогда можно использовать следующий код gnuplot:

max_color=1
# for a datafile one could extract the maximum diffference with e.g.
# stats 'hotcold.dat' using 1:($3-$2)
# max_color = (abs(STATS_min_y) > abs(STATS_max_y)) ? abs(STATS_min_y) : abs(STATS_max_y)

red(val) = (val < 0 ? abs(1+val/max_color) : 1)
green(val) = (1 - abs(val)/max_color)
blue(val) = red(-val)
rgb(val) = 65536*int(255*red(val)) + 256*int(255*green(val)) + int(255*blue(val))

set yrange[0:1]
set xrange[400:2500]
set samples 200

fhot(x) = 0.1*exp(-((x-400)/200)**2) + 0.8*exp(-((x-2000)/300)**2)
fcold(x) = 0.25*exp(-((x-700)/100)**6)+ 0.4 - (2e-4*(x-2500))**2
plot '+' using 1:(fhot($1)):(fcold($1)):(rgb(fhot($1)-fcold($1))) with filledcurves lc rgb var t '',\
     '' using 1:(fhot($1)) with lines lw 4 lc rgb rgb(max_color) t 'Hot',\
     '' using 1:(fcold($1)) with lines lw 4 lc rgb rgb(-max_color) t 'Cold'

Это дает следующий результат: введите описание изображения здесь

Я еще не отправил патч, потому что не знаю, правильно ли я понял вопрос и не знаю, рассмотрел ли я все случаи. Так что может потребоваться некоторая тонкая настройка.

person Christoph    schedule 06.08.2013
comment
Так как продвигается этот патч? Вы его куда-то загрузили? Это можно использовать? - person rgcalsaverini; 09.12.2013
comment
@rgcalsaverini Нет, не загружал. Я написал это для удовольствия, но поскольку мне не нужна такая графика, я не знал, был ли это правильный подход, если я что-то упустил ... И так как я никогда не получал отзывов об этом, я остановился на первой элементарной реализации. - person Christoph; 09.12.2013
comment
Хороший патч! Это решение заслуживает, по крайней мере, столько же голосов, сколько и вопрос! ;) - person John_West; 04.02.2016
comment
@John_West К сожалению, я больше не могу найти патч :( - person Christoph; 04.02.2016
comment
@Christoph, поскольку ваш патч утерян и иначе он не закодирован (не было бы самым простым решением разрешить column ссылку в rgb значении?), Я предлагаю почти такой же грязный способ сделать это. - person Joce; 25.09.2020

Попробуйте использовать заполненные гистограммы.

set style fill solid 1.0
plot \
 datafile u 1:2:3 lt palette w boxes,\
 datafile u 1:2:3 lt palette lw 2 w l

Столбец 3 определяет цвет заливки цвета в соответствии с настройками палитры, столбцы 1 и 2 определяют точки данных. Вы также можете использовать гистограмму цвета фона для очистки частей под графиком.

Хочу добавить изображение, но не могу из-за низкой репутации.

person Luuuucky    schedule 04.07.2014

AFAIK, это все еще не реализовано в gnuplot. Однако вы можете сделать грязную (*) работу, наложив несколько прозрачных кривых с заливкой.

E.g.,

max_color=1
max_diff=0.5
N_col=6
TRSP="E0"
HOTCOL="FF0000"
COLDCOL="0000FF"
RGBA_HOT="#".TRSP.HOTCOL
RGBA_COLD="#".TRSP.COLDCOL
RGB_HOT="#".HOTCOL
RGB_COLD="#".COLDCOL
#red(val) = (val < 0 ? abs(1+val/max_color) : 1)
#green(val) = (1 - abs(val)/max_color)
#blue(val) = red(-val)
#rgb(val) = 65536*int(255*red(val)) + 256*int(255*green(val)) + int(255*blue(val))
fhot(x) = 0.1*exp(-((x-400)/200)**2) + 0.8*exp(-((x-2000)/300)**2)
fcold(x) = 0.25*exp(-((x-700)/100)**6)+ 0.4 - (2e-4*(x-2500))**2
plot [400:2600] for [thr=0:N_col] '+' using (((fhot($1)-fcold($1))/max_diff*N_col>thr)?$1:1/0):(fhot($1)):(fcold($1)) with filledcurves lc rgb RGBA_HOT title '',\
     for [thr=0:N_col] '+' using ((-(fhot($1)-fcold($1))/max_diff*N_col>thr)?$1:1/0):(fhot($1)):(fcold($1)) with filledcurves lc rgb RGBA_COLD title '',\
     '' using 1:(fhot($1)) with lines lw 4 lc rgb RGB_HOT t 'Hot',\
     '' using 1:(fcold($1)) with lines lw 4 lc rgb RGB_COLD t 'Cold'

Отрегулируйте N_col и TRSP, чтобы изменить градиент: количество наложенных кривых с заливкой и прозрачность каждой (большее количество кривых подразумевает близость к максимальной прозрачности FE).

введите описание изображения здесь

(*) Это менее грязно, если информация, которую вы хотите отобразить, является дискретной переменной, например. количество наборов данных, доступных по заданной оси абсцисс.

person Joce    schedule 25.09.2020

Еще один неудобный обходной путь: вместо filledcurves используйте толстые вертикальные векторные линии.

Это будет работать, когда у вас есть функции, как в примере, или данные на одинаковом расстоянии в x. Если у вас нет эквидистантных данных в x, вам придется интерполировать. К сожалению, в gnuplot нет функции интерполяции или передискретизации. Вы можете сделать это либо с помощью внешних инструментов, либо, тем не менее, с помощью gnuplot, который становится немного длиннее, см. Здесь: Передискретизация данных с помощью gnuplot

Чтобы получить красивый цветовой градиент, вам необходимо настроить размер графика / холста, выборку и / или ширину линии, чтобы найти оптимальное решение для устранения пробелов, выступов или наложения спектров. Слишком тонкий (lw 1) и слишком толстый (lw 8) не годятся. В приведенном ниже примере lw 3 кажется разумным значением. Может есть еще способы дальнейшей оптимизации.

В приведенном ниже примере используется код @ Christoph, слегка измененный.

Код:

max_color=1
# for a datafile one could extract the maximum diffference with e.g.
# stats 'hotcold.dat' using 1:($3-$2)
# max_color = (abs(STATS_min_y) > abs(STATS_max_y)) ? abs(STATS_min_y) : abs(STATS_max_y)

red(val) = (val < 0 ? abs(1+val/max_color) : 1)
green(val) = (1 - abs(val)/max_color)
blue(val) = red(-val)
rgb(val) = 65536*int(255*red(val)) + 256*int(255*green(val)) + int(255*blue(val))

set yrange[0:1]
set xrange[400:2500]
set samples 200

fhot(x) = 0.1*exp(-((x-400)/200)**2) + 0.8*exp(-((x-2000)/300)**2)
fcold(x) = 0.25*exp(-((x-700)/100)**6)+ 0.4 - (2e-4*(x-2500))**2

plot \
     '+' using 1:(fhot($1)):(0):(fcold($1)-fhot($1)):(rgb(fhot($1)-fcold($1))) with vectors nohead lw 3 lc rgb var t '',\
     '' using 1:(fhot($1)) with lines lw 4 lc rgb rgb(max_color) t 'Hot',\
     '' using 1:(fcold($1)) with lines lw 4 lc rgb rgb(-max_color) t 'Cold'
     

Результат: (wxt 640x480, lw 1)  введите описание изображения здесь

Результат: (wxt 640 x 480, lw 3)

введите описание изображения здесь

Результат: (wxt 640x480, lw 8)  введите описание изображения здесь

person theozh    schedule 25.09.2020

Еще одно решение

Если 2D-карта pm3d разрешена без заполненных кривых, то для этого можно использовать следующий код.

В части обработки данных данные сетки для splot строятся из исходных входных данных. Цвет области заливки определяется значением z, заданным для пятна.

set table $first
plot "test.dat" using 1:2:($3-$2) with table
set table $second
plot "test.dat" using 1:3:($3-$2) with table
unset table

set print $data
do for [i=1:|$first|] {
  print $first[i]
  print $second[i]
  print ""
}
set print

set yrange [-2:2]
set palette define (-1 "skyblue", 0 "gray90", 1 "pink")

splot $data using 1:2:3 with pm3d 
person binzo    schedule 25.10.2020

Уловка состоит в том, чтобы нарисовать линии, а затем заполнить их filledcurves. Вот как это сделать (на основе примеров в gnuplot):

set style line 2 lc rgb 'forest-green'
set style line 3 lc rgb 'plum'
set style fill pattern 5 lc 'yellow'
set xrange [0:3000]
set yrange [0:1]
plot 'data.txt' u 1:2:3 w filledcurves notitle, \
     '' u 1:2 ls 2 with lines notitle, \
     '' u 1:3 ls 3 with lines notitle

Результат выглядит так: введите описание изображения здесь

Файл данных содержит эти фиктивные значения (которые напоминают ваш второй график):

500     0.90    0.90
1000    0.90    0.75
1500    0.92    0.40
2000    0.95    0.30
2500    0.94    0.23
person Yehia    schedule 23.04.2013