#lang scribble/doc @(require scribble/manual scribble/basic (for-template scheme "main.ss") ) @title{gnuplot.plt} @section{Overview} This library provides a wrapper interface to @link["http://www.gnuplot.info"]{gnuplot}. Using the library, mzscheme programs can spawn inferior gnuplot processes and plot data to windows or hardcopy with a programmatic interface. The library assumes gnuplot version 4.x (tested with 4.2.3). @subsection{License} (C) Copyright 2008 Dimitris Vyzovitis gnuplot.plt is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. gnuplot.plt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gnuplot.plt. If not, see . @section{API} @declare-exporting["main.ss"] @subsection{Gnuplot processes} @deftogether[( @defproc[(gnuplot-spawn (read? bool? #f)) gnuplot?] @defproc[(gnuplot-kill (gplot gnuplot?)) any] @defproc[(gnuplot? (o any)) bool?] @defproc[(gnuplot-input-port (o gnuplot?)) input-port?] @defproc[(gnuplot-writeln (o gnuplot?) (fmt string?) (arg any) ...) any] )]{ @scheme[gnuplot-spawn] spawns a gnuplot processes, using @scheme[(gnuplot-program)]. When @scheme[read?] is @scheme[#t] then output from gnuplot can be collected through the port accessible with @scheme[gnuplot-input-port]. @scheme[gnuplot-writeln] can be used to write directly to the process's input port. The processes is garbage collected when unreachable, but can be explicitly killed with @scheme[gnuplot-kill] } @deftogether[( @defproc[(gnuplot-program) path-string?] @defproc[(gnuplot-set-program! (o path-string?)) any] )]{ The gnuplot executable. Defaults to @scheme["gnuplot"] under unix/macosx and @scheme["pgnuplot.exe"] under windows. } @subsection{Data sources} @defproc[(gnuplot-data (data list?) (#:file fname path-string? #f) (#:comments comments list? #f) (#:tmpdir tmpdir path-string? #f) (#:binary bin? bool? #f)) gnuplot-data?]{ Creates a data source using @scheme[data], which must be a list of lists of numbers, written to a temporary file when @scheme[fname] is @scheme[#f]. When @scheme[bin?] is @scheme[#f] files are written in ascii, optionally prepending comments from @scheme[comments] which when supplied must be a list of strings. When @scheme[bin?] is @scheme[#t] data is written in binary form, following gnuplot's binary matrix file format. Temporary files are automatically deleted when the data sources become unreachable. } @defproc[(gnuplot-data/file (fname path-string?) (bin? bool? #f)) gnuplot-data?]{ Create a data source using an existing file. } @defproc[(gnuplot-data? (o any)) bool?]{ @scheme[#t] when @scheme[o] is a gnuplot data source. } @subsection{Plotting} Plotting is controlled using a simple translation scheme that maps @scheme[items] to gnuplot's idiosyncratic syntax, with the following grammar: @schemegrammar*[ #:literals (seq seq: seq* range = path str item) [source-item (item ...)] [sequence-item (seq ...) (seq: ...) (seq* ...)] [range-item () (/#f /#f) ( /#f /#f) ] [param-item (= )] [path-item (path )] [str-item (str )] [empty-item #f] [any-item ]] @itemize{ @item{@scheme[_source-item] --- is a plot directive.} @item{@scheme[_sequence-item] --- is mapped to a sequence of items, joined with ",", ":", or " " respectively.} @item{@scheme[_range-item] --- is a plot range.} @item{@scheme[_param-item] --- is a parametric expression.} @item{@scheme[_path-item] --- is a single quoted string, while a @scheme[_str-item] is a double-quoted string.} @item{@scheme[_empty-item] --- is translated to an empty string} @item{Any other object is translated to its printed representation using @scheme[format].} } @defproc[(gnuplot-item (data gnuplot-data?) (options plot-item? null)) item?]{ Create a plot item, using @scheme[data] as the data source, prepended to @scheme[options]. } @deftogether[( @defproc[(gnuplot-plot (gplot gnuplot?) (#:range range range-item #f) (item item?) ...) any] @defproc[(gnuplot-splot (gplot gnuplot?) (#:range range range-item #f) (item item?) ...) any] @defproc[(gnuplot-replot (gplot gnuplot?) (item item?) ...) any] )]{ Basic plotting functions. } @defproc[(gnuplot-multiplot (gplot gnuplot?) (#:layout layout list? null) (plot procedure?) ...) any]{ Performs a multiplot, with @scheme[layout] a list of @scheme[items], by calling the @scheme[plot] procedures in order with @scheme[gplot] as argument. } @defproc[(gnuplot-hardcopy (gplot gnuplot?) (fname path-string?) (plot procedure? gnuplot-replot) (#:term term item? '(postscript color))) any]{ Plots with output to file. } @deftogether[( @defproc[(gnuplot-set (gplot gnuplot?) (opt item?)) any] @defproc[(gnuplot-set* (gplot gnuplot?) (opt list?)) any] @defproc[(gnuplot-unset (gplot gnuplot?) (opt symbol?)) any] @defproc[(gnuplot-reset (gplot gnuplot?)) any] )]{ Modify plot options. } @section{Example} @margin-note{The images were created with @scheme[gnuplot-hardcopy] and converted to png using imagemagick's convert utility} Here we use a simple iterative example to illustrate how to use the library, assuming familiarity with gnuplot. First, let's create a gnuplot process and a simple data source: @schemeblock[ (define gplot (gnuplot-spawn)) (define sin+cos (build-list 200 (lambda (x) (let ((x (/ (* x pi) 100))) (list x (sin x) (cos x)))))) (define mydata (gnuplot-data sin+cos)) ] Here, @scheme[mydata] is a data source that contains 200 samples from the @scheme[sin] and @scheme[cos] functions. We can split the two functions, creating two plot items: @schemeblock[ (define mysin (gnuplot-item mydata '(using (seq: 1 2) title (str "sin(x)") with line 1))) (define mycos (gnuplot-item mydata '(using (seq: 1 3) title (str "cos(x)") with line 2))) ] Now, to plot the two functions together: @schemeblock[ (gnuplot-set gplot '(title (str "my trigonometrics"))) (gnuplot-plot gplot #:range `((#f ,(* 2 pi)) ()) mysin mycos) ] @image["img/trig.png"] We can take a hardcopy of the plot using @scheme[gnuplot-hardcopy]: @schemeblock[ (gnuplot-hardcopy gplot "/tmp/trig.eps") ] We can create a multiplot layout using @scheme[gnuplot-multiplot]: @schemeblock[ (define (plot-sin gplot) (gnuplot-plot gplot #:range `((#f ,(* 2 pi)) ()) mysin)) (define (plot-cos gplot) (gnuplot-plot gplot #:range `((#f ,(* 2 pi)) ()) mycos)) (gnuplot-reset gplot) (code:comment #, @t{reset plotting}) (gnuplot-multiplot gplot #:layout '(layout (seq 2 1) title (str "multiplot layout")) plot-sin plot-cos) ] @image["img/multi.png"] Finally, to take a hard copy of the multiplot layout: @schemeblock[ (gnuplot-hardcopy gplot "/tmp/multi.eps" (lambda (gplot) (gnuplot-multiplot gplot #:layout '(layout (seq 2 1) title (str "multiplot layout")) plot-sin plot-cos))) ]