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

PriorityRule
1--delimiter flag
2File extension: .csv,, .tsv/.txt → tab
3Sniff 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

FlagEffect
(omitted)SVG to stdout
-o out.svgSVG to file
-o out.pngPNG (requires --features png)
-o out.pdfPDF (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

FlagDefaultDescription
-o, --output <FILE>stdout (SVG)Output file path (mutually exclusive with --terminal)
--title <TEXT>Title displayed above the chart
--width <PX>800Canvas width in pixels
--height <PX>500Canvas height in pixels
--theme <NAME>lightTheme: light, dark, solarized, minimal
--palette <NAME>category10Color 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

FlagDefaultDescription
--embed-fontoffEmbed 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

FlagDefaultDescription
--interactiveoffEmbed 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

FlagDefaultDescription
--terminaloffRender 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. Running kuva upset --terminal prints a message and exits cleanly; use -o file.svg instead.

Axes (most subcommands)

FlagDefaultDescription
--x-label <TEXT>X-axis label
--y-label <TEXT>Y-axis label
--ticks <N>5Hint for number of tick marks
--no-gridoffDisable background grid

Log scale (scatter, line, histogram, density, hist2d)

FlagDescription
--log-xLogarithmic X axis
--log-yLogarithmic Y axis

Input

FlagDescription
--no-headerTreat first row as data, not a header
-d, --delimiter <CHAR>Override field delimiter

Subcommands

SubcommandDescription
scatterScatter plot of (x, y) point pairs
lineLine plot
barBar chart from label/value pairs
histogramFrequency histogram from a single numeric column
densityKernel density estimate curve
ridgelineStacked KDE density curves, one per group
boxBox-and-whisker plot
violinKernel-density violin plot
piePie or donut chart
forestForest plot — point estimates with confidence intervals
stripStrip / jitter plot
waterfallWaterfall / bridge chart
stacked-areaStacked area chart
volcanoVolcano plot for differential expression
manhattanManhattan plot for GWAS results
candlestickOHLC candlestick chart
heatmapColor-encoded matrix heatmap
hist2dTwo-dimensional histogram
contourContour plot from scattered (x, y, z) triplets
dotDot plot (size + color at categorical positions)
upsetUpSet plot for set-intersection analysis
chordChord diagram for pairwise flow data
networkNetwork / graph diagram from edge list or matrix
sankeySankey / alluvial flow diagram
phyloPhylogenetic tree
syntenySynteny / genomic alignment ribbon plot
polarPolar coordinate scatter/line plot
ternaryTernary (simplex) scatter plot
scatter3d3D scatter plot with orthographic projection
surface3d3D 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.

FlagDefaultDescription
--x <COL>0X coordinate column
--y <COL>1Y coordinate column
--z <COL>2Z coordinate column
--color-by <COL>Group by column for per-group colors
--color <CSS>steelbluePoint color
--size <PX>3.0Point radius in pixels
--azimuth <DEG>-60Azimuth viewing angle
--elevation <DEG>30Elevation viewing angle
--z-color <MAP>Color by Z: viridis, inferno, grayscale
--depth-shadeoffFade distant points for depth cue
--z-axis-leftoffPlace Z-axis on the left side
--no-gridoffHide grid lines on back walls
--no-boxoffHide wireframe bounding box
--grid-lines <N>5Grid/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.

FlagDefaultDescription
--x <COL>0X coordinate column (long format)
--y <COL>1Y coordinate column (long format)
--z <COL>2Z coordinate column (long format)
--matrixoffRead as Z-value matrix (one row per grid row)
--z-color <MAP>Color by Z: viridis, inferno, grayscale
--color <CSS>steelblueUniform surface color (when no colormap)
--alpha <F>1.0Surface opacity (0.0–1.0)
--no-wireframeoffDisable wireframe edges on mesh
--resolution <N>Upsample grid to NxN via bilinear interpolation (max 1000)
--azimuth <DEG>-60Azimuth viewing angle
--elevation <DEG>30Elevation viewing angle
--z-axis-leftoffPlace Z-axis on the left side
--no-gridoffHide grid lines on back walls
--no-boxoffHide wireframe bounding box
--grid-lines <N>5Grid/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