5

假设我有一些数据数组(具体的向量)。我可以使用 Gnuplot 逐个元素地绘制它,这样看起来就好像它是通过监视器跟踪的真实生活信号?

我知道我可以使用 Common Lisp 将整个数据写入文本文件,然后使用 gnuplot 我可以将其绘制成批处理格式。我需要的是当数据按顺序出现时,我想在我的情节上加一个点。

数据可能会在循环内生成,因此您可以将 x 轴视为整数值离散时间轴。所以在循环中,如果数组的第一个元素生成为 5,我想在我的绘图上放一个点到 (0,5)。然后,如果第二个元素生成为 3,我想将我的绘图上的另一个点放在 (1,7) 上(保留旧数据点)。因此,当我遍历循环时,我会按顺序绘制数据。

我出于我的目的使用 emacs 和 Common Lisp,并且我想将这些数据绘制在这些工具中。如果除了 Gnuplot 之外还有其他选择,我想听听。

如果这不容易实现,那会很酷,如果我可以通过一些 Common Lisp 命令运行 Gnuplot 命令文件。

编辑:

cgn按照人们在这个线程下给出的建议,我使用which uses编写了一个代码ltk
现在,我在屏幕上预先指定的位置打开两个 x11 窗口,然后进入循环。每次我打开一个流并将数据(以 20 Hz 采样的 0.25 Hz 正弦波和余弦波)写入带有:if-exists :append选项的文本文件 trial.txt 并关闭流时,循环中。format-gnuplot然后在每次迭代中,我通过命令使用 gnuplot 绘制整个数据。这段代码给了我两个预先指定的 x 和 y 范围的窗口,然后可以观察窗口中上述正弦波和余弦波的演变。
正如我之前所说的,我没有很强的编程背景(我是一名电气工程师,不知何故最终使用了 common 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)

非常感谢。

4

5 回答 5

3

cgn是一个与 gnuplot 交互的 Common Lisp 解决方案,它使用LTK

于 2012-02-16T23:09:55.883 回答
2

您可能会看一下 orgplot 模式,它将 gnuplot 绑定到 emacs org 表中。

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

于 2012-02-15T21:07:54.293 回答
2

您可以创建 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")

有了这样的异步过程,很容易编写一些东西来让它随着新数据的出现而交互式地更新绘图。

于 2012-02-15T21:05:38.563 回答
2

你可以使用eazy-gnuplot,我愿意。在此处查看:eazy-gnuplot 示例。github repo 在这里:github repo。我没有更多时间在这里提供示例,抱歉。

于 2018-03-30T18:51:47.510 回答
1

I am not experienced with Gnuplot, and a quick search didn't turn up too much information. But perhaps i can propose an approach. Say you chunk your input, for example '(1 2 3 4 5) would be '((1) (1 2) (1 2 3) (1 2 3 4) (1 2 3 4 5)), you can then generate a plot for each, and use a graphics library like lispbuilder-sdl to display it in a window with a time delay. SDL has a timer and it can display images just fine.

于 2012-02-15T18:57:15.647 回答