Построение графиков в gnuplot достаточно просто и очень эффективно, особенно когда их нужно строить много. Ниже на примерах будет показано, как строить двухмерные графики.
Как построить несколько функций на одном графике?
Есть два варианта: использовать функцию multiplot или внешними редакторами шаманить с EPS-файлами. Ниже будет описан первый вариант как более простой.
При построении нескольких графиков нужно включить режим multi-plot, после чего будет возможно размещать несколько функций или графиков данных в одном окне. Например, построим три функции: y=x, y=x*x и y=x*x*x. Что для этого дополнительно нужно задать в интерактивном режиме: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
Как построить простую гистограмму?
Если вы создаёте графики в формате PostScript, самый простой способ заключается в том, чтобы нарисовать это при помощи with impluses с очень тонкими линиями. Например, так: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
Так же можно заполнять столбики гистограмм цветом или вариантами текстурной заливки при помощи команд
with boxes fs [pattern | solid] номерстилязаливки. Так же можно задавать независимо стиль при помощи команды set style fill.
В случае с with boxes fs pattern, параметр pattern используется для определения заполняющей текстуры. Параметр solid определяет плотность заполнения столбца гистограммы, значени от 0 до 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
Как на одном графике построить данные в логарифмическом и обычном масштабе?
Например, есть такой график:
По оси Х в диапазоне [0:30], но вблизи нуля по оси Х данные очень важны и нужно показать их детально. Можно сделать два разных графика, но можно провернуть тоже и на одном.
Сначала построим график до единицы в логарифмическом масштабе: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>
Как сравнить похожие данные на одном графике?
Если нужно сравнить два набора сходных данных на одном и том же графике, полезно построить график в масштабе относительно другого набора данных. Абсолютная величина значений сравнивается на логарифмическом графике в верхней части, а сотношение показывается в нижней части графика в линейных осях.
Для того, чтобы вычислить соотношение данных одного ряда по отношению к другому, значения по оси Х должны быть одинаковы для обоих рядов. В примере ниже, первая колонка содержит значения Х, вторая колонка содержит значения по оси Y набора данных А, третья колонка содержит значения Y набора данных Б.
Сначала устанавливаем параметры оси Х, одинаковые для обоих наборов данных: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 2gnuplot> 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 1multiplot> 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: двухмерные графики
Подписаться на:
Комментарии к сообщению (Atom)
9 комментариев: |высказаться!| RSS-лента дискуссии.|
Всё хорошо, отличный пост. Только я бы не называл это «двумерными» графиками. Если так, то что тогда такое «одномерные» графики?
В общем, я сторонник классифицировать средства визуализации по размерности данных (функция заданная на 1D-множестве — одномерный график, на двумерном — двумерный).
Поставил ссылки на твои статьи в заметке Строим графики: графический интерфейс для gnuplot.
Отличная информация! Особенно понравилось совмещение логирифмического и линейного масштабов.
А может быть Вы знаете как правильно построить график с разрывами по оси абсцисс? Дело в том, что мне нужно строить рентгенограммы. Снимались они широком интервале по углу, однако, интересны только несколько узких участков с пиками. Простой опции разрыва оси не нашел в документации. Можно, конечно, строить мультиплоты, как в примере с разными масштабами, однако придется вручную подбирать ориджины, сложновато будет.
2 jetxee пишет...
я бы не называл это «двумерными» графиками. Если так, то что тогда такое «одномерные» графики?
А как же тогда это называть?
Поставил ссылки на твои статьи
Спасибо!
2 Анонимный пишет...
Особенно понравилось совмещение логирифмического и линейного масштабов.
В общем, это довольно экзотический пример, но оказывается, что и ему можно найти применение.
А может быть Вы знаете как правильно построить график с разрывами по оси абсцисс?
Надо смотреть конкретно, а у меня со временем очень туго.
Для построения графиков кроме общеизвестного gnuplot в Линуксе есть куда менее известная, но ничуть не менее могучая программа Grace. Вопреки первому впечатлению после запуска, в ней таки ЕСТЬ
командный язык, а не только "мышиный интерфейс".
И может она очень многое - в дебиановском пакете
с ней вместе лежит ряд наглядных примеров в виде
программ на встроенном языке.
Сам я стал пользоваться Grace тогда, когда потребовалось сделать динамически меняющуюся визуализацию поступающих в компьютер данных - программа оказалась способна делать это несколько более интеллигентно чем gnuplot.
а-яй-яй. Копируете статью - поставьте ссылку на оригинал! = http://t16web.lanl.gov/Kawano/gnuplot
# RAZRYV OSI
reset
unset key
bm = 0.15
lm = 0.12
rm = 0.95
gap = 0.03
size = 0.75
y1 = 0.0; y2 = 11.5; y3 = 58.5; y4 = 64.0
#kk = 0.7 #relative height of bottom plot
# or to keep proportional scale
kk = (abs(y2-y1) / (abs(y2-y1) + abs(y4-y3) ) )
set multiplot
set xlabel 'Time [ns]'
set border 1+2+8
set xtics nomirror
set ytics nomirror
set lmargin at screen lm
set rmargin at screen rm
set bmargin at screen bm
set tmargin at screen bm + size * kk
set yrange [y1:y2]
plot [0:40] 20.0*atan(x-20.0) + 32 + sin(x)
unset xtics
unset xlabel
set border 2+4+8
set bmargin at screen bm + size * kk + gap
set tmargin at screen bm + size + gap
set yrange [y3:y4]
set label 'Power [mW]' at screen 0.03, bm + 0.5 * (size + gap) offset 0,-strlen("Power [mW]")/4.0 rotate by 90
set arrow from screen lm - gap / 4.0, bm + size * kk - gap / 4.0 to screen \
lm + gap / 4.0, bm + size * kk + gap / 4.0 nohead
set arrow from screen lm - gap / 4.0, bm + size * kk - gap / 4.0 + gap to screen \
lm + gap / 4.0, bm + size * kk + gap / 4.0 + gap nohead
set arrow from screen rm - gap / 4.0, bm + size *kk - gap / 4.0 to screen \
rm + gap / 4.0, bm + size * kk + gap / 4.0 nohead
set arrow from screen rm - gap / 4.0, bm + size * kk - gap / 4.0 + gap to screen \
rm + gap / 4.0, bm + size * kk + gap / 4.0 + gap nohead
plot [0:40] 20.0*atan(x-20.0) + 32 + sin(x)
unset multiplot
как можно поставить точки в конкретных (x,y) кординатах
Насчет logscale-гнуплот умеет это делать только для положительной части оси,а мне нужно ее всю сделать в логарифмическом масштабе,т.е. чтобы на оси ординат откладывались lg(y) при y>0 и -lg(-y) при y<0. Просто брать отрицательные данные со знаком минус - "plot data.dat using 1:(-$2)" и потом сделать set yrange reverse не получится,т.к. рисуется сложная картина,вместе с различными обьектами,данные берутся из многих файлов. Может кто-то сталкивался с таким,подскажите как это сделать?
Катерина: «Насчет logscale-гнуплот умеет это делать только для положительной части оси,а мне нужно ее всю сделать в логарифмическом масштабе,т.е. чтобы на оси ординат откладывались lg(y) при y>0 и -lg(-y) при y<0.»
Катерина, вещественный логарифм определён только для положительных аргументов. Он отображает положительную полуось на всё множество вещественных чисел. Если параметр не строго положителен, то логарифмический масштаб оси ему не подходит. Не подходит логарифмический масштаб и для параметров, которые могут принимать нулевые значения — в нуле логарифм тоже не определён.
А то, что хотите сделать вы, не является взаимно-однозначным отображением и поэтому не является стандартным масштабом для осей.
Впрочем, в гнуплоте можно построить график функции, которую вы описали. Предполагая, что исходная функция, например x**3, ваш график будет строится вот такой командой:
plot sgn(x**3)*log(abs(x**3)) with lines
Однако в нуле эта функция всё равно не определена.
Отправить комментарий