From 56e46764357201011faf240b0ae63ed00ab3a1ca Mon Sep 17 00:00:00 2001 From: Tectin Date: Tue, 8 Aug 2023 17:37:29 +0200 Subject: [PATCH 1/5] added impl Color for number types + colorscale example --- examples/3d_charts/Cargo.toml | 1 + examples/3d_charts/src/main.rs | 74 +++++++++++++++++++++++++++++++++- plotly/src/common/color.rs | 29 +++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) diff --git a/examples/3d_charts/Cargo.toml b/examples/3d_charts/Cargo.toml index 21a4f1ce..48058077 100644 --- a/examples/3d_charts/Cargo.toml +++ b/examples/3d_charts/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" [dependencies] ndarray = "0.15.6" +rand = "0.8.5" plotly = { path = "../../plotly" } diff --git a/examples/3d_charts/src/main.rs b/examples/3d_charts/src/main.rs index 87653b57..9fa31435 100644 --- a/examples/3d_charts/src/main.rs +++ b/examples/3d_charts/src/main.rs @@ -3,11 +3,13 @@ use ndarray::Array; use plotly::{ color::Rgb, - common::{ColorScale, ColorScalePalette, Font, Marker, MarkerSymbol, Mode, Title}, + common::{ColorBar, ColorScale, ColorScalePalette, Font, Marker, MarkerSymbol, Mode, Title}, layout::{Axis, Camera, Layout, LayoutScene, Legend, Margin, ProjectionType}, Mesh3D, Plot, Scatter3D, Surface, }; +use rand::Rng; + // 3D Scatter Plots fn simple_scatter3d_plot() { let n: usize = 100; @@ -161,6 +163,75 @@ fn mesh_3d_plot() { plot.show(); } +fn colorscale_plot() { + let mut plot = Plot::new(); + + let x = (0..100) + .into_iter() + .map(|x| ((x - 50) as f64) / 100f64) + .collect::>(); + + let y = x.clone(); + + let iproduct = |x: &[f64], y: &[f64]| -> Vec<(f64, f64)> { + let mut result = Vec::new(); + for x in x { + for y in y { + result.push((*x, *y)); + } + } + result + }; + + let ((x, y), z): ((Vec, Vec), Vec) = iproduct(&x, &y) + .into_iter() + .map(|(x, y)| ((x, y), -(x.powi(2) + y.powi(2)) + 0.5)) + .unzip(); + + let color: Vec = z.clone().into_iter().rev().collect(); + // let color: Vec = (0..z.len()).collect(); + // let color: Vec = (0..z.len()).into_iter().map(|x| x as u8).collect(); + // let color: Vec = { + // let mut rng = rand::thread_rng(); + // (0..z.len()) + // .into_iter() + // .map(|_| rng.gen_range(0..100)) + // .collect() + // }; + + let color_max = color.iter().fold(f64::MIN, |acc, x| acc.max(*x as f64)); + + let colorscale = ColorScalePalette::YlGnBu; + + let marker = Marker::new() + .color_array(color) + .color_scale(plotly::common::ColorScale::Palette(colorscale.clone())) + .cauto(false) + .cmax(color_max * 1.5) + .color_bar(ColorBar::new()); + + let scatter = Scatter3D::new(x, y, z).mode(Mode::Markers).marker(marker); + + plot.add_trace(scatter); + + let layout = Layout::new() + .font(Font::new().size(18).family("Palatino-Linotype")) + .title(format!("Colorscale: {colorscale:?}").as_str().into()) + .width(1200) + .height(1000) + .scene( + LayoutScene::new() + .aspect_mode(plotly::layout::AspectMode::Data) + .x_axis(Axis::new().tick_format(".1f")) + .y_axis(Axis::new().tick_format(".1f")) + .z_axis(Axis::new().tick_format(".1f")), + ); + + plot.set_layout(layout); + + plot.show(); +} + fn main() { // Uncomment any of these lines to display the example. @@ -168,6 +239,7 @@ fn main() { // simple_scatter3d_plot(); // simple_line3d_plot(); // customized_scatter3d_plot(); + // colorscale_plot(); // Surface Plots // surface_plot(); diff --git a/plotly/src/common/color.rs b/plotly/src/common/color.rs index 06121ef8..1c807c97 100644 --- a/plotly/src/common/color.rs +++ b/plotly/src/common/color.rs @@ -20,6 +20,7 @@ use dyn_clone::DynClone; use erased_serde::Serialize as ErasedSerialize; + use serde::Serialize; /// A marker trait allowing several ways to describe a color. @@ -33,6 +34,20 @@ impl Color for &'static str {} impl Color for String {} impl Color for Rgb {} impl Color for Rgba {} +impl Color for f64 {} +impl Color for f32 {} +impl Color for u64 {} +impl Color for u32 {} +impl Color for u16 {} +impl Color for u8 {} +impl Color for i64 {} +impl Color for i32 {} +impl Color for i16 {} +impl Color for i8 {} +impl Color for usize {} + +// #[derive(Debug, Clone, Copy, serde::Serialize)] +// pub struct ColorRef(pub T); /// ColorArray is only used internally to provide a helper method for converting /// Vec to Vec>, as we would otherwise fall foul of @@ -290,6 +305,20 @@ mod tests { assert_eq!(to_value(color).unwrap(), json!("any_arbitrary_string")); } + #[test] + fn test_serialize_numbers() { + assert_eq!(to_value(1f64).unwrap(), json!(1f64)); + assert_eq!(to_value(1f32).unwrap(), json!(1f32)); + assert_eq!(to_value(1i64).unwrap(), json!(1i64)); + assert_eq!(to_value(1i32).unwrap(), json!(1i32)); + assert_eq!(to_value(1i16).unwrap(), json!(1i16)); + assert_eq!(to_value(1i8).unwrap(), json!(1i8)); + assert_eq!(to_value(1u64).unwrap(), json!(1u64)); + assert_eq!(to_value(1u32).unwrap(), json!(1u32)); + assert_eq!(to_value(1u16).unwrap(), json!(1u16)); + assert_eq!(to_value(1u8).unwrap(), json!(1u8)); + } + #[test] #[rustfmt::skip] fn test_serialize_named_color() { From 82797fd38590256404243d8c0931090b13f32449 Mon Sep 17 00:00:00 2001 From: Tectin Date: Tue, 8 Aug 2023 17:45:59 +0200 Subject: [PATCH 2/5] clippy fix --- examples/3d_charts/src/main.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/examples/3d_charts/src/main.rs b/examples/3d_charts/src/main.rs index 9fa31435..75b60032 100644 --- a/examples/3d_charts/src/main.rs +++ b/examples/3d_charts/src/main.rs @@ -167,7 +167,6 @@ fn colorscale_plot() { let mut plot = Plot::new(); let x = (0..100) - .into_iter() .map(|x| ((x - 50) as f64) / 100f64) .collect::>(); @@ -188,16 +187,13 @@ fn colorscale_plot() { .map(|(x, y)| ((x, y), -(x.powi(2) + y.powi(2)) + 0.5)) .unzip(); - let color: Vec = z.clone().into_iter().rev().collect(); - // let color: Vec = (0..z.len()).collect(); - // let color: Vec = (0..z.len()).into_iter().map(|x| x as u8).collect(); - // let color: Vec = { - // let mut rng = rand::thread_rng(); - // (0..z.len()) - // .into_iter() - // .map(|_| rng.gen_range(0..100)) - // .collect() - // }; + let color: Vec = z.clone().into_iter().rev().map(|x| x as f32).collect(); + let _color: Vec = (0..z.len()).collect(); + let _color: Vec = (0..z.len()).map(|x| x as u8).collect(); + let _color: Vec = { + let mut rng = rand::thread_rng(); + (0..z.len()).map(|_| rng.gen_range(0..100)).collect() + }; let color_max = color.iter().fold(f64::MIN, |acc, x| acc.max(*x as f64)); From 16ba8268439df7ce703ca0e1ca3334ff18514d52 Mon Sep 17 00:00:00 2001 From: Tectin Date: Tue, 8 Aug 2023 19:34:29 +0200 Subject: [PATCH 3/5] removed unnecessary new lines --- examples/3d_charts/src/main.rs | 1 - plotly/src/common/color.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/examples/3d_charts/src/main.rs b/examples/3d_charts/src/main.rs index 75b60032..070cd5fd 100644 --- a/examples/3d_charts/src/main.rs +++ b/examples/3d_charts/src/main.rs @@ -7,7 +7,6 @@ use plotly::{ layout::{Axis, Camera, Layout, LayoutScene, Legend, Margin, ProjectionType}, Mesh3D, Plot, Scatter3D, Surface, }; - use rand::Rng; // 3D Scatter Plots diff --git a/plotly/src/common/color.rs b/plotly/src/common/color.rs index 1c807c97..c7ac3129 100644 --- a/plotly/src/common/color.rs +++ b/plotly/src/common/color.rs @@ -20,7 +20,6 @@ use dyn_clone::DynClone; use erased_serde::Serialize as ErasedSerialize; - use serde::Serialize; /// A marker trait allowing several ways to describe a color. From 6997e0fbbcf0c53a22323c4e66ea9105684eda74 Mon Sep 17 00:00:00 2001 From: Tectin Date: Tue, 8 Aug 2023 19:50:32 +0200 Subject: [PATCH 4/5] removed left behind comment --- plotly/src/common/color.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/plotly/src/common/color.rs b/plotly/src/common/color.rs index c7ac3129..1d7a03af 100644 --- a/plotly/src/common/color.rs +++ b/plotly/src/common/color.rs @@ -45,9 +45,6 @@ impl Color for i16 {} impl Color for i8 {} impl Color for usize {} -// #[derive(Debug, Clone, Copy, serde::Serialize)] -// pub struct ColorRef(pub T); - /// ColorArray is only used internally to provide a helper method for converting /// Vec to Vec>, as we would otherwise fall foul of /// the orphan rules. From e067207c5663a0f955131e66c2714238d062d654 Mon Sep 17 00:00:00 2001 From: Tectin Date: Tue, 8 Aug 2023 19:57:23 +0200 Subject: [PATCH 5/5] fixed colorscale in customized_scatter3d_plot --- examples/3d_charts/src/main.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/3d_charts/src/main.rs b/examples/3d_charts/src/main.rs index 070cd5fd..e575daf1 100644 --- a/examples/3d_charts/src/main.rs +++ b/examples/3d_charts/src/main.rs @@ -42,10 +42,11 @@ fn customized_scatter3d_plot() { .map(|i| (i.abs() * 25f64) as usize) .collect(), ) - .color_scale(ColorScale::Palette(ColorScalePalette::Viridis)), + .color_scale(ColorScale::Palette(ColorScalePalette::Viridis)) + .color_array(z.clone()), ); - let trace2 = Scatter3D::new(t, z, y) + let trace2 = Scatter3D::new(t, z.clone(), y) .name("Helix 2") .mode(Mode::Markers) .marker( @@ -56,7 +57,8 @@ fn customized_scatter3d_plot() { .map(|i| (i.abs() * 25f64) as usize) .collect(), ) - .color_scale(ColorScale::Palette(ColorScalePalette::Viridis)), + .color_scale(ColorScale::Palette(ColorScalePalette::Viridis)) + .color_array(z), ); let mut plot = Plot::new();