lab/gnuplot.ss
#lang scheme/base

(require
 "output-process.ss"
 "../tools.ss"
 scheme/system
 scheme/match)

(provide
 gnuplot
 open-gnuplot
 close-gnuplot
 current-gnuplot
 close-current-gnuplot
 plot
 splot
 mplot
 lplot
 )


(define current-gnuplot (make-parameter #f))

(define (close-current-gnuplot)
  (when (current-gnuplot)
    (close-gnuplot (current-gnuplot))
    (current-gnuplot #f)))

(define (need-current-gnuplot)
  (let ((p (current-gnuplot)))
    (unless p
      (current-gnuplot (open-gnuplot))))
  (current-gnuplot))
        
(define (open-gnuplot)
  (open-output-process "gnuplot"))

(define close-gnuplot close-output-port)

(define (gnuplot . args)
  (parameterize ((current-output-port (need-current-gnuplot)))
    (if (null? args)
        (flush-output)
        (apply printf args))))

(define (plot xs ys #:with [with 'lines])
  (gnuplot "plot '-' with ~s\n" with)
  (for ((x xs)
        (y ys))
    (gnuplot "~a ~a\n" x y))
  (gnuplot "e\n")
  (gnuplot))

(define (splot xs ys zs #:with [with 'lines])
  (gnuplot "splot '-' with ~s\n" with)
  (for ((x xs)
        (y ys)
        (z zs))
    (gnuplot "~a ~a ~a\n" x y z))
  (gnuplot "e\n")
  (gnuplot))

(define (mplot rows
               #:plot (plot 'plot)
               #:with (with 'lines))
  (gnuplot "~a '-' matrix with ~a\n" plot with)
  (for ((row rows))
    (for ((el row))
       (gnuplot "~a " el))
    (gnuplot "\n"))
  (gnuplot "e\ne\n")
  (gnuplot))

(define (lplot row #:with (with 'lines))
  (mplot (list row) #:with with))