Themes

Themes control the colours of all plot chrome — background, axes, grid lines, tick marks, text, and legend. Plot data colours are not affected by themes; those come from the color passed to each plot or from a Palette.

Four built-in themes are available. The default is light.


Applying a theme

Rust API

#![allow(unused)]
fn main() {
use kuva::render::layout::Layout;
use kuva::render::theme::Theme;

let layout = Layout::auto_from_plots(&plots)
    .with_theme(Theme::dark());
}

CLI

kuva scatter data.tsv --x x --y y --theme dark
kuva bar data.tsv --label-col gene --value-col count --theme minimal

Available CLI values: light, dark, minimal, solarized.


Built-in themes

light (default)

White background, black axes and text, light gray grid lines.

PropertyValue
Backgroundwhite
Axes / ticks / textblack
Grid#ccc
Legend backgroundwhite
Legend borderblack
FontDejaVu Sans, Liberation Sans, Arial, sans-serif (default)
Grid shownyes

dark

Dark charcoal background, light gray text and axes.

PropertyValue
Background#1e1e1e
Axes / ticks#cccccc
Text#e0e0e0
Grid#444444
Legend background#2d2d2d
Legend border#666666
FontDejaVu Sans, Liberation Sans, Arial, sans-serif (default)
Grid shownyes

minimal

White background, no grid, serif font, no legend border. Suited for publication figures where grid lines add visual noise.

PropertyValue
Backgroundwhite
Axes / ticks / textblack
Grid#e0e0e0
Legend bordernone
Fontserif
Grid shownno

solarized

Warm cream background based on Ethan Schoonover's Solarized palette.

PropertyValue
Background#fdf6e3
Axes / ticks#586e75
Text#657b83
Grid#eee8d5
Legend background#fdf6e3
Legend border#93a1a1
FontDejaVu Sans, Liberation Sans, Arial, sans-serif (default)
Grid shownyes

Fonts and portability

The default font stack — DejaVu Sans, Liberation Sans, Arial, sans-serif — is resolved by the viewer or renderer at display time. This works on any desktop system but can fail in minimal environments (containers, CI pipelines, bioconda recipes) where no system fonts are installed.

kuva handles this in two ways depending on output format:

PNG and PDF always work, regardless of system fonts. DejaVu Sans is bundled inside the crate and loaded into the font database before the system font scan, so text renders correctly even in a bare container.

SVG references fonts by name and relies on the viewer. If your SVG will be processed by rsvg-convert, Inkscape, or a similar tool on a font-free system, pass --embed-font on the CLI or call .with_embedded_font(true) on SvgBackend:

#![allow(unused)]
fn main() {
use kuva::backend::svg::SvgBackend;
use kuva::render::render::render_multiple;

let scene = render_multiple(plots, layout);
let svg = SvgBackend::new()
    .with_embedded_font(true)
    .render_scene(&scene);
}

This injects a base64 @font-face block into the SVG, making it self-contained at the cost of roughly 1 MB of added file size. Leave it off (the default) for normal SVG output where smaller files are preferable.


Custom themes

Build a Theme struct directly to set any combination of properties:

#![allow(unused)]
fn main() {
use kuva::render::theme::Theme;

let theme = Theme {
    background: "#0d1117".into(),   // GitHub dark background
    axis_color: "#8b949e".into(),
    grid_color: "#21262d".into(),
    tick_color: "#8b949e".into(),
    text_color: "#c9d1d9".into(),
    legend_bg: "#161b22".into(),
    legend_border: "#30363d".into(),
    pie_leader: "#8b949e".into(),
    box_median: "#0d1117".into(),
    violin_border: "#8b949e".into(),
    colorbar_border: "#8b949e".into(),
    font_family: None,  // None inherits the default: "DejaVu Sans, Liberation Sans, Arial, sans-serif"
    show_grid: true,
};

let layout = Layout::auto_from_plots(&plots).with_theme(theme);
}