From 8ca2b8b0da0d8a32bbd4ea1f2cbcdc8616f598a8 Mon Sep 17 00:00:00 2001 From: Pavel Sountsov Date: Mon, 24 Jun 2024 01:05:09 -0700 Subject: [PATCH] Add polygons to draw filled polygons --- gnuplot/Cargo.toml | 5 ++++ gnuplot/examples/common.rs | 1 + gnuplot/examples/polygons.rs | 48 ++++++++++++++++++++++++++++++++++++ gnuplot/src/axes2d.rs | 30 ++++++++++++++++++++++ gnuplot/src/axes_common.rs | 13 ++++++---- 5 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 gnuplot/examples/polygons.rs diff --git a/gnuplot/Cargo.toml b/gnuplot/Cargo.toml index e9b5193b..ac2a7c7e 100644 --- a/gnuplot/Cargo.toml +++ b/gnuplot/Cargo.toml @@ -120,6 +120,11 @@ path = "examples/multiple_axes.rs" name = "text" path = "examples/text.rs" +[[example]] + +name = "polygons" +path = "examples/polygons.rs" + [dependencies] byteorder = "1.4.3" tempfile = "3.9" diff --git a/gnuplot/examples/common.rs b/gnuplot/examples/common.rs index f6769d99..d8e4ee7e 100644 --- a/gnuplot/examples/common.rs +++ b/gnuplot/examples/common.rs @@ -1,4 +1,5 @@ // This file is released into Public Domain. +#![allow(dead_code)] use argparse_rs::*; use gnuplot::*; use std::env; diff --git a/gnuplot/examples/polygons.rs b/gnuplot/examples/polygons.rs new file mode 100644 index 00000000..2a5c43bd --- /dev/null +++ b/gnuplot/examples/polygons.rs @@ -0,0 +1,48 @@ +// This file is released into Public Domain. +use crate::common::*; +use gnuplot::*; + +mod common; + +fn example(c: Common) +{ + let coords = [[0., 0.], [1., 1.], [2., 0.5], [2., -0.5], [1., -1.]]; + + let mut fg = Figure::new(); + fg.set_title("Polygons"); + + let ax = fg.axes2d(); + ax.polygon( + coords.iter().map(|x| x[0]), + coords.iter().map(|x| x[1]), + &[], + ); + + ax.polygon( + coords.iter().map(|x| x[0] + 2.), + coords.iter().map(|x| x[1]), + &[FillAlpha(0.), BorderColor("black"), LineWidth(4.)], + ); + ax.polygon( + coords.iter().map(|x| x[0]), + coords.iter().map(|x| x[1] + 2.), + &[Color("#FF0000"), BorderColor("black"), LineWidth(4.)], + ); + ax.polygon( + coords.iter().map(|x| x[0] + 2.), + coords.iter().map(|x| x[1] + 2.), + &[ + FillPattern(Fix(BigCrosses)), + Color("#FF0000"), + BorderColor("black"), + LineWidth(4.), + LineStyle(Dash), + ], + ); + c.show(&mut fg, "polygons"); +} + +fn main() +{ + Common::new().map(|c| example(c)); +} diff --git a/gnuplot/src/axes2d.rs b/gnuplot/src/axes2d.rs index 9de698d7..a874426d 100644 --- a/gnuplot/src/axes2d.rs +++ b/gnuplot/src/axes2d.rs @@ -607,6 +607,36 @@ impl Axes2D self } + // Plot a polygon given coordinates of its vertices. + // + // # Arguments + // * `x` - x coordinates of the vertices + // * `y` - y coordinates of the vertices + // * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are: + // * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default). + // * `FillAlpha` - Sets the transparency of the filled region + // * `Color` - Sets the color of the filled region (and the border, unless `BorderColor` is set) + // * `BorderColor` - Sets the color of the border + // * `FillPattern` - Sets the fill pattern + pub fn polygon< + 'l, + Tx: DataType, + X: IntoIterator, + Ty: DataType, + Y: IntoIterator, + >( + &'l mut self, x: X, y: Y, options: &[PlotOption<&str>], + ) -> &'l mut Self + { + self.common.elems.push(PlotElement::new_plot2( + Polygons, + x, + y, + options.to_one_way_owned(), + )); + self + } + /// Plot a 2D scatter-plot using boxes of automatic width. Box widths are set so that there are no gaps between successive boxes (i.e. each box may have a different width). /// Boxes start at the x-axis and go towards the y value of the datapoint. /// # Arguments diff --git a/gnuplot/src/axes_common.rs b/gnuplot/src/axes_common.rs index 2684d0c5..ed87c39c 100644 --- a/gnuplot/src/axes_common.rs +++ b/gnuplot/src/axes_common.rs @@ -6,7 +6,6 @@ use self::DataSourceType::*; pub use self::LabelType::*; pub use self::PlotType::*; -pub use self::TickAxis::*; use crate::coordinates::*; use crate::datatype::*; @@ -305,6 +304,7 @@ impl PlotElement XErrorBars => "xerrorbars", YErrorBars => "yerrorbars", FillBetween => "filledcurves", + Polygons => "polygons", Boxes => "boxes", BoxAndWhisker => "candlestick", Pm3D => "pm3d", @@ -352,13 +352,15 @@ impl PlotElement if !is_pattern { - writer.write_str("transparent solid "); + writer.write_str("transparent solid"); + let mut alpha = 1.; first_opt! {self.options, FillAlpha(a) => { - write!(writer, "{:.12e}", a); + alpha = a; } } + write!(writer, " {:.12e}", alpha); } if self.plot_type.is_line() @@ -725,6 +727,7 @@ pub enum PlotType XErrorBars, YErrorBars, FillBetween, + Polygons, Boxes, BoxAndWhisker, Pm3D, @@ -737,7 +740,7 @@ impl PlotType { matches!( *self, - Lines | LinesPoints | XErrorLines | Boxes | YErrorLines | BoxAndWhisker + Lines | LinesPoints | XErrorLines | Boxes | YErrorLines | BoxAndWhisker | Polygons ) } @@ -751,7 +754,7 @@ impl PlotType fn is_fill(&self) -> bool { - matches!(*self, Boxes | FillBetween | BoxAndWhisker) + matches!(*self, Boxes | FillBetween | BoxAndWhisker | Polygons) } }