Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,410 changes: 2,340 additions & 70 deletions Cargo.lock

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions examples/polars/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "polars_example"
version = "0.1.0"
license.workspace = true
edition.workspace = true
rust-version.workspace = true
publish = false

[lints]
workspace = true

[dependencies]
eframe = { workspace = true, features = ["default"] }
egui_plot.workspace = true
env_logger = { version = "0.11.8", default-features = false, features = [
"auto-color",
"humantime",
] }
examples_utils.workspace = true

polars = { version = "0.44.2", features = ["lazy"] }

[package.metadata.cargo-shear]
ignored = [
"env_logger",
] # used by make_main! macroenv_logger = { version = "0.11.6", default-features = false, features = [
19 changes: 19 additions & 0 deletions examples/polars/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Box Plot Demo

This example demonstrates how to create box plots (box-and-whisker plots) with customizable orientation, zoom, and drag controls. It shows multiple box plots with different experiments and days, allowing you to visualize statistical distributions.

## Running

Native
```sh
cargo run -p box_plot
```

Web (WASM)
```sh
cd examples/box_plot
trunk serve
```

![](screenshot.png)

3 changes: 3 additions & 0 deletions examples/polars/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions examples/polars/screenshot_thumb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
133 changes: 133 additions & 0 deletions examples/polars/src/app.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
use eframe::egui;
use eframe::egui::Response;
use egui_plot::Legend;
use egui_plot::Line;
use egui_plot::Plot;
use egui_plot::PlotPoints;
use polars::prelude::*;

pub struct PolarsExample {
df: DataFrame,
x_column: String,
y_column: String,
city: String,
}

impl Default for PolarsExample {
fn default() -> Self {
let df = df![
"time" => &[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0],
"temp" => &[10.5, 12.3, 15.1, 14.8, 16.2, 18.5, 20.1, 22.3, 19.8, 17.5, 15.2, 13.8, 12.1, 11.5, 10.9,
8.2, 9.5, 11.3, 13.7, 16.1, 19.2, 22.5, 24.8, 23.1, 20.5, 18.3, 15.9, 13.2, 10.8, 9.1],
"humidity" => &[65.0, 68.5, 72.3, 70.1, 67.8, 65.2, 62.5, 60.8, 63.2, 66.5, 69.8, 73.2, 75.5, 77.8, 80.1,
55.3, 58.7, 62.1, 60.5, 57.9, 54.2, 51.8, 49.5, 52.3, 55.8, 59.2, 62.8, 66.5, 70.1, 73.8],
"city" => &["London", "London", "London", "London", "London", "London", "London", "London", "London", "London", "London", "London", "London", "London", "London",
"Paris", "Paris", "Paris", "Paris", "Paris", "Paris", "Paris", "Paris", "Paris", "Paris", "Paris", "Paris", "Paris", "Paris", "Paris"],
]
.unwrap();

Self {
df,
x_column: "time".to_owned(),
y_column: "temp".to_owned(),
city: "London".to_owned(),
}
}
}

impl PolarsExample {
/// Get all float column names from the DataFrame.
fn get_float_columns(&self) -> Vec<String> {
self.df
.get_columns()
.iter()
.filter(|col| col.dtype().is_float())
.map(|col| col.name().to_string())
.collect()
}

fn get_cities(&self) -> Vec<String> {
let mut cities: Vec<String> = self
.df
.column("city")
.ok()
.and_then(|col| col.str().ok())
.and_then(|s| s.unique().ok())
.map(|unique| unique.into_iter().flatten().map(str::to_owned).collect())
.unwrap_or_default();
cities.sort();
cities
}

pub fn show_controls(&mut self, ui: &mut egui::Ui) -> Response {
let numerical_columns = self.get_float_columns();

ui.horizontal(|ui| {
egui::ComboBox::new("x_column", "X column")
.selected_text(&self.x_column)
.show_ui(ui, |ui| {
for col in &numerical_columns {
ui.selectable_value(&mut self.x_column, col.clone(), col);
}
});

ui.separator();

egui::ComboBox::new("y_column", "Y column")
.selected_text(&self.y_column)
.show_ui(ui, |ui| {
for col in &numerical_columns {
ui.selectable_value(&mut self.y_column, col.clone(), col);
}
});

ui.separator();
egui::ComboBox::new("city", "City")
.selected_text(self.city.as_str())
.show_ui(ui, |ui| {
for city in self.get_cities() {
ui.selectable_value(&mut self.city, city.clone(), city);
}
});
})
.response
}

pub fn show_plot(&self, ui: &mut egui::Ui) -> Response {
// Filter DataFrame by selected city using lazy API
let filtered_df = self
.df
.clone()
.lazy()
.filter(col("city").eq(lit(self.city.as_str())))
.collect()
.unwrap_or_else(|_| self.df.clone());

// Extract x and y columns as continuous slices
let xs: Option<&[f64]> = filtered_df
.column(&self.x_column)
.ok()
.and_then(|col| col.f64().ok())
.and_then(|ca| ca.cont_slice().ok());
let ys: Option<&[f64]> = filtered_df
.column(&self.y_column)
.ok()
.and_then(|col| col.f64().ok())
.and_then(|ca| ca.cont_slice().ok());

// Create plot points from x and y values
let points: Option<PlotPoints<'_>> = xs
.zip(ys)
.map(|(xs, ys)| xs.iter().zip(ys.iter()).map(|(&x, &y)| [x, y]).collect());

Plot::new("PolarsExample")
.legend(Legend::default())
.show(ui, |plot_ui| {
if let Some(points) = points {
plot_ui.line(Line::new(&self.y_column, points));
}
})
.response
}
}
41 changes: 41 additions & 0 deletions examples/polars/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#![doc = include_str!("../README.md")]

use eframe::egui;
use examples_utils::PlotExample;

mod app;
pub use app::PolarsExample;

impl PlotExample for PolarsExample {
fn name(&self) -> &'static str {
"polars"
}

fn title(&self) -> &'static str {
"Polars Demo"
}

fn description(&self) -> &'static str {
"This example demonstrates how to create plots with Polars dataframes."
}

fn tags(&self) -> &'static [&'static str] {
&["polars", "dataframe"]
}

fn thumbnail_bytes(&self) -> &'static [u8] {
include_bytes!("../screenshot_thumb.png")
}

fn code_bytes(&self) -> &'static [u8] {
include_bytes!("./app.rs")
}

fn show_ui(&mut self, ui: &mut egui::Ui) -> egui::Response {
self.show_plot(ui)
}

fn show_controls(&mut self, ui: &mut egui::Ui) -> egui::Response {
self.show_controls(ui)
}
}
4 changes: 4 additions & 0 deletions examples/polars/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
use examples_utils::make_main;
use polars_example::PolarsExample;

make_main!(PolarsExample);
Loading