Skip to content

Commit

Permalink
Ver 0.35.0
Browse files Browse the repository at this point in the history
Allow specific plot options
  • Loading branch information
Axect committed Mar 29, 2024
2 parents d659bd0 + a51f8f6 commit dad6071
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 100 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "peroxide"
version = "0.34.7"
version = "0.35.0"
authors = ["axect <[email protected]>"]
edition = "2018"
description = "Rust comprehensive scientific computation library contains linear algebra, numerical analysis, statistics and machine learning tools with farmiliar syntax"
Expand Down Expand Up @@ -30,7 +30,7 @@ peroxide-ad = "0.3"
peroxide-num = "0.1"
#num-complex = "0.3"
netcdf = { version = "0.7", optional = true, default_features = false }
pyo3 = { version = "0.20", optional = true, features = ["auto-initialize"] }
pyo3 = { version = "0.21", optional = true, features = ["auto-initialize", "gil-refs"] }
blas = { version = "0.22", optional = true }
lapack = { version = "0.19", optional = true }
serde = { version = "1.0", features = ["derive"], optional = true }
Expand Down
10 changes: 10 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# Release 0.35.0 (2024-03-29)

## Change some plot functions

- Now you can set marker, line style, color, alpha option for specific element.
- `set_marker(vec![(usize, Marker)])` : `usize` is index of element (image or pair)
- `set_line_style(vec![(usize, LineStyle)])`
- `set_color(vec![(usize, String)])`
- `set_alpha(vec![(usize, f64)])`

# Release 0.34.7 (2024-03-11)

## More updates for `plot` feature
Expand Down
Binary file modified example_data/test_plot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion src/structure/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,6 @@ use self::csv::{ReaderBuilder, StringRecord, WriterBuilder};
extern crate blas;
#[cfg(feature = "O3")]
extern crate lapack;
use ::matrixmultiply;
#[cfg(feature = "O3")]
use blas::{daxpy, dgemm, dgemv};
#[cfg(feature = "O3")]
Expand Down
169 changes: 72 additions & 97 deletions src/util/plot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,83 +3,44 @@
//! For Rust, there are some plot libraries but, still difficult to use.
//! Practically, using python is best choice to plot. And there is awesome crate - [pyo3](https://crates.io/crates/pyo3).
//!
//! Let's see next ordinary code file.
//! # Prerequisite
//!
//! ```no-run
//! #[macro_use]
//! extern crate peroxide;
//! use peroxide::fuga::*;
//!
//! fn main() {
//! let init_state = State::<f64>::new(0f64, c!(1), c!(0));
//!
//! let mut ode_solver = ExplicitODE::new(test_fn);
//! - python 3
//! - matplotlib
//! - scienceplots (Optional)
//!
//! ode_solver
//! .set_method(ExMethod::RK4)
//! .set_initial_condition(init_state)
//! .set_step_size(0.01)
//! .set_times(1000);
//! # Usage
//!
//! let result = ode_solver.integrate();
//! result.write("example_data/test.csv");
//! }
//! To use this module, you should enable `plot` feature in `Cargo.toml`
//!
//! fn test_fn(st: &mut State<f64>, _: &NoEnv) {
//! let x = st.param;
//! let y = &st.value;
//! let dy = &mut st.deriv;
//! dy[0] = (5f64*x.powi(2) - y[0]) / (x + y[0]).exp();
//! }
//! ```
//!
//! Now, let's modify this code to below. Then it works surprisingly!
//!
//! ```rust
//! #[macro_use]
//! extern crate peroxide;
//! use peroxide::fuga::*;
//!
//! fn main() {
//! let init_state = State::<f64>::new(0f64, c!(1), c!(0));
//!
//! let mut ode_solver = ExplicitODE::new(test_fn);
//!
//! ode_solver
//! .set_method(ExMethod::RK4)
//! .set_initial_condition(init_state)
//! .set_step_size(0.01)
//! .set_times(1000);
//!
//! let result = ode_solver.integrate();
//!
//! let x = result.col(0);
//! let y = result.col(1);
//!
//! // Remove below comments to execute
//! //let mut plt = Plot2D::new();
//! //plt.set_domain(x)
//! // .insert_image(y)
//! // .set_title("Test Figure")
//! // .set_fig_size((10, 6))
//! // .set_dpi(300)
//! // .set_legend(vec!["RK4"])
//! // .set_path("example_data/test_plot.png");
//!
//! //plt.savefig();
//! }
//! let x = linspace(0, 1, 100);
//! let y1 = x.fmap(|t| t.powi(2));
//! let y2 = x.fmap(|t| t.powi(3));
//!
//! fn test_fn(st: &mut State<f64>, _: &NoEnv) {
//! let x = st.param;
//! let y = &st.value;
//! let dy = &mut st.deriv;
//! dy[0] = (5f64 * x.powi(2) - y[0]) / (x + y[0]).exp();
//! let mut plt = Plot2D::new();
//! plt.set_domain(x)
//! .insert_image(y1)
//! .insert_image(y2)
//! .set_legend(vec![r"$y=x^2$", r"$y=x^3$"])
//! .set_line_style(vec![(0, LineStyle::Dashed), (1, LineStyle::Dotted)])
//! .set_color(vec![(0, "red"), (1, "darkblue")])
//! .set_xlabel(r"$x$")
//! .set_ylabel(r"$y$")
//! .set_style(PlotStyle::Nature) // if you want to use scienceplots
//! .set_dpi(600)
//! .tight_layout()
//! .set_path("example_data/test_plot.png")
//! .savefig().unwrap();
//! }
//! ```
//!
//! It draws next image
//! This code will generate below plot
//!
//! ![test_plot](https://raw.githubusercontent.com/Axect/Peroxide/master/example_data/test_plot.png)
//! ![test_plot](https://github.com/Axect/Peroxide/blob/master/example_data/test_plot.png?raw=true)
//!
//! # Available Plot Options
//! - `set_domain` : Set x data
Expand Down Expand Up @@ -128,7 +89,6 @@ pub enum PlotOptions {
#[derive(Debug, Copy, Clone, Hash, PartialOrd, PartialEq, Eq)]
pub enum Markers {
Point,
Line,
Circle,
Pixel,
TriangleDown,
Expand All @@ -152,7 +112,6 @@ impl Display for Markers {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let str = match self {
Markers::Point => ".".to_string(),
Markers::Line => "-".to_string(),
Markers::Circle => "o".to_string(),
Markers::Pixel => ",".to_string(),
Markers::TriangleDown => "v".to_string(),
Expand Down Expand Up @@ -238,12 +197,12 @@ pub trait Plot {
fn set_fig_size(&mut self, fig_size: (usize, usize)) -> &mut Self;
fn set_dpi(&mut self, dpi: usize) -> &mut Self;
fn grid(&mut self, grid: Grid) -> &mut Self;
fn set_marker(&mut self, styles: Vec<Markers>) -> &mut Self;
fn set_marker(&mut self, styles: Vec<(usize, Markers)>) -> &mut Self;
fn set_style(&mut self, style: PlotStyle) -> &mut Self;
fn tight_layout(&mut self) -> &mut Self;
fn set_line_style(&mut self, style: Vec<LineStyle>) -> &mut Self;
fn set_color(&mut self, color: Vec<&str>) -> &mut Self;
fn set_alpha(&mut self, alpha: Vec<f64>) -> &mut Self;
fn set_line_style(&mut self, style: Vec<(usize, LineStyle)>) -> &mut Self;
fn set_color(&mut self, color: Vec<(usize, &str)>) -> &mut Self;
fn set_alpha(&mut self, alpha: Vec<(usize, f64)>) -> &mut Self;
fn savefig(&self) -> PyResult<()>;
}

Expand All @@ -260,10 +219,10 @@ pub struct Plot2D {
xlim: Option<(f64, f64)>,
ylim: Option<(f64, f64)>,
legends: Vec<String>,
markers: Vec<Markers>,
line_style: Vec<LineStyle>,
color: Vec<String>,
alpha: Vec<f64>,
markers: Vec<(usize, Markers)>,
line_style: Vec<(usize, LineStyle)>,
color: Vec<(usize, String)>,
alpha: Vec<(usize, f64)>,
path: String,
fig_size: Option<(usize, usize)>,
dpi: usize,
Expand Down Expand Up @@ -403,7 +362,7 @@ impl Plot for Plot2D {
self
}

fn set_marker(&mut self, styles: Vec<Markers>) -> &mut Self {
fn set_marker(&mut self, styles: Vec<(usize, Markers)>) -> &mut Self {
self.markers = styles;
self
}
Expand All @@ -418,17 +377,17 @@ impl Plot for Plot2D {
self
}

fn set_line_style(&mut self, style: Vec<LineStyle>) -> &mut Self {
fn set_line_style(&mut self, style: Vec<(usize, LineStyle)>) -> &mut Self {
self.line_style = style;
self
}

fn set_color(&mut self, color: Vec<&str>) -> &mut Self {
self.color = color.into_iter().map(|x| x.to_owned()).collect();
fn set_color(&mut self, color: Vec<(usize, &str)>) -> &mut Self {
self.color = color.into_iter().map(|(i, x)| (i, x.to_owned())).collect();
self
}

fn set_alpha(&mut self, alpha: Vec<f64>) -> &mut Self {
fn set_alpha(&mut self, alpha: Vec<(usize, f64)>) -> &mut Self {
self.alpha = alpha;
self
}
Expand Down Expand Up @@ -493,8 +452,8 @@ impl Plot for Plot2D {
let ylabel = self.ylabel.clone();
let legends = self.legends.clone();
let path = self.path.clone();
let markers = self.markers.iter().map(|x| format!("{}", x)).collect::<Vec<String>>();
let line_style = self.line_style.iter().map(|x| format!("{}", x)).collect::<Vec<String>>();
let markers = self.markers.iter().map(|(i, x)| (i, format!("{}", x))).collect::<Vec<_>>();
let line_style = self.line_style.iter().map(|(i, x)| (i, format!("{}", x))).collect::<Vec<_>>();
let color = self.color.clone();
let alpha = self.alpha.clone();

Expand Down Expand Up @@ -571,39 +530,55 @@ impl Plot for Plot2D {

for i in 0..y_length {
let mut inner_string = format!("x,y[{}]", i);
if !markers.is_empty() {
inner_string.push_str(&format!(",marker=\"{}\"", markers[i])[..]);
let is_corresponding_marker = !markers.is_empty() && (markers.iter().any(|(&j, _)| j == i));
if is_corresponding_marker {
let marker = markers.iter().find(|(&j, _)| j == i).unwrap().1.as_str();
inner_string.push_str(&format!(",marker=\"{}\"", marker)[..]);
}
if !line_style.is_empty() {
inner_string.push_str(&format!(",linestyle=\"{}\"", line_style[i])[..]);
let is_corresponding_line_style = !line_style.is_empty() && (line_style.iter().any(|(&j, _)| j == i));
if is_corresponding_line_style {
let style = line_style.iter().find(|(&j, _)| j == i).unwrap().1.as_str();
inner_string.push_str(&format!(",linestyle=\"{}\"", style)[..]);
}
if !color.is_empty() {
inner_string.push_str(&format!(",color=\"{}\"", color[i])[..]);
let is_corresponding_color = !color.is_empty() && (color.iter().any(|(j, _)| j == &i));
if is_corresponding_color {
let color = color.iter().find(|(j, _)| j == &i).unwrap().1.as_str();
inner_string.push_str(&format!(",color=\"{}\"", color)[..]);
}
if !legends.is_empty() {
inner_string.push_str(&format!(",label=r\"{}\"", legends[i])[..]);
}
if !alpha.is_empty() {
inner_string.push_str(&format!(",alpha={}", alpha[i])[..]);
let is_corresponding_alpha = !alpha.is_empty() && (alpha.iter().any(|(j, _)| j == &i));
if is_corresponding_alpha {
let alpha = alpha.iter().find(|(j, _)| j == &i).unwrap().1;
inner_string.push_str(&format!(",alpha={}", alpha)[..]);
}
plot_string.push_str(&format!("plt.plot({})\n", inner_string)[..]);
}
for i in 0..pair_length {
let mut inner_string = format!("pair[{}][0],pair[{}][1]", i, i);
if !markers.is_empty() {
inner_string.push_str(&format!(",marker=\"{}\"", markers[i + y_length])[..]);
let is_corresponding_marker = !markers.is_empty() && (markers.iter().any(|(&j, _)| j == (i + y_length)));
if is_corresponding_marker {
let marker = markers.iter().find(|(&j, _)| j == (i + y_length)).unwrap().1.as_str();
inner_string.push_str(&format!(",marker=\"{}\"", marker)[..]);
}
if !line_style.is_empty() {
inner_string.push_str(&format!(",linestyle=\"{}\"", line_style[i + y_length])[..]);
let is_corresponding_line_style = !line_style.is_empty() && (line_style.iter().any(|(&j, _)| j == (i + y_length)));
if is_corresponding_line_style {
let style = line_style.iter().find(|(&j, _)| j == (i + y_length)).unwrap().1.as_str();
inner_string.push_str(&format!(",linestyle=\"{}\"", style)[..]);
}
if !color.is_empty() {
inner_string.push_str(&format!(",color=\"{}\"", color[i + y_length])[..]);
let is_corresponding_color = !color.is_empty() && (color.iter().any(|(j, _)| j == &(i + y_length)));
if is_corresponding_color {
let color = color.iter().find(|(j, _)| j == &(i + y_length)).unwrap().1.as_str();
inner_string.push_str(&format!(",color=\"{}\"", color)[..]);
}
if !legends.is_empty() {
inner_string.push_str(&format!(",label=r\"{}\"", legends[i + y_length])[..]);
}
if !alpha.is_empty() {
inner_string.push_str(&format!(",alpha={}", alpha[i + y_length])[..]);
let is_corresponding_alpha = !alpha.is_empty() && (alpha.iter().any(|(j, _)| j == &(i + y_length)));
if is_corresponding_alpha {
let alpha = alpha.iter().find(|(j, _)| j == &(i + y_length)).unwrap().1;
inner_string.push_str(&format!(",alpha={}", alpha)[..]);
}
plot_string.push_str(&format!("plt.plot({})\n", inner_string)[..]);
}
Expand Down

0 comments on commit dad6071

Please sign in to comment.