The Layout struct controls all aspects of plot layout including dimensions, axis ranges, scales, labels, themes, and formatting. It provides a builder API for fluent configuration.
Constructor
new
pub fn new(x_range: (f64, f64), y_range: (f64, f64)) -> Self
Create a new layout with explicit axis ranges.
The minimum and maximum values for the x-axis.
The minimum and maximum values for the y-axis.
Example:
let layout = Layout::new((0.0, 10.0), (0.0, 100.0));
Auto-generation Methods
auto_from_plots
pub fn auto_from_plots(plots: &[Plot]) -> Self
Automatically compute layout from a collection of plots. This analyzes the data bounds, detects categorical axes, configures legends and colorbars, and applies sensible defaults.
A slice of plots to analyze for automatic layout configuration.
Example:
let scatter = ScatterPlot::new()
.with_data(vec![(1.0, 2.0), (3.0, 4.0)]);
let plots: Vec<Plot> = vec![scatter.into()];
let layout = Layout::auto_from_plots(&plots)
.with_title("My Plot")
.with_x_label("X Axis");
auto_from_data
pub fn auto_from_data(data: &[f64], x_range: std::ops::Range<f64>) -> Self
Create a layout from raw data values, suitable for simple histograms or distributions.
Data values to determine y-axis range.
The range for the x-axis.
auto_from_twin_y_plots
pub fn auto_from_twin_y_plots(primary: &[Plot], secondary: &[Plot]) -> Self
Convenience method to auto-range both axes from separate plot lists for dual y-axis plots.
Plots to render on the primary (left) y-axis.
Plots to render on the secondary (right) y-axis.
Dimension Methods
with_width
pub fn with_width(mut self, width: f64) -> Self
Set the total width of the plot in pixels.
Width in pixels. Default is 600.0 + margins.
with_height
pub fn with_height(mut self, height: f64) -> Self
Set the total height of the plot in pixels.
Height in pixels. Default is 450.0 + margins.
Example:
let layout = Layout::auto_from_plots(&plots)
.with_width(800.0)
.with_height(600.0);
Label and Title Methods
with_title
pub fn with_title<S: Into<String>>(mut self, title: S) -> Self
Set the plot title.
title
impl Into<String>
required
The title text.
with_x_label
pub fn with_x_label<S: Into<String>>(mut self, label: S) -> Self
Set the x-axis label.
label
impl Into<String>
required
The x-axis label text.
with_y_label
pub fn with_y_label<S: Into<String>>(mut self, label: S) -> Self
Set the y-axis label.
label
impl Into<String>
required
The y-axis label text.
Example:
let layout = Layout::auto_from_plots(&plots)
.with_title("Gene Expression Analysis")
.with_x_label("Time (hours)")
.with_y_label("Expression Level");
Grid and Tick Methods
with_ticks
pub fn with_ticks(mut self, ticks: usize) -> Self
Set the number of tick marks on each axis.
Number of ticks. Default is 5.
with_show_grid
pub fn with_show_grid(mut self, show: bool) -> Self
Enable or disable the grid lines.
true to show grid, false to hide. Default is true.
Example:
let layout = Layout::auto_from_plots(&plots)
.with_ticks(10)
.with_show_grid(false);
Categorical Axis Methods
with_x_categories
pub fn with_x_categories(mut self, labels: Vec<String>) -> Self
Define categorical labels for the x-axis (e.g., for bar plots).
Category labels in order.
with_y_categories
pub fn with_y_categories(mut self, labels: Vec<String>) -> Self
Define categorical labels for the y-axis.
Category labels in order.
Logarithmic Scale Methods
with_log_x
pub fn with_log_x(mut self) -> Self
Enable logarithmic scale for the x-axis.
with_log_y
pub fn with_log_y(mut self) -> Self
Enable logarithmic scale for the y-axis.
with_log_scale
pub fn with_log_scale(mut self) -> Self
Enable logarithmic scale for both axes.
Example:
let layout = Layout::auto_from_plots(&plots)
.with_log_y() // Log scale for y-axis only
.with_title("Log-scale Plot");
Legend Methods
with_legend_position
pub fn with_legend_position(mut self, pos: LegendPosition) -> Self
Set the position of the legend.
One of: TopRight, TopLeft, BottomRight, BottomLeft, OutsideRight. Default is TopRight.
Example:
use kuva::plot::legend::LegendPosition;
let layout = Layout::auto_from_plots(&plots)
.with_legend_position(LegendPosition::BottomRight);
The legend is only shown when plots contain legend labels. Use with_legend_label() on individual plot types.
pub fn with_tick_format(mut self, fmt: TickFormat) -> Self
Set the tick format for both x and y axes.
The tick formatting style. Options: Auto, Fixed(n), Integer, Sci, Percent, Custom(fn).
pub fn with_x_tick_format(mut self, fmt: TickFormat) -> Self
Set the tick format for the x-axis only.
pub fn with_y_tick_format(mut self, fmt: TickFormat) -> Self
Set the tick format for the y-axis only.
Example:
use kuva::render::layout::TickFormat;
let layout = Layout::auto_from_plots(&plots)
.with_y_tick_format(TickFormat::Percent) // Show y-axis as percentages
.with_x_tick_format(TickFormat::Integer); // Show x-axis as integers
TickFormat::Auto: Smart default with minimal decimals, scientific notation for extremes
TickFormat::Fixed(n): Exactly n decimal places (e.g., Fixed(2) → "3.14")
TickFormat::Integer: Round to nearest integer (e.g., "5")
TickFormat::Sci: ASCII scientific notation (e.g., "1.23e4")
TickFormat::Percent: Multiply by 100 and append % (e.g., 0.45 → "45.0%")
TickFormat::Custom(fn): Custom formatter function Arc<dyn Fn(f64) -> String + Send + Sync>
Font and Typography Methods
with_font_family
pub fn with_font_family<S: Into<String>>(mut self, family: S) -> Self
Set the font family for all text in the plot.
family
impl Into<String>
required
Font family name (e.g., "Arial", "Helvetica", "monospace").
with_title_size
pub fn with_title_size(mut self, size: u32) -> Self
Set the title font size in pixels.
Font size. Default is 16.
with_label_size
pub fn with_label_size(mut self, size: u32) -> Self
Set the axis label font size in pixels.
Font size. Default is 14.
with_tick_size
pub fn with_tick_size(mut self, size: u32) -> Self
Set the tick label font size in pixels.
Font size. Default is 10.
with_body_size
pub fn with_body_size(mut self, size: u32) -> Self
Set the body text font size (used in legends and annotations) in pixels.
Font size. Default is 12.
Example:
let layout = Layout::auto_from_plots(&plots)
.with_font_family("Arial")
.with_title_size(20)
.with_label_size(16)
.with_tick_size(12);
Theme and Color Methods
with_theme
pub fn with_theme(mut self, theme: Theme) -> Self
Set the overall theme (background, colors, grid style).
A Theme instance. Built-in themes include Theme::default(), Theme::dark(), etc.
with_palette
pub fn with_palette(mut self, palette: Palette) -> Self
Set the color palette for multi-series plots.
A Palette instance. Built-in palettes include Palette::tableau10(), Palette::category10(), etc.
Example:
use kuva::render::theme::Theme;
use kuva::render::palette::Palette;
let layout = Layout::auto_from_plots(&plots)
.with_theme(Theme::dark())
.with_palette(Palette::tableau10());
Secondary Y-axis Methods
with_y2_range
pub fn with_y2_range(mut self, min: f64, max: f64) -> Self
Define a range for a secondary (right-side) y-axis.
Minimum value for the secondary y-axis.
Maximum value for the secondary y-axis.
with_y2_label
pub fn with_y2_label<S: Into<String>>(mut self, label: S) -> Self
Set the label for the secondary y-axis.
with_log_y2
pub fn with_log_y2(mut self) -> Self
Enable logarithmic scale for the secondary y-axis.
pub fn with_y2_tick_format(mut self, fmt: TickFormat) -> Self
Set the tick format for the secondary y-axis.
with_y2_auto
pub fn with_y2_auto(mut self, secondary: &[Plot]) -> Self
Auto-compute y2_range from secondary plots, also expanding x_range to cover them.
Plots to render on the secondary y-axis.
Example:
let primary_plots = vec![line1.into()];
let secondary_plots = vec![line2.into()];
let layout = Layout::auto_from_twin_y_plots(&primary_plots, &secondary_plots)
.with_y_label("Primary")
.with_y2_label("Secondary");
DateTime Axis Methods
with_x_datetime
pub fn with_x_datetime(mut self, axis: DateTimeAxis) -> Self
Configure the x-axis to display datetime values.
A DateTimeAxis configuration specifying the time unit and formatting.
with_y_datetime
pub fn with_y_datetime(mut self, axis: DateTimeAxis) -> Self
Configure the y-axis to display datetime values.
with_x_tick_rotate
pub fn with_x_tick_rotate(mut self, angle: f64) -> Self
Rotate x-axis tick labels by the specified angle in degrees (e.g., -45.0 for diagonal labels).
Rotation angle in degrees. Negative values rotate counter-clockwise.
Example:
use kuva::render::datetime::{DateTimeAxis, DateUnit};
let layout = Layout::auto_from_plots(&plots)
.with_x_datetime(DateTimeAxis::new(DateUnit::Day))
.with_x_tick_rotate(-45.0); // Diagonal labels
Annotation Methods
with_annotation
pub fn with_annotation(mut self, annotation: TextAnnotation) -> Self
Add a text annotation to the plot.
A TextAnnotation instance specifying the text, position, and style.
with_reference_line
pub fn with_reference_line(mut self, line: ReferenceLine) -> Self
Add a reference line (horizontal or vertical) to the plot.
A ReferenceLine instance specifying the position, orientation, and style.
with_shaded_region
pub fn with_shaded_region(mut self, region: ShadedRegion) -> Self
Add a shaded region to highlight a range on the plot.
A ShadedRegion instance specifying the bounds and fill color.
Advanced Configuration Methods
with_clamp_axis
pub fn with_clamp_axis(mut self) -> Self
Snap both axes to the tick boundary that just contains the data, with no extra breathing-room step. Useful for TickFormat::Percent where you want the axis to stop exactly at 100% instead of 110%.
with_clamp_y_axis
pub fn with_clamp_y_axis(mut self) -> Self
Like with_clamp_axis but only for the y-axis. Automatically set by auto_from_plots for normalized histograms.
with_term_rows
pub fn with_term_rows(mut self, rows: u32) -> Self
Set the number of character rows in the terminal target for terminal backend rendering.
Complete Example
use kuva::prelude::*;
use kuva::render::layout::{Layout, TickFormat};
use kuva::render::theme::Theme;
use kuva::render::palette::Palette;
use kuva::plot::legend::LegendPosition;
// Create multiple plots
let scatter = ScatterPlot::new()
.with_data(vec![(1.0, 2.0), (2.0, 4.0), (3.0, 3.5)])
.with_color("steelblue")
.with_legend_label("Data Series");
let line = LinePlot::new()
.with_data(vec![(0.0, 1.0), (1.0, 2.0), (2.0, 3.0), (3.0, 4.0)])
.with_color("red")
.with_legend_label("Trend");
let plots: Vec<Plot> = vec![scatter.into(), line.into()];
// Configure comprehensive layout
let layout = Layout::auto_from_plots(&plots)
.with_width(1000.0)
.with_height(700.0)
.with_title("Comprehensive Analysis")
.with_x_label("Time (seconds)")
.with_y_label("Signal Intensity")
.with_ticks(8)
.with_show_grid(true)
.with_y_tick_format(TickFormat::Fixed(2))
.with_theme(Theme::default())
.with_palette(Palette::tableau10())
.with_legend_position(LegendPosition::TopRight)
.with_font_family("Arial")
.with_title_size(18)
.with_label_size(14);
let svg = kuva::render_to_svg(plots, layout);