Terminal plotting using Unicode Braille/Block/ASCII. Zero dependencies. Pipe data, plot math functions, read CSV -- all from the CLI.
Project description
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file plotcli_py-0.1.0.tar.gz.
File metadata
- Download URL: plotcli_py-0.1.0.tar.gz
- Upload date:
- Size: 460.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6e37789efd468fc7227b60c9e2f07dd1c0df5f50c1dd0021a037fce0620d005b
|
|
| MD5 |
e8167b62cd3fda36be09acd94fd1cc88
|
|
| BLAKE2b-256 |
7fec6e5c3b7e35de68b829301abe8db1b8db919f583d526fda2c392648035926
|
File details
Details for the file plotcli_py-0.1.0-py3-none-any.whl.
File metadata
- Download URL: plotcli_py-0.1.0-py3-none-any.whl
- Upload date:
- Size: 520.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
87703e425dacc47964a51ee62a91f5dabe360b1b098dd5387b30cc9e92551c6b
|
|
| MD5 |
ec5c07d112ac084e0287a4901f401cec
|
|
| BLAKE2b-256 |
ebe3bfff2c3ced84bfe47df4cb279e82ac649aaa384f11215bd66e7b376891d3
|