Scatter plots visualize the relationship between two continuous variables by placing individual data points at (x, y) coordinates. Kuva’s ScatterPlot supports six marker shapes, per-point sizing for bubble plots, symmetric and asymmetric error bars, linear trend lines with equations, and shaded confidence bands.
When to Use
- Exploring relationships between two continuous variables
- Identifying correlation patterns
- Detecting outliers and clusters
- Showing measurement uncertainty with error bars
- Creating bubble plots where point size encodes a third variable
Basic Example
use kuva::plot::scatter::ScatterPlot;
use kuva::backend::svg::SvgBackend;
use kuva::render::render::render_multiple;
use kuva::render::layout::Layout;
use kuva::render::plots::Plot;
let data = vec![
(0.5_f64, 1.2_f64),
(1.4, 3.1),
(2.1, 2.4),
(3.3, 5.0),
(4.0, 4.3),
(5.2, 6.8),
];
let plot = ScatterPlot::new()
.with_data(data)
.with_color("steelblue")
.with_size(5.0);
let plots = vec![Plot::Scatter(plot)];
let layout = Layout::auto_from_plots(&plots)
.with_title("Scatter Plot")
.with_x_label("X")
.with_y_label("Y");
let svg = SvgBackend.render_scene(&render_multiple(plots, layout));
std::fs::write("scatter.svg", svg).unwrap();
Key Methods
Set the (x, y) data points. Accepts any iterator of (T, U) pairs where T and U implement Into<f64>:// Works with integers
.with_data(vec![(1_i32, 5_i32), (2, 8), (3, 6)])
// Works with floats
.with_data(vec![(1.0_f64, 2.0_f64), (3.0, 5.0)])
Styling
Set the point color using CSS color strings:.with_color("steelblue") // Named colors
.with_color("#4682b4") // Hex codes
.with_color("rgb(70,130,180)") // RGB
Set the uniform point radius in pixels (default 3.0):.with_size(5.0) // Larger points
Choose from six marker shapes:use kuva::plot::scatter::MarkerShape;
.with_marker(MarkerShape::Circle) // Default
.with_marker(MarkerShape::Square)
.with_marker(MarkerShape::Triangle)
.with_marker(MarkerShape::Diamond)
.with_marker(MarkerShape::Cross)
.with_marker(MarkerShape::Plus)
Error Bars
Add symmetric X error bars (half-width values):let x_err = vec![0.2_f64, 0.15, 0.3];
.with_x_err(x_err)
Add symmetric Y error bars:let y_err = vec![0.6_f64, 0.8, 0.4];
.with_y_err(y_err)
Add asymmetric X error bars with (negative_arm, positive_arm) tuples:let x_err = vec![(0.1_f64, 0.3_f64), (0.15, 0.25)];
.with_x_err_asymmetric(x_err)
Add asymmetric Y error bars:let y_err = vec![(0.5_f64, 0.8_f64), (0.6, 0.9)];
.with_y_err_asymmetric(y_err)
Trend Lines
Overlay a linear regression trend line:use kuva::plot::scatter::TrendLine;
.with_trend(TrendLine::Linear)
Set trend line color (default "black"):.with_trend_color("crimson")
Annotate with regression equation (y = mx + b):.with_trend(TrendLine::Linear)
.with_equation()
Annotate with Pearson R² correlation coefficient:.with_trend(TrendLine::Linear)
.with_correlation()
Set trend line stroke width in pixels (default 1.0):
Confidence Bands
Add a shaded confidence region:let lower = vec![1.5_f64, 3.5, 5.5];
let upper = vec![2.5_f64, 4.5, 6.5];
.with_band(lower, upper)
The band color matches the scatter series color automatically.
Bubble Plots
Set per-point radii for bubble plots (overrides uniform size):let sizes = vec![5.0_f64, 12.0, 8.0, 18.0];
.with_sizes(sizes)
Legend
Attach a legend label for this series:.with_legend("Experimental data")
A legend renders automatically when at least one plot has a label.
Examples
Scatter with Trend Line
let data = vec![
(1.0_f64, 2.1_f64), (2.0, 3.9), (3.0, 6.2),
(4.0, 7.8), (5.0, 10.1), (6.0, 12.3),
];
let plot = ScatterPlot::new()
.with_data(data)
.with_color("steelblue")
.with_size(5.0)
.with_trend(TrendLine::Linear)
.with_trend_color("crimson")
.with_equation()
.with_correlation();
Scatter with Error Bars
let data = vec![
(1.0_f64, 2.0_f64),
(2.0, 4.5),
(3.0, 5.8),
(4.0, 8.2),
(5.0, 10.1),
];
let x_err = vec![0.2_f64, 0.15, 0.3, 0.1, 0.25];
let y_err = vec![0.6_f64, 0.8, 0.4, 0.9, 0.5];
let plot = ScatterPlot::new()
.with_data(data)
.with_x_err(x_err)
.with_y_err(y_err)
.with_color("steelblue")
.with_size(5.0);
Bubble Plot
let data = vec![
(1.0_f64, 3.0_f64),
(2.5, 6.5),
(4.0, 4.0),
(5.5, 8.0),
];
let sizes = vec![5.0_f64, 14.0, 9.0, 18.0];
let plot = ScatterPlot::new()
.with_data(data)
.with_sizes(sizes) // Variable point sizes
.with_color("steelblue");
Multiple Series with Markers
let plots: Vec<Plot> = vec![
Plot::Scatter(
ScatterPlot::new()
.with_data(vec![(1.0, 2.0), (2.0, 4.0), (3.0, 3.0)])
.with_color("steelblue")
.with_marker(MarkerShape::Circle)
.with_legend("Series A")
),
Plot::Scatter(
ScatterPlot::new()
.with_data(vec![(1.0, 3.0), (2.0, 2.5), (3.0, 4.5)])
.with_color("crimson")
.with_marker(MarkerShape::Square)
.with_legend("Series B")
),
];
Confidence Band
let xs: Vec<f64> = (1..=10).map(|i| i as f64).collect();
let ys: Vec<f64> = xs.iter().map(|&x| x * 1.8 + 0.5).collect();
let lower: Vec<f64> = ys.iter().map(|&y| y - 1.2).collect();
let upper: Vec<f64> = ys.iter().map(|&y| y + 1.2).collect();
let data: Vec<(f64, f64)> = xs.into_iter().zip(ys).collect();
let plot = ScatterPlot::new()
.with_data(data)
.with_color("steelblue")
.with_size(5.0)
.with_band(lower, upper);
Tips
Point overlap: For dense data, reduce point size (.with_size(2.0)) or use semi-transparent colors (rgba(70,130,180,0.6)).
Error bars: Must call .with_data() before adding error bars since they need to match the data point count.
Trend lines: Combine .with_equation() and .with_correlation() to show both the regression formula and goodness-of-fit.
Bubble plots with .with_sizes() override the uniform .with_size() value. Make sure the sizes vector has the same length as your data.
Source Location
Implementation: src/plot/scatter.rs
Examples: examples/scatter.rs