Анимированные графики с помощью gnuplot+bash+Avidemux

Анимированные графики с помощью gnuplot+bash+Avidemux

Практически неотъемлемая часть любой презентации на естественно-научной конференции — это графики. Нередко интересно увидеть не только график какой-нибудь зависимости в некоторый момент времени, но и посмотреть, как эта зависимость меняется во времени. Очень наглядно это можно показать, сделав много-много графиков и собрав из них видео. Об одном из вариантов, как это сделать, и будет мой пост. Красивые графики можно делать во многих программах: проприетарные Grapher и Origin, свободные gnuplot, QtiPlot, Veusz и другие. Большинство популярных программ для построения графиков имеют интерактивный графический интерфейс, позволяющий быстро сделать publication-quality график, не особо напрягая мозг. Однако, сейчас у нас другая задача — надо наштамповать очень много картинок с однотипными графиками. Редактировать каждый график вручную — дело неблагодарное, поэтому будем пользоваться не гламурным Origin, а невзрачным gnuplot. Его сила в возможности строить график по заданному заранее сценарию (т.е. gnuplot имеет свой скриптовый язык). Далее я покажу, как с помощью нехитрых скриптов быстро делать графики в любом необходимом количестве.

Установка gnuplot

Для пользователей Windows. Идем на сайт проекта. Там жмем «Download» и выбираем подходящий вариант для скачивания. Затем устанавливаем, как обычно. Для линуксоидов. Устанавливаем пакет с помощью любимого пакетного менеджера. Для пользователей Ubuntu Lucid рекомендую этот PPA — в нем есть новая версия с дополнительными плюшками.

Пример 1. Меняющийся график

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

Первая строчка — момент времени и число точек N. Затем идут N строк в формате

Затем 2 переноса строки и снова так же. Переносы строк между блоками важны — gnuplot воспринимает блоки, разделенные несколькими переносами строк, как различные. Таким образом, можно строить график, соответствующий только одному блоку.

Теперь запускаем gnuplot — мы заходим в командный интерфейс программы. Набираем

Что это означает? plot — команда построить график; «rdf.txt» — путь к файлу, из которого мы хотим считать данные; using 2:3 значит «использовать столбец 2 как значения X, столбец 3 как значения Y»; with lines — просьба выводить на график только линии, соединяющие точки данных.

Результатом этой команды будет примерно следующее:

Как видим, нарисованы все графики, содержащиеся в файле. Чтобы нарисовать график только по части точек, используем ключевое слово index. Например, строим график, используя только первые 100 строчек с данными:

Здесь linewidth 5 говорит о том, что линия будет толще обычного. Результат:

Будем считать, что такой вид графика нас устраивает. Теперь надо пробежать по всем записям во входном файле, построить по всем ним графики и экспортировать их в картинки. Я это делал с помощью пары скриптов на bash. На самом деле, можно обойтись встроенными средствами gnuplot (что лучше, т.к. не привязывает к Юниксам). Делаем скрипты animator.gp и animate.gp. В animator.gp настраиваем график и терминал:

В animate.gp делаем, собственно, генерацию картинок.

Мне хотелось, чтобы график постепенно менял цвет, поэтому я задал некоторую палитру от зеленого к фиолетовому. Опции unset colorbox и set key off — отключение вывода палитры и легенды на график.

Главные команды в этих скриптах:

Первая включает экспорт графика в png с размером 750x750 и шрифтом Droid, когда дается команда plot, вторая задает имя файла. Во второй команде мы воспользовались тем, что gnuplot умеет «конкатенировать» целые числа (но не float!) со строками.

Команда if во втором скрипте выполняет последующие команды при выполнении условия (обратите внимание, что все команды в теле if-a должны быть на одной строчке и разделены точкой с запятой). Команда reread считывает весь скрипт с самого начала, т.е. получается своего рода цикл. Скрипты выполняются либо простым добавлением прав на исполнение файлу animator.gp с последующим его запуском (в Юниксах) или командой

в командной строке gnuplot (любая ОС). Запустив скрипты, я получил в папке figures ряд картинок: 1.png, 2.png и т.д. Из них уже можно собирать анимацию. Я это делал с помощью свободного видеоредактора Avidemux.

Собрать анимацию проще простого. Открываем редактор, нажимаем «Открыть», выбираем первую картинку в последовательности (в моем случае было «1.png») — готово, анимация загружена. Можно нажать Play и проверить, что все нормально. Затем сохраняем анимацию в нужном нам формате. Вот мой результат:

Пример 2. Наложение графика на рисунки

Более сложная задача — сделать то же самое, но фон должен быть не белый, а являться картинкой, причем сам еще являться анимированным. У меня такая необходимость появилась, когда понадобилось визуализировать капиллярные флуктуации в двухфазной системе по результатам молекулярной динамики (МД). В принципе, можно накладывать, например, границы циклонов на карту, визуализацию какого-нибудь поля скоростей на видео работы сопла, да мало ли что еще. Итак, приступаем.

Нужен будет gnuplot версии не ниже 4.4 (у пользователей Ubuntu есть в репозитории для версий позднее 10.04. Для 10.04 скачиваем из указанного PPA). Дело в том, что в этой версии gnuplot умеет загружать на график png-файлы с альфа-каналом. У меня было около тысячи файлов со снимками МД ячейки в формате png и столько же файлов, содержащих координаты межфазной границы. animator.gp остается примерно таким же:

В animate.gp добавляем подгрузку картинки из png-файла:

Png загружается командой вида

Опция with rgbalpha требует, чтобы график был с четырьмя «осями» (каналы R, G, B, alpha, как ни странно). У меня в фоновых картинках альфа-канала не было, и я просто задал его значение как (160). Значение прозрачности подбиралось методом научного тыка, чтобы и наложенный график было видно, и фон был не слишком блеклый.

Запускается все так же, как и в прошлый раз, генерируются картинки и собираются в видео все тем же Avidemux. Вот результат:

📎📎📎📎📎📎📎📎📎📎