kuva CLI
kuva is the command-line front-end for the kuva plotting library. It reads tabular data from a TSV or CSV file (or stdin) and writes an SVG — or PNG/PDF with the right feature flag — to a file or stdout.
kuva <SUBCOMMAND> [FILE] [OPTIONS]
Installation
Step 1 — install Rust
If you don't have Rust installed, get it via rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Follow the on-screen prompts (the defaults are fine). Then either restart your shell or run:
source ~/.cargo/env
Verify with cargo --version. You only need to do this once.
Step 2 — install kuva
From crates.io (recommended once a release is published):
cargo install kuva --features cli # SVG output
cargo install kuva --features cli,full # SVG + PNG + PDF
From a local clone (install to ~/.cargo/bin/ and put it on your $PATH):
git clone https://github.com/Psy-Fer/kuva && cd kuva
cargo install --path . --features cli # SVG output
cargo install --path . --features cli,full # SVG + PNG + PDF
After either method, kuva is available anywhere in your shell — no need to reference ./target/release/kuva or modify $PATH manually. Confirm with:
kuva --help
Building without installing
If you only want to build and run from the repo without installing:
cargo build --release --bin kuva --features cli,full
./target/release/kuva --help
Input
Every subcommand takes an optional positional FILE argument. If omitted or -, data is read from stdin.
# from file
kuva scatter data.tsv
# from stdin
cat data.tsv | kuva scatter
# explicit stdin
kuva scatter - < data.tsv
Delimiter detection
| Priority | Rule |
|---|---|
| 1 | --delimiter flag |
| 2 | File extension: .csv → ,, .tsv/.txt → tab |
| 3 | Sniff first line: whichever of tab or comma appears more often |
Header detection
If the first field of the first row fails to parse as a number, the row is treated as a header. Override with --no-header.
Column selection
Columns are selected by 0-based integer index or header name:
kuva scatter data.tsv --x 0 --y 1 # by index
kuva scatter data.tsv --x time --y value # by name (requires header)
Output
| Flag | Effect |
|---|---|
| (omitted) | SVG to stdout |
-o out.svg | SVG to file |
-o out.png | PNG (requires --features png) |
-o out.pdf | PDF (requires --features pdf) |
Format is inferred from the file extension. Any unrecognised extension is treated as SVG.
Shared flags
These flags are available on every subcommand.
Output & appearance
| Flag | Default | Description |
|---|---|---|
-o, --output <FILE> | stdout (SVG) | Output file path (mutually exclusive with --terminal) |
--title <TEXT> | — | Title displayed above the chart |
--width <PX> | 800 | Canvas width in pixels |
--height <PX> | 500 | Canvas height in pixels |
--theme <NAME> | light | Theme: light, dark, solarized, minimal |
--palette <NAME> | category10 | Color palette for multi-series plots |
--cvd-palette <NAME> | — | Colour-vision-deficiency palette: deuteranopia, protanopia, tritanopia. Overrides --palette. |
--background <COLOR> | (theme default) | SVG background color (any CSS color string) |
Fonts
| Flag | Default | Description |
|---|---|---|
--embed-font | off | Embed DejaVu Sans directly in SVG output (mutually exclusive with --terminal) |
By default, SVG output references fonts by name and relies on the viewer to resolve them. This works fine in browsers and on any system where DejaVu Sans, Liberation Sans, or Arial is installed. In environments with no system fonts — headless servers, containers, CI pipelines — text may be missing or fall back to an unexpected face.
--embed-font bakes DejaVu Sans as a base64 @font-face block into the SVG <style> element, making the file fully self-contained at the cost of roughly 1 MB of extra size. PNG and PDF output is unaffected: those backends always have the font available regardless of this flag.
# Self-contained SVG for use with rsvg-convert or similar tools in containers
kuva scatter data.tsv --x x --y y --embed-font -o plot.svg
# Pipe into rsvg-convert in a minimal container
kuva scatter data.tsv --x x --y y --embed-font | rsvg-convert -o plot.png
SVG interactivity
| Flag | Default | Description |
|---|---|---|
--interactive | off | Embed browser interactivity in SVG output (ignored for PNG/PDF/terminal) |
When --interactive is set the output SVG contains a self-contained <script> block with no external dependencies. Features:
- Hover tooltip — hovering a data point shows its label and value.
- Click to pin — click a point to keep its highlight; click again or press Escape to clear all pins.
- Search — type in the search box (top-left of the plot area) to dim non-matching points. Escape clears.
- Coordinate readout — mouse position inside the plot area is shown in data-space coordinates.
- Legend toggle — click a legend entry to show/hide that series.
- Save button — top-right button serialises the current SVG DOM (including any pinned/dimmed state). Note: the download is not yet functional; this will be fixed in v0.2.
Supported in this release: scatter, line, bar, strip, volcano. All other subcommands accept --interactive and load the UI chrome (coordinate readout, search box) but do not yet have per-point hover/search — remaining renderers will be wired in v0.2.
kuva scatter data.tsv --x x --y y --color-by group --legend --interactive -o plot.svg
kuva volcano hits.tsv --gene gene --log2fc log2fc --pvalue pvalue --legend --interactive -o volcano.svg
Terminal output
| Flag | Default | Description |
|---|---|---|
--terminal | off | Render directly in the terminal using Unicode braille and block characters; mutually exclusive with -o |
--term-width <N> | (auto) | Terminal width in columns (overrides auto-detect) |
--term-height <N> | (auto) | Terminal height in rows (overrides auto-detect) |
Terminal output uses Unicode braille dots (U+2800–U+28FF) for scatter points and continuous curves, full-block characters (█) for bar and histogram fills, and ANSI 24-bit colour. Terminal dimensions are auto-detected from the current tty; pass --term-width and --term-height to override (useful in scripts or when piping).
# Scatter plot directly in terminal
kuva scatter data.tsv --x x --y y --terminal
# Explicit dimensions
kuva bar counts.tsv --label-col gene --value-col count --terminal --term-width 120 --term-height 40
# Manhattan plot on a remote server
cat gwas.tsv | kuva manhattan --chr-col chr --pvalue-col pvalue --terminal
Note: Terminal output is not yet supported for
upset. Runningkuva upset --terminalprints a message and exits cleanly; use-o file.svginstead.
Axes (most subcommands)
| Flag | Default | Description |
|---|---|---|
--x-label <TEXT> | — | X-axis label |
--y-label <TEXT> | — | Y-axis label |
--ticks <N> | 5 | Hint for number of tick marks |
--no-grid | off | Disable background grid |
Log scale (scatter, line, histogram, density, hist2d)
| Flag | Description |
|---|---|
--log-x | Logarithmic X axis |
--log-y | Logarithmic Y axis |
Input
| Flag | Description |
|---|---|
--no-header | Treat first row as data, not a header |
-d, --delimiter <CHAR> | Override field delimiter |
Subcommands
| Subcommand | Description |
|---|---|
| scatter | Scatter plot of (x, y) point pairs |
| line | Line plot |
| bar | Bar chart from label/value pairs |
| histogram | Frequency histogram from a single numeric column |
| density | Kernel density estimate curve |
| ridgeline | Stacked KDE density curves, one per group |
| box | Box-and-whisker plot |
| violin | Kernel-density violin plot |
| pie | Pie or donut chart |
| forest | Forest plot — point estimates with confidence intervals |
| strip | Strip / jitter plot |
| waterfall | Waterfall / bridge chart |
| stacked-area | Stacked area chart |
| volcano | Volcano plot for differential expression |
| manhattan | Manhattan plot for GWAS results |
| candlestick | OHLC candlestick chart |
| heatmap | Color-encoded matrix heatmap |
| hist2d | Two-dimensional histogram |
| contour | Contour plot from scattered (x, y, z) triplets |
| dot | Dot plot (size + color at categorical positions) |
| upset | UpSet plot for set-intersection analysis |
| chord | Chord diagram for pairwise flow data |
| network | Network / graph diagram from edge list or matrix |
| sankey | Sankey / alluvial flow diagram |
| phylo | Phylogenetic tree |
| synteny | Synteny / genomic alignment ribbon plot |
| polar | Polar coordinate scatter/line plot |
| ternary | Ternary (simplex) scatter plot |
| scatter3d | 3D scatter plot with orthographic projection |
| surface3d | 3D surface mesh with depth-sorted rendering |
scatter3d
3D scatter plot with orthographic projection and depth-sorted rendering.
Input: TSV/CSV with three numeric columns for X, Y, Z coordinates, plus an optional group column.
| Flag | Default | Description |
|---|---|---|
--x <COL> | 0 | X coordinate column |
--y <COL> | 1 | Y coordinate column |
--z <COL> | 2 | Z coordinate column |
--color-by <COL> | — | Group by column for per-group colors |
--color <CSS> | steelblue | Point color |
--size <PX> | 3.0 | Point radius in pixels |
--azimuth <DEG> | -60 | Azimuth viewing angle |
--elevation <DEG> | 30 | Elevation viewing angle |
--z-color <MAP> | — | Color by Z: viridis, inferno, grayscale |
--depth-shade | off | Fade distant points for depth cue |
--z-axis-left | off | Place Z-axis on the left side |
--no-grid | off | Hide grid lines on back walls |
--no-box | off | Hide wireframe bounding box |
--grid-lines <N> | 5 | Grid/tick divisions per axis |
kuva scatter3d data.tsv --x x --y y --z z \
--title "3D Scatter" --x-label "X" --y-label "Y" --z-label "Z"
kuva scatter3d data.tsv --x x --y y --z z --color-by group \
--z-color viridis --depth-shade
surface3d
3D surface mesh with depth-sorted filled quadrilaterals.
Input: Either XYZ columns (long format, auto-pivoted to grid) or --matrix mode where each row is a grid row of Z values.
| Flag | Default | Description |
|---|---|---|
--x <COL> | 0 | X coordinate column (long format) |
--y <COL> | 1 | Y coordinate column (long format) |
--z <COL> | 2 | Z coordinate column (long format) |
--matrix | off | Read as Z-value matrix (one row per grid row) |
--z-color <MAP> | — | Color by Z: viridis, inferno, grayscale |
--color <CSS> | steelblue | Uniform surface color (when no colormap) |
--alpha <F> | 1.0 | Surface opacity (0.0–1.0) |
--no-wireframe | off | Disable wireframe edges on mesh |
--resolution <N> | — | Upsample grid to NxN via bilinear interpolation (max 1000) |
--azimuth <DEG> | -60 | Azimuth viewing angle |
--elevation <DEG> | 30 | Elevation viewing angle |
--z-axis-left | off | Place Z-axis on the left side |
--no-grid | off | Hide grid lines on back walls |
--no-box | off | Hide wireframe bounding box |
--grid-lines <N> | 5 | Grid/tick divisions per axis |
kuva surface3d data.tsv --x x --y y --z z --z-color viridis \
--title "3D Surface"
kuva surface3d matrix.tsv --matrix --z-color inferno \
--resolution 50 --alpha 0.9
Tips
Pipe to a viewer:
kuva scatter data.tsv | display # ImageMagick
kuva scatter data.tsv | inkscape --pipe # Inkscape
Quick PNG without a file:
kuva scatter data.tsv -o /tmp/out.png # requires --features png
Themed dark output:
kuva manhattan gwas.tsv --chr-col chr --pvalue-col pvalue \
--theme dark --background "#1a1a2e" -o manhattan_dark.svg
Colour-vision-deficiency palette:
kuva scatter data.tsv --x time --y value --color-by group \
--cvd-palette deuteranopia