The current chart rendering has very limited customization support for both legends and labels, which makes the visualization difficult to use in real-world scenarios.
Legend issues:
- There is no way to hide or disable it.
Label issues:
- Labels cannot be formatted or customized. No support for custom text formatting, precision, abbreviations, prefixes/suffixes, etc.
I tried using Charton to recreate Economist-style charts, but the current customization capabilities are too limited for production-quality results.
use charton::{alt::color, core::guide::LegendPosition, prelude::*};
use polars::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut df = CsvReadOptions::default()
.try_into_reader_with_file_path(Some(
"private-investment-in-artificial-intelligence-by-focus-area.csv".into(),
))
.unwrap()
.finish()
.unwrap();
df = df
.lazy()
.with_columns([col("Year").cast(DataType::String)])
.collect()
.unwrap();
let mask = df.column("Entity")?.str()?.not_equal("Total");
let df = df.filter(&mask)?;
let entity = df.column("Entity")?.str()?;
let highlight_colors = [
"Data management, processing, cloud",
"Medical and healthcare",
"Retail",
"Natural language, customer support",
"Facial recognition",
];
let mask: BooleanChunked = entity
.into_iter()
.map(|opt_v| opt_v.map(|v| highlight_colors.contains(&v)))
.collect();
println!("{:?}", df.shape());
let highlight = df.filter(&mask)?;
println!("{:?}", highlight.shape());
let not_highlight = df.filter(&!mask)?;
println!("{:?}", not_highlight.shape());
let ds = load_polars_df!(not_highlight)?;
let ds_highlight = load_polars_df!(highlight)?;
println!("dataset: {:?}", ds_highlight.head(10));
println!("dataset: {:?}", ds.head(10));
let cp = vec![
"#17648d".into(),
"#51bec7".into(),
"#008c8f".into(),
"#d6ab63".into(),
"#843844".into(),
];
let highlight_chart = Chart::build(ds_highlight)?
.mark_line()?
.configure_line(|l| l.with_stroke_width(1.25))
.encode((
alt::x("Year"),
alt::y("total_private_investment_by_focus_area_inflation_adjusted"),
color("Entity"),
))?
.configure_theme(|t| {
t.with_palette(ColorPalette::Custom(cp))
.with_legend_position(LegendPosition::Top)
})
.with_title("Annual global private investment in artificial intelligence, by focus area")
// .with_y_ticks([
// -1e9, 0.0, 1e9, 2e9, 3e9, 4e9, 5e9, 6e9, 7e9, 8e9, 9e9, 1e10, 11e9, 12e10,
// ])
.with_y_label("");
highlight_chart.save("highlight.svg")?;
let base_chart = Chart::build(ds)?
.mark_line()?
.configure_line(|l| l.with_stroke_width(0.75).with_color("#d4dddd"))
.encode((
alt::x("Year"),
alt::y("total_private_investment_by_focus_area_inflation_adjusted"),
alt::color("Entity"),
))?
.configure_theme(|t| {
t.with_palette(ColorPalette::Custom(vec!["#d4dddd".into()]))
.with_legend_position(LegendPosition::Top)
})
.with_title("Annual global private investment in artificial intelligence, by focus area")
.with_y_label("");
base_chart.save("base.svg")?;
highlight_chart.and(base_chart).save("economist.svg")?;
Ok(())
}
The current chart rendering has very limited customization support for both legends and labels, which makes the visualization difficult to use in real-world scenarios.
Legend issues:
Label issues:
I tried using Charton to recreate Economist-style charts, but the current customization capabilities are too limited for production-quality results.