From 98c6ab537c79e214b1ed934e1f8e66582ab87057 Mon Sep 17 00:00:00 2001 From: Dimitri Lozeve Date: Sat, 23 Oct 2021 19:34:10 +0200 Subject: [PATCH] Allow plotting very large CSV files Using apply leads to implementation limits in the number of arguments which are fairly low. Refactoring everything as folds allows to handle an arbitrary number of datapoints. --- uniplot.ss | 11 +++++++---- uniplot/lineplot.ss | 12 ++++++------ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/uniplot.ss b/uniplot.ss index 95476d0..53ed9eb 100755 --- a/uniplot.ss +++ b/uniplot.ss @@ -3,15 +3,18 @@ (export main) (import :std/iter + :std/misc/func :std/text/csv :dlozeve/uniplot/lineplot) +(def (parse-number s) + (or (string->number s) +nan.0)) + (def (main . args) (def csv (read-csv-lines (current-input-port))) (def names (car csv)) (def lsts - (apply map list - (for/collect ((row (cdr csv))) - (for/collect ((x row)) - (or (string->number x) +nan.0))))) + (for/fold (lsts (repeat '() (length names))) + ((row (cdr csv))) + (map cons (map parse-number row) lsts))) (displayln (line-plot lsts title: (if (null? args) "" (car args)) names: names))) diff --git a/uniplot/lineplot.ss b/uniplot/lineplot.ss index b5fec98..291683b 100644 --- a/uniplot/lineplot.ss +++ b/uniplot/lineplot.ss @@ -76,18 +76,18 @@ (match lsts ([ys] (let ((xmin 0) (xmax (length ys)) - (ymin (apply nanmin ys)) - (ymax (apply nanmax ys))) + (ymin (for/fold (ymin +nan.0) (y ys) (nanmin ymin y))) + (ymax (for/fold (ymax +nan.0) (y ys) (nanmax ymax y)))) (values xmin xmax ymin ymax [(draw-canvas (iota (length ys)) ys (scale-fn xmin xmax) (scale-fn ymin ymax) width: width height: height)]))) - ([xs . yss] (let* ((xmin (apply nanmin xs)) - (xmax (apply nanmax xs)) + ([xs . yss] (let* ((xmin (for/fold (xmin +nan.0) (x xs) (nanmin xmin x))) + (xmax (for/fold (xmax +nan.0) (x xs) (nanmax xmax x))) (all-ys (flatten yss)) - (ymin (apply nanmin all-ys)) - (ymax (apply nanmax all-ys)) + (ymin (for/fold (ymin +nan.0) (y all-ys) (nanmin ymin y))) + (ymax (for/fold (ymax +nan.0) (y all-ys) (nanmax ymax y))) (x-scale-fn (scale-fn xmin xmax)) (y-scale-fn (scale-fn ymin ymax))) (values xmin xmax ymin ymax