;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; GnuPlot based plotting functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar plot-stream nil) (defvar plot-error nil) (defvar plot-pid nil) ;;; Open a connection to a gnuplot process (defun open-plot () (multiple-value-bind (input error pid) (excl:run-shell-command "gnuplot" :wait nil :input :stream :error-output :output) (setf plot-stream input plot-error error plot-pid pid))) ;;; Close and terminate gnuplot (defun close-plot () (when plot-stream (format plot-stream "quit~%") (close plot-stream) (setf plot-stream nil) (multiple-value-bind (status pid) (sys:os-wait) (declare (ignore status pid))))) ;;; Send an arbitrary command to gnuplot (defun plot-command (&optional (command "")) (if (not plot-stream) (open-plot)) (format plot-stream command) (format plot-stream "~%") (finish-output plot-stream)) ;;; Reset all 'set' options to the default values (defun plot-reset () (plot-command "reset")) ;;; Set autoscale for selected axes (defun plot-set-autoscale () (if (not plot-stream) (open-plot)) (format plot-stream "set autoscale~%") (finish-output plot-stream)) ;;; Set x range (defun plot-set-x-range (range) (if (not plot-stream) (open-plot)) (when range (format plot-stream "set xrange [~f:~f]~%" (first range)(second range)) (finish-output plot-stream))) ;;; Set y range (defun plot-set-y-range (range) (if (not plot-stream) (open-plot)) (when range (format plot-stream "set yrange [~f:~f]~%" (first range)(second range)) (finish-output plot-stream))) ;;; Set z range (defun plot-set-z-range (range) (if (not plot-stream) (open-plot)) (when range (format plot-stream "set zrange [~f:~f]~%" (first range)(second range)) (finish-output plot-stream))) ;;; Set grid (defun plot-set-grid () (if (not plot-stream) (open-plot)) (format plot-stream "set grid xtics; set grid ytics; set grid ztics~%") (finish-output plot-stream)) ;;; Set surface (defun plot-set-surface () (if (not plot-stream) (open-plot)) (format plot-stream "set surface~%") (finish-output plot-stream)) ;;; Set parametric mode (defun plot-set-parametric () (if (not plot-stream) (open-plot)) (format plot-stream "set parametric~%") (finish-output plot-stream)) ;;; Set ticslevel (defun plot-set-ticslevel (&optional (level 0)) (if (not plot-stream) (open-plot)) (format plot-stream "set ticslevel ~s~%" level) (finish-output plot-stream)) ;;; Set title (defun plot-set-title (&optional (title nil)) (if (not plot-stream) (open-plot)) (when title (format plot-stream "set title ~s~%" title) (finish-output plot-stream))) ;;; Set the labels for a plot (defun plot-set-label (&optional (label nil)) (if (not plot-stream) (open-plot)) (when label (format plot-stream "set label ~s~%" label) (finish-output plot-stream))) ;;; Set the margins of a plot (defun plot-set-margins (&optional (margin 1)) (if (not plot-stream) (open-plot)) (when margin (format plot-stream "set tmargin ~s~%" margin) (format plot-stream "set lmargin ~s~%" margin) (format plot-stream "set rmargin ~s~%" margin) (format plot-stream "set bmargin ~s~%" margin) (finish-output plot-stream))) ;;; Set the borders of a plot (defun plot-set-border (&optional (border nil)) (if (not plot-stream) (open-plot)) (when border (format plot-stream "set border ~s~%" border) (finish-output plot-stream))) ;;; Start a multiplot (defun plot-start-multiplot () (if (not plot-stream) (open-plot)) (format plot-stream "set multiplot~%") (finish-output plot-stream)) ;;; End a multiplot (defun plot-end-multiplot () (if (not plot-stream) (open-plot)) (format plot-stream "set nomultiplot~%") (finish-output plot-stream)) ;;; Set origin and size of plot area (defun plot-size (xorigin yorigin xsize ysize) (if (not plot-stream) (open-plot)) (format plot-stream "set origin ~s,~s~%" (coerce xorigin 'float) (coerce yorigin 'float)) (format plot-stream "set size ~s,~s~%" (coerce xsize 'float) (coerce ysize 'float)) (finish-output plot-stream)) ;;; Simple data plot (defun plot-data (data &key (style "linespoints") (label "")) (if (not plot-stream) (open-plot)) (plot-set-grid) (format plot-stream "plot '-'") (if label (format plot-stream " title ~s" label)) (if style (format plot-stream " with ~a" style)) (format plot-stream "~%") (loop for x from 0 for y in data do (format plot-stream "~f ~f~%" x y)) (format plot-stream "e~%") (finish-output plot-stream)) ;;; Plot a supplied curve (defun plot-2d-curve (curve &key (style "linespoints") (label "")) (if (not plot-stream) (open-plot)) (plot-set-grid) (format plot-stream "plot '-'") (if label (format plot-stream " title ~s" label)) (if style (format plot-stream " with ~a" style)) (format plot-stream "~%") (loop for x in curve by #'cddr for y in (cdr curve) by #'cddr do (format plot-stream "~f ~f~%" x y)) (format plot-stream "e~%") (finish-output plot-stream)) ;; Plot a list of supplied curves (defun plot-2d-curves (curves &key (styles "linespoints") (labels "")) (if (not plot-stream) (open-plot)) (plot-set-grid) (if (not (listp styles)) (setf styles (loop repeat (length curves) collect styles))) (if (not (listp labels)) (setf labels (loop repeat (length curves) collect labels))) (format plot-stream "plot") (loop for index from 0 for style in styles for label in labels do (format plot-stream " '-' ") (if label (format plot-stream " title ~s" label)) (if style (format plot-stream " with ~a" style)) (if (/= index (- (length curves) 1)) (format plot-stream ", "))) (format plot-stream "~%") (loop for curve in curves do (loop for x in curve by #'cddr for y in (cdr curve) by #'cddr do (format plot-stream "~f ~f~%" x y)) (format plot-stream "e~%")) (finish-output plot-stream)) ;;; Plot a 3d curve (defun plot-3d-curve (3d-curve &key (style "linespoints") (label "") (zstyle "impulses") (xrot) (zrot) (scale) (zscale)) (if (not plot-stream) (open-plot)) (plot-set-border (+ 127 256 512)) (plot-set-grid) (plot-set-surface) (plot-set-parametric) (plot-set-ticslevel 0) (if (or xrot zrot scale zscale) (format plot-stream "set view ~a,~a,~a,~a~%" (if xrot xrot "") (if zrot zrot "") (if scale scale "") (if zscale zscale ""))) (format plot-stream "splot '-'") (if label (format plot-stream " title ~s" label)) (if style (format plot-stream " with ~a 1" style)) (if zstyle (format plot-stream ", '-' notitle with ~a 1" zstyle)) (format plot-stream "~%") (loop for x in 3d-curve by #'cdddr for y in (cdr 3d-curve) by #'cdddr for z in (cddr 3d-curve) by #'cdddr do (format plot-stream "~f ~f ~f~%" x y z)) (format plot-stream "e~%") (if zstyle (loop for x in 3d-curve by #'cdddr for y in (cdr 3d-curve) by #'cdddr for z in (cddr 3d-curve) by #'cdddr do (format plot-stream "~f ~f ~f~%" x y z) finally (format plot-stream "e~%"))) (finish-output plot-stream))