axes2d.rs - source

gnuplot/

axes2d.rs

1// Copyright (c) 2013-2014 by SiegeLord
2//
3// All rights reserved. Distributed under LGPL 3.0. For full terms see the file LICENSE.
4
5use std::iter;
6
7use crate::axes_common::*;
8use crate::coordinates::*;
9use crate::datatype::*;
10use crate::options::*;
11use crate::util::{escape, OneWayOwned};
12use crate::writer::Writer;
13use crate::ColorType;
14
15struct LegendData
16{
17	x: Coordinate,
18	y: Coordinate,
19	legend_options: Vec<LegendOption<String>>,
20	text_options: Vec<LabelOption<String>>,
21}
22
23impl LegendData
24{
25	fn write_out(&self, writer: &mut dyn Writer)
26	{
27		let w = writer;
28		write!(w, "set key at {},{}", self.x, self.y);
29
30		first_opt_default! {self.legend_options,
31			Placement(h, v) =>
32			{
33				w.write_str(match h
34				{
35					AlignLeft => " left",
36					AlignRight => " right",
37					_ => " center"
38				});
39				w.write_str(match v
40				{
41					AlignTop => " top",
42					AlignBottom => " bottom",
43					_ => " center"
44				});
45			},
46			_ =>
47			{
48				w.write_str(" right top");
49			}
50		}
51
52		first_opt_default! {self.legend_options,
53			Horizontal =>
54			{
55				w.write_str(" horizontal");
56			},
57			_ =>
58			{
59				w.write_str(" vertical");
60			}
61		}
62
63		first_opt_default! {self.legend_options,
64			Reverse =>
65			{
66				w.write_str(" reverse");
67			},
68			_ =>
69			{
70				w.write_str(" noreverse");
71			}
72		}
73
74		first_opt_default! {self.legend_options,
75			Invert =>
76			{
77				w.write_str(" invert");
78			},
79			_ =>
80			{
81				w.write_str(" noinvert");
82			}
83		}
84
85		first_opt! {self.legend_options,
86			Title(ref s) =>
87			{
88				w.write_str(" title \"");
89				w.write_str(&escape(s));
90				w.write_str("\"");
91			}
92		}
93
94		first_opt! {self.text_options,
95			Font(ref f, s) =>
96			{
97				w.write_str(" font \"");
98				w.write_str(&escape(f));
99				w.write_str(",");
100				w.write_str(&s.to_string()[..]);
101				w.write_str("\"");
102			}
103		}
104		first_opt! {self.text_options,
105			TextColor(ref s) =>
106			{
107				write!(w, " textcolor {} ", s.command());
108			}
109		}
110		first_opt! {self.text_options,
111			TextAlign(a) =>
112			{
113				w.write_str(match a
114				{
115					AlignLeft => " Left",
116					AlignRight => " Right",
117					_ => ""
118				});
119			}
120		}
121
122		first_opt! {self.legend_options,
123			MaxRows(r) =>
124			{
125				write!(w, " maxrows {}", r as i32);
126			}
127		}
128
129		first_opt! {self.legend_options,
130			MaxCols(l) =>
131			{
132				write!(w, " maxcols {}", l as i32);
133			}
134		}
135
136		w.write_str("\n");
137	}
138
139	fn reset_state(&self, writer: &mut dyn Writer)
140	{
141		writer.write_str("unset key\n");
142	}
143}
144
145struct ArrowData
146{
147	x1: Coordinate,
148	y1: Coordinate,
149	x2: Coordinate,
150	y2: Coordinate,
151	plot_options: Vec<PlotOption<String>>,
152	tag: i32,
153}
154
155impl ArrowData
156{
157	fn write_out(&self, writer: &mut dyn Writer)
158	{
159		let w = writer;
160		write!(
161			w,
162			"set arrow {} from {},{} to {},{}",
163			self.tag, self.x1, self.y1, self.x2, self.y2
164		);
165
166		first_opt! {self.plot_options,
167			ArrowType(s) =>
168			{
169				w.write_str(match s
170				{
171					Open => "",
172					Closed => " empty",
173					Filled => " filled",
174					NoArrow => " nohead",
175				});
176			}
177		}
178
179		w.write_str(" size graph ");
180		first_opt_default! {self.plot_options,
181			ArrowSize(z) =>
182			{
183				write!(w, "{:.12e}", z);
184			},
185			_ =>
186			{
187				w.write_str("0.05");
188			}
189		}
190		w.write_str(",12");
191
192		AxesCommonData::write_color_options(w, &self.plot_options, false, Some(ColorType::Black));
193		AxesCommonData::write_line_options(
194			w,
195			&self.plot_options,
196			GnuplotVersion { major: 0, minor: 0 },
197		);
198
199		w.write_str("\n");
200	}
201
202	fn reset_state(&self, writer: &mut dyn Writer)
203	{
204		writeln!(writer, "unset arrow {}", self.tag);
205	}
206}
207
208struct BorderOptions
209{
210	front: bool,
211	locations: Vec<BorderLocation2D>,
212	options: Vec<PlotOption<String>>,
213}
214
215impl BorderOptions
216{
217	fn new() -> BorderOptions
218	{
219		BorderOptions {
220			front: true,
221			locations: vec![Bottom, Left, Top, Right],
222			options: vec![],
223		}
224	}
225
226	fn write_out(&self, writer: &mut dyn Writer, version: GnuplotVersion)
227	{
228		writer.write_str("set border ");
229		let mut f: i32 = 0;
230		for &l in self.locations.iter()
231		{
232			f |= l as i32;
233		}
234		write!(writer, "{}", f);
235		writer.write_str(if self.front { " front " } else { " back " });
236
237		AxesCommonData::write_color_options(writer, &self.options, false, Some(ColorType::Black));
238		AxesCommonData::write_line_options(writer, &self.options, version);
239
240		writer.write_str("\n");
241	}
242}
243
244/// 2D axes that is used for drawing 2D plots
245pub struct Axes2D
246{
247	common: AxesCommonData,
248	border_options: BorderOptions,
249	arrows: Vec<ArrowData>,
250	legend: Option<LegendData>,
251}
252
253impl Axes2D
254{
255	pub(crate) fn new() -> Axes2D
256	{
257		Axes2D {
258			common: AxesCommonData::new(),
259			border_options: BorderOptions::new(),
260			arrows: vec![],
261			legend: None,
262		}
263	}
264
265	/// Sets the properties of the plot border
266	///
267	/// # Arguments
268	///
269	/// * `front` - Whether or not to draw the border above or below the plot contents
270	/// * `locations` - Which locations of the border to draw
271	/// * `options` - Array of PlotOption controlling the appearance of the border. Relevant options are:
272	///      * `Color` - Specifies the color of the border
273	///      * `LineStyle` - Specifies the style of the border
274	///      * `LineWidth` - Specifies the width of the border
275	pub fn set_border<'l>(
276		&'l mut self, front: bool, locations: &[BorderLocation2D], options: &[PlotOption<&str>],
277	) -> &'l mut Self
278	{
279		self.border_options.front = front;
280		self.border_options.locations = locations.into();
281		self.border_options.options = options.to_one_way_owned();
282		self
283	}
284
285	/// Sets the properties of x axis.
286	///
287	/// # Arguments
288	///
289	/// * `show` - Whether or not draw the axis
290	/// * `options` - Array of PlotOption<&str> controlling the appearance of the axis. Relevant options are:
291	///      * `Color` - Specifies the color of the border
292	///      * `LineStyle` - Specifies the style of the border
293	///      * `LineWidth` - Specifies the width of the border
294	pub fn set_x_axis<'l>(&'l mut self, show: bool, options: &[PlotOption<&str>]) -> &'l mut Self
295	{
296		self.common.x_axis.show = show;
297		self.common.x_axis.options = options.to_one_way_owned();
298		self
299	}
300
301	/// Like `set_x_axis` but for the y axis.
302	pub fn set_y_axis<'l>(&'l mut self, show: bool, options: &[PlotOption<&str>]) -> &'l mut Self
303	{
304		self.common.y_axis.show = show;
305		self.common.y_axis.options = options.to_one_way_owned();
306		self
307	}
308
309	/// Adds an arrow to the plot. The arrow is drawn from `(x1, y1)` to `(x2, y2)` with the arrow point towards `(x2, y2)`.
310	/// # Arguments
311	/// * `x1` - X coordinate of the arrow start
312	/// * `y1` - Y coordinate of the arrow start
313	/// * `x2` - X coordinate of the arrow end
314	/// * `y2` - Y coordinate of the arrow end
315	/// * `options` - Array of PlotOption<&str> controlling the appearance of the arrowhead and arrow shaft. Relevant options are:
316	///      * `ArrowType` - Specifies the style of the arrow head (or an option to omit it)
317	///      * `ArrowSize` - Sets the size of the arrow head (in graph units)
318	///      * `Color` - Specifies the color of the arrow
319	///      * `LineStyle` - Specifies the style of the arrow shaft
320	///      * `LineWidth` - Specifies the width of the arrow shaft
321	pub fn arrow<'l>(
322		&'l mut self, x1: Coordinate, y1: Coordinate, x2: Coordinate, y2: Coordinate,
323		options: &[PlotOption<&str>],
324	) -> &'l mut Self
325	{
326		self.arrows.push(ArrowData {
327			x1,
328			y1,
329			x2,
330			y2,
331			tag: self.arrows.len() as i32 + 1,
332			plot_options: options.to_one_way_owned(),
333		});
334		self
335	}
336
337	/// Specifies the location and other properties of the legend
338	/// # Arguments
339	/// * `x` - X coordinate of the legend
340	/// * `y` - Y coordinate of the legend
341	/// * `legend_options` - Array of LegendOption options
342	/// * `text_options` - Array of LabelOption options specifying the appearance of the plot titles. Valid options are:
343	///     * `Font`
344	///     * `TextColor`
345	///     * `TextAlign(AlignLeft)`
346	///     * `TextAlign(AlignRight)`
347	pub fn set_legend<'l>(
348		&'l mut self, x: Coordinate, y: Coordinate, legend_options: &[LegendOption<&str>],
349		text_options: &[LabelOption<&str>],
350	) -> &'l mut Self
351	{
352		self.legend = Some(LegendData {
353			x,
354			y,
355			legend_options: legend_options.to_one_way_owned(),
356			text_options: text_options.to_one_way_owned(),
357		});
358		self
359	}
360
361	/// Plot a 2D scatter-plot with lines connecting each data point
362	/// # Arguments
363	/// * `x` - x values
364	/// * `y` - y values
365	/// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are:
366	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
367	///     * `LineWidth` - Sets the width of the line
368	///     * `LineStyle` - Sets the style of the line
369	///     * `Color` - Sets the color
370	pub fn lines<
371		'l,
372		Tx: DataType,
373		X: IntoIterator<Item = Tx>,
374		Ty: DataType,
375		Y: IntoIterator<Item = Ty>,
376	>(
377		&'l mut self, x: X, y: Y, options: &[PlotOption<&str>],
378	) -> &'l mut Self
379	{
380		let (data, num_rows, num_cols) = generate_data!(options, x, y);
381		self.common.elems.push(PlotElement::new_plot(
382			Lines, data, num_rows, num_cols, options,
383		));
384		self
385	}
386
387	/// Plot a 2D scatter-plot with a point standing in for each data point
388	/// # Arguments
389	/// * `x` - x values
390	/// * `y` - y values
391	/// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are:
392	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
393	///     * `PointSymbol` - Sets symbol for each point
394	///     * `PointSize` - Sets the size of each point
395	///     * `Color` - Sets the color
396	pub fn points<
397		'l,
398		Tx: DataType,
399		X: IntoIterator<Item = Tx>,
400		Ty: DataType,
401		Y: IntoIterator<Item = Ty>,
402	>(
403		&'l mut self, x: X, y: Y, options: &[PlotOption<&str>],
404	) -> &'l mut Self
405	{
406		let (data, num_rows, num_cols) = generate_data!(options, x, y);
407		self.common.elems.push(PlotElement::new_plot(
408			Points, data, num_rows, num_cols, options,
409		));
410		self
411	}
412
413	/// A combination of lines and points methods (drawn in that order).
414	/// # Arguments
415	/// * `x` - x values
416	/// * `y` - y values
417	/// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element
418	pub fn lines_points<
419		'l,
420		Tx: DataType,
421		X: IntoIterator<Item = Tx>,
422		Ty: DataType,
423		Y: IntoIterator<Item = Ty>,
424	>(
425		&'l mut self, x: X, y: Y, options: &[PlotOption<&str>],
426	) -> &'l mut Self
427	{
428		let (data, num_rows, num_cols) = generate_data!(options, x, y);
429		self.common.elems.push(PlotElement::new_plot(
430			LinesPoints,
431			data,
432			num_rows,
433			num_cols,
434			options,
435		));
436		self
437	}
438
439	/// Plot a 2D scatter-plot with a point standing in for each data point.
440	/// Additionally, error bars are attached to each data point in the X direction.
441	/// # Arguments
442	/// * `x` - x values
443	/// * `y` - y values
444	/// * `x_error` - Errors associated with the x value
445	/// * `options` - Array of PlotOption controlling the appearance of the plot element. The relevant options are:
446	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
447	///     * `PointSymbol` - Sets symbol for each point
448	///     * `PointSize` - Sets the size of each point
449	///     * `Color` - Sets the color
450	pub fn x_error_bars<
451		'l,
452		Tx: DataType,
453		X: IntoIterator<Item = Tx>,
454		Ty: DataType,
455		Y: IntoIterator<Item = Ty>,
456		Txe: DataType,
457		XE: IntoIterator<Item = Txe>,
458	>(
459		&'l mut self, x: X, y: Y, x_error: XE, options: &[PlotOption<&str>],
460	) -> &'l mut Self
461	{
462		let (data, num_rows, num_cols) = generate_data!(options, x, y, x_error);
463		self.common.elems.push(PlotElement::new_plot(
464			XErrorBars, data, num_rows, num_cols, options,
465		));
466		self
467	}
468
469	/// Plot a 2D scatter-plot with a point standing in for each data point.
470	/// Additionally, error bars are attached to each data point in the Y direction.
471	/// # Arguments
472	/// * `x` - x values
473	/// * `y` - y values
474	/// * `y_error` - Errors associated with the y values
475	/// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are:
476	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
477	///     * `PointSymbol` - Sets symbol for each point
478	///     * `PointSize` - Sets the size of each point
479	///     * `Color` - Sets the color
480	pub fn y_error_bars<
481		'l,
482		Tx: DataType,
483		X: IntoIterator<Item = Tx>,
484		Ty: DataType,
485		Y: IntoIterator<Item = Ty>,
486		Tye: DataType,
487		YE: IntoIterator<Item = Tye>,
488	>(
489		&'l mut self, x: X, y: Y, y_error: YE, options: &[PlotOption<&str>],
490	) -> &'l mut Self
491	{
492		let (data, num_rows, num_cols) = generate_data!(options, x, y, y_error);
493		self.common.elems.push(PlotElement::new_plot(
494			YErrorBars, data, num_rows, num_cols, options,
495		));
496		self
497	}
498
499	/// Plot a 2D scatter-plot with a point standing in for each data point.
500	/// Additionally, error bars are attached to each data point in the X and Y directions.
501	/// # Arguments
502	/// * `x` - x values
503	/// * `y` - y values
504	/// * `x_error` - Errors associated with the x value
505	/// * `options` - Array of PlotOption controlling the appearance of the plot element. The relevant options are:
506	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
507	///     * `PointSymbol` - Sets symbol for each point
508	///     * `PointSize` - Sets the size of each point
509	///     * `Color` - Sets the color
510	pub fn xy_error_bars<
511		'l,
512		Tx: DataType,
513		X: IntoIterator<Item = Tx>,
514		Ty: DataType,
515		Y: IntoIterator<Item = Ty>,
516		Txe: DataType,
517		XE: IntoIterator<Item = Txe>,
518		Tye: DataType,
519		YE: IntoIterator<Item = Tye>,
520	>(
521		&'l mut self, x: X, y: Y, x_error: XE, y_error: YE, options: &[PlotOption<&str>],
522	) -> &'l mut Self
523	{
524		let (data, num_rows, num_cols) = generate_data!(options, x, y, x_error, y_error);
525		self.common.elems.push(PlotElement::new_plot(
526			XYErrorBars,
527			data,
528			num_rows,
529			num_cols,
530			options,
531		));
532		self
533	}
534
535	/// Plot a 2D scatter-plot with a point standing in for each data point and lines connecting each data point.
536	/// Additionally, error bars are attached to each data point in the X direction.
537	/// # Arguments
538	/// * `x` - x values
539	/// * `y` - y values
540	/// * `x_error` - Errors associated with the x value
541	/// * `options` - Array of PlotOption controlling the appearance of the plot element. The relevant options are:
542	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
543	///     * `PointSymbol` - Sets symbol for each point
544	///     * `PointSize` - Sets the size of each point
545	///     * `LineWidth` - Sets the width of the line
546	///     * `LineStyle` - Sets the style of the line
547	///     * `Color` - Sets the color
548	pub fn x_error_lines<
549		'l,
550		Tx: DataType,
551		X: IntoIterator<Item = Tx>,
552		Ty: DataType,
553		Y: IntoIterator<Item = Ty>,
554		Txe: DataType,
555		XE: IntoIterator<Item = Txe>,
556	>(
557		&'l mut self, x: X, y: Y, x_error: XE, options: &[PlotOption<&str>],
558	) -> &'l mut Self
559	{
560		let (data, num_rows, num_cols) = generate_data!(options, x, y, x_error);
561		self.common.elems.push(PlotElement::new_plot(
562			XErrorLines,
563			data,
564			num_rows,
565			num_cols,
566			options,
567		));
568		self
569	}
570
571	/// Plot a 2D scatter-plot with a point standing in for each data point and lines connecting each data point.
572	/// Additionally, error bars are attached to each data point in the Y direction.
573	/// # Arguments
574	/// * `x` - x values
575	/// * `y` - y values
576	/// * `y_error` - Errors associated with the y values
577	/// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are:
578	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
579	///     * `PointSymbol` - Sets symbol for each point
580	///     * `PointSize` - Sets the size of each point
581	///     * `LineWidth` - Sets the width of the line
582	///     * `LineStyle` - Sets the style of the line
583	///     * `Color` - Sets the color
584	pub fn y_error_lines<
585		'l,
586		Tx: DataType,
587		X: IntoIterator<Item = Tx>,
588		Ty: DataType,
589		Y: IntoIterator<Item = Ty>,
590		Tye: DataType,
591		YE: IntoIterator<Item = Tye>,
592	>(
593		&'l mut self, x: X, y: Y, y_error: YE, options: &[PlotOption<&str>],
594	) -> &'l mut Self
595	{
596		let (data, num_rows, num_cols) = generate_data!(options, x, y, y_error);
597		self.common.elems.push(PlotElement::new_plot(
598			YErrorLines,
599			data,
600			num_rows,
601			num_cols,
602			options,
603		));
604		self
605	}
606
607	/// Plot a 2D scatter-plot of two curves (bound by `y_lo` and `y_hi`) with a filled region between them.
608	/// `FillRegion` plot option can be used to control what happens when the curves intersect. If set to Above, then the `y_lo < y_hi` region is filled.
609	/// If set to Below, then the `y_lo > y_hi` region is filled. Otherwise both regions are filled.
610	/// # Arguments
611	/// * `x` - x values
612	/// * `y_lo` - Bottom y values
613	/// * `y_hi` - Top y values
614	/// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are:
615	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
616	///     * `FillRegion` - Specifies the region between the two curves to fill
617	///     * `Color` - Sets the color of the filled region
618	///     * `FillAlpha` - Sets the transparency of the filled region
619	pub fn fill_between<
620		'l,
621		Tx: DataType,
622		X: IntoIterator<Item = Tx>,
623		Tyl: DataType,
624		YL: IntoIterator<Item = Tyl>,
625		Tyh: DataType,
626		YH: IntoIterator<Item = Tyh>,
627	>(
628		&'l mut self, x: X, y_lo: YL, y_hi: YH, options: &[PlotOption<&str>],
629	) -> &'l mut Self
630	{
631		let (data, num_rows, num_cols) = generate_data!(options, x, y_lo, y_hi);
632		self.common.elems.push(PlotElement::new_plot(
633			FillBetween,
634			data,
635			num_rows,
636			num_cols,
637			options,
638		));
639		self
640	}
641
642	// Plot a polygon given coordinates of its vertices.
643	//
644	// # Arguments
645	// * `x` - x coordinates of the vertices
646	// * `y` - y coordinates of the vertices
647	// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are:
648	//	   * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
649	//	   * `FillAlpha` - Sets the transparency of the filled region
650	//	   * `Color` - Sets the color of the filled region (and the border, unless `BorderColor` is set)
651	//	   * `BorderColor` - Sets the color of the border
652	//	   * `FillPattern` - Sets the fill pattern
653	pub fn polygon<
654		'l,
655		Tx: DataType,
656		X: IntoIterator<Item = Tx>,
657		Ty: DataType,
658		Y: IntoIterator<Item = Ty>,
659	>(
660		&'l mut self, x: X, y: Y, options: &[PlotOption<&str>],
661	) -> &'l mut Self
662	{
663		let (data, num_rows, num_cols) = generate_data!(options, x, y);
664		self.common.elems.push(PlotElement::new_plot(
665			Polygons, data, num_rows, num_cols, options,
666		));
667		self
668	}
669
670	/// Plot a 2D box-plot.
671	/// Box widths are, by default set so that there are no gaps between successive boxes
672	/// (i.e. each box may have a different width). This may be adjusted with (set_box_width())[Axes2D::set_box_width()]
673	/// or by using the `BoxWidth` option.
674	/// Boxes start at the x-axis and go towards the y value of the datapoint.
675	///
676	/// # Arguments
677	/// * `x` - x values (center of the box)
678	/// * `y` - y values
679	/// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are:
680	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
681	///     * `LineWidth` - Sets the width of the border
682	///     * `LineStyle` - Sets the style of the border
683	///     * `BorderColor` - Sets the color of the border
684	///     * `Color` - Sets the color of the box fill
685	///     * `FillAlpha` - Sets the transparency of the box fill
686	///		* `BoxWidth` - Sets the width of each box. If not supplied, the width will use the
687	/// 		previously set box width, or be set to the spacing of the boxes
688	pub fn boxes<
689		'l,
690		Tx: DataType,
691		X: IntoIterator<Item = Tx>,
692		Ty: DataType,
693		Y: IntoIterator<Item = Ty>,
694	>(
695		&'l mut self, x: X, y: Y, options: &[PlotOption<&str>],
696	) -> &'l mut Self
697	{
698		let (data, num_rows, num_cols) = generate_data!(options, x, y);
699		self.common.elems.push(PlotElement::new_plot(
700			Boxes, data, num_rows, num_cols, options,
701		));
702		self
703	}
704
705	/// Plot a 2D box-plot with error bars using boxes of automatic width.
706	/// Box widths are, by default set so that there are no gaps between successive boxes
707	/// (i.e. each box may have a different width). This may be adjusted with (set_box_width())[Axes2D::set_box_width()]
708	/// or by using the `BoxWidth` option.
709	/// Boxes start at the x-axis and go towards the y value of the datapoint.
710	/// Each box has an error bar from y - y_delta to y + y_delta.
711	///
712	/// # Arguments
713	/// * `x` - x values (center of the box)
714	/// * `y` - y values
715	/// * `y_delta` - errors in y (error bars are plotted from y - y_delta to y + y_delta)
716	/// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are:
717	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
718	///     * `LineWidth` - Sets the width of the border
719	///     * `LineStyle` - Sets the style of the border
720	///     * `BorderColor` - Sets the color of the border
721	///     * `Color` - Sets the color of the box fill
722	///     * `FillAlpha` - Sets the transparency of the box fill
723	///		* `BoxWidth` - Sets the width of each box. If not supplied, the width will use the
724	/// 		previously set box width, or be set to the spacing of the boxes
725	pub fn box_error_delta<
726		'l,
727		Tx: DataType,
728		X: IntoIterator<Item = Tx>,
729		Ty: DataType,
730		Y: IntoIterator<Item = Ty>,
731		Tye: DataType,
732		YE: IntoIterator<Item = Tye>,
733	>(
734		&'l mut self, x: X, y: Y, y_error: YE, options: &[PlotOption<&str>],
735	) -> &'l mut Self
736	{
737		let (data, num_rows, num_cols) = generate_data!(options, x, y, y_error);
738		self.common.elems.push(PlotElement::new_plot(
739			BoxErrorBars,
740			data,
741			num_rows,
742			num_cols,
743			options,
744		));
745		self
746	}
747
748	/// Plot a 2D box-plot with error bars.
749	/// Box widths are, by default set so that there are no gaps between successive boxes
750	/// (i.e. each box may have a different width). This may be adjusted with (set_box_width())[Axes2D::set_box_width()]
751	/// or by using the `BoxWidth` option.
752	/// Boxes start at the x-axis and go towards the y value of the datapoint.
753	/// Each box has an error bar from y - y_low to y + y_high.
754	/// # Arguments
755	/// * `x` - x values (center of the box)
756	/// * `y` - y values
757	/// * `y_low` - minimum of error bar
758	/// * `y_high` - maximum of error bar
759	/// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are:
760	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
761	///     * `LineWidth` - Sets the width of the border
762	///     * `LineStyle` - Sets the style of the border
763	///     * `BorderColor` - Sets the color of the border
764	///     * `Color` - Sets the color of the box fill
765	///     * `FillAlpha` - Sets the transparency of the box fill
766	///		* `BoxWidth` - Sets the width of each box. If not supplied, the width will use the
767	/// 		previously set box width, or be set to the spacing of the boxes
768	pub fn box_error_low_high<
769		'l,
770		Tx: DataType,
771		X: IntoIterator<Item = Tx>,
772		Ty: DataType,
773		Y: IntoIterator<Item = Ty>,
774		Tyl: DataType,
775		YL: IntoIterator<Item = Tyl>,
776		Tyh: DataType,
777		YH: IntoIterator<Item = Tyh>,
778	>(
779		&'l mut self, x: X, y: Y, y_low: YL, y_high: YH, options: &[PlotOption<&str>],
780	) -> &'l mut Self
781	{
782		// The way to get boxerrorbars to interpret low and high y values is to use a dummy negative value for
783		// xdelta (box width). If you supply four values rather than five, the fourth is interpreted as width.
784		let dummy_width = iter::repeat(-1.0);
785		let (data, num_rows, num_cols) = generate_data!(options, x, y, y_low, y_high, dummy_width);
786		self.common.elems.push(PlotElement::new_plot(
787			BoxErrorBars,
788			data,
789			num_rows,
790			num_cols,
791			options,
792		));
793		self
794	}
795
796	/// Plot a 2D box-and-whisker plot.
797	///
798	/// Box widths are, by default set so that there are no gaps between successive boxes
799	/// (i.e. each box may have a different width). This may be adjusted with (set_box_width())[Axes2D::set_box_width()]
800	/// or by using the `BoxWidth` option.
801	///
802	/// # Arguments
803	/// * `x` - x values (center of the box)
804	/// * `box_min` - minimum box y value
805	/// * `whisker_min` - minimum whisker y value
806	/// * `whisker_max` - maximum whisker y value
807	/// * `box_max` - maximum box y value
808	/// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are:
809	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
810	///     * `LineWidth` - Sets the width of the border
811	///     * `LineStyle` - Sets the style of the border
812	///     * `BorderColor` - Sets the color of the border
813	///     * `Color` - Sets the color of the box fill
814	///     * `FillAlpha` - Sets the transparency of the box fill
815	///     * `WhiskerBars` - Sets the width of the whisker bars
816	///		* `BoxWidth` - Sets the width of each box. If not supplied, the width will use the
817	/// 		previously set box width, or be set to the spacing of the boxes
818	pub fn box_and_whisker<
819		'l,
820		Tx: DataType,
821		X: IntoIterator<Item = Tx>,
822		TBoxMin: DataType,
823		BoxMin: IntoIterator<Item = TBoxMin>,
824		TWhiskerMin: DataType,
825		WhiskerMin: IntoIterator<Item = TWhiskerMin>,
826		TWhiskerMax: DataType,
827		WhiskerMax: IntoIterator<Item = TWhiskerMax>,
828		TBoxMax: DataType,
829		BoxMax: IntoIterator<Item = TBoxMax>,
830	>(
831		&'l mut self, x: X, box_min: BoxMin, whisker_min: WhiskerMin, whisker_max: WhiskerMax,
832		box_max: BoxMax, options: &[PlotOption<&str>],
833	) -> &'l mut Self
834	{
835		let (data, num_rows, num_cols) =
836			generate_data!(options, x, box_min, whisker_min, whisker_max, box_max);
837		self.common.elems.push(PlotElement::new_plot(
838			BoxAndWhisker,
839			data,
840			num_rows,
841			num_cols,
842			options,
843		));
844		self
845	}
846
847	/// Plot 2D rectangular boxes - usually used for error bars - using specified by width (x_delta) and height (y_delta).
848	///
849	/// # Arguments
850	/// * `x` - x values (horizontal center of the box)
851	/// * `y` - y values (vertical center of the box)
852	/// * `x_delta` - Error in x (horizontal half-width of the box)
853	/// * `y_delta` - Error in y (vertical half-width of the box)
854	/// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are:
855	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
856	///     * `LineWidth` - Sets the width of the border
857	///     * `LineStyle` - Sets the style of the border
858	///     * `BorderColor` - Sets the color of the border
859	///     * `Color` - Sets the color of the box fill
860	///     * `FillAlpha` - Sets the transparency of the box fill
861	pub fn box_xy_error_delta<
862		'l,
863		Tx: DataType,
864		X: IntoIterator<Item = Tx>,
865		Ty: DataType,
866		Y: IntoIterator<Item = Ty>,
867		TXDelta: DataType,
868		XDelta: IntoIterator<Item = TXDelta>,
869		TYDelta: DataType,
870		YDelta: IntoIterator<Item = TYDelta>,
871	>(
872		&'l mut self, x: X, y: Y, x_delta: XDelta, y_delta: YDelta, options: &[PlotOption<&str>],
873	) -> &'l mut Self
874	{
875		let (data, num_rows, num_cols) = generate_data!(options, x, y, x_delta, y_delta);
876		self.common.elems.push(PlotElement::new_plot(
877			BoxXYError, data, num_rows, num_cols, options,
878		));
879		self
880	}
881
882	/// Plot 2D rectangular boxes - usually used for error bars - using specified low and high limits for x and y.
883	///
884	/// # Arguments
885	/// * `x` - x values (horizontal center of the box)
886	/// * `y` - y values (vertical center of the box)
887	/// * `x_low` - Horizontal lower limit of the box
888	/// * `x_high` - Horizontal upper limit of the box
889	/// * `y_low` - Vertical lower limit of the box
890	/// * `y_high` - Vertical upper limit of the box
891	/// * `options` - Array of PlotOption<&str> controlling the appearance of the plot element. The relevant options are:
892	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
893	///     * `LineWidth` - Sets the width of the border
894	///     * `LineStyle` - Sets the style of the border
895	///     * `BorderColor` - Sets the color of the border
896	///     * `Color` - Sets the color of the box fill
897	///     * `FillAlpha` - Sets the transparency of the box fill
898	pub fn box_xy_error_low_high<
899		'l,
900		Tx: DataType,
901		X: IntoIterator<Item = Tx>,
902		Ty: DataType,
903		Y: IntoIterator<Item = Ty>,
904		TXLow: DataType,
905		XLow: IntoIterator<Item = TXLow>,
906		TXHigh: DataType,
907		XHigh: IntoIterator<Item = TXHigh>,
908		TYLow: DataType,
909		YLow: IntoIterator<Item = TYLow>,
910		TYHigh: DataType,
911		YHigh: IntoIterator<Item = TYHigh>,
912	>(
913		&'l mut self, x: X, y: Y, x_low: XLow, x_high: XHigh, y_low: YLow, y_high: YHigh,
914		options: &[PlotOption<&str>],
915	) -> &'l mut Self
916	{
917		let (data, num_rows, num_cols) =
918			generate_data!(options, x, y, x_low, x_high, y_low, y_high);
919		self.common.elems.push(PlotElement::new_plot(
920			BoxXYError, data, num_rows, num_cols, options,
921		));
922		self
923	}
924
925	/// Draws an image from a rectangular array of data by connecting the individual datapoints with polygons.
926	///
927	/// #Arguments:
928	/// * `mat` - Row-major 2D array signifying the value of the datapoints. The X and Y coordinates of the datapoints are determined automatically,
929	///           and optionally scaled using the `dimensions` argument.
930	/// * `num_rows` - Number of rows in the data array
931	/// * `num_cols` - Number of columns in the data array
932	/// * `dimensions` - Optional X and Y coordinates of the first and last data points (with the rest of the coordinates spaced evenly between).
933	///                  By default this will be `(0, 0)` and `(num_rows - 1, num_cols - 1)`.
934	/// * `options` - Array of PlotOption<&str> controlling the appearance of the surface. Relevant options are:
935	///     * `Caption` - Specifies the caption for this dataset. Use an empty string to hide it (default).
936	pub fn image<'l, T: DataType, X: IntoIterator<Item = T>>(
937		&'l mut self, mat: X, num_rows: usize, num_cols: usize,
938		dimensions: Option<(f64, f64, f64, f64)>, options: &[PlotOption<&str>],
939	) -> &'l mut Self
940	{
941		self.common.elems.push(PlotElement::new_plot_matrix(
942			Image,
943			false,
944			mat,
945			num_rows,
946			num_cols,
947			dimensions,
948			options.to_one_way_owned(),
949		));
950		self
951	}
952
953	pub(crate) fn write_out(
954		&self, data_directory: Option<&str>, writer: &mut dyn Writer, auto_layout: bool,
955		version: GnuplotVersion,
956	)
957	{
958		self.common.write_out_commands(writer, auto_layout, version);
959		self.border_options.write_out(writer, version);
960		let mut grid_axes = vec![];
961		if self.common.x_axis.grid
962		{
963			grid_axes.push(self.common.x_axis.axis);
964		}
965		if self.common.y_axis.grid
966		{
967			grid_axes.push(self.common.y_axis.axis);
968		}
969		if self.common.cb_axis.grid
970		{
971			grid_axes.push(self.common.cb_axis.axis);
972		}
973		self.common.write_grid_options(writer, &grid_axes, version);
974		for arrow in &self.arrows
975		{
976			arrow.write_out(writer);
977		}
978		if let Some(l) = self.legend.as_ref()
979		{
980			l.write_out(writer)
981		};
982		self.common
983			.write_out_elements("plot", data_directory, writer, version);
984	}
985
986	pub(crate) fn reset_state(&self, writer: &mut dyn Writer)
987	{
988		self.common.reset_state(writer);
989		for arrow in &self.arrows
990		{
991			arrow.reset_state(writer);
992		}
993		if let Some(l) = self.legend.as_ref()
994		{
995			l.reset_state(writer)
996		};
997	}
998}
999
1000impl AxesCommonPrivate for Axes2D
1001{
1002	fn get_common_data(&self) -> &AxesCommonData
1003	{
1004		&self.common
1005	}
1006
1007	fn get_common_data_mut(&mut self) -> &mut AxesCommonData
1008	{
1009		&mut self.common
1010	}
1011}
1012
1013impl AxesCommon for Axes2D {}