use charton::prelude::*;
use polars::prelude::*;
use std::error::Error;
fn manual_melt(df: &DataFrame, value_vars: &[&str], id_vars: &[&str]) -> PolarsResult<DataFrame> {
let mut melted_dfs: Vec<DataFrame> = Vec::new();
let id_col = id_vars[0];
for &col_name in value_vars {
let mut sub_df = df.select([id_col, col_name])?;
let variable_series = Series::new("variable".into(), vec![col_name; sub_df.height()]);
sub_df.with_column(variable_series)?; sub_df.rename(col_name, "value".into())?;
sub_df = sub_df.select([id_col, "variable", "value"])?;
melted_dfs.push(sub_df);
}
let mut final_df = melted_dfs.remove(0);
for df_to_stack in melted_dfs {
final_df = final_df.vstack(&df_to_stack)?;
}
Ok(final_df)
}
fn main() -> Result<(), Box<dyn Error>> {
let df = load_dataset("iris")?;
let df_melted = manual_melt(
&df,
&["sepal_length", "sepal_width", "petal_length", "petal_width"],
&["species"],
)?;
println!("{}", &df_melted);
Chart::build(&df_melted)?
.mark_boxplot()?
.encode((x("variable"), y("value"), color("species")))?
.save("docs/src/images/grouped_boxplot.svg")?;
Ok(())
}