Skip to content

Legend and labels are not customizable enough #70

@Tsai002

Description

@Tsai002

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.

Image Image
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(())
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions