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]

Building

cargo build --bin kuva                  # SVG output only
cargo build --bin kuva --features png   # adds PNG output via resvg
cargo build --bin kuva --features pdf   # adds PDF output via svg2pdf
cargo build --bin kuva --features full  # both PNG and PDF

After building, the binary is at target/debug/kuva (or target/release/kuva with --release).


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)

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, 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


scatter

Scatter plot of (x, y) point pairs. Supports multi-series coloring, trend lines, and log scale.

Input: any tabular file with two numeric columns.

FlagDefaultDescription
--x <COL>0X-axis column
--y <COL>1Y-axis column
--color-by <COL>Group by this column; each group gets a distinct color
--color <CSS>steelbluePoint color (single-series only)
--size <PX>3.0Point radius in pixels
--trendoffOverlay a linear trend line
--equationoffAnnotate with regression equation (requires --trend)
--correlationoffAnnotate with Pearson R² (requires --trend)
--legendoffShow legend
kuva scatter measurements.tsv --x time --y value --color steelblue

kuva scatter measurements.tsv --x time --y value \
    --color-by group --legend --title "Expression over time"

kuva scatter measurements.tsv --x time --y value \
    --trend --equation --correlation --log-y

line

Line plot. Identical column flags to scatter; adds line-style options.

Input: any tabular file with two numeric columns, sorted by x.

FlagDefaultDescription
--x <COL>0X-axis column
--y <COL>1Y-axis column
--color-by <COL>Multi-series grouping
--color <CSS>steelblueLine color (single-series)
--stroke-width <PX>2.0Line stroke width
--dashedoffDashed line style
--dottedoffDotted line style
--filloffFill area under the line
--legendoffShow legend
kuva line measurements.tsv --x time --y value --color-by group --legend

kuva line measurements.tsv --x time --y value --fill --color "rgba(70,130,180,0.4)"

bar

Bar chart from label/value pairs.

Input: first column labels, second column numeric values.

FlagDefaultDescription
--label-col <COL>0Label column
--value-col <COL>1Value column
--color <CSS>steelblueBar fill color
--bar-width <F>0.8Bar width as a fraction of the slot
kuva bar bar.tsv --label-col category --value-col count --color "#4682b4"

kuva bar bar.tsv --x-label "Pathway" --y-label "Gene count" \
    -o pathways.svg

histogram

Frequency histogram from a single numeric column.

Input: one numeric column per row.

FlagDefaultDescription
--value-col <COL>0Value column
--color <CSS>steelblueBar fill color
--bins <N>10Number of bins
--normalizeoffNormalize to probability density (area = 1)
kuva histogram histogram.tsv --value-col value --bins 30

kuva histogram histogram.tsv --bins 20 --normalize \
    --title "Expression distribution" --y-label "Density"

box

Box-and-whisker plot. Groups are taken from one column; values from another.

Input: two columns — group label and numeric value, one observation per row.

FlagDefaultDescription
--group-col <COL>0Group label column
--value-col <COL>1Numeric value column
--color <CSS>steelblueBox fill color
--overlay-pointsoffOverlay individual points as a jittered strip
--overlay-swarmoffOverlay individual points as a non-overlapping beeswarm
kuva box samples.tsv --group-col group --value-col expression

kuva box samples.tsv --group-col group --value-col expression \
    --overlay-swarm --color "rgba(70,130,180,0.6)"

violin

Kernel-density violin plot. Same input format as box.

Input: two columns — group label and numeric value, one observation per row.

FlagDefaultDescription
--group-col <COL>0Group label column
--value-col <COL>1Numeric value column
--color <CSS>steelblueViolin fill color
--bandwidth <F>(Silverman)KDE bandwidth
--overlay-pointsoffOverlay individual points as a jittered strip
--overlay-swarmoffOverlay individual points as a non-overlapping beeswarm
kuva violin samples.tsv --group-col group --value-col expression

kuva violin samples.tsv --group-col group --value-col expression \
    --overlay-swarm --bandwidth 0.3

pie

Pie or donut chart.

Input: label column + numeric value column.

FlagDefaultDescription
--label-col <COL>0Label column
--value-col <COL>1Value column
--color-col <COL>Optional CSS color column
--donutoffRender as a donut (hollow center)
--inner-radius <PX>80Donut hole radius in pixels
--percentoffAppend percentage to slice labels
--label-position <MODE>(auto)inside, outside, or none
--legendoffShow legend
kuva pie pie.tsv --label-col feature --value-col percentage --percent

kuva pie pie.tsv --label-col feature --value-col percentage \
    --donut --legend --label-position outside

strip

Strip / jitter plot — individual points along a categorical axis.

Input: group label column + numeric value column, one observation per row.

FlagDefaultDescription
--group-col <COL>0Group label column
--value-col <COL>1Numeric value column
--color <CSS>steelbluePoint color
--point-size <PX>4.0Point radius in pixels
--swarmoffBeeswarm (non-overlapping) layout
--centeroffAll points at group center (no spread)

Default layout when neither --swarm nor --center is given: random jitter (±30 % of slot width).

kuva strip samples.tsv --group-col group --value-col expression

kuva strip samples.tsv --group-col group --value-col expression --swarm

waterfall

Waterfall / bridge chart showing a running total built from incremental bars.

Input: label column + numeric value column. Mark subtotal/total bars with --total.

FlagDefaultDescription
--label-col <COL>0Label column
--value-col <COL>1Value column
--total <LABEL>Mark this label as a summary bar (repeatable)
--connectorsoffDraw dashed connector lines between bars
--valuesoffPrint numeric values on each bar
--color-pos <CSS>greenPositive delta bar color
--color-neg <CSS>redNegative delta bar color
--color-total <CSS>steelblueTotal/subtotal bar color
kuva waterfall waterfall.tsv --label-col process --value-col log2fc \
    --connectors --values

# mark two rows as summary bars
kuva waterfall income.tsv \
    --total "Gross profit" --total "Net income" \
    --connectors --values

stacked-area

Stacked area chart in long format.

Input: three columns — x value, group label, y value — one observation per row. Rows are grouped by the group column; within each group the x/y pairs are collected in order.

FlagDefaultDescription
--x-col <COL>0X-axis column
--group-col <COL>1Series group column
--y-col <COL>2Y-axis column
--normalizeoffNormalize each x-position to 100 %
--fill-opacity <F>0.7Fill opacity for each band
kuva stacked-area stacked_area.tsv \
    --x-col week --group-col species --y-col abundance

kuva stacked-area stacked_area.tsv \
    --x-col week --group-col species --y-col abundance \
    --normalize --y-label "Relative abundance (%)"

volcano

Volcano plot for differential expression results.

Input: three columns — gene name, log₂ fold change, raw p-value.

FlagDefaultDescription
--name-col <COL>0Gene/feature name column
--x-col <COL>1log₂FC column
--y-col <COL>2p-value column (raw, not −log₁₀)
--fc-cutoff <F>1.0|log₂FC| threshold
--p-cutoff <F>0.05p-value significance threshold
--top-n <N>0Label the N most-significant points
--color-up <CSS>firebrickUp-regulated point color
--color-down <CSS>steelblueDown-regulated point color
--color-ns <CSS>#aaaaaaNot-significant point color
--point-size <PX>3.0Point radius
--legendoffShow Up / Down / NS legend
kuva volcano gene_stats.tsv \
    --name-col gene --x-col log2fc --y-col pvalue \
    --top-n 20 --legend

kuva volcano gene_stats.tsv \
    --name-col gene --x-col log2fc --y-col pvalue \
    --fc-cutoff 2.0 --p-cutoff 0.01 --top-n 10

manhattan

Manhattan plot for GWAS results.

Input: chromosome, (optional) base-pair position, and p-value columns.

Two layout modes:

  • Sequential (default): chromosomes are sorted and SNPs receive consecutive integer x-positions. Position column is not used.
  • Base-pair (--genome-build): SNP x-coordinates are resolved from chromosome sizes in a reference build.
FlagDefaultDescription
--chr-col <COL>0Chromosome column
--pos-col <COL>1Base-pair position column (bp mode only)
--pvalue-col <COL>2p-value column
--genome-build <BUILD>Enable bp mode: hg19, hg38, or t2t
--genome-wide <F>7.301Genome-wide threshold (−log₁₀ scale)
--suggestive <F>5.0Suggestive threshold (−log₁₀ scale)
--top-n <N>0Label N most-significant points above genome-wide threshold
--point-size <PX>2.5Point radius
--color-a <CSS>steelblueEven-chromosome color
--color-b <CSS>#5aadcbOdd-chromosome color
--legendoffShow threshold legend
# sequential mode (no position column needed)
kuva manhattan gene_stats.tsv --chr-col chr --pvalue-col pvalue --top-n 5

# base-pair mode
kuva manhattan gwas.tsv \
    --chr-col chr --pos-col pos --pvalue-col pvalue \
    --genome-build hg38 --top-n 10 --legend

candlestick

OHLC candlestick chart.

Input: label, open, high, low, close columns (and optionally volume).

FlagDefaultDescription
--label-col <COL>0Period label column
--open-col <COL>1Open price column
--high-col <COL>2High price column
--low-col <COL>3Low price column
--close-col <COL>4Close price column
--volume-col <COL>Optional volume column
--volume-paneloffShow volume bar panel below price chart
--candle-width <F>0.7Body width as a fraction of slot
--color-up <CSS>greenBullish candle color
--color-down <CSS>redBearish candle color
--color-doji <CSS>#888888Doji candle color
kuva candlestick candlestick.tsv \
    --label-col date --open-col open --high-col high \
    --low-col low --close-col close

kuva candlestick candlestick.tsv \
    --label-col date --open-col open --high-col high \
    --low-col low --close-col close \
    --volume-col volume --volume-panel

heatmap

Color-encoded matrix heatmap.

Input: wide-format matrix — first column is the row label, remaining columns are numeric values. The header row (if present) supplies column labels.

gene    Sample_01  Sample_02  Sample_03 …
TP53    0.25       -1.78       1.58     …
BRCA1   0.23        0.48       1.06     …
FlagDefaultDescription
--colormap <NAME>viridisColor map: viridis, inferno, grayscale
--valuesoffPrint numeric values in each cell
--legend <LABEL>Show color bar with this label
kuva heatmap heatmap.tsv

kuva heatmap heatmap.tsv --colormap inferno --values --legend "z-score"

hist2d

Two-dimensional histogram (density grid) from two numeric columns.

Input: two numeric columns.

FlagDefaultDescription
--x <COL>0X-axis column
--y <COL>1Y-axis column
--bins-x <N>10Number of bins on the X axis
--bins-y <N>10Number of bins on the Y axis
--colormap <NAME>viridisColor map: viridis, inferno, grayscale
--correlationoffOverlay Pearson correlation coefficient
kuva hist2d measurements.tsv --x time --y value

kuva hist2d measurements.tsv --x time --y value \
    --bins-x 20 --bins-y 20 --correlation

contour

Contour plot from scattered (x, y, z) triplets.

Input: three columns — x coordinate, y coordinate, scalar value.

FlagDefaultDescription
--x <COL>0X column
--y <COL>1Y column
--z <COL>2Scalar value column
--levels <N>8Number of contour levels
--filledoffFill between contour levels
--colormap <NAME>viridisColor map (filled mode)
--line-color <CSS>Line color (unfilled mode)
--legend <LABEL>Show legend entry
kuva contour contour.tsv --x x --y y --z density

kuva contour contour.tsv --x x --y y --z density \
    --filled --levels 12 --colormap inferno

dot

Dot plot encoding two variables (size and color) at categorical (x, y) positions.

Input: four columns — x category, y category, size value, color value.

FlagDefaultDescription
--x-col <COL>0X-category column
--y-col <COL>1Y-category column
--size-col <COL>2Size-encoding column
--color-col <COL>3Color-encoding column
--colormap <NAME>viridisColor map
--max-radius <PX>12.0Maximum dot radius
--size-legend <LABEL>Show size legend with this label
--colorbar <LABEL>Show color bar with this label
kuva dot dot.tsv \
    --x-col pathway --y-col cell_type \
    --size-col pct_expressed --color-col mean_expr

kuva dot dot.tsv \
    --x-col pathway --y-col cell_type \
    --size-col pct_expressed --color-col mean_expr \
    --size-legend "% expressed" --colorbar "mean expr"

upset

UpSet plot for set-intersection analysis.

Input: binary (0/1) matrix — one column per set, one row per element. Column headers become set names.

GWAS_hit  eQTL  Splicing_QTL  Methylation_QTL  Conservation  ClinVar
1         0     0             1                1             1
0         0     1             1                1             0
FlagDefaultDescription
--sort <MODE>frequencySort intersections: frequency, degree, natural
--max-visible <N>Show only the top N intersections
kuva upset upset.tsv

kuva upset upset.tsv --sort degree --max-visible 15

Terminal output: not yet supported. kuva upset --terminal prints a message and exits cleanly; use -o file.svg instead.


chord

Chord diagram for pairwise flow data.

Input: square N×N matrix — first column is the row label (ignored for layout), header row supplies node names.

region        Cortex  Hippocampus  Amygdala …
Cortex        0       320          13       …
Hippocampus   320     0            210      …
FlagDefaultDescription
--gap <DEG>2.0Gap between arcs in degrees
--opacity <F>0.7Ribbon opacity
--legend <LABEL>Show legend
kuva chord chord.tsv

kuva chord chord.tsv --gap 3.0 --opacity 0.5 --legend "connectivity"

sankey

Sankey / alluvial flow diagram.

Input: three columns — source node, target node, flow value.

FlagDefaultDescription
--source-col <COL>0Source node column
--target-col <COL>1Target node column
--value-col <COL>2Flow value column
--link-gradientoffFill each link with a gradient from source node colour to target node colour
--opacity <F>0.5Link opacity
--legend <LABEL>Show legend
kuva sankey sankey.tsv \
    --source-col source --target-col target --value-col value

kuva sankey sankey.tsv \
    --source-col source --target-col target --value-col value \
    --link-gradient --legend "read flow"

phylo

Phylogenetic tree from a Newick string or edge-list TSV.

Input (default): edge-list TSV with parent, child, and branch-length columns.

Input (alternative): pass --newick with a Newick string; the file argument is not used.

FlagDefaultDescription
--newick <STR>Newick string (overrides file input)
--parent-col <COL>0Parent node column
--child-col <COL>1Child node column
--length-col <COL>2Branch length column
--orientation <DIR>leftleft, right, top, bottom
--branch-style <STYLE>rectangularrectangular, slanted, circular
--phylogramoffScale branches by length
--legend <LABEL>Show legend
# from edge-list TSV
kuva phylo phylo.tsv \
    --parent-col parent --child-col child --length-col length

# from Newick string
kuva phylo --newick "((A:0.1,B:0.2):0.3,C:0.4);" --branch-style circular

# phylogram, top orientation
kuva phylo phylo.tsv \
    --parent-col parent --child-col child --length-col length \
    --phylogram --orientation top

synteny

Synteny / genomic alignment ribbon plot.

Input: two files:

  • Sequences file (positional): TSV with sequence name and length columns.
  • Blocks file (--blocks-file): TSV with columns seq1, start1, end1, seq2, start2, end2, strand.
# sequences.tsv
name    length
Chr1A   2800000
Chr1B   2650000

# blocks.tsv
seq1   start1  end1    seq2   start2  end2    strand
Chr1A  56000   137237  Chr1B  63958   143705  +
Chr1A  150674  271188  Chr1B  165366  303075  -
FlagDefaultDescription
--blocks-file <FILE>(required)Blocks TSV file
--bar-height <PX>18.0Sequence bar height in pixels
--opacity <F>0.65Block ribbon opacity
--proportionaloffScale bar widths proportionally to sequence length
--legend <LABEL>Show legend
kuva synteny synteny_seqs.tsv --blocks-file synteny_blocks.tsv

kuva synteny synteny_seqs.tsv --blocks-file synteny_blocks.tsv \
    --proportional --legend "synteny blocks"

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