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.
| Property | Value |
|---|---|
| Background | white |
| Axes / ticks / text | black |
| Grid | #ccc |
| Legend background | white |
| Legend border | black |
| Font | DejaVu Sans, Liberation Sans, Arial, sans-serif (default) |
| Grid shown | yes |
dark
Dark charcoal background, light gray text and axes.
| Property | Value |
|---|---|
| Background | #1e1e1e |
| Axes / ticks | #cccccc |
| Text | #e0e0e0 |
| Grid | #444444 |
| Legend background | #2d2d2d |
| Legend border | #666666 |
| Font | DejaVu Sans, Liberation Sans, Arial, sans-serif (default) |
| Grid shown | yes |
minimal
White background, no grid, serif font, no legend border. Suited for publication figures where grid lines add visual noise.
| Property | Value |
|---|---|
| Background | white |
| Axes / ticks / text | black |
| Grid | #e0e0e0 |
| Legend border | none |
| Font | serif |
| Grid shown | no |
solarized
Warm cream background based on Ethan Schoonover's Solarized palette.
| Property | Value |
|---|---|
| Background | #fdf6e3 |
| Axes / ticks | #586e75 |
| Text | #657b83 |
| Grid | #eee8d5 |
| Legend background | #fdf6e3 |
| Legend border | #93a1a1 |
| Font | DejaVu Sans, Liberation Sans, Arial, sans-serif (default) |
| Grid shown | yes |
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); }