/
germanubis
/
criterion.rs
Обзор
Документация
Войти
/
germanubis
/
criterion.rs
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
plot/src/errorbar.rs
289 строк
7 KB
Bruce Mitchener
deps: Require itertools 0.13 (#793)
26 июл 2024, 21:39
Не верифицирован
26 июл 2024, 21:39
2d955de
Код
Авторство
О чём код?
//! Error bar plots use std::borrow::Cow; use crate::data::Matrix; use crate::traits::{self, Data, Set}; use crate::{ Color, Display, ErrorBarDefault, Figure, Label, LineType, LineWidth, Plot, PointSize, PointType, Script, }; /// Properties common to error bar plots pub struct Properties { color: Option<Color>, label: Option<Cow<'static, str>>, line_type: LineType, linewidth: Option<f64>, point_size: Option<f64>, point_type: Option<PointType>, style: Style, } impl ErrorBarDefault<Style> for Properties { fn default(style: Style) -> Properties { Properties { color: None, label: None, line_type: LineType::Solid, linewidth: None, point_type: None, point_size: None, style, } } } impl Script for Properties { fn script(&self) -> String { let mut script = format!("with {} ", self.style.display()); script.push_str(&format!("lt {} ", self.line_type.display())); if let Some(lw) = self.linewidth { script.push_str(&format!("lw {} ", lw)) } if let Some(color) = self.color { script.push_str(&format!("lc rgb '{}' ", color.display())) } if let Some(pt) = self.point_type { script.push_str(&format!("pt {} ", pt.display())) } if let Some(ps) = self.point_size { script.push_str(&format!("ps {} ", ps)) } if let Some(ref label) = self.label { script.push_str("title '"); script.push_str(label); script.push('\'') } else { script.push_str("notitle") } script } } impl Set<Color> for Properties { /// Changes the color of the error bars fn set(&mut self, color: Color) -> &mut Properties { self.color = Some(color); self } } impl Set<Label> for Properties { /// Sets the legend label fn set(&mut self, label: Label) -> &mut Properties { self.label = Some(label.0); self } } impl Set<LineType> for Properties { /// Change the line type /// /// **Note** By default `Solid` lines are used fn set(&mut self, lt: LineType) -> &mut Properties { self.line_type = lt; self } } impl Set<LineWidth> for Properties { /// Changes the linewidth /// /// # Panics /// /// Panics if `lw` is a non-positive value fn set(&mut self, lw: LineWidth) -> &mut Properties { let lw = lw.0; assert!(lw > 0.); self.linewidth = Some(lw); self } } impl Set<PointSize> for Properties { /// Changes the size of the points /// /// # Panics /// /// Panics if `size` is a non-positive value fn set(&mut self, ps: PointSize) -> &mut Properties { let ps = ps.0; assert!(ps > 0.); self.point_size = Some(ps); self } } impl Set<PointType> for Properties { /// Changes the point type fn set(&mut self, pt: PointType) -> &mut Properties { self.point_type = Some(pt); self } } #[derive(Clone, Copy)] enum Style { XErrorBars, XErrorLines, YErrorBars, YErrorLines, } impl Display<&'static str> for Style { fn display(&self) -> &'static str { match *self { Style::XErrorBars => "xerrorbars", Style::XErrorLines => "xerrorlines", Style::YErrorBars => "yerrorbars", Style::YErrorLines => "yerrorlines", } } } /// Asymmetric error bar plots pub enum ErrorBar<X, Y, L, H> { /// Horizontal error bars XErrorBars { /// X coordinate of the data points x: X, /// Y coordinate of the data points y: Y, /// X coordinate of the left end of the error bar x_low: L, /// Y coordinate of the right end of the error bar x_high: H, }, /// Horizontal error bars, where each point is joined by a line XErrorLines { /// X coordinate of the data points x: X, /// Y coordinate of the data points y: Y, /// X coordinate of the left end of the error bar x_low: L, /// Y coordinate of the right end of the error bar x_high: H, }, /// Vertical error bars YErrorBars { /// X coordinate of the data points x: X, /// Y coordinate of the data points y: Y, /// Y coordinate of the bottom of the error bar y_low: L, /// Y coordinate of the top of the error bar y_high: H, }, /// Vertical error bars, where each point is joined by a line YErrorLines { /// X coordinate of the data points x: X, /// Y coordinate of the data points y: Y, /// Y coordinate of the bottom of the error bar y_low: L, /// Y coordinate of the top of the error bar y_high: H, }, } impl<X, Y, L, H> ErrorBar<X, Y, L, H> { fn style(&self) -> Style { match *self { ErrorBar::XErrorBars { .. } => Style::XErrorBars, ErrorBar::XErrorLines { .. } => Style::XErrorLines, ErrorBar::YErrorBars { .. } => Style::YErrorBars, ErrorBar::YErrorLines { .. } => Style::YErrorLines, } } } impl<X, Y, L, H> traits::Plot<ErrorBar<X, Y, L, H>> for Figure where H: IntoIterator, H::Item: Data, L: IntoIterator, L::Item: Data, X: IntoIterator, X::Item: Data, Y: IntoIterator, Y::Item: Data, { type Properties = Properties; fn plot<F>(&mut self, e: ErrorBar<X, Y, L, H>, configure: F) -> &mut Figure where F: FnOnce(&mut Properties) -> &mut Properties, { let (x_factor, y_factor) = crate::scale_factor(&self.axes, crate::Axes::BottomXLeftY); let style = e.style(); let (x, y, length, height, e_factor) = match e { ErrorBar::XErrorBars { x, y, x_low, x_high, } | ErrorBar::XErrorLines { x, y, x_low, x_high, } => (x, y, x_low, x_high, x_factor), ErrorBar::YErrorBars { x, y, y_low, y_high, } | ErrorBar::YErrorLines { x, y, y_low, y_high, } => (x, y, y_low, y_high, y_factor), }; let data = Matrix::new( itertools::izip!(x, y, length, height), (x_factor, y_factor, e_factor, e_factor), ); self.plots.push(Plot::new( data, configure(&mut ErrorBarDefault::default(style)), )); self } } // TODO XY error bar // pub struct XyErrorBar<X, Y, XL, XH, YL, YH> { // x: X, // y: Y, // x_low: XL, // x_high: XH, // y_low: YL, // y_high: YH, // } // TODO Symmetric error bars // pub enum SymmetricErrorBar { // XSymmetricErrorBar { x: X, y: Y, x_delta: D }, // XSymmetricErrorLines { x: X, y: Y, x_delta: D }, // YSymmetricErrorBar { x: X, y: Y, y_delta: D }, // YSymmetricErrorLines { x: X, y: Y, y_delta: D }, // }