263bbc98d96d58e04538c0357194850242f73130 — axect 2 months ago 17a7b26
Ver 0.16.2 - Plot with pair
5 files changed, 65 insertions(+), 9 deletions(-)

M Cargo.toml
M RELEASES.md
M example_data/lm_test.png
A example_data/plot_test.png
M src/util/plot.rs
M Cargo.toml => Cargo.toml +1 -1
@@ 1,6 1,6 @@
 [package]
 name = "peroxide"
-version = "0.16.1"
+version = "0.16.2"
 authors = ["axect <edeftg@gmail.com>"]
 description = "Rust comprehensive scientific computation library contains linear algebra, numerical analysis, statistics and machine learning tools with farmiliar syntax"
 repository = "https://github.com/Axect/Peroxide"

M RELEASES.md => RELEASES.md +5 -0
@@ 1,3 1,8 @@
+# Release 0.16.2 (2019-09-21)
+
+* Now, we can insert pair of data to `plot`
+    * `fn insert_pair(&self, pait: (Vec<f64>, Vec<f64>)) -> &mut Self`
+
 # Release 0.16.1 (2019-09-19)
 
 * More generic `optimize`

M example_data/lm_test.png => example_data/lm_test.png +0 -0

A example_data/plot_test.png => example_data/plot_test.png +0 -0

M src/util/plot.rs => src/util/plot.rs +59 -8
@@ 83,7 83,7 @@ use self::pyo3::types::IntoPyDict;
 use self::pyo3::{PyResult, Python};
 pub use self::Grid::{Off, On};
 pub use self::Markers::{Circle, Line, Point};
-use self::PlotOptions::{Domain, Images, Legends, Path};
+use self::PlotOptions::{Domain, Images, Pairs, Legends, Path};
 use std::collections::HashMap;
 
 type Vector = Vec<f64>;


@@ 92,6 92,7 @@ type Vector = Vec<f64>;
 pub enum PlotOptions {
     Domain,
     Images,
+    Pairs,
     Legends,
     Path,
 }


@@ 112,6 113,7 @@ pub enum Grid {
 pub trait Plot {
     fn set_domain(&mut self, x: Vec<f64>) -> &mut Self;
     fn insert_image(&mut self, y: Vec<f64>) -> &mut Self;
+    fn insert_pair(&mut self, xy: (Vec<f64>, Vec<f64>)) -> &mut Self;
     fn set_title(&mut self, title: &str) -> &mut Self;
     fn set_xlabel(&mut self, xlabel: &str) -> &mut Self;
     fn set_ylabel(&mut self, ylabel: &str) -> &mut Self;


@@ 129,6 131,7 @@ pub trait Plot {
 pub struct Plot2D {
     domain: Vector,
     images: Vec<Vector>,
+    pairs: Vec<(Vector, Vector)>,
     title: String,
     xlabel: String,
     ylabel: String,


@@ 146,12 149,14 @@ impl Plot2D {
         let mut default_options: HashMap<PlotOptions, bool> = HashMap::new();
         default_options.insert(Domain, false);
         default_options.insert(Images, false);
+        default_options.insert(Pairs, false);
         default_options.insert(Legends, false);
         default_options.insert(Path, false);
 
         Plot2D {
             domain: vec![],
             images: vec![],
+            pairs: vec![],
             title: "Title".to_string(),
             xlabel: "$x$".to_string(),
             ylabel: "$y$".to_string(),


@@ 183,6 188,14 @@ impl Plot for Plot2D {
         self
     }
 
+    fn insert_pair(&mut self, xy: (Vec<f64>, Vec<f64>)) -> &mut Self {
+        if let Some(t) = self.options.get_mut(&Pairs) {
+            *t = true
+        }
+        self.pairs.push(xy);
+        self
+    }
+
     fn set_title(&mut self, title: &str) -> &mut Self {
         self.title = title.to_owned();
         self


@@ 244,22 257,40 @@ impl Plot for Plot2D {
     fn savefig(&self) -> PyResult<()> {
         // Check domain
         match self.options.get(&Domain) {
-            Some(x) => {
-                assert!(*x, "Domain is not defined");
+            Some(x) if !*x => {
+                match self.options.get(&Pairs) {
+                    Some(xy) if !*xy => {
+                        panic!("There are no data to plot");
+                    }
+                    None => {
+                        panic!("There are some serious problems in plot system");
+                    }
+                    _ => (),
+                }
             }
             None => {
-                assert!(false, "Domain is None");
+                panic!("There are some serious problems in plot system");
             }
+            _ => (),
         }
 
         // Check images
         match self.options.get(&Images) {
-            Some(x) => {
-                assert!(*x, "Images are not defined");
+            Some(x) if !*x => {
+                match self.options.get(&Pairs) {
+                    Some(xy) if !*xy => {
+                        panic!("there are no data to plot");
+                    }
+                    None => {
+                        panic!("There are some serious problems in plot system");
+                    }
+                    _ => (),
+                }
             }
             None => {
-                assert!(false, "Images are None");
+                panic!("There are some serious problems in plot system");
             }
+            _ => (),
         }
 
         // Check legends


@@ 267,7 298,7 @@ impl Plot for Plot2D {
             Some(x) => {
                 assert!(*x, "Legends are not defined");
                 assert!(
-                    self.images.len() == self.legends.len(),
+                    self.images.len() + self.pairs.len() == self.legends.len(),
                     "Legends are not matched with images"
                 );
             }


@@ 283,7 314,9 @@ impl Plot for Plot2D {
         // Input data
         let x = self.domain.clone();
         let ys = self.images.clone();
+        let pairs = self.pairs.clone();
         let y_length = ys.len();
+        let pair_length = pairs.len();
         let title = self.title.clone();
         let fig_size = self.fig_size;
         let dpi = self.dpi;


@@ 300,7 333,9 @@ impl Plot for Plot2D {
         let globals = vec![("plt", py.import("pylab")?)].into_py_dict(py);
         globals.set_item("x", x)?;
         globals.set_item("y", ys)?;
+        globals.set_item("pair", pairs)?;
         globals.set_item("n", y_length)?;
+        globals.set_item("p", pair_length)?;
         globals.set_item("fs", fig_size)?;
         globals.set_item("dp", dpi)?;
         globals.set_item("gr", grid)?;


@@ 325,6 360,10 @@ impl Plot for Plot2D {
                 plot_string
                     .push_str(&format!("plt.plot(x,y[{}],label=r\"{}\")\n", i, legends[i])[..])
             }
+            for i in 0..pair_length {
+                plot_string
+                    .push_str(&format!("plt.plot(pair[{}][0],pair[{}][1],label=r\"{}\")\n", i, i, legends[i+y_length])[..])
+            }
         } else {
             for i in 0..y_length {
                 match self.markers[i] {


@@ 338,6 377,18 @@ impl Plot for Plot2D {
                     ),
                 }
             }
+            for i in 0..pair_length {
+                match self.markers[i+y_length] {
+                    Line => plot_string
+                        .push_str(&format!("plt.plot(pair[{}][0],pair[{}][1],label=r\"{}\")\n", i, i, legends[i+y_length])[..]),
+                    Point => plot_string.push_str(
+                        &format!("plt.plot(pair[{}][0],pair[{}][1],\".\",label=r\"{}\")\n", i, i, legends[i+y_length])[..],
+                    ),
+                    Circle => plot_string.push_str(
+                        &format!("plt.plot(pair[{}][0],pair[{}][1],\"o\",label=r\"{}\")\n", i, i, legends[i+y_length])[..],
+                    ),
+                }
+            }
         }
 
         plot_string.push_str("plt.legend(fontsize=12)\nplt.savefig(pa)");