ASCII Plots

6 functions for terminal-friendly visualizations using Unicode characters. Render directly in the REPL, notebooks, or pipe to log files. Zero dependencies.

sparkline

Render a compact inline chart using Unicode block characters. Perfect for showing trends in a single line.

sparkline(data) -> string
sparkline([1, 5, 2, 8, 3, 7, 4, 6])
# "▂▆▃█▃▇▄▆"

let coverage = [12, 45, 89, 102, 67, 54, 33, 28, 15]
println("Coverage: ", sparkline(coverage))
Output
Coverage: ▁▃▆█▅▄▂▂▁

bar_chart

Bar chart in the terminal.

bar_chart(data, opts?) -> string
OptionTypeDescription
labelslist<string>Bar labels
widthintMax bar width (default: 40)
titlestringChart title
let counts = {"A": 2500, "T": 2300, "C": 2600, "G": 2400}
println(bar_chart(counts, {title: "Nucleotide Counts", width: 50}))
Output
Nucleotide Counts
A |████████████████████████████████████████████████  | 2500
T |████████████████████████████████████████████      | 2300
C |██████████████████████████████████████████████████| 2600
G |██████████████████████████████████████████████    | 2400

boxplot

ASCII boxplot showing min, Q1, median, Q3, max, and outliers.

boxplot(data, opts?) -> string
let quality = [28, 30, 32, 35, 33, 31, 29, 36, 34, 27, 38, 12]
println(boxplot(quality, {title: "Base Quality Scores", width: 60}))

# Multiple boxplots
let samples = table({
  "Control": [28, 30, 32, 35, 33],
  "Treated": [22, 25, 28, 24, 26],
  "Mutant":  [35, 38, 40, 37, 36]
})
println(boxplot(samples))
Output
Base Quality Scores
 o           |----[======|=====]---|
 12          27   29    32    35   38

hist

Text-mode histogram with configurable bin count.

hist(data, bins?) -> string
set_seed(42)
let lengths = range(0, 1000) |> map(|_| int(random() * 300))
println(hist(lengths, 15))
Output
Histogram (n=1000, bins=15):
  [     0.0,     19.9) |█████████████████████████████ 59
  [    19.9,     39.9) |████████████████████████████ 57
  [    39.9,     59.8) |█████████████████████████████████ 68
  [    59.8,     79.7) |██████████████████████████████ 61
  [    79.7,     99.7) |█████████████████████████████ 59
  [    99.7,    119.6) |██████████████████████████████████ 69
  [   119.6,    139.5) |█████████████████████████████████████ 75
  [   139.5,    159.5) |███████████████████████████████████████ 79
  [   159.5,    179.4) |█████████████████████████████████ 67
  [   179.4,    199.3) |███████████████████████████████ 63
  [   199.3,    219.3) |████████████████████████████████████████ 81
  [   219.3,    239.2) |██████████████████████████████████ 70
  [   239.2,    259.1) |█████████████████████████████ 60
  [   259.1,    279.1) |████████████████████████████████████ 73
  [   279.1,    299.0] |█████████████████████████████ 59

scatter

Terminal scatter plot using Braille characters for sub-cell resolution.

scatter(x, y) -> string
let x = range(0, 50) |> map(|i| float(i) / 10.0)
let y = map(x, |v| sin(v))
println(scatter(x, y))
Output
sin(x)
 1.0│    ⠠⡐                    ⠀⡐
    │  ⠀☁  ⠀                  ☁  ⠀
 0.5│⠀☁      ⠐                      ⠐
    │☁        ⠀              ☁        ⠀
 0.0│──────────⠒──────────────⠒──────────
    │           ⠀            ☁
-0.5│            ⠐          ⠀
    │              ⠀      ☁
-1.0│                ⠐⠀⡐☁
    └──────────────────────────────────
     0.0    1.0    2.0    3.0    4.0    5.0

heatmap_ascii

Render a heatmap in the terminal using Unicode block characters.

heatmap_ascii(data, opts?) -> string
let data = matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
println(heatmap_ascii(data, {title: "Expression"}))