понедельник, 30 августа 2010 г.

интерфейс к gnuplot

Решил написать лисповый интерфейс к отличной рисовалке графиков gnuplot. Отчасти потому что существующие интерфейсы в печальном состоянии, отчасти из-за своей страсти к велосипедостроению.

Выложил одну из версий на github. Приведу небольшой обзор возможностей.

;; запускаем gnuplot
(gplt-start)
;; далее передаем ему команды
#G(plot (/ (sin x)))
;; смотрим, что получилось
(gplt-display)
;; убиваем процесс
(gplt-stop)

После вызова gplt-display появилось обычное окошко gnuplot:

#G() - это макрос чтения, соответствующий вызову (gplt-exec '(plot (/ (sin x)))). здесь могут быть любые команды, которые поймет сам gnuplot. s-выражение преобразуется в строку по следующим правилам.

  • Если выражение начинается с plot или splot, то следующий элемент выражения считается функцией либо файлом с данными. Функция задается обычным s-выражением и преобразуется в инфиксную форму, понятную gnuplot.
  • Интервалы задаются словом range. (range 0 1) преобразуется в [0:1]
  • Перечисления задаются словом enum. (enum 10 10) преобразуется в 10,10
  • Остальные ключевые слова передаются без изменений
Таким образом, мы можем написать следующее:

(gplt-restart)
(map nil #'gplt-exec
  '((unset key)
    (set xrange (range 0 2))
    (set yrange (range 2 5))
    (set isosamples (enum 30 30))
    (splot (sin (* x y)) with pm3d)))
(gplt-display)

Это будет соответствовать следующим командам, набранным в самом интерпретаторе gnuplot:

unset key
set xrange [0:2]
set yrange [2:5]
set isosamples 30,30
splot sin(x*y) with pm3d

В результате получим такую картинку.
Неплохо, но наверняка можно лучше. Поэтому буду рад услышать критику и предложения, и в особенности примеры команд gnuplot, которые нельзя передать с помощью текущего парсера.

2 комментария:

  1. А какой смысл в использовании ридер-макроса? Ведь тут достаточно будет простого макроса.

    ОтветитьУдалить
  2. просто так. потом понял, что он не нужен, а лучше применять gplt-exec к списку команд, как в последнем примере

    ОтветитьУдалить