Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add boxxyerror interface #104

Merged
merged 1 commit into from
Feb 9, 2025
Merged
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
5 changes: 5 additions & 0 deletions gnuplot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ path = "examples/box_and_whisker.rs"

[[example]]

name = "box_xy_error"
path = "examples/box_xy_error.rs"

[[example]]

name = "lines_3d"
path = "examples/lines_3d.rs"

Expand Down
43 changes: 43 additions & 0 deletions gnuplot/examples/box_xy_error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// This file is released into Public Domain.
use crate::common::*;
use gnuplot::*;

mod common;

fn example(c: Common)
{
let mut fg = Figure::new();

fg.axes2d()
.set_title("Box XY Error", &[])
.box_xy_error_delta(
[0.0f32, 1.0, 2.0].iter(),
[-1.0f32, 0.0, 1.0].iter(),
[0.25f32, 0.375, 0.15].iter(),
[2.0f32, 3.0, 4.0].iter(),
&[],
)
.box_xy_error_low_high(
[-0.6f32, 1.5, 2.5].iter(),
[-1.0f32, 0.0, 1.0].iter(),
[-0.9f32, -1.0, 2.2].iter(),
[-0.45f32, 3.0, 2.95].iter(),
[-1.5f32, 4.5, 3.0].iter(),
[0.5f32, 4.75, 0.125].iter(),
&[
Color("blue"),
LineWidth(2.0),
LineStyle(SmallDot),
FillAlpha(0.5),
],
)
.set_x_range(Fix(-1.0), Fix(3.0))
.set_y_range(Fix(-3.0), Fix(5.0));

c.show(&mut fg, "box_xy_error");
}

fn main()
{
Common::new().map(|c| example(c));
}
87 changes: 87 additions & 0 deletions gnuplot/src/axes2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,93 @@ impl Axes2D
self
}

/// Plot 2D rectangular boxes - usually used for error bars - using specified by width (x_delta) and height (y_delta).
///
/// # Arguments
/// * `x` - x values (horizontal center of the box)
/// * `y` - y values (vertical center of the box)
/// * `x_delta` - Error in x (horizontal half-width of the box)
/// * `y_delta` - Error in y (vertical half-width of the box)
/// * `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).
/// * `LineWidth` - Sets the width of the border
/// * `LineStyle` - Sets the style of the border
/// * `BorderColor` - Sets the color of the border
/// * `Color` - Sets the color of the box fill
/// * `FillAlpha` - Sets the transparency of the box fill
pub fn box_xy_error_delta<
'l,
Tx: DataType,
X: IntoIterator<Item = Tx>,
Ty: DataType,
Y: IntoIterator<Item = Ty>,
TXDelta: DataType,
XDelta: IntoIterator<Item = TXDelta>,
TYDelta: DataType,
YDelta: IntoIterator<Item = TYDelta>,
>(
&'l mut self, x: X, y: Y, x_delta: XDelta, y_delta: YDelta, options: &[PlotOption<&str>],
) -> &'l mut Self
{
self.common.elems.push(PlotElement::new_plot4(
BoxXYError,
x,
y,
x_delta,
y_delta,
options.to_one_way_owned(),
));
self
}

/// Plot 2D rectangular boxes - usually used for error bars - using specified low and high limits for x and y.
///
/// # Arguments
/// * `x` - x values (horizontal center of the box)
/// * `y` - y values (vertical center of the box)
/// * `x_low` - Horizontal lower limit of the box
/// * `x_high` - Horizontal upper limit of the box
/// * `y_low` - Vertical lower limit of the box
/// * `y_high` - Vertical upper limit of the box
/// * `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).
/// * `LineWidth` - Sets the width of the border
/// * `LineStyle` - Sets the style of the border
/// * `BorderColor` - Sets the color of the border
/// * `Color` - Sets the color of the box fill
/// * `FillAlpha` - Sets the transparency of the box fill
pub fn box_xy_error_low_high<
'l,
Tx: DataType,
X: IntoIterator<Item = Tx>,
Ty: DataType,
Y: IntoIterator<Item = Ty>,
TXLow: DataType,
XLow: IntoIterator<Item = TXLow>,
TXHigh: DataType,
XHigh: IntoIterator<Item = TXHigh>,
TYLow: DataType,
YLow: IntoIterator<Item = TYLow>,
TYHigh: DataType,
YHigh: IntoIterator<Item = TYHigh>,
>(
&'l mut self, x: X, y: Y, x_low: XLow, x_high: XHigh, y_low: YLow, y_high: YHigh,
options: &[PlotOption<&str>],
) -> &'l mut Self
{
self.common.elems.push(PlotElement::new_plot6(
BoxXYError,
x,
y,
x_low,
x_high,
y_low,
y_high,
options.to_one_way_owned(),
));
self
}

/// Draws an image from a rectangular array of data by connecting the individual datapoints with polygons.
///
/// #Arguments:
Expand Down
54 changes: 52 additions & 2 deletions gnuplot/src/axes_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,46 @@ impl PlotElement
}
}

pub fn new_plot4<T1, X1, T2, X2, T3, X3, T4, X4>(
plot_type: PlotType, x1: X1, x2: X2, x3: X3, x4: X4, options: Vec<PlotOption<String>>,
) -> PlotElement
where
T1: DataType,
X1: IntoIterator<Item = T1>,
T2: DataType,
X2: IntoIterator<Item = T2>,
T3: DataType,
X3: IntoIterator<Item = T3>,
T4: DataType,
X4: IntoIterator<Item = T4>,
{
let mut num_rows = 0;
let mut data = vec![];
// TODO: Reserve.
for (((x1, x2), x3), x4) in x1
.into_iter()
.zip(x2.into_iter())
.zip(x3.into_iter())
.zip(x4.into_iter())
{
data.push(x1.get());
data.push(x2.get());
data.push(x3.get());
data.push(x4.get());
num_rows += 1;
}

PlotElement {
data,
num_rows,
num_cols: 4,
plot_type,
source_type: Record,
is_3d: false,
options,
}
}

pub fn new_plot5<T1, X1, T2, X2, T3, X3, T4, X4, T5, X5>(
plot_type: PlotType, x1: X1, x2: X2, x3: X3, x4: X4, x5: X5,
options: Vec<PlotOption<String>>,
Expand Down Expand Up @@ -307,6 +347,7 @@ impl PlotElement
Polygons => "polygons",
Boxes => "boxes",
BoxAndWhisker => "candlestick",
BoxXYError => "boxxyerror",
Pm3D => "pm3d",
Image => "image",
};
Expand Down Expand Up @@ -724,6 +765,7 @@ pub enum PlotType
Polygons,
Boxes,
BoxAndWhisker,
BoxXYError,
Pm3D,
Image,
}
Expand All @@ -734,7 +776,12 @@ impl PlotType
{
matches!(
*self,
Lines | LinesPoints | XErrorLines | Boxes | YErrorLines | BoxAndWhisker | Polygons
Lines
| LinesPoints
| XErrorLines
| Boxes | YErrorLines
| BoxAndWhisker
| BoxXYError | Polygons
)
}

Expand All @@ -748,7 +795,10 @@ impl PlotType

fn is_fill(&self) -> bool
{
matches!(*self, Boxes | FillBetween | BoxAndWhisker | Polygons)
matches!(
*self,
Boxes | FillBetween | BoxAndWhisker | BoxXYError | Polygons
)
}
}

Expand Down