This section explores how to visualize data variability, confidence intervals, and statistical trends. By leveraging Charton's Layered Chart system and Polars expressions, you can easily combine summary statistics (like bars or lines) with their associated error ranges.
Basic Bar with Error Bars
Error bars are essential for communicating the precision of your data. This example shows the most common use case: a bar chart where each bar is accompanied by a vertical error bar calculated from pre-defined standard deviation values.
Key Concept: We use transform_calculate to dynamically create value_min and value_max columns within the chart pipeline.
use charton::prelude::*; use polars::prelude::*; use std::error::Error; fn main() -> Result<(), Box<dyn Error>> { // Create sample data with x and y values let df = df! [ "type" => ["a", "b", "c", "d"], "value" => [4.9, 5.3, 5.5, 6.5], "value_std" => [0.3, 0.39, 0.34, 0.20] ]?; // Create error bar chart using transform_calculate to add min/max values let errorbar = Chart::build(&df)? // Use transform_calculate to create ymin and ymax columns based on fixed std values .transform_calculate( (col("value") - col("value_std")).alias("value_min"), // ymin = y - std (col("value") + col("value_std")).alias("value_max"), // ymax = y + std )? .mark_errorbar()? .encode((x("type"), y("value_min"), y2("value_max")))?; let bar = Chart::build(&df)? .mark_bar()? .encode((x("type"), y("value")))?; // Create a layered chart and add the errorbar chart as a layer errorbar .and(bar) .with_y_label("value") .save("docs/src/images/bar_with_errorbar.svg")?; Ok(()) }
Grouped Bar with ErrorBar
When multiple groups are present (mapped to color), Charton automatically applies "dodge" logic to ensure that both the bars and the error bars are aligned side-by-side for each category.
use charton::prelude::*; use std::error::Error; fn main() -> Result<(), Box<dyn Error>> { let df = load_dataset("penguins")?; println!("{:?}", df); // 2. Build the Error Bar layer let errorbar = Chart::build(&df)? .mark_errorbar()? // Mapping 'Sex' to color triggers the dodge logic .encode((x("Species"), y("Body Mass (g)"), color("Sex")))?; // 3. Add a Bar layer to see the alignment let bar = Chart::build(&df)?.mark_bar()?.encode(( x("Species"), y("Body Mass (g)").with_aggregate("mean"), color("Sex"), ))?; // 4. Create the multiple layered Chart errorbar .and(bar) .with_size(600, 400) .with_title("Grouped Error Bars with Mean & Std Dev") .save("docs/src/images/grouped_bar_with_errorbar_1.svg")?; Ok(()) }
As an alternative approach, we demonstrate how to create a grouped error bar chart by manually defining the error boundaries using transform_calculate. While the previous one use automatic statistical aggregations, this method shows that the data generated through Charton's internal transformation pipeline is fully compatible across different layers. By calculating value_min and value_max within the errorbar layer, we ensure that the resulting dataset structure remains consistent with the mark_bar layer.
use charton::prelude::*; use polars::prelude::*; use std::error::Error; fn main() -> Result<(), Box<dyn Error>> { // Create sample data with x and y values let df = df! [ "type" => ["a", "a", "a", "a", "b", "b", "b", "b", "c", "c", "c", "c"], "value" => [4.1, 5.3, 5.5, 6.5, 4.2, 5.1, 5.7, 5.5, 4.3, 5.5, 5.1, 6.8], "value_std" => [0.22, 0.26, 0.14, 0.23, 0.2, 0.23, 0.12, 0.25, 0.21, 0.20, 0.16, 0.25], "group" => ["E", "F", "G", "H", "E", "F", "G", "H", "E", "F", "G", "H"] ]?; // Create error bar chart using transform_calculate to add min/max values let errorbar = Chart::build(&df)? // Use transform_calculate to create ymin and ymax columns based on fixed std values .transform_calculate( (col("value") - col("value_std")).alias("value_min"), // ymin = y - std (col("value") + col("value_std")).alias("value_max"), // ymax = y + std )? .mark_errorbar()? .encode((x("type"), y("value_min"), y2("value_max"), color("group")))?; // Create a bar chart let bar = Chart::build(&df)? .mark_bar()? .encode((x("type"), y("value"), color("group")))?; // Create a layered chart errorbar .and(bar) .save("docs/src/images/grouped_bar_with_errorbar_2.svg")?; Ok(()) }