[0.3.0] — 2026-06-19
Added
- Math in labels — any label (title, axis labels,
TextPlotmarkdown bodies) may embed$...$math written in LaTeX-ish syntax ($\sigma^2$,$\frac{a}{b}$,$\sqrt{x^2+y^2}$). Math regions are lowered to inline Unicode — Greek letters, operators, super/subscripts (all-or-nothing, with a cleanx^(2q)fallback),\frac→a/b,\sqrt→√(…)— by every backend including the terminal. Zero dependencies, always on; a literal dollar is written\$. See Reference → Math in Labels. QuiverPlot— 2-D vector field rendered as arrows. Each arrow has a tail at(x, y)and a vector(u, v). Features:from_function()constructor for sampling a closure on a regular grid; auto-scaled arrow length (longest arrow ≈ one grid cell via aspan/√nheuristic) or explicitwith_scale; proportional arrow heads that make every arrow "look like an arrow" regardless of magnitude; three pivot modes (Tail,Middle,Tip); optional magnitude-driven colormap with automatic colorbar;tight_boundsopt-in for dense fields and independentwith_clip_to_plot_area()for plot-area clipping; combo helperwith_magnitude_colormap(cmap, label). CLI:kuva quiver.- Pre-compiled release binaries — pushing a
vX.Y.Ztag now builds standalonekuvaCLI binaries (with thecli,fullfeature set: SVG + PNG + PDF) for Linux (x86_64 gnu/musl, aarch64), macOS (Intel + Apple Silicon) and Windows (x86_64), and attaches them with SHA-256 checksums to the matching GitHub Release. Users can download a binary and run it without installing Rust. See.github/workflows/release.yml(resolves #17). AxisLabelOverlap— collision-aware x-axis label thinning —Layout::with_x_label_overlap(AxisLabelOverlap)opts any plot into collision-aware x-axis labelling. Three modes:Allow(default — existing behaviour),Thin(left-to-right pass; skip any label whose estimated footprint overlaps the previous one), andStagger(alternate two vertical offsets so adjacent labels no longer need horizontal clearance). Works with both upright and rotated (Layout::with_x_tick_rotate) labels.ManhattanPlotgains the convenience builderwith_thin_overlapping_labels(). CLI:--x-label-overlap allow|thin|staggeron all subcommands..parquetinput for all CLI subcommands — all ~50 CLI subcommands can read.parquetfiles directly (extension sniffing), or detect parquet piped via stdin by magic bytes (PAR1header/footer). Uses projected Arrow reads viaParquetRecordBatchReaderBuilder+ProjectionMask::roots()— only requested columns are decoded; 35–154× faster and 7–29× less memory than full-file row API on wide files. Gated behind--features parquet. (Community PR #79 by mud2monarch; extended to all subcommands in this release.)- Horizontal mode for
BarPlot,BoxPlot,ViolinPlot,RaincloudPlot—.with_horizontal(true)rotates any of these charts so categories appear on the Y-axis and values on the X-axis. Useful when category labels are long or when a horizontal layout reads more naturally. Slot-fraction width/gap builders work identically in both orientations. CLI:--horizontalflag added tokuva bar,kuva box,kuva violin,kuva raincloud. - CLI multi-column
--yextended —--y A,B,C(comma-separated column names or indices) is now supported onhistogram,bar,strip,violin,box,density, andridgelinein addition to thescatterandlinesubcommands added in v0.2.0. One series / group / ridge / curve is created per column; legend labels use column header names. Bar mode aggregates rows by--label-col(mean by default;--aggoverrides). All existing--group-col/--value-colflags remain supported. - Enclosed plots —
AxisLine::InternalandAxisLine::Mirrored—Layout::with_axis_line(AxisLine)controls how axes are drawn.AxisLine::Open(renamed from the previousLeft) draws a standard open axis;AxisLine::Internaldraws tick marks inward;AxisLine::Mirroreddraws ticks on both sides of the plot area. (PR #77.) embed_fontCargo feature —flate2is now optional. The newembed_fontfeature gates font embedding in SVG output; thepngandpdffeatures pull inflate2for their own font loading; SVG-only builds no longer depend on it. Thefontsmodule is gated onany(embed_font, png, pdf). (Adapted from PR #81 by Zodey-hub.)NetworkPlotenhancements — cubic-Bézier curved edges via.with_curves(true); inside-node label placement (labels drawn centred inside node circles for compact graphs); legend group color fix (group entries now use the correct per-group color rather than a single fallback).- Bundled font variants (Bold, Oblique, Mono) — DejaVu Sans Bold, Oblique, and Mono TTFs are now bundled (gzip-compressed, inflated on first use via
OnceLock). All three are gated behind#[cfg(any(feature = "png", feature = "pdf", feature = "embed_font"))]— SVG-only builds pay no binary-size cost. Theembed_font@font-faceblock now embeds all four variants with correctfont-weight/font-styledescriptors so bold, italic, and code spans inTextPlotrender correctly in self-contained SVGs. TextPlotcodespan markup — backtick syntax (`code`) is now parsed byparse_inline_markupand produces aTextSpan { code: true }. SVG renders code spans withfont-family="DejaVu Sans Mono,monospace"; PNG/PDF use the bundled DejaVu Sans Mono font face.TextPlotfull markup in PNG/PDF — bold, italic, and code spans now render correctly in PNG and PDF. Each span is drawn with the matching bundled font face (Bold / Oblique / Mono); text metrics are computed per-font so multi-style lines are correctly anchored.
Fixed
- Tick generation overflow (#80) —
generate_ticksused an absolute loop guardend + 1e-8; on sub-1e-8 data ranges (e.g. values in the 1e-10 range) the guard was never reached and the loop could produce millions of ticks or run indefinitely. Fixed with a relative tolerancestep.abs() * 1e-6plus scale-invariant significant-figure rounding. - Y-axis label centering without title (#83) — the y-axis label y-position was computed from the canvas centre (
height / 2); when no title was present this placed the label above the plot midpoint. Corrected tomargin_top + plot_height() / 2. - Legend box right-padding — the auto-sizing formula
max_chars * 7.2 + 35underestimated required box width, clipping long labels at larger font sizes or scale factors. Updated tomax_chars * 8.5 + 41. - Negative values in CLI numeric flags —
--y-min,--y-max,--x-min,--x-max,--x-tick-step,--y-tick-stepnow accept negative numbers (e.g.--x-min -1.5) without being misinterpreted as unknown flags. Fixed viaallow_hyphen_values = trueon the relevant arguments. - BrickPlot multifigure bleed — row heights are now normalized to a consistent pixel height when
BrickPlotis placed inside aFigurepanel, preventing render bleed into adjacent cells. group_byperformance — changed from O(n²) to O(n) using aHashMap+ insertion-orderVec. Affects all CLI subcommands that use--color-byor grouped input.
Changed
- PNG backend — new raster pipeline —
PngBackendnow uses a direct RGBA pixel-buffer rasterizer withfontduetext rendering. The previousresvg-based SVG round-trip path is removed. Renders are faster and no longer depend onresvgorusvg.PngBackendretains its existing public API as a compatibility shim over the newRasterBackend. BrickPlotlegend improvements — new builderswith_legend_columns(n)(fixed column count) andwith_legend_max_entries(n)(cap before overflow); legend entries per column are now evenly distributed. Prevents legend overflow when many repeat motifs are present.- Refactor:
render_utils::arrow_head_path— factored a shared arrow-head triangle helper now used byQuiverPlot,NetworkPlot(directed-edge arrowheads), andTextAnnotationarrows. Eliminates three inlined copies of the same geometry. - Refactor:
colorbar_linearhelper inrender/plots.rs— consolidates six near-identicalArc<Fn>closures that built linearly-normalized colorbars acrossHeatmap,DotPlot,DicePlot,Contour,Clustermap, and (new)Quiver. The 3-Dcolorbar_from_zpath also routes through it now.
Pull Requests
- doc updates, and small tweaks to png raster backend by @Psy-Fer in #86
- manhattan: opt-in thinning of overlapping chromosome labels by @wdecoster in #82
- ci: build and publish release binaries on version tags by @wdecoster in #85
- Add QuiverPlot — 2-D vector field plot (re-submit of #70) by @gabo515 in #87
- feat: add support for enclosed plots with internal and mirrored ticks by @Ryan-D-Gast in #77
- Add unicode math shorthand for
$...$regions in labels by @gabo515 in #89 - Add parquet for scatter plots in CLI by @mud2monarch in #79
- Dev merge for v0.3.0 by @Psy-Fer in #90
New Contributors
- @wdecoster made their first contribution in #82
- @Ryan-D-Gast made their first contribution in #77
- @mud2monarch made their first contribution in #79
Full Changelog: v0.2.0...v0.3.0