gnuplot/
axes2d.rs1// 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 {}