Построение графиков с помощью программы gnuplot
Для чего нужна отдельная программа построения графиков?
gnuplot является OpenSource-программой с большими возможностями по построению различных 2-D и 3-D графиков. Можно задаться вопросом, для чего в эпоху различных математических пакетов необходимо обращать внимание на такого рода программы. Когда вся работа выполняется в самом математическом пакете, то и отображение результатов тоже удобнее всего выполнить в нём же.
Но что, если необходимые данные поступают откуда-то извне, например, из собственноручно разработанной программы? Эти данные сначала надо как-то оформить в требуемом виде, удобном для пакета, потом зайти в нужную программу, загрузить файл и начать работать.
Это можно сделать раз или два, но когда таких частей становится много (например, они представляют собой состояние системы в различные моменты времени), то gnuplot тут будет в самый раз. Достаточно передать ему простой файл и готовый набор команд, необходимых для оформления, и получить на выходе красивый график (а то и целую серию) с указанием осей, их подписей, сеткой и так далее.
В данном описании будут приведены некоторые базовые принципы работы с программой, позволяющие быстро набить руку. Все подробности по каждому параметру, по коэффициентам, влияющим на конечный результат, нужно будет обратиться к первоисточнику.
Общие принципы работы с программой
При запуске программы gnuplot без аргументов на экране появится приглашение к выполнению команд самой программы. Все команды, описанные ниже, нужно вводить или в эту командную строку, или записывать в файл скрипта по команде на строку (можно и несколько команд в одной строке, разделяя их символом "точка с запятой"), а потом этот скрипт передавать для исполнения при запуске программы:
gnuplot -e my_script
gnuplot -e my_script file1.in
где
- -e
- параметр, указывающий, что дальше идёт скрипт;
- my_script
- скрипт с набором команд для gnuplot;
- file.in
- данные для скрипта.
Вне зависимости от требуемых результатов порядок действий обычно один и тот же:
- Определяемся, как и куда мы хотим выводить наши результаты. Это может быть экран компьютера, графический файл или даже вставка в HTML5-страницу, а сами графики могут быть в виде линий, серии точек, столбчатые диаграммы, с указанием погрешностей и т.д. Не забываем про описание осей, а также названия самого графика, вывода легенды.
- Перед началом серии обработки данных подготавливается набор команд, в котором помимо самой команды отрисовки можно включить команды описания самого графика.
- При поступлении нового блока данных запускается программа gnuplot, которой передаётся файл с командами и файл с данными.
- Используем красиво оформленные результаты в большом отчёте по Megascience.
И не забываем про команду show plot
, чтобы увидеть свои результаты.
Куда отправлять результат?
Для управления выводом используется команда set
с параметром terminal
или output
.
Если предполагается установка обоих параметров, то сначала крайне желательно задать параметр terminal
, а потом уже output
, так как они зависят друг от друга.
Чтобы узнать текущий терминал или параметры вывода, достаточно вместо команды set
использовать команду show
.
Выбрать в качестве вывода окно графического терминала в Unix размером 800х600 точек и назвать его "Example graphics" (это НЕ подпись самого графика):
set terminal x11 title "Example graphics" size 800,600
Выбрать в качестве вывода окно Windows:
set terminal windows
Записывать результат в файл в формате png размером 800х600 точек с фоном белого цвета:
set terminal png truecolor size 800,600 background '#ffffff'
Некоторые терминалы помимо выбора типа и формата могут принимать указание, где же будет находиться результат.
В этом нам поможет параметр output
. Так, для сохранения ранее подготовленного вывода в формат png в файле output.png достаточно ввести:
set output "output.png"
А если в Windows хотите завести у себя "бешеный принтер", то одним движением руки набираете
set output "PRN"
Не каждый терминал учитывает вывод, поэтому для точной настройки обращайтесь к полноценной документации на gnuplot.
2-D графики
В списке 2-D графиков в программе значатся:
- обычные графики от известной функции или математического выражения: Y=f(x);
- параметрические графики с использованием функций: X=f(t), Y=g(t);
- графики по заранее подготовленным блокам данных из файлов или поступивших на вход программы:
x1 y1 x2 y2 ...
Для построения используется команда plot
. Этой команде необходимо передать соответствующий блок вывода. Каждый блок, по сути,
описывает тот или иной вариант построения графиков в общей области отображения и в одних и тех же осях. Так, команда
plot sin(x)
show plot
отобразит известную нам функцию.
Обычные графики
Для построения графика в осях XY можно использовать стандартные математичекие операции, набор встроенных функций и их комбинации, среди них:
- сложение, вычитане, умножение, деление, возведение в степень, модуль, знак числа;
- десятичный и натуральный логарифмы, экспонента, квадратный и кубический корень;
- тригонометрические и обратные тригонометрические функции;
- гиперболические и обратные гиперболические функции;
- различные функции Бесселя;
- функции W(z,k) Ламберта;
- вычисление функций с комплексным аргументом (c = x + iy), выделение вещественной и мнимой частей, фазы, модуля;
- и другие.
Замечание: результат в комплексных числах не может быть представлен на графике, необходимо либо выделить вещественную или мнимую часть выражения, определить его фазу или модуль.
Для построения графика в самом простом случае можно указать лишь функцию. Пример:
plot cos(x)
show plot
Тогда, к примеру, ось X лежит в диапазоне [-10,10], ось Y же получит автоматический масштаб в зависимости от предложенной функции, чтобы она заполняла всё поле вывода по вертикали.
Для изменения границ осей только одного графика сразу после команды plot
можно указать диапазон вручную в виде [A:B]
. Например, для оси X (здесь pi
- уже известная программе константа):
plot [0:pi] cos(x)+sin(x)
show plot
Или для обеих осей сразу:
plot [0:pi] [-2:2] tan(x)
show plot
Если, например, ось X мы не хотим определять, но ось Y нам важна, то на месте задания оси X можно поставить пустые квадратные скобки:
plot [] [-2:2] cos(x)
show plot
Параметрические графики
У параметрических графиков появляется ещё одна переменная, описывающая поведение как координаты X, так и координаты Y. Поэтому всё немного усложняется.
Во-первых, необходимо сказать программе, что мы хотим построить именно параметрический график.
Для этого до команды plot
необходимо включить этот режим при помощи всё той же команды set
:
set parametric
После этого команда построения будет ждать пару функций X(t),Y(t):
plot sin(t),t**2
show plot
Без указания диапазонов по осям программа нарисует график в диапазоне, который задан в параметре trange
.
Для вывода нужной нам части графика также можно задать границы изменения осей, только теперь таких блоков уже будет до 3 штук: параметр, ось X, ось Y:
plot [0:1] sin(t),t**2
show plot
plot [0:1] [-pi:pi] sin(t),t**2
show plot
plot [0:1] [-pi:pi] [-5:5] sin(t),t**2
show plot
Точно также, как и для обычных графиков, неиспользуемые, но требуемые как поле диапазоны параметра или осей можно отметить пустыми квадратными скобками:
plot [] [-pi:pi] [-5:5] sin(t),t**2
show plot
Графики по наборам данных
В данном случае всё становится намного интереснее, ибо теперь можно подготовить один набор команд, а данные подавать откуда душе угодно. Их можно как вставить в текст скрипта, так и сохранить в отдельный файл, откуда сам скрипт будет забирать данные для обработки.
Пример построения графика по данным из текстового файла с данными, представленными в виде двух столбцов чисел:
Структура файла megadata.txt:
1.0 2.34e2
2.0 3e2
3.0 3.716e2
Сама команда:
plot 'megadata.txt'
show plot
Что равносильно команде:
plot 'megadata.txt' using 1:2
show plot
числа после using
определяют номер столбца данных. Например, с помощью этого параметра можно X и Y поменять местами:
plot 'megadata.txt' using 2:1
show plot
Построение графиков не заканчивается на простом перечислении, внутри таится целая бездна возможностей. Пусть мы хотим построить сразу несколько графиков, используя один столбец данных как аргумент, а остальные столбцы как значения функций. Тогда нужно будет как-то обратиться к нашим столбцам и рассказать, что же мы хотим с ними сделать:
Структура файла megadata.txt (числа выстроены друг под другом лишь для красоты, программа отличает числа между собой при помощи разделителей, например, пробелов):
1.0 2.340e2 2.018e2
2.0 3.000e2 3.130e2
3.0 3.716e2 3.644e2
4.0 4.180e2 2.280e2
Сама же команда вывода графиков двух функций с одним аргументом выглядит так:
plot 'megadata.txt' using 1:2, 'megadata.txt' using 1:3
show plot
После using
можно указать и одну выборку данных, в таком случае аргументом будет порядковый номер числа, а выборка станет значением функции:
plot 'megadata.txt' using 2
show plot
Пусть мы набрали некоторые данные и хотим вывести их в виде натурального логарифма:
plot 'megadata.txt' using 1:(log($2))
show plot
Как мы видим, номер второго столбца надо набирать как \$2, чтобы отличить его от обычного числа. Обратите внимание, что при использовании выражения вместо поля всё выражение необходимо заключить в круглые скобки.
Также обратите внимание, что нумерация столбцов начинается с 1, а не 0, как это обычно принято у программистов. Нулевой столбец - фиктивный, на самом деле в эту позицию программа подставляет порядковый номер набора данных, получаемого из файла (1, 2, 3, ...).
3-D графики
Для трёхмерных графиков используется отдельная команда splot
. Важно не забывать об этом, чтобы не увидеть неожиданную ошибку
или не получить совершенно неожиданный результат. Как и в случае двухмерных графиков, для 3-D графиков пользователям gnuplot также доступны:
- обычные графики от известной функции или математического выражения: Z=f(x,y);
- параметрические графики с использованием функций: X=f(u,v), Y=g(u,v), Z=h(u,v);
- графики по заранее подготовленным блокам данных из файлов или поступивших на вход программы:
x1 y1 z1 x2 y2 z2 ....
Обычные графики
Здесь ничего нового нет, наблюдается полная аналогия с построениями двухмерных графиков:
splot cos(x+y)
show plot
В отличие от команды plot
, команде splot
можно указать до 3 диапазонов осей: X, Y, Z:
splot [0:pi] cos(x)+sin(y)
show plot
splot [0:pi] [0:pi] cos(x)+sin(y)
show plot
splot [0:pi] [0:pi] [-2:2] cos(x)+sin(y)
show plot
Если, к примеру, нужна только ось Z, то не забываем поставить указания на оси X и Y в виде пустых квадратных скобок:
splot [] [] [-2:2] cos(x)+sin(y)
show plot
Параметрические графики
И снова мы наблюдаем единодушие с двухмерными графиками, но с двумя отличиями:
- у нас теперь 3 функции, по одной для каждой оси;
- каждая функция может иметь до двух аргументов, которые обозначаются u и v (у двухмерных параметрических графиков есть только один параметр t).
Функции указываются по-очереди: X, Y, Z. Вот один из примеров параметрического трёхмерного графика:
splot sin(u+v),v**2,cos(u-v)
show plot
Без указания диапазонов по осям программа нарисует график в диапазонах, которые заданы в параметрах urange
, vrange
. Для определения конкретных
диапазонов изменения как параметров, так и самих осей, используются уже до 5 блоков диапазонов, указывая по-очереди u v X Y Z. В полной форме это записывается так:
splot [-pi:pi] [-pi:pi] [-3:3] [-3:3] [-2:2] sin(u+v),v**2,cos(u-v)
show plot
Когда, к примеру, не нужны оси Y и Z, то можно записать так:
splot [-pi:pi] [-pi:pi] [-3:3] sin(u+v),v**2,cos(u-v)
show plot
А вот начальные не требуемые диапазоны всё же надо отмечать уже знакомыми квадратными скобками:
splot [] [] [-3:3] sin(u+v),v**2,cos(u-v)
show plot
Примечательно, что обычные трёхмерные графики можно построить как параметрические, если их записать в виде:
splot u,v,f(u,v)
show plot
Графики по наборам данных
При построении 3D-графиков по имеющимся наборам данных нужно поступать схожим образом, как для двухмерных графиков, только составляем не дуплет, а триплет данных X Y Z:
plot 'megadata.txt' using 1:2:3
show plot
Если данные уже представлены в нужном порядке в виде триплета, то их указание можно опустить:
plot 'megadata.txt'
show plot
Также можно указать один столбец данных. Тогда первым элементом будет порядковый номер в блоке данных, а вторым элементом номер блока данных (блоки данных будут описаны чуть ниже).
plot 'megadata.txt' using 3
show plot
Некоторые полезности и приятности
В дополнение стоит указать на некоторые возможности, которые используются чаще всего при построении графиков. Среди них:
- цвет графика;
- вывод элементов данных;
- вид графика.
Всё это можно сделать при помощи ключа with
, который добавляется после описания каждой функции.
И это ещё не всё! Коночно,никто не забыл и такие базовые потребности, как:
- написать любой текст, не привязанный к графикам;
- расположить оси заданным образом;
- назвать каждый график.
Цвет графика
Обычно программа автоматически подбирает цвета для построения, но часто нам этого не хватает. Тогда нам приходит на помощь дополнительный ключ with
.
Для того,чтобы задать цвет, нужно после ключа with
поставить параметр linecolor N
, где N - цвет графика. В качестве цвета могут выступать:
- заранее известное название цвета: "violet";
- цвет в формате RGB:
- заранее известный: rgbcolor "blue";
- в 24-битном шестнадцатиричном формате: rgbcolor "0xRRGGBB";
- в 32-битном шестнадцатиричном формате с альфа-каналом: rgbcolor "0xAARRGGBB";
- в формате X11: rgbcolor "#RRGGBB";
- в формате X11 с альфа-каналом: rgbcolor "#AARRGGBB";
- в десятиричном формате: rgbcolor число;
- в виде дополнительного столбца данных, указав 24-битный цвет как rgbcolor variable;
- палитра:
- в виде дробного числа: palette frac f_число;
- в виде доли: palette cb z_число;
- в виде зависимости от значения по оси Z: palette z.
Кодирование 24-битных и 32-битных цветов выполнено практически одинаково. RR, GG, BB определяют 8-битный красный, зелёный и синий цвета (00 - отсутствие цвета, FF - максимальная насыщенность), AA - прозрачность (00 - непрозрачный, FF - полностью прозрачный). Цвет 0xRRGGBB равнозначен 0x00RRGGBB. Символы 0x и # полностью равнозначны между собой и выбор оставлен сугубо на вкус пользователя. Десятиричное число лишь конвертируется в 32-битный шестнадцатиричный вид и подставляется вместо исходного числа. Примеры:
plot 'megadata.txt' using 1:2 with linecolor rgbcolor "#0000FF"
show plot
plot 'megadata.txt' using 1:2 with linecolor rgbcolor "0x0000FF80"
show plot
Особо интересен вариант самостоятельного раскрашивания при обработке данных из файла. Для этого к набору данных добавляется еще одно поле (варианты написания приведены в примерах):
plot 'megadata.txt' using 1:2:3
show plot
splot 'megadata.txt' using 1:2:3:4
show plot
splot 'megadata.txt' using 1:4
show plot
Дополнительный столбец в файле данных должен быть 24-битным целым числом. Вместо ввода столбца можно его задать в виде некоторой функции, возвращающей 24-битное целое число. Вот вариант для трёхмерного графика, где цвет задаётся отдельной функцией:
rgb(r,g,b) = 65536 * int(r) + 256 * int(g) + int(b)
splot "data" using 1:2:3:(rgb($1,$2,$3)) with points linecolor rgbcolor variable
show plot
gnuplot позволяет заранее задать палитру, в которой каждому цвету соответствует некоторое дробное число от 0 до 1. Варианты значений параметра palette
:
- f_число - это то самое дробное число от 0 до 1, по которому определяется цвет из палитры.
- z_число - это число между заранее установленными границами, записанными в переменную cbrange
.
Для получения f_числа нужно вычислить (z - cbmin)/(cbmax-cbmin). Если получаемое число меньше 0 или больше 1, то оно принимается равным 0 или 1
соответственно. palette z
используется только в трёхмерных графиках и представляет собой z-число, которое принимается равным значению по оси Z,
тем самым позволяя менять цвет по мере изменения значения функции в процессе построения. Примеры:
plot sin(x) with lines linecolor palette frac 0.3
show plot
plot sin(x) with lines linecolor palette cb 4.0
show plot
splot sin(x*y) with lines linecolor palette z
show plot
Название графика и осей
Пожалуй, это самая важная часть любого результата. Кому захочется видеть некое невнятное using 1:2? Для исправления этого достаточно добавить параметр
title
:
plot sin(x) title "sin"
show plot
Также можно график назвать. Для этого перед командой plot
или splot
нужно установить переменную title, а после чего нарисовать сам график:
set title "название графика"
plot sin(x) title "sin"
show plot
Для того, чтобы на график поместить любой текст (а название графика - это частный случай нанесения текста), необходимо выполнить следующие команды:
set label 1 "Мой замечательный график"
set label 1 at screen 0.1, 0.9
В данном случае мы присваиваем тексту номер 1, присваиваем текст "Мой замечательный график" и располагаем его слева сверху на терминале, отступив по 10%
ширины и высоты от верхней и левой границ. В режиме screen
левый нижний угол имеет координаты (0, 0), верхний правый - (1, 1). Текст может быть
оформлен определённым шрифтом заданного размера, его можно повернуть и так далее. Вариаций много и все сразу не расскажешь.
Небольшие хитрости
Расположение осей
Также можно указать расположение осей на двухмерном графике, точнее, точку начала координат. Желаемое достигается параметром axes XY
, где XY означают
следующее:
- x1y1 - левый нижний угол;
- x1y2 - левый верхний угол;
- x2y1 - правый нижний угол;
- x2y2 - правый верхний угол.
Стоит отметить, что указание границ для команды plot
действует только на первый вариант.
Сокращения команд и параметров gnuplot
Многие полные названия команд и параметров можно указывать и в сокращённом виде. Так, linecolor
можно записать в виде lc
и программа это примет.
Названия графиков сразу из файла
Ещё один лайфхак для графиков из файлов данных - это возможность назвать каждый из графиков, введя в первой строке в каждом столбце текстовое название, а потом по этим именам можно обратиться для отрисовки графиков.
Структура файла megadata.txt (названия и числа выстроены друг под другом лишь для красоты, программа отличает числа между собой при помощи разделителей, например, пробелов):
Age Height
8 130
15 160
22 170
25 170
И сами команды для построения графиков:
plot 'megadata.txt' using "Age":"Height"
show plot
plot 'megadata.txt' using (column("Age")):(column(1))
show plot
Примечание: column - это функция получения значения из заданного столбца текущей строки данных.
Разрыв графика
Иногда возникает необходимость, когда последовательные точки графика не надо соединять. Например, при построении функции тангенса соединение всех точек между собой приводит к появлениям несуществующих вертикальных линий на графике. Для исключения появления таких "артефактов" графики, строящиеся из файла, можно разрывать. Для этого достаточно в данных поставить одну пустую строку.
Структура файла megadata.txt:
8 130
15 160
22 170
25 170
И сама команда:
plot 'megadata.txt'
show plot
Заключение
Программа gnuplot является отличным подспорьем любому учёному, позволяя реализовывать самые разные воплощения по визуализации, которые только можно себе представить. В данном кратком очерке были затронуты лишь малая часть всех её возможностей. Предлагаю не стесняться, а более полно применять любые инструменты, подходящие под Ваши задачи, даже такие экзотические, как специализированные системы визуализации полученных данных.
Более полную информацию по работе с gnuplot можно прочесть на сайте программы.
Епифанов С.В.