Построение данных последовательно из emacs с использованием Common Lisp и Gnuplot - PullRequest
5 голосов
/ 15 февраля 2012

Предположим, у меня есть некоторый массив данных (вектор, чтобы быть конкретным). Могу ли я отобразить его элемент за элементом последовательно, используя Gnuplot, чтобы казалось, что это реальный сигнал, который отслеживается через монитор?

Я знаю, что могу записать все данные в текстовый файл, используя Common Lisp, а затем используя gnuplot, я могу отобразить их в пакетном формате. Что мне нужно, так это то, что я хочу поставить точку на своем графике, поскольку данные поступают последовательно.

Данные, вероятно, будут сгенерированы внутри цикла, поэтому вы можете рассматривать ось x как целочисленную ось дискретного времени. Так что в цикле, если первый элемент массива генерируется как 5, я бы хотел поставить точку на моем графике в (0,5). Затем, если второй элемент сгенерирован как 3, я бы хотел поставить другую точку на моем графике в (1,7) (сохраняя старую точку данных). Поэтому, когда я повторяю цикл, я строю данные последовательно.

Я использую emacs и Common Lisp для своих целей и хочу отобразить эти данные, оставаясь в этих инструментах. Если есть другие варианты, кроме Gnuplot, я бы хотел их услышать.

Если это нелегко сделать, было бы здорово, если бы я мог запустить командный файл Gnuplot какой-нибудь командой Common Lisp.

редактирование:

Следуя советам, которые люди давали в этой теме, я написал код, используя cgn, который использует ltk.
Прямо сейчас я открываю два окна x11 в заданных местах на моем экране и вхожу в цикл. Каждый раз в цикле я открываю поток и записываю данные (синусоидальные и косинусоидальные волны 0,25 Гц, дискретизированные с частотой 20 Гц) в текстовый файл trial.txt с параметром :if-exists :append и закрываю поток. Затем на каждой итерации я строю данные целиком с помощью gnuplot с помощью команды format-gnuplot. Этот код дает мне два окна предварительно заданных диапазонов x и y, а затем можно наблюдать эволюцию вышеупомянутых синусоидальных и косинусных волн в окнах.
Как я уже говорил ранее, у меня нет сильного опыта программирования (я инженер-электрик, который каким-то образом закончил с использованием общего lisp), и я почти уверен, что мой код неоптимален и нелегок. Если у вас есть какие-либо дополнительные советы, исправления и т. Д., Я бы очень хотел их услышать. Код здесь:

(setf filename "trial.txt")
(setf path (make-pathname :name filename))
(setf str (open path :direction :output  :if-exists :supersede :if-does-not-exist :create))
(format str "~,4F ~,4F" -1 -1)
(close str)

;start gnuplot process
(start-gnuplot "/Applications/Gnuplot.app/Contents/Resources/bin/gnuplot")

;set 2 x11 windows with the following properties
(format-gnuplot "cd ~S" "Users/yberol/Desktop/lispbox/code")
(format-gnuplot "set terminal x11 0 position 0,0")
(format-gnuplot "set xrange [0:10]")
(format-gnuplot "set yrange [-1:1]")
(format-gnuplot "unset key")
(format-gnuplot "set grid")

(format-gnuplot "plot ~S using 1" filename)
(format-gnuplot "set terminal x11 1 position 800,0")
(format-gnuplot "plot ~S using 2" filename) 

;write data into text 
(loop :for i :from 0 :to 10 :by (/ 1 20) :do
   (setf str (open path :direction :output  :if-exists :append :if-does-not-exist :create))
   (format str "~,4F ~,4F ~,4F ~%" i (sin (* 2 pi (/ 5 20) i)) (cos (* 2 pi (/ 5 20) i)))
   (close str)
   (format-gnuplot "set terminal x11 0")
   (format-gnuplot "plot ~S using 1:2 with lines" filename)
   (format-gnuplot "set terminal x11 1")
   (format-gnuplot "plot ~S using 1:3 with lines" filename)
   (sleep 0.1))
(close-gnuplot)

Большое спасибо.

Ответы [ 5 ]

3 голосов
/ 17 февраля 2012

cgn - это рабочее решение Common Lisp для взаимодействия с gnuplot, которое использует LTK

2 голосов
/ 30 марта 2018

Вы могли бы использовать eazy-gnuplot, я делаю. Смотрите здесь: примеры eazy-gnuplot . Репозиторий github находится здесь: репозиторий github . У меня нет больше времени, чтобы привести пример, извините.

2 голосов
/ 16 февраля 2012

Вы можете создать процесс для gnuplot и отправить данные в его стандартный поток вместе с командами печати.Я не уверен, как управлять таким процессом в Common Lisp, но вы определенно можете сделать это в Emacs:

(setf *gnuplot-proc* (start-process "gnuplot" "*gnuplot-proc*" "gnuplot"))
;;; initiate plotting of data from stdin
(process-send-string *gnuplot-proc*
                     "plot \"-\" with lines\n")
;; send your data
(process-send-string *gnuplot-proc*
                     "5 -1\n4 -3.5\n3 9.5\n")
;; end of data, after this gnuplot would pop up interactive window
(process-send-string *gnuplot-proc* "e\n")

С таким асинхронным процессом легко написать что-то, чтобы он мог интерактивно обновлять график по мере поступления новых данных.вместе.

2 голосов
/ 16 февраля 2012

Вы можете взглянуть на режим orgplot, который связывает gnuplot с таблицами emacs org.

http://orgmode.org/worg/org-tutorials/org-plot.html

1 голос
/ 15 февраля 2012

У меня нет опыта работы с Gnuplot, и быстрый поиск не дал слишком много информации. Но, возможно, я могу предложить подход. Скажем, вы разделяете свой ввод, например, «(1 2 3 4 5) будет» ((1) (1 2) (1 2 3) (1 2 3 4) (1 2 3 4 5)), затем вы можете сгенерируйте график для каждого и используйте графическую библиотеку, например lispbuilder-sdl , чтобы отобразить ее в окне с временной задержкой. SDL имеет таймер, и он может отображать изображения очень хорошо.

...