scatter-plot.scm 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #!/usr/bin/env guile
  2. !#
  3. (use-modules (charting) (charting csv) (ice-9 match)
  4. ((srfi srfi-1) #:select (filter-map append-map)))
  5. (define (parse-series headers data)
  6. (let lp ((in data) (out (make-list (length headers) '())))
  7. (if (null? in)
  8. (map cons
  9. headers
  10. (map (lambda (test-data) (filter-map string->number test-data))
  11. out))
  12. (lp (cdr in) (map cons (vector->list (car in)) out)))))
  13. (define (read-series file)
  14. (let ((rows (csv-port->row-list (open-input-file file) #\,)))
  15. (if (null? rows)
  16. '()
  17. (cons (basename file)
  18. (parse-series (vector->list (car rows)) (cdr rows))))))
  19. (define (main args)
  20. (match args
  21. ((title output file . max-y)
  22. (unless (string-suffix? ".png" output)
  23. ;; Otherwise we would have the possibility of overwriting data.
  24. ;; That would be bad!
  25. (format (current-error-port)
  26. "Error: output name does not end with .png: ~a\n" output)
  27. (exit 1))
  28. (let ((data (read-series file)))
  29. (make-scatter-plot title
  30. (match data
  31. ((basename (x-label x ...) (y-label y ...) ...)
  32. (map (lambda (y-label y)
  33. (cons y-label (map cons x y)))
  34. y-label y)))
  35. #:y-axis-label (match data
  36. ((basename . _) basename))
  37. #:x-axis-label (match data
  38. ((basename (x-label . _) . _) x-label))
  39. #:min-x 1
  40. #:log-x-base 2
  41. #:max-y (match max-y
  42. ((max-y) (string->number max-y))
  43. (() #f)
  44. (else (error "expecting max-y")))
  45. #:write-to-png output)))
  46. (_
  47. (format (current-error-port)
  48. "Usage: scatter-plot.scm title output file1 [max-y]
  49. The files are expected to be in CSV format, with one row of headers, and
  50. one row per point. The different columns in the CSV file identify the
  51. different series that you want to plot.
  52. ")
  53. (exit 1))))
  54. (main (cdr (command-line)))