Skip to main content

Beautiful terminal charts using only the Python standard library

Project description

termplotx

Beautiful terminal charts using only the Python standard library.

termplotx renders crisp charts directly in your terminal — no matplotlib, no browser, zero required dependencies. It's built for ML engineers, data scientists, and DevOps folks who live in SSH sessions, CI logs, Jupyter terminals, or just want a quick plot without leaving the shell.

Note on the name: the import name and the install name are both termplotx (the shorter termplot was already taken on PyPI).

   200 ┤              ╭───╮
       │          ╭───╯   ╰╮
   145 ┤   ╭──────╯        ╰────
       │╭──╯
    90 ┤╯
       └────────────────────────
        Jan      Mar       May
  • 📈 Sparklines — inline mini charts for metrics: ▂▅▃▇▁▆
  • 📊 Line charts — single and multi-series, high-res braille rendering
  • 📊 Bar charts — horizontal and vertical
  • 📉 Histograms — auto or fixed bins (NumPy-accelerated if installed)
  • Scatter plots — braille sub-pixel resolution
  • 🔥 Heatmaps — truecolor or shade-glyph fallback
  • ⏱️ Live charts — update in place with ANSI escapes
  • 🎨 Themesdark, light, neon, minimal
  • 📐 Responsive — auto-detects terminal width/height
  • 🪟 Cross-platform — Linux, macOS, Windows (auto-enables ANSI)
  • 🧩 Typed — ships py.typed, great Pylance/mypy experience

Table of contents


Install

pip install termplotx

Optional extras:

pip install "termplotx[numpy]"     # faster histogram binning
pip install "termplotx[windows]"   # colorama for older Windows consoles
pip install "termplotx[all]"       # everything optional

termplotx requires Python 3.9+ and has no required dependencies.


Quick start

import termplotx as tp

# A sparkline for a row of metrics
print(tp.sparkline([1, 5, 3, 9, 2, 7, 4, 8]))

# A line chart
import math
print(tp.line([math.sin(i / 5) for i in range(60)], title="sine wave"))

# A bar chart
print(tp.bar([120, 150, 90, 170, 200], labels=["Jan", "Feb", "Mar", "Apr", "May"]))

Every function returns a plain string, so you can print it, log it, write it to a file, put it in an f-string, or embed it in a TUI.


Charts

Sparklines

Compact, one-line charts — perfect for dashboards, log lines, and metrics.

tp.sparkline([1, 5, 3, 9, 2, 7])           # ▁▅▃█▂▆
tp.sparkline(values, width=20)             # resample to 20 chars
tp.sparkline(values, min=0, max=100)       # fixed scale
tp.sparkline(values, theme="neon")         # colored

Line charts

# Single series
print(tp.line(values, title="latency (ms)", width=70, height=15))

# Multiple series with a legend
print(tp.line(
    [series_a, series_b],
    labels=["train", "val"],
    title="loss",
))

# Custom x-axis and fixed y-range
print(tp.line(y, x=timestamps, y_min=0, y_max=1))
          loss
   0.9996 ┤⡠⠊⠉⠒⠤⡀          ⢀⠔⠊⠉⠒⡄
          │⡜      ⠈⢆      ⡠⠃     ⠱⡀
 -2.08e-4 ┤          ⠘⡄  ⡎          ⢣
       -1 ┤            ⠉            ⠈
          └────────────────────────
           0          29.5        59
           ■ train  ■ val

Bar charts

# Horizontal (default)
print(tp.bar([3, 7, 2, 9], labels=["a", "b", "c", "d"]))
print(tp.barh(values, labels))             # explicit

# Vertical (columns)
print(tp.barv([3, 7, 2, 9, 5], labels=["a", "b", "c", "d", "e"], height=8))

# Or dispatch by keyword
print(tp.bar(values, labels, orientation="vertical"))
  a ████████                 3
 bb ██████████████████▋      7
ccc █████▍                   2
  d ████████████████████████ 9

Histograms

print(tp.histogram(samples))               # automatic bin count
print(tp.histogram(samples, bins=20))      # fixed bins
[-2.84, -2.15) █▋                              3
[-2.15, -1.46) ███▏                            6
[-1.46, -0.77) ███████████████▊               30
[-0.77, -0.08) ███████████████████████▋       45
[-0.08,  0.61) ██████████████████████████████ 57

Install the numpy extra for faster binning on large arrays — the output is identical either way.

Scatter plots

print(tp.scatter(xs, ys, title="x vs y", width=60, height=20))

Heatmaps

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(tp.heatmap(matrix, row_labels=["r1", "r2", "r3"], col_labels=["a", "b", "c"]))

With color it paints each cell with a gradient background; without color it falls back to shade glyphs ░▒▓█.

Live charts

Update a chart in place without scrolling the terminal:

import random, time
import termplotx as tp

window = []
with tp.LiveChart() as chart:
    for _ in range(100):
        window.append(random.random())
        window = window[-60:]
        chart.update(tp.sparkline(window, min=0, max=1, width=60))
        time.sleep(0.1)

Or use the convenience loop:

tp.live(lambda: tp.sparkline(next_window()), frames=200, interval=0.1)

Themes & color

Four built-in themes: dark (default), light, neon, minimal.

tp.line(values, theme="neon")
tp.bar(values, labels, theme="light")

Color is auto-detected from the output stream. You can force it:

tp.sparkline(values, color=True)    # force on
tp.sparkline(values, color=False)   # force off (e.g. for log files)

termplotx honors the NO_COLOR and FORCE_COLOR environment variables.


Loading data

termplotx reads many formats out of the box via tp.load:

table = tp.load("data.csv")        # CSV (header auto-detected)
table = tp.load("data.tsv")        # TSV
table = tp.load("data.json")       # list / list-of-lists / list-of-dicts / dict-of-lists
table = tp.load("data.txt")        # whitespace/newline-separated numbers
table = tp.load("-")               # read from stdin

# Columns by name or index
prices = table.column_floats("price")
first  = table.column_floats(0)

print(tp.line(prices, title="price"))

Command-line interface

# Inline numbers
termplotx sparkline 1 5 3 9 2 7

# From files (column by name or index)
termplotx line   data.csv --column price --title "Price"
termplotx bar    data.csv --label name --column score
termplotx hist   data.csv -c value --bins 20
termplotx scatter data.csv --x lon --y lat
termplotx heatmap matrix.csv

# Auto-detect a sensible chart from the data shape
termplotx plot data.csv

# Pipe data in
cat metrics.txt | termplotx sparkline -
psql -c "..." | termplotx line -

Common flags: --theme, --color / --no-color, --ascii, --width, --height, --title, --column/-c (repeatable), --format.

Run termplotx <command> --help for the full list.


How it adapts to your terminal

  • Width/height are auto-detected (shutil.get_terminal_size) and respect COLUMNS/LINES; pass width=/height= to override.
  • Color is emitted only when the output is an interactive TTY (so piped or redirected output stays clean), unless you force it.
  • Unicode glyphs are used when the stream can encode them; otherwise charts fall back to ASCII automatically. Force ASCII with unicode=False or the TERMPLOT_ASCII=1 environment variable.
  • Windows: ANSI is enabled automatically via colorama (if installed) or a built-in ctypes fallback — nothing to configure.

API reference

Function Description
sparkline(data, *, width, min, max, color, theme, unicode) One-line sparkline
line(data, x=None, *, labels, width, height, title, y_min, y_max, ...) Line chart (1D or list of series)
bar(values, labels=None, *, orientation="horizontal", ...) Bar chart dispatcher
barh(values, labels=None, *, width, show_values, ...) Horizontal bars
barv(values, labels=None, *, height, bar_width, gap, ...) Vertical bars
histogram(data, bins=None, *, width, show_counts, ...) Histogram
scatter(x, y, *, width, height, title, ...) Scatter plot
heatmap(matrix, *, row_labels, col_labels, cell_width, ...) 2D heatmap
LiveChart(stream=None, *, hide_cursor=True) Context manager for in-place updates
live(render, *, frames=None, interval=0.2) Convenience live loop
load(path, *, fmt=None) Load CSV/TSV/JSON/TXT/stdin into a Table
THEMES, get_theme(name) Theme registry
terminal_size(), supports_color(), supports_unicode() Terminal helpers

All chart functions return str.


Optional dependencies

Extra Installs Enables
numpy numpy Faster histogram binning
windows colorama ANSI on older Windows consoles
all numpy + colorama Everything optional
dev pytest, build, twine, … Development & release

None are required — the core is pure standard library.


FAQ

Why is there no color in my logs / CI output? That's intentional — color is disabled for non-TTY streams so files and CI logs stay clean. Use color=True (or FORCE_COLOR=1) to force it.

I see ? boxes / garbled characters. Your terminal can't render the Unicode glyphs. Pass unicode=False or set TERMPLOT_ASCII=1 for ASCII-only output.

Does it work in Jupyter? Yes — in a terminal-attached kernel. Printed strings show up fine; truecolor depends on the front-end.


Development

git clone https://github.com/amanmukati09/termplot
cd termplot
python -m venv .venv
.venv\Scripts\activate            # Windows
# source .venv/bin/activate        # macOS/Linux
pip install -e ".[dev]"
pytest

See INSTRUCTIONS.md for the complete build-and-publish walkthrough.


License

MIT © 2026 Aman Mukati

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

termplotx-0.1.0.tar.gz (42.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

termplotx-0.1.0-py3-none-any.whl (37.3 kB view details)

Uploaded Python 3

File details

Details for the file termplotx-0.1.0.tar.gz.

File metadata

  • Download URL: termplotx-0.1.0.tar.gz
  • Upload date:
  • Size: 42.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for termplotx-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3431d25d3f5176861468590dd836690ffb39261a91db422a86a0879368b88a2c
MD5 05041df22458566fd46acbcc0782e87d
BLAKE2b-256 7f7b246df23293d7a2f247715fb7390c76eab3fa9f2303f5a4659b7cc5bd77d1

See more details on using hashes here.

File details

Details for the file termplotx-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: termplotx-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 37.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for termplotx-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9f607b7e56672e1477bdc020f1bff49c24de8bada388f2844cadcb10134c6cf3
MD5 02d7ceb9dd619641000ee185a2e92c4c
BLAKE2b-256 3110a7c04a0674cdb6c69c91d1ed4274e32408202ea6ad3fb030dfdb79c69cfc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page