Skip to content

wowave/plotcli-py

Repository files navigation

plotcli

Terminal plotting in Python using Unicode Braille characters, block elements, or ASCII. Zero dependencies. Designed for CLI workflows and AI coding assistants like Claude Code.

Inspired by the R plotcli package and Julia's UnicodePlots.jl.

Install

# With uv (recommended)
uv tool install plotcli

# With pip
pip install plotcli

# Or run directly without installing
uvx plotcli fn "sin(x)" 0 6.28

Quick Start

# Pipe data
echo "1 4 9 16 25 36 49 64 81 100" | plotcli line

# Plot a math function
plotcli fn "sin(x)" 0 6.28

# From a Python expression
plotcli scatter -e "[(x, x**2) for x in range(50)]"

# From a CSV file
plotcli line -f data.csv -x time -y value

# Pipe from other commands
seq 100 | awk '{print sin($1/10)}' | plotcli line

Examples

Line Plot

echo "1 4 9 16 25 36 49 64 81 100" | plotcli line --title "Squares"
                               Squares
           ┌───────────────────────────────────────────────────────┐
       100 ┤                                                    ⢀⠤⠊│
           │                                                  ⡠⠒⠁  │
      80.2 ┤                                               ⡠⠔⠉     │
           │                                            ⡠⠔⠉        │
      60.4 ┤                                        ⢀⡠⠔⠉           │
           │                                     ⣀⠤⠒⠁              │
y          │                                 ⢀⡠⠔⠊                  │
      40.6 ┤                             ⣀⠤⠔⠊⠁                     │
           │                         ⣀⠤⠒⠉                          │
      20.8 ┤                   ⣀⡠⠤⠒⠊⠉                              │
           │           ⢀⣀⡠⠤⠔⠒⠊⠉                                    │
         1 ┤⣀⣀⣀⡠⠤⠤⠤⠔⠒⠊⠉⠁                                           │
           └───────────────────────────────────────────────────────┘
            0           2.25          4.5         6.75            9
                                       x

Math Functions

plotcli fn "sin(x)" 0 6.28 --title "Sine Wave"
                              Sine Wave
           ┌───────────────────────────────────────────────────────┐
         1 ┤         ⣀⠴⠒⠋⠉⠉⠙⠒⠤⣀                                    │
           │      ⢀⡴⠋⠁        ⠈⠳⢄                                  │
       0.6 ┤    ⢀⡤⠋              ⠑⣄                                │
           │   ⢠⠊                 ⠈⠱⡄                              │
f      0.2 ┤ ⢀⠜⠁                    ⠘⢆                             │
(          │⢠⠊                        ⠱⡄                           │
x          │⠁                          ⠘⢆                        ⣠⠋│
)     -0.2 ┤                             ⠱⡄                     ⡔⠁ │
           │                              ⠈⢆⡀                 ⡠⠋   │
      -0.6 ┤                                ⠙⢄              ⣠⠚⠁    │
           │                                  ⠑⢦⡀        ⢀⣠⠞⠁      │
        -1 ┤                                    ⠉⠒⠤⣄⣀⣀⣠⠤⠖⠋         │
           └───────────────────────────────────────────────────────┘
            0           1.57         3.14         4.71          6.28
                                       x

Built-in math: sin, cos, tan, sqrt, log, exp, pi, e, and Python's math module.

plotcli fn "exp(-x/5) * cos(x*2)" 0 15 --title "Damped Oscillation"
plotcli fn "x**3 - 3*x" -3 3 --title "Cubic"
plotcli fn "log(x)" 0.1 10 --title "Logarithm"

Histogram

plotcli hist -e "[random.gauss(0,1) for _ in range(500)]" --title "Normal Distribution"
                         Normal Distribution
           ┌───────────────────────────────────────────────────────┐
        62 ┤                       ⣿⡇                              │
           │                       ⣿⡇⢸⣿                            │
      49.6 ┤                 ⢰⣶    ⣿⡇⢸⣿ ⣿⡇⢰⣶                       │
           │                 ⢸⣿    ⣿⡇⢸⣿ ⣿⡇⢸⣿                       │
c     37.2 ┤                 ⢸⣿ ⢰⣶ ⣿⡇⢸⣿ ⣿⡇⢸⣿                       │
o          │               ⣀⡀⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿                       │
u          │            ⢰⣶ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿                       │
n     24.8 ┤            ⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣀⡀ ⣤⡄                 │
t          │          ⣶⡆⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣿⡇                 │
      12.4 ┤    ⢰⣶    ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣿⡇⢠⣤ ⣶⡆            │
           │  ⣀⡀⢸⣿ ⢠⣤ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣿⡇⢸⣿ ⣿⡇⢠⣤ ⣤⡄       │
         0 ┤⣶ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣀⡀⢀⣀ ⣶│
           └───────────────────────────────────────────────────────┘
          -2.48         -1.06        0.36         1.78           3.2
                                       x

Density Plot

plotcli density -e "[random.gauss(0,1) for _ in range(1000)]" --title "Kernel Density"
                            Kernel Density
           ┌───────────────────────────────────────────────────────┐
      0.38 ┤                       ⢀⠤⠒⠊⠉⠉⠢⢄                        │
           │                      ⢰⠁       ⢣                       │
       0.3 ┤                     ⢠⠃         ⢣                      │
d          │                     ⡎           ⢣                     │
e     0.23 ┤                    ⡜             ⢣                    │
n          │                   ⡰⠁              ⠑⡄                  │
s          │                 ⢀⠎                 ⠘⡄                 │
i     0.15 ┤                ⢀⠎                   ⠱⡀                │
t          │               ⢀⠎                     ⢣                │
y     0.08 ┤              ⢠⠊                       ⠱⡀              │
           │           ⢀⠤⠒⠁                         ⠈⠑⠤⡀           │
   1.7e-05 ┤⣀⣀⣀⣀⣀⣀⣀⡠⠤⠔⠊⠁                               ⠈⠑⠢⠤⠤⢄⣀⣀⣀⣀⣀⣀│
           └───────────────────────────────────────────────────────┘
          -4.01         -2.01        -0.02        1.97          3.96
                                       x

Boxplot

plotcli boxplot \
  -e "[[random.gauss(m, 1+i*0.3) for _ in range(100)] for i, m in enumerate([0, 3, 7])]" \
  --title "Boxplots"
                               Boxplots
           ┌───────────────────────────────────────────────────────┐
     10.45 ┤                                           ⠈⠉⢹⠉⠉       │
           │                                             ⢸         │
      7.83 ┤                                         ⡖⠒⠒⠒⠚⠒⠒⠒⠒⡆    │
           │                           ⢀             ⡏⠉⠉⠉⠉⠉⠉⠉⠉⡇    │
v     5.22 ┤                         ⠐⠒⢲⠒⠒           ⠉⠉⠉⠉⢹⠉⠉⠉⠉⠁    │
a          │                           ⢸                 ⢸         │
l          │                       ⣖⣒⣒⣒⣚⣒⣒⣒⣒⡆          ⢀⣀⣸⣀⣀       │
u      2.6 ┤       ⠒⠒⡖⠒⠂           ⠧⠤⠤⠤⢤⠤⠤⠤⠤⠇            ⠐         │
e          │    ⢀⣀⣀⣀⣀⣇⣀⣀⣀⣀             ⢸                           │
     -0.02 ┤    ⢸⣒⣒⣒⣒⣒⣒⣒⣒⣺           ⠐⠒⠚⠒⠒                         │
           │         ⡇                                             │
     -2.63 ┤       ⠉⠉⡉⠉⠁                                           │
           └───────────────────────────────────────────────────────┘
                   box_1             box_2             box_3
                                       x

Scatter Plot

plotcli scatter \
  -e "[(x, x**1.5 + random.gauss(0,5)) for x in range(40)]" \
  --title "Noisy Power Law"

Heatmap

plotcli heatmap \
  -e "[[math.sin(r/3+c/3) for c in range(20)] for r in range(10)]" \
  --title "Heatmap"

Canvas Types

Three rendering backends with different resolution/compatibility tradeoffs:

Braille (default) -- highest resolution

plotcli fn "sin(x)" 0 6.28 --canvas braille

Uses Unicode Braille patterns (U+2800-U+28FF). Each character cell contains a 2x4 dot grid, giving 8x the effective resolution of ASCII.

Block -- medium resolution

plotcli fn "sin(x)" 0 6.28 --canvas block
                             Block Canvas
           ┌───────────────────────────────────────────────────────┐
         1 ┤         ▄▄█▀▀▀▀█▄▄                                    │
           │       ▄█▀        ▀▀▄                                  │
       0.6 ┤     ▄▀▀             █▄                                │
           │   ▄█▀                 █▄                              │
f      0.2 ┤  █▀                    ▀█▄                            │
(          │▄█                        █▄                           │
x          │▀                          ▀█                        █▀│
)     -0.2 ┤                             █▄                    ▄█  │
           │                              ▀█                 ▄█▀   │
      -0.6 ┤                                ▀█             ▄▄▀     │
           │                                  ▀█▄        ▄█▀       │
        -1 ┤                                    ▀▀█▄▄▄▄█▀▀         │
           └───────────────────────────────────────────────────────┘

Uses half-block characters (▀ ▄ █) for 2x vertical resolution.

ASCII -- maximum compatibility

plotcli fn "sin(x)" 0 6.28 --canvas ascii
                             ASCII Canvas
           ┌───────────────────────────────────────────────────────┐
         1 ┤          ********                                     │
           │       ****      ****                                  │
       0.6 ┤     ***            ***                                │
           │   ***                ***                              │
f      0.2 ┤  **                    **                             │
(          │**                        **                           │
x          │*                          **                        **│
)     -0.2 ┤                             **                    **  │
           │                              ***                ***   │
      -0.6 ┤                                ***            ***     │
           │                                  ****      ****       │
        -1 ┤                                     ********          │
           └───────────────────────────────────────────────────────┘

Works in any terminal. Uses * for data points.

Data Input

Method Example
Pipe values echo "1 4 9 16" | plotcli line
Pipe lines seq 50 | plotcli line
x,y pairs echo -e "1,2\n3,4\n5,6" | plotcli scatter -d ","
Expression plotcli line -e "[x**2 for x in range(20)]"
Tuple list plotcli scatter -e "[(x, sin(x)) for x in range(50)]"
CSV file plotcli line -f data.csv -x time -y price
JSON echo '[1,4,9,16]' | plotcli line -j
Math function plotcli fn "sin(x)*exp(-x/5)" 0 20
Shell pipeline curl -s api | jq '.[].value' | plotcli line

Options

-W, --width       Canvas width in characters (auto-detected)
-H, --height      Canvas height in characters (auto-detected)
-t, --title       Plot title
--x-label         X-axis label
--y-label         Y-axis label
-c, --color       Series color (red, green, blue, yellow, magenta, cyan, ...)
--canvas          braille (default), block, or ascii
--xlim MIN MAX    X-axis limits
--ylim MIN MAX    Y-axis limits
--bins N          Number of histogram bins
--no-legend       Hide legend
-d, --delimiter   Input delimiter
-j, --json        Parse stdin as JSON
-e, --eval        Python expression for data
-f, --file        CSV/TSV file path
-x, --x-col       X column name or index
-y, --y-col       Y column name or index

Use with Claude Code

plotcli is designed for AI-assisted CLI workflows. Claude Code can generate and display plots inline:

> Plot a sine wave

$ plotcli fn "sin(x)" 0 6.28 --title "Sine Wave"

> Show me the distribution of file sizes in this directory

$ find . -type f -exec stat -f%z {} \; | plotcli hist --title "File Sizes" --bins 20

> Visualize the CSV data

$ plotcli scatter -f measurements.csv -x temperature -y pressure --title "T vs P"

To make plotcli available globally for Claude Code:

uv tool install plotcli          # install globally via uv
# or
pip install plotcli              # install globally via pip

Python API

import plotcli

# Quick one-liners
plotcli.line(range(10), [x**2 for x in range(10)], title="Squares").show()
plotcli.scatter(xs, ys, title="My Data", canvas_type="braille").show()
plotcli.histogram(data, bins=20, title="Distribution").show()
plotcli.density(data, title="KDE").show()
plotcli.boxplot([group_a, group_b], names=["A", "B"]).show()
plotcli.function_plot("sin(x)*x", 0, 10).show()

# Multi-series
from plotcli import Plot
p = Plot(title="Comparison", width=60, height=15)
p.add(x1, y1, "line", color="blue", name="model")
p.add(x2, y2, "scatter", color="red", name="data")
p.show()

# Get string output (no print)
output = p.render()

License

LGPL-3.0 (same as the original R plotcli)

Credits

Python port inspired by plotcli by Claas Heuer, which was in turn inspired by UnicodePlots.jl.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages