Skip to content

amanmukati09/termplot

Repository files navigation

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

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages