1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- #!/usr/bin/env guile
- !#
- (use-modules (charting) (charting csv) (ice-9 match)
- ((srfi srfi-1) #:select (filter-map append-map)))
- (define (parse-series headers data)
- (let lp ((in data) (out (make-list (length headers) '())))
- (if (null? in)
- (map cons
- headers
- (map (lambda (test-data) (filter-map string->number test-data))
- out))
- (lp (cdr in) (map cons (vector->list (car in)) out)))))
- (define (read-series file)
- (let ((rows (csv-port->row-list (open-input-file file) #\,)))
- (if (null? rows)
- '()
- (cons (basename file)
- (parse-series (vector->list (car rows)) (cdr rows))))))
- (define (main args)
- (match args
- ((title output file . max-y)
- (unless (string-suffix? ".png" output)
- ;; Otherwise we would have the possibility of overwriting data.
- ;; That would be bad!
- (format (current-error-port)
- "Error: output name does not end with .png: ~a\n" output)
- (exit 1))
- (let ((data (read-series file)))
- (make-scatter-plot title
- (match data
- ((basename (x-label x ...) (y-label y ...) ...)
- (map (lambda (y-label y)
- (cons y-label (map cons x y)))
- y-label y)))
- #:y-axis-label (match data
- ((basename . _) basename))
- #:x-axis-label (match data
- ((basename (x-label . _) . _) x-label))
- #:min-x 1
- #:log-x-base 2
- #:max-y (match max-y
- ((max-y) (string->number max-y))
- (() #f)
- (else (error "expecting max-y")))
- #:write-to-png output)))
- (_
- (format (current-error-port)
- "Usage: scatter-plot.scm title output file1 [max-y]
- The files are expected to be in CSV format, with one row of headers, and
- one row per point. The different columns in the CSV file identify the
- different series that you want to plot.
- ")
- (exit 1))))
- (main (cdr (command-line)))
|