From 1c9f6e9a55bb3fe6d1ddea3280a00d0f603584de Mon Sep 17 00:00:00 2001 From: Dimitri Lozeve Date: Thu, 29 Apr 2021 21:33:03 +0200 Subject: [PATCH] Add tick labels on axes --- demo.png | Bin 21621 -> 23770 bytes uniplot/braille.ss | 2 +- uniplot/lineplot.ss | 60 +++++++++++++++++++++++++++----------------- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/demo.png b/demo.png index 8fc99f3f74ca5338852c63e49f6848a526bbd71c..431681c6ae7c6592556fdc99d94ca739a0d59ac1 100644 GIT binary patch literal 23770 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 literal 21621 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 diff --git a/uniplot/braille.ss b/uniplot/braille.ss index b73642b..05547c9 100644 --- a/uniplot/braille.ss +++ b/uniplot/braille.ss @@ -39,7 +39,7 @@ (def row (vector-ref canvas (1- i))) (for/collect ((j (in-range (u8vector-length row)))) (integer->char (+ (char->integer #\⠀) (u8vector-ref row j)))))) - (list->string (flatten (map (lambda (l) (append1 l #\newline)) chars)))) + (string-join (map list->string chars) #\newline)) (def (indexf pred . lsts) (find pred (apply map list lsts))) diff --git a/uniplot/lineplot.ss b/uniplot/lineplot.ss index a3fc2be..a0ee8d1 100644 --- a/uniplot/lineplot.ss +++ b/uniplot/lineplot.ss @@ -1,6 +1,7 @@ (export #t) -(import :std/iter +(import :std/format + :std/iter :std/misc/list :std/misc/string :dlozeve/uniplot/braille @@ -23,33 +24,46 @@ (def (line-plot lsts (colors +default-colors+) width: (width 160) height: (height 80) borders: (borders #t) xlabel: (xlabel #f)) - (def canvases + (define-values (xmin xmax ymin ymax canvases) (match lsts - ([ys] [(draw-canvas (iota (length ys)) ys - (scale-fn 0 (length ys)) - (scale-fn (apply min ys) (apply max ys)) - width: width height: height)]) - ([xs ys] [(draw-canvas xs ys - (scale-fn (apply min xs) (apply max xs)) - (scale-fn (apply min ys) (apply max ys)) - width: width height: height)]) - ([xs . yss] - (let* ((x-scale-fn (scale-fn (apply min xs) (apply max xs))) - (all-ys (flatten yss)) - (min-ys (apply min all-ys)) - (max-ys (apply max all-ys)) - (y-scale-fn (scale-fn min-ys max-ys))) - (for/collect ((ys yss)) - (draw-canvas xs ys x-scale-fn y-scale-fn - width: width height: height)))))) + ([ys] (let ((xmin 0) + (xmax (length ys)) + (ymin (apply min ys)) + (ymax (apply max ys))) + (values xmin xmax ymin ymax + [(draw-canvas (iota (length ys)) ys + (scale-fn xmin xmax) + (scale-fn ymin ymax) + width: width height: height)]))) + ([xs ys] (let ((xmin (apply min xs)) + (xmax (apply max xs)) + (ymin (apply min ys)) + (ymax (apply max ys))) + (values xmin xmax ymin ymax + [(draw-canvas xs ys + (scale-fn xmin xmax) + (scale-fn ymin ymax) + width: width height: height)]))) + ([xs . yss] (let* ((xmin (apply min xs)) + (xmax (apply max xs)) + (all-ys (flatten yss)) + (ymin (apply min all-ys)) + (ymax (apply max all-ys)) + (x-scale-fn (scale-fn xmin xmax)) + (y-scale-fn (scale-fn ymin ymax))) + (values xmin xmax ymin ymax + (for/collect ((ys yss)) + (draw-canvas xs ys x-scale-fn y-scale-fn + width: width height: height))))))) (def canvases-str (canvases->string canvases colors)) (def hor-size (u8vector-length (vector-ref (car canvases) 0))) (def plot (if borders (str - " ┌" (make-string (+ 2 hor-size) #\─) "┐\n │ " - (string-subst canvases-str "\n" " │ \n │ ") - (make-string (+ 1 hor-size) #\ ) - "│\n └" (make-string (+ 2 hor-size) #\─) "┘\n") + (format " ┌─~a─┐\n~5,1F ┤ " (make-string hor-size #\─) ymax) + (string-subst canvases-str "\n" " │\n │ ") + (format " │\n~5,1F ┤~a │\n" ymin (make-string (+ 1 hor-size) #\ )) + (format " └─┬~a┬─┘\n" (make-string (- hor-size 2) #\─)) + (format "\n ~5,1F~a~5,1F\n" xmin (make-string (- hor-size 6) #\ ) xmax)) canvases-str)) (if xlabel (str plot (make-string (quotient hor-size 2) #\ ) xlabel "\n")