гнуплот
12 коммент.
В этом блоге публикуются заметки и решения, найденные в процессе работы, освоения и жизни в дистрибутиве Debian GNU/Linux.
Как всегда, беда пришла, и её совсем не ждали. Организаторы конференции SPIE, в которой я заядлый участник, что-то там поменяли в своей системе приёма PDFников статей. Теперь система Numbus Roman не переваривает, и заменяет его чудовищным Courier. Вопрос о внедрении английских шрифтов в графики, созданные gnuplot, встал в полный рост. Летопись героической победы приложенных титанических усилий прилагается.
# X Y dX dY
1.0 1.2 0.8 1.5
2.0 1.8 0.3 2.3
3.0 1.6 1.0 2.1
gnuplot> plot "test.dat" using 1:2:3 with yerrorbarsОбщая идея, думаю, понятна: сначала указываются колонки, содержащие данные, а потом колонки, содержащие значения погрешностей. Таблица, любезно утянутая отсюда, даёт прекрасную иллюстрацию:
| Data Format | Column | using | with |
|---|---|---|---|
| (X,Y) data | X Y | 1:2 | lines, points, steps, linespoints, boxes, etc. |
| Y has an error of dY | X Y dY | 1:2:3 | yerrorbars |
| X has an error of dX | X Y dX | 1:2:3 | xerrorbars |
| Y has an error of dY, and X has an error of dX | X Y dX dY | 1:2:3:4 | xyerrorbars |
| Y has a range of [Y1,Y2] | X Y Y1 Y2 | 1:2:3:4 | yerrorbars |
| X has a range of [X1,X2] | X Y X1 X2 | 1:2:3:4 | xerrorbars |
| Y has a range of [Y1,Y2], and X has a range of [X1,X2] | X Y X1 X2 Y1 Y2 | 1:2:3:4:5:6 | xyerrorbars |
16 18 0.72 10 whiteLEDS 1 10
12 30 0.61 12 greenUltraBrightLEDS 1 10
8 200 0.45 20 HGlamp 1 15
6 1600 0.35 35 AlGaAsLser 1 50
4 17000 0.28 68 NdYAG-laser 1 900
4 25000 0.27 70 HeNeLaser 1 1100
Нужно построить зависимость первой колонки от второй, при этом погрешности по оси X составляют 7% от данных, а по оси Y указаны в колонке 7. Вот такой при этом получается код для gnuplot:
Что в этом коде (и графике) есть примечательного, заставившего меня таки покопаться в мануале?| every I:J:K:L:M:N |
| ||||||||||||
| every 2 | plot every 2 line | ||||||||||||
| every ::3 | plot from the 3-rd lines | ||||||||||||
| every ::3::5 | plot from the 3-rd to 5-th lines | ||||||||||||
| every ::0::0 | plot the first line only | ||||||||||||
| every 2::::6 | plot the 1,3,5,7-th lines | ||||||||||||
| every :2 | plot every 2 data block | ||||||||||||
| every :::5::8 | plot from 5-th to 8-th data blocks |

gnuplot> set terminal postscript enhancedНадстрочные символы пишутся как X^2, подстрочные Y_3. Если необходимо написать так несколько символов, следует использвать фигурные скобки: Z_{64}. При одновременном надстрочном и подстрочном индексе используйте Z@^2_{64}.
gnuplot> set terminal postscript eps enhanced
gnuplot> set key spacing 1.3
gnuplot> set xrange [ 0 : pi ]
gnuplot> set yrange [ 0 : 1.5 ]
gnuplot> plot sin(x)**2 ti "sin^2(x)", \
sin(x)**3 ti "sin^3(x)",\
sqrt(sin(x)) ti "sin^{1/2}(x)"

gnuplot> set terminal postscript enhancedГреческие символы пишутся в виде {/Symbol a} - это, например, для буквы "альфа". Другие буквы можно найти в таблице:
| Буква | Символ | Буква | Символ | Буква | Символ | Буква | Символ |
|---|---|---|---|---|---|---|---|
| A | Alpha | N | Nu | a | alpha | n | nu |
| B | Beta | O | Omicron | b | beta | o | omicron |
| C | Chi | P | Pi | c | chi | p | pi |
| D | Delta | Q | Theta | d | delta | q | theta |
| E | Epsilon | R | Rho | e | epsilon | r | rho |
| F | Phi | S | Sigma | f | phi | s | sigma |
| G | Gamma | T | Tau | g | gamma | t | tau |
| H | Eta | U | Upsilon | h | eta | u | upsilon |
| I | iota | W | Omega | i | iota | w | omega |
| K | Kappa | X | Xi | k | kappa | x | xi |
| L | Lambda | Y | Psi | l | lambda | y | psi |
| M | Mu | Z | Zeta | m | mu | z | zeta |
Так же можно использовать различные postscript-символы в их восьмеричном коде, например {/243} это символ фунта-стерлинга.
Следующий пример иллюстрирует построение линейной функции y=Alpha x+ Gamma при использовании двух греческих букв.
gnuplot> set terminal postscript eps enhanced
gnuplot> set xrange [ 0 : 5 ]
gnuplot> set label "{/Symbol a}=0.5, {/Symbol g}=0.2" at 2,0
gnuplot> plot 0.5*x-0.2 ti "y={/Symbol a}x-{/Symbol g}"
Как использовать в текстах подписей другие символы (проценты, копирайты)?
Выше уже говорилось о том, что можно использовать специальные postscript-символы, и это совсем не трудно. Для этого следует установить пакет gnuplot-doc и после этого обратиться к файлу ps_guide.ps - там перечислены все коды символов PostScript. Чтобы на одной из осей, к примеру, поставить знак процента в подписи, следует использовать команду:
gnuplot> set xlabel "Halftones, {/Symbol \\045} of grey"
То есть в подписи по оси X будет стоять: Halftones, 45% of grey
Как изменить расстояние между осями и подписью к ним?
Интервал можно изменить при помощи команд set {x|y}label
Например, это:
gnuplot> set xlabel "x" 0.0,1.0смещает ось Х на высоту одной буквы вверх. Если задать положительное смещение по Y, подпись оси X налезает на содержимое графика, как показано на рисунках ниже.

Y offset = 0
Y offset = +5
Y offset = -5
если смещение по Y отрицательное, расстояние между подписью оси X и графиком становится больше.
Gnuplot пытается нарисовать график таким большим, насколько это возможно, так что высота графика становится больше, когда подпись оси Х смещается вверх. И наоборот, график становится меньше, когда подпись к оси Х смещается вниз.
gnuplot> set multiplotВот что при этом может произойти:
multiplot> plot x
multiplot> plot x*x
multiplot> plot x*x*x
multiplot> set nomultiplot

gnuplot> set xrange [-10:10]
gnuplot> set yrange [-10:10]

Это не должно вызывать вопросов - подобное разбиралось тут. Дальше:#! /usr/bin/gnuplot -persist
set terminal postscript eps enhanced color solid
set output "~/matlab/programs/kmvdecoder/plots/2conventionalRAWMAXtoSaturatecomparing.ps"
set encoding koi8r
set xlabel "Exposure time, sec." font "Helvetica,18"
set xrange [1:60]
set key top right
set ylabel "Pixels maximum value" font "Helvetica,18"
Устанавливаем стиль линий, которыми будем строить графикиset multiplot
set origin 0.0,0.0
set size 1.0,1.0
Теперь, собственно, строим основной график.set style line 1 lt 1 pt 9
set style line 2 lt 3 pt 7
set style line 3 lt 2 pt 5
Пути и имена файлов, естественно, нужно поменять, так как я даю всё на примере собственных файлов. Напоминаю, что для ленивых людей, помимо гнуплота, есть ещё и Perl, скрипты которого резво подставят всё нужное в имя файла: и вы поймёте, и цикл перебора организовать проще. Основной график построен - загружаем его в программу просмотра PostScript-файлов и смотрим, где значения, которые нужно строить внутри маленького графика.plot "~/matlab/programs/kmvdecoder/plots/RAWMAXmeasurementresult"
using 3 notitle with linespoints linestyle 2,
"~/matlab/programs/kmvdecoder/plots/RAWMAXmeasurementresult" using 3 n
Первый параметр задаёт положение левой верхней границы маленького графика в относительных единицах длины. Второй - размер графика. Так как подписи к осям на вложенном графике будут только мешать - отключаем их:set origin 0.55,0.1
set size 0.4,0.4
С видом графика определились, теперь определяемся с осями:set noxlabel
set noylabel
Всё, теперь осталось приказать гнуплоту перестроить график (чтобы появился вложенный):set xrange [ 30 : 38]
set yrange [ 3300 : 3800 ]
Готово - качественный график быстро и легко построен. Вот как он выглядит:replot
set nomultiplot

gnuplot> set term postscript eps enhanced colorВот что при этом получится:
gnuplot> set style line 1 lt 1 lw 50
gnuplot> plot "test.dat" using 1:2 with imp ls 1

gnuplot> plot "test.dat" usi 1:2:(3) w boxes fs pattern 1,\
gnuplot> "test.dat" usi ($1+5):2:(3) w boxes fs solid 0.7


gnuplot> set log xyДля данных в диапазоне [1:30] используем линейные оси, и поместим второй график за первым, используя возможности multiplot. Таким образом, логарифмическая часть графика будет слева, а линейная - справа. Каждый подграфик займёт половину размера картинки. Вот как это выглядит в коде:
gnuplot> set xrange [ 0.001 : 1 ]
gnuplot> set yrange [ 0.1 : 5000 ]
gnuplot> set xlabel "Energy [eV]"
gnuplot> set multiplotРезультат смотрится очень эффектно:
multiplot> set size 0.5,1
multiplot> set origin 0.0,0.0
multiplot> set lmargin 10
multiplot> set rmargin 0
multiplot> plot "calc.dat" u 1:2 w l
multiplot> set origin 0.5,0.0
multiplot> set format y ""
multiplot> set lmargin 0
multiplot> set rmargin 2
multiplot> set nolog x
multiplot> set xrange [1:30]
multiplot> set xtic 0,10
multiplot> set mxtic 5
multiplot> plot "calc.dat" u 1:2 w l
multiplot> set nomultiplot
gnuplot>

gnuplot> set xrange [ 0.01 : 30 ]Теперь создаём нижнюю часть графика, которая показывает соотношение данных. Так как данные по оси Y находятся во втором и третьем столбце файла с данными, можно построить их соотношение так plot 1:($2/$3). Таким образом, вторая часть выглядит так:
gnuplot> set nokey
gnuplot> set log x
gnuplot> set xtics 10
gnuplot> set mxtics 10
gnuplot> set lmargin 10
gnuplot> set rmargin 2
gnuplot> set multiplotОсталось доделать верхнюю часть, чем сейчас и займёмся. Сделаем размер графика поменьше и отобразим в логарифмических осях. Наименования по оси Х стираем, и вот что получилось:
multiplot> set yrange [ 0.5 : 1.5 ]
multiplot> set ytic 0.6,0.2,1.4
multiplot> set ylabel "Ratio"
multiplot> set size 1,0.4
multiplot> set xlabel "Energy [eV]"
multiplot> set origin 0.0,0.0
multiplot> set bmargin 3
multiplot> set tmargin 0
multiplot> plot 1 w l 0,"cross.dat" u 1:($2/$3) w l 1
multiplot> set log xyРезультат:
multiplot> set yrange [ 0.1 : 5000 ]
multiplot> set ytic 0.1,10
multiplot> set ylabel "Cross Section [b]"
multiplot> set size 1,0.6
multiplot> set origin 0.0,0.4
multiplot> set bmargin 0
multiplot> set tmargin 1
multiplot> set format x ""
multiplot> set xlabel ""
multiplot> plot "cross.dat" u 1:2 w l,"" u 1:3 w l
multiplot> set nomultiplot
gnuplot>

gnuplot> set xtics 2
gnuplot> set ytics 0,200
gnuplot> plot x**3

gnuplot> set ytics 0,200,600.Дополнительные деления задаются параметром set m{x|y}tics. Интервалы между основными засечками делений делятся на это значение:
gnuplot> set mxtics 2
gnuplot> set mytics 2

gnuplot> set xtics ("April" 1, "May" 2, "June" 3, "July" 4)
gnuplot> plot "test.dat" using 1:2:3 notitle with boxes,\
"test.dat" using 1:2 notitle with lines

gnuplot> set tics out
gnuplot> set format x "10^{%g}"Теперь по оси Х деления станут вида 10^0, 10^1... и так далее.

gnuplot> set format y "10^{%L}"Для корректного отображения надстрочных и подстрочных индексов следует использовать расширенный postscript-терминал, добавив в скрипт построения графиков:
gnuplot> set terminal postscript eps enhancedВот что получится:

gnuplot> set format x ""деления по оси Х отображаться не будут.
gnuplot> set logscale yТёмно-красным выделен небольшой хак, который позволяет выводить деления как "число умноженное на 10^n".
gnuplot> set yrange [1:50]
gnuplot> set ytics (1,2,5,10,20,50)
gnuplot> set format y "%2.0t{/Symbol \327}10^{%L}"
gnuplot> set lmargin 8
gnuplot> set terminal postscript eps enhanced
gnuplot> plot exp(x)/x

set format имяоси{x|y|z|xy|x2|y2} "формат строки"Например, чтобы гнуплот показывал деления в как десять цифр и три после запятой, нужно дать команду:
gnuplot> set format x "%10.3f"Синтаксис для цифро такой: "%" + (полная длина).(точность).
| Пример (подчёркивание означает пробел) | |||
|---|---|---|---|
| f | десятичны | %6.3f | __6.00 |
| e,E | экспоненциальный | %11.4e | _5.0000e+01 |
| x,X | шестнадцатеричный | %x | fffffffb |
| o,O | восьмеричный | %o | 37777766 |
gnuplot> set format y "%T %t %g"
gnuplot> plot exp(-x)+exp(x)

gnuplot> set logscale y
gnuplot> replot

1.6593991e+00 1.6523134e+00 1.6407763e+00Нужно построить цветной график, с подписями на осях по-английски, шрифт Helvetica. Вот что у меня получилось:
1.8986703e+00 1.8667678e+00 1.8595763e+00
2.6304331e+00 2.5340401e+00 2.4999678e+00
4.2843754e+00 4.0227936e+00 4.0423230e+00
7.6136102e+00 7.0438436e+00 7.1057056e+00
#! /usr/bin/gnuplot -persist
set terminal postscript eps enhanced color solid
set output "~/matlab/programs/kmvdecoder/plots/1NoiseRAWSTDtoISOnoisecomparing.ps"
set xlabel "ISO number" font "Helvetica,18"
set bmargin 4
set ylabel "Pixels standard deviation" font "Helvetica,18"
set yrange [0:50]
set key top left
set xtics ("100" 0,"200" 1,"400" 2,"800" 3,"1600" 4)
set style line 1 lt 1 pt 9
set style line 2 lt 3 pt 7
set style line 3 lt 2 pt 5
plot "~/matlab/programs/kmvdecoder/plots/RAWSTDmeasurementresult" using 1 title "RAW data, Red channel" with linespoints linestyle 1,"~/matlab/programs/kmvdecoder/plots/RAWSTDmeasurementresult" using 2 title "RAW data, Green channel" with linespoints linestyle 3,"~/matlab/programs/kmvdecoder/plots/RAWSTDmeasurementresult" using 3 title "RAW data, Blue channel" with linespoints linestyle 2
Вот, кстати, почему и зачем у меня появился в своё время пост о вертикальной конкатенации: мне нужно было добавить в файл данных ещё один ряд, полученный при других измерениях. После этого можно скармливать новый файл данных гнуплоту и он будет воспринимать это как новый ряд.Ничего демонического, как видите, в гнуплоте нет. А вот и результат наших стараний:

Следует отметить, что, вопреки распространённому заблуждению, gnuplot выдаёт графики с publication-ready качеством, которые без вопросов принимаются в любом зарубежном (и уж тем более местном) научном журнале. Например, NASA с помощью gnuplot создаёт карты погоды, а некоторые математические системы (типа MATLAB) просто используют куски кода gnuplot чтобы отрисовывать графики. Так что график, который выдаст гнуплот, в любом случае на порядок краше того, на что способен ексель или Openoffice.org Calc.
gnuplot> set nokeyили можно указать параметр notitle при построении графика, например так:
gnuplot> plot f(x) notitle, "file.dat" title "data"После этого в графике легенда отображаться не будет.
gnuplot> set key bottom left
gnuplot> set key bottom right
gnuplot> set key top left
gnuplot> set key top right
Здесь перечислены варианты, позволяющие отрисовывать легенду в левом нижнем, правом нижнем, левом верхнем и правом верхнем углу графика соответственно. Так же можно попросить gnuplot рисовать легенду за пределами графика - для этого следует добавить параметр outside, или под графиком - для этого есть параметр bottom. Например:
gnuplot> set key outside bottom
Так же можно задать положение легенды с помощью координат, хотя это менее гибкий способ. Если хотите сдвинуть легенду в положение (X,Y)=(100,100), даём команду:
gnuplot> set key 100,100
Координата (100,100) это позиция точки между текстом и линией/символом первой линии легенды. Координаты задаются по осям X и Y.
Как избавиться от отображения погрешностей в легенде?
Когда один из рядов данных имеет погрешности, они тоже отображаются в легенде (например, на рисунке ниже). Даже тогда, когда погрешности по оси Y, они отображаются в легенде горизонтально, и это не нужно.
# X Y Y-погрешность
1.0 1.2 0.2
2.0 1.8 0.3
3.0 1.6 0.2
Строим график:
gnuplot> set xrange [0:4]
gnuplot> set yrange [0:3]
gnuplot> plot "test.dat" usi 1:2:3 title "data" w yerrorbars

gnuplot> set xrange [0:4]Но работает хорошо.
gnuplot> set yrange [0:3]
gnuplot> plot "test.dat" usi 1:2:3 notitle w yerrorbars 1,\
"test.dat" usi 1:2 title "data" w points 1

gnuplot> set key spacing 1.5Это увеличит расстояние между строками в легенде.
gnuplot> set style line 1 lt 2 lw 3Таким образом, вокруг легенды появится рамка.
gnuplot> set key box linestyle 1
#apt-get install gnuplotЕсли его теперь запустить, вызвав в консольке
$gnuplotто он нас поприветствует примерно таким образом:
G N U P L O TТо есть запустилась интерактивная часть программы. Здесь нам предлагают набирать команды и сразу видеть их результат - что не очень удобно, особенно если вы в первый раз работаете с gnuplot.
Version 4.0 patchlevel 0
last modified Thu Apr 15 14:44:22 CEST 2004
System: Linux 2.6.15.7
Copyright (C) 1986 - 1993, 1998, 2004
Thomas Williams, Colin Kelley and many others
This is gnuplot version 4.0. Please refer to the documentation
for command syntax changes. The old syntax will be accepted
throughout the 4.0 series, but all save files use the new syntax.
Type `help` to access the on-line reference manual.
The gnuplot FAQ is available from
http://www.gnuplot.info/faq/
Send comments and requests for help to
Send bugs, suggestions and mods to
Terminal type set to 'x11'
gnuplot>
#! /usr/bin/gnuplot -persistДалее выведем график в виде файла формата постскрипт (который можно скормить LaTeX)
set terminal postscript eps enhancedзадаётся имя выводимого файла с графиком, имя в кавычках
set output "~/RMSresearch.ps"Ставим поддержку кириллицы, а то не увидим в подписях
set encoding koi8rУстанавливаем метки по осям, размер и тип шрифта: сейчас по оси Х
set xlabel "Параметр регуляризациии {/Symbol a}, 10^{-n}" font "Helvetica,18"Устанавливаем метки по осям, размер и тип шрифта: теперь по оси Y
set ylabel "Величина СКО, отн.ед" font "Helvetica,18"Устанавливаем предел значений по оси Y
set yrange [0:1]Задаём стиль линии (line1): сплошная прямая(lt - от linetype) с круглыми точками (pt - от pointstyle) типа 7
set style line 1 lt 1 pt 7Теперь, задав все параметры, строим график, беря данные из файла RMSresult (для примера), где мы берём только второй столбец. Легенду для данных второго столбца называем СКО (среднеквадратичное отклонение) и заставляем строить график, используя тип линии, который мы задали.
plot "~/RMSresult" using 2 title "СКО" with linespoints linestyle 1
$ cat simple.graph | gnuplotВсё, должен появиться график RMSresearch.ps, который можно просмотреть любым графическим редактором. Выглядеть он должен примерно так:

Материалы сайта «Записки дебианщика» написаны virens’ом и доступны на условиях лицензии Creative Commons Attribution-Non-Commercial-Share Alike 3.0 Unported License. Вы можете копировать, распространять, показывать эту работу, и создавать производные работы в некоммерческих целях на условиях:
1) обязательной ссылки на автора (virens, http://mydebianblog.blogspot.com/);
2) распространении любых производных работ на условиях этой же лицензии (ссылка на эту лицензию обязательна!).
Пожалуйста соблюдайте условия лицензии Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Авторские права - Михаил Конник aka virens.