I have been trying to use the common lisp interface to gnuplot that is
included in the Common Lisp Open Code Collection with little success.
Does anyone know of any tutorials or documentation that I can find online?
lowell
Lowell <······@cs.ubc.ca> writes:
> I have been trying to use the common lisp interface to gnuplot that is
> included in the Common Lisp Open Code Collection with little
> success. Does anyone know of any tutorials or documentation that I can
> find online?
>
> lowell
I ended up writing a little wrapper function to generate the gnuplot
command file, then fire off gnuplot to draw it. The nice thing about
it is you can keep invoking it to start up additional gnuplots, so you
can grind thru a pile of data and plot everything in one pass.
Since you're supplying all the gnuplot commanding yourself, it can be
as simple or as complex as you choose to make it. Code follows, it
runs fine on Lispworks, but its not doing anything interesting so
should be trivially portable to most any other CL.
This code was a one-off utility to analyze interrupt timing data
coming off a fairly ancient MIPS board we were working with, so I
needed something I could learn quickly, but still have Lisp do the
grovelling around for me. Various optimizations obviously apply, but
aren't really necessary
(flet ((gen-graph (gpscript) (format outf ".")
(with-open-stream (gpstr (sys:open-pipe
"/usr/bin/gnuplot -geometry 1200x768 -persist"
:direction :io :buffered nil))
(mapc #'(lambda (s)
#+ignore (format outf " ~A~%" s)
(format gpstr "~A~%" s)) gpscript) ))
)
then invoke, for example;
(gen-graph (list "set format y \"%5.0f\""
"set format y2 \"%5.0f\""
;;"set yrange [9800:10150]"
;;"set y2range [50:2200]"
(format nil "set xtics ~A" (floor (/ numdatapoints 20)))
"set xtics nomirror"
"set ytics nomirror"
"set y2tics nomirror"
"set grid y"
(format nil "set title \"Mongoose V RTEMS Interrupt Distributions (~A)\"" graph-label)
"set xlabel \"Sample Number\""
"set ylabel \"Tick Interval(us)\""
"set y2label \"1Sec Interval(us)\""
"set key width .12 box"
(format nil "plot '~A' axes x1y1 title \"Tick Interval (~A)\" with linespoints, \\"
cooked-output-intticks
(print-stats cstats-tickinterval) )
(format nil "'~A' axes x1y2 title \"1sec Interval (~A)\" with linespoints pt 3"
cooked-output-int1sec
(print-stats cstats-1secinterval) )
"quit"))
Oserve the "cooked-output-*" variables are pathnames to the actual
data files, your code will have to generate its own data files suited
to the graphs your're making, then call gen-graph to invoke gnuplot
which will read the files and do the drawing. Its a rather manual and
unenlightened process, but it is straightforward and does manage to
keep everything together, and perhaps more importantly, reduces the
learning curve to understanding how to command gnuplot.
Gregm
I played with the gnuplot/CLOCC code a bunch, and added some
functionality of my own (barplots), but basically ended up finding it
somewhat painful and looked for alternatives. I found a very nice one.
The R statistical language (http://www.r-project.org) is an open
source language that has very nice graphical capabilities (much more
sophisticated than gnuplot). These days, I just run R from CMUCL
(using run-program, I'd guess most other CL's have equivalent
functionality), and then wrote some simple wrapper functions to
communicate with R. (For large datafiles, I save them as temporary
files and tell R to read the files back in rather than sending them as
ascii over the connection; I haven't compared this directly to tell if
it's better, but sending many thousand numbers via this method is
essentially instantaneous.)
In any case, R offers a lot of good high-level graphics (plot,
barplots with lots of options, charts, 3D graphs), and there are
lower-level commands to adjust the plots to your liking, so you can
fine-tune if that's important. I'm fairly pleased with it so far.
rif