kaz
Pipe data to an honest terminal plot. A stdin-first CLI over malevich: the first look at any data, straight from the shell.
|
|
|
The plot goes to stderr by default, so stdout stays the data channel — and
-O echoes the input through, so the plot can sit in the middle of a pipeline
without breaking it:
| |
sine
20 ┤ ⡠⠤⠒⠉⠉⠉⠉⠉⠒⠤⣀
│ ⡠⠔⠊ ⠉⠢⡀
│ ⠔⠊ ⠈⠢⢄ ⢀⡠⠊
10 ┤ ⠑⠤⡀ ⢀⠔⠁
│ ⠈⠢⢄⡀ ⢀⠤⠒⠁
│ ⠈⠢⣀⡀ ⢀⡠⠔⠊⠁
0 ┤ ⠈⠉⠉⠒⠉⠉⠁
└┬───────────┬───────────┬──────────┬───────────┬
0 10 20 30 40
count tallies bare labels — the log-wrangler's friend, no sort | uniq -c:
|
status codes
5 ┤ ███████
│ ███████ ▁▁▁▁▁▁
│ ███████ ██████
│ ███████ ██████ ▂▂▂▂▂▂▂ ▂▂▂▂▂▂
0 ┤ ███████ ██████ ███████ ██████
└─────────────────────────────────────
200 404 301 500
Install
The Homebrew formula (homebrew/kaz.rb) also installs the
completions and man page. Shell completions (bash, zsh, fish) live in
completions/ and a man page in man/kaz.1 — to
wire them up by hand:
Charts
| Command | Alias | What | Input shape |
|---|---|---|---|
line |
l |
line chart, one line per series | y | xy | xyy | xyxy | yx |
scatter |
s |
scatter plot | xy | xyy |
bar |
b |
one bar per label | label value |
hist |
— | histogram (--bins N to fix the count) |
columns of numbers |
count |
c |
value frequencies as bars | one column of labels |
density |
d |
kernel density estimate | columns of numbers |
ecdf |
— | empirical cumulative distribution | columns of numbers |
box |
— | a box plot per column | columns are groups |
violin |
— | a violin plot per column | columns are groups |
hist2d |
— | 2D histogram (density grid) | xy |
heatmap |
— | shade a row-major matrix | rows of numbers |
ecdf, violin, and hist2d are charts no other CLI plotter ships.
Input
Fields are separated by any run of whitespace by default — bare numbers,
TSV, and column-style output all just work. -d CHAR sets one explicit
separator (-d, for CSV-shaped data). -H reads a header row and uses its
names to label the series.
--fmt decides how columns map onto axes:
y— each column is a y-series over its row index (default: one column)xy— first column x, second column yxyy— first column x, every remaining column a series (default: 2+ columns)xyxy— columns pair up:(x0,y0) (x1,y1) …yx— first column y, second column x (YouPlot compatibility)
A field that will not parse becomes an honest gap in the plot, and a one-line
tally (3 values could not be parsed) goes to stderr afterward — silenced with
-q. This parses fields, not CSV: for quotes and embedded delimiters, shape
the data upstream (xsv select …, mlr --c2t …) and pipe the result in.
Options
-o TARGET plot destination: stderr (default), - for stdout, or a FILE
-O pass input through to stdout (mid-pipeline mode)
-d CHAR field separator (default: any run of whitespace)
-H first row is a header; its names label the series
--fmt FMT column mapping: y | xy | xyy | xyxy | yx
-w N, -h N frame width and height in cells (0..4096; max 4194304 cells)
-t TITLE plot title
--xlabel TEXT --ylabel TEXT
--xlim A,B --ylim A,B fix an axis range
--log-x --log-y
--time-x read the x column as time (unix seconds or ISO 8601)
--bins N histogram bin count (hist; 1..1000000; default: automatic)
--cols LIST select/reorder columns: header names (with -H) or 0-based indices
--by COL scatter: color points by this column's categories
--colormap M heatmap/hist2d: viridis | magma | cividis | greys | red-blue | purple-orange
--midpoint V center the colormap on a value (signed data)
--emit-code print the equivalent malevich Rust program, data inlined
--color WHEN auto | always | never
--charset SET auto | ascii | half | quad | sextant | braille | octant
--pixels WHEN auto | always | never — sixel/kitty/iTerm2 image panel from a pipe
-q suppress the unparsed-values tally
--version --help
Color auto-detects from the destination stream. The glyph tier defaults to
quadrants in UTF-8 (ASCII for a non-UTF-8 locale); use --charset or
MALEVICH_CHARSET to opt into a denser tier your font supports. Where the terminal
speaks a pixel protocol the plot panel upgrades to a real image — even
mid-pipeline. -h is height; help is --help only.
--emit-code is the bridge out of the shell: once the piped chart looks right,
it prints the equivalent malevich Rust program — same calls, your parsed data
inlined as literals — ready to paste into a project:
Live
--live reads stdin forever, one value per line, and repaints a sliding line in
place — no alt-screen, so the final frame stays in your scrollback, and Ctrl-C
restores the cursor. Line only.
| | |
| |
--window N sets the window length (1..1000000), --fps N the repaint rate
(1..1000; default 10), and --rate plots the per-interval delta of a monotonic
counter.
If a live plot looks frozen, the producer is buffering — pipes hold output
until a block fills. Unbuffer at the source: stdbuf -oL producer,
grep --line-buffered, or awk '{print; fflush()}'.
Design
kaz contains zero rendering logic: it parses arguments, frames stdin, and
calls the public malevich API. Every flag names an existing library concept — a
frame field, a preset argument, a scale option, or plot furniture. It is the
proof of the library's central claim, that a pure string-renderer is enough.
License
MIT or Apache-2.0, matching malevich.