Skip to main content
Line plots connect (x, y) data points with a continuous line, ideal for visualizing trends, time series, and functional relationships. Kuva’s LinePlot supports four built-in line styles (solid, dashed, dotted, dash-dot), area fills, step interpolation, confidence bands, and error bars.

When to Use

  • Time series data and trends over time
  • Continuous functional relationships (y = f(x))
  • Comparing multiple series on the same axes
  • Showing uncertainty with error bars or confidence bands
  • Step functions and discrete-time data
  • Area charts showing cumulative values

Basic Example

use kuva::plot::LinePlot;
use kuva::backend::svg::SvgBackend;
use kuva::render::render::render_multiple;
use kuva::render::layout::Layout;
use kuva::render::plots::Plot;

let data: Vec<(f64, f64)> = (0..=100)
    .map(|i| {
        let x = i as f64 * 0.1;
        (x, x.sin())
    })
    .collect();

let plot = LinePlot::new()
    .with_data(data)
    .with_color("steelblue")
    .with_stroke_width(2.0);

let plots = vec![Plot::Line(plot)];
let layout = Layout::auto_from_plots(&plots)
    .with_title("Sine Wave")
    .with_x_label("X")
    .with_y_label("Y");

let svg = SvgBackend.render_scene(&render_multiple(plots, layout));
std::fs::write("line.svg", svg).unwrap();

Key Methods

Data Input

with_data
method
Set the (x, y) data points to connect. Accepts any iterator of (T, U) pairs where T and U implement Into<f64>:
// Integer input
.with_data(vec![(0_i32, 0_i32), (1, 2), (2, 1)])

// Float input
.with_data(vec![(0.0_f64, 0.0_f64), (1.5, 2.3), (3.0, 1.8)])

Styling

with_color
method
Set the line color using CSS color strings:
.with_color("steelblue")
.with_color("#4682b4")
.with_color("rgb(70,130,180)")
with_stroke_width
method
Set the line width in pixels (default 2.0):
.with_stroke_width(3.0)  // Thicker line
with_line_style
method
Set the line style explicitly:
use kuva::plot::LineStyle;

.with_line_style(LineStyle::Solid)     // Default
.with_line_style(LineStyle::Dashed)    // 8 4 dasharray
.with_line_style(LineStyle::Dotted)    // 2 4 dasharray
.with_line_style(LineStyle::DashDot)   // 8 4 2 4 dasharray
.with_line_style(LineStyle::Custom("10 5 2 5".into()))  // Custom SVG dasharray
with_dashed
method
Shortcut for dashed line style:
.with_dashed()
with_dotted
method
Shortcut for dotted line style:
.with_dotted()
with_dashdot
method
Shortcut for dash-dot line style:
.with_dashdot()

Area Fill

with_fill
method
Fill the area between the line and the x-axis:
.with_fill()
Uses the line color at the opacity set by with_fill_opacity() (default 0.3).
with_fill_opacity
method
Set fill opacity for area charts (default 0.3):
.with_fill()
.with_fill_opacity(0.5)  // 50% opacity

Step Interpolation

with_step
method
Use step interpolation (horizontal then vertical segments):
.with_step()
Instead of diagonal lines between points, draws horizontal segments at each y-value then vertical steps. Useful for histograms and discrete-time series.

Error Bars

with_x_err
method
Add symmetric X error bars:
let x_err = vec![0.1_f64, 0.15, 0.2];
.with_x_err(x_err)
with_y_err
method
Add symmetric Y error bars:
let y_err = vec![0.15_f64, 0.20, 0.12];
.with_y_err(y_err)
with_x_err_asymmetric
method
Add asymmetric X error bars:
let x_err = vec![(0.1_f64, 0.2_f64), (0.15, 0.25)];
.with_x_err_asymmetric(x_err)
with_y_err_asymmetric
method
Add asymmetric Y error bars:
let y_err = vec![(0.1_f64, 0.3_f64), (0.2, 0.4)];
.with_y_err_asymmetric(y_err)

Confidence Bands

with_band
method
Add a shaded confidence region:
let data: Vec<(f64, f64)> = /* your data */;
let lower: Vec<f64> = /* lower bounds */;
let upper: Vec<f64> = /* upper bounds */;

.with_band(lower, upper)
The band color matches the line color at 30% opacity.

Legend

with_legend
method
Attach a legend label for this series:
.with_legend("Temperature")

Examples

Multiple Line Styles

let xs: Vec<f64> = (0..=80).map(|i| i as f64 * 0.125).collect();

let plots = vec![
    Plot::Line(
        LinePlot::new()
            .with_data(xs.iter().map(|&x| (x, x.sin())))
            .with_color("steelblue")
            .with_stroke_width(2.0)
            .with_legend("Solid")
    ),
    Plot::Line(
        LinePlot::new()
            .with_data(xs.iter().map(|&x| (x, x.cos())))
            .with_color("crimson")
            .with_stroke_width(2.0)
            .with_dashed()
            .with_legend("Dashed")
    ),
    Plot::Line(
        LinePlot::new()
            .with_data(xs.iter().map(|&x| (x, (x * 0.7).sin())))
            .with_color("seagreen")
            .with_stroke_width(2.0)
            .with_dotted()
            .with_legend("Dotted")
    ),
];

Area Plot

let data: Vec<(f64, f64)> = (0..=100)
    .map(|i| {
        let x = i as f64 * 0.1;
        (x, x.sin())
    })
    .collect();

let plot = LinePlot::new()
    .with_data(data)
    .with_color("steelblue")
    .with_stroke_width(2.0)
    .with_fill()
    .with_fill_opacity(0.3);

Step Plot

let data: Vec<(f64, f64)> = vec![
    (0.0, 2.0), (1.0, 5.0), (2.0, 3.0), (3.0, 7.0),
    (4.0, 4.0), (5.0, 8.0), (6.0, 5.0), (7.0, 9.0),
];

let plot = LinePlot::new()
    .with_data(data)
    .with_color("steelblue")
    .with_stroke_width(2.0)
    .with_step();

Line with Confidence Band

let xs: Vec<f64> = (0..=80).map(|i| i as f64 * 0.125).collect();
let ys: Vec<f64> = xs.iter().map(|&x| x.sin()).collect();
let lower: Vec<f64> = ys.iter().map(|&y| y - 0.3).collect();
let upper: Vec<f64> = ys.iter().map(|&y| y + 0.3).collect();

let data: Vec<(f64, f64)> = xs.into_iter().zip(ys).collect();

let plot = LinePlot::new()
    .with_data(data)
    .with_color("steelblue")
    .with_stroke_width(2.0)
    .with_band(lower, upper);

Line with Error Bars

let data: Vec<(f64, f64)> = (0..=8)
    .map(|i| (i as f64, (i as f64 * 0.8).sin()))
    .collect();
let y_err: Vec<f64> = vec![
    0.15, 0.20, 0.12, 0.18, 0.22, 0.14, 0.19, 0.16, 0.21
];

let plot = LinePlot::new()
    .with_data(data)
    .with_y_err(y_err)
    .with_color("steelblue")
    .with_stroke_width(2.0);

Tips

Multiple series: Use different colors and line styles to distinguish overlapping series. Combine with .with_legend() for clarity.
Time series: For discrete time steps (daily, monthly data), consider using .with_step() to emphasize the stepwise nature of the data.
Smooth curves: For very smooth curves, generate more data points. For mathematical functions, use 100-200 points for most screen resolutions.
Error bars and bands must have the same length as your data points. Call .with_data() first, then add error bars or bands.

Source Location

Implementation: src/plot/line.rs
Examples: examples/line.rs

Build docs developers (and LLMs) love