Graphics
Printing an ASCII bar chart in REPL
Problem
How do I print an ASCII bar chart in REPL to quickly visualize my data?
Solution
(defn ascii-bar-chart
[data marker scale]
(let [vals (map second data)
max-val (apply max vals)
min-val (apply min vals)
val-range (- (max 0 max-val) (min 0 min-val))
scaled-min-val (/ (* scale (- min-val)) val-range)
scaled-max-val (/ (* scale max-val) val-range)
marker-len (count marker)]
(doseq [[k v] data]
(let [neg-bars (if (< v 0) (round (/ (* scale (- v)) val-range)) 0)
pos-bars (if (>= v 0) (round (/ (* scale v) val-range)) 0)
neg-ws (- scaled-min-val neg-bars)
pos-ws (- scaled-max-val pos-bars)]
(println
(str
(apply str (take (* marker-len neg-ws) (repeat " ")))
(apply str (take neg-bars (repeat marker)))
(apply str (take (inc pos-bars) (repeat marker)))
(apply str (take (* marker-len pos-ws) (repeat " "))))
k "-" v)))))
This function prints the horizontal ASCII bar chart for the data given. It handles both positive and negative values.
Arguments:
- data: A seq of key value pairs or a sorted-map. The chart is printed in the order of this seq or sorted-map.
- Keys should be strings (or have a proper toString method).
- Values should be numbers.
- marker: The string to use as the marker in the chart.
- scale: The scale of the chart.
Example:
user=> (ascii-bar-chart [["Jan" 80] ["Feb" -50] ["Mar" 35] ["Apr" -10]] "|" 40)
|||||||||||||||||||||||||| Jan - 80
|||||||||||||||| Feb - -50
|||||||||||| Mar - 35
|||| Apr - -10
nil
user=> (ascii-bar-chart {"Jan" 80 "Feb" -50 "Mar" 35 "Apr" -10} "*" 40)
************************** Jan - 80
**************** Feb - -50
************ Mar - 35
**** Apr - -10
nil
Source: https://gist.github.com/757834
Post preview:
Close preview