1use plotters::prelude::IntoDrawingArea;
2
3use crate::aes::Aes;
4use crate::annotate::Annotation;
5use crate::build::PlotBuilder;
6use crate::coord::cartesian::CoordCartesian;
7use crate::coord::fixed::CoordFixed;
8use crate::coord::flip::CoordFlip;
9use crate::coord::polar::CoordPolar;
10use crate::coord::Coord;
11use crate::data::{DataFrame, GGData};
12use crate::facet::{Facet, FacetLabeller, FacetScales};
13use crate::geom::area::GeomArea;
14use crate::geom::bar::GeomBar;
15use crate::geom::bin2d::GeomBin2d;
16use crate::geom::blank::GeomBlank;
17use crate::geom::boxplot::GeomBoxplot;
18use crate::geom::col::GeomCol;
19use crate::geom::contour::GeomContour;
20use crate::geom::count::GeomCount;
21use crate::geom::crossbar::GeomCrossbar;
22use crate::geom::curve::GeomCurve;
23use crate::geom::density::GeomDensity;
24use crate::geom::density2d::GeomDensity2d;
25use crate::geom::dotplot::GeomDotplot;
26use crate::geom::errorbar::GeomErrorbar;
27use crate::geom::freqpoly::GeomFreqpoly;
28use crate::geom::hex::GeomHex;
29use crate::geom::histogram::GeomHistogram;
30use crate::geom::jitter::GeomJitter;
31use crate::geom::line::GeomLine;
32use crate::geom::linerange::GeomLinerange;
33use crate::geom::path::GeomPath;
34use crate::geom::point::GeomPoint;
35use crate::geom::pointrange::GeomPointrange;
36use crate::geom::polygon::GeomPolygon;
37use crate::geom::qq::{GeomQQ, GeomQQLine};
38use crate::geom::rect::GeomRect;
39use crate::geom::refline::{GeomAbline, GeomHline, GeomVline};
40use crate::geom::ribbon::GeomRibbon;
41use crate::geom::rug::GeomRug;
42use crate::geom::segment::GeomSegment;
43use crate::geom::smooth::GeomSmooth;
44use crate::geom::spoke::GeomSpoke;
45use crate::geom::step::GeomStep;
46use crate::geom::text::{GeomLabel, GeomText};
47use crate::geom::tile::GeomTile;
48use crate::geom::violin::GeomViolin;
49use crate::geom::{Geom, GeomParams};
50use crate::position::Position;
51use crate::render::layout::PlotLayout;
52use crate::render::plotters_backend::PlottersAdapter;
53use crate::render::renderer::PlotRenderer;
54use crate::render::RenderError;
55use crate::scale::continuous::ScaleContinuous;
56use crate::scale::transform::ScaleTransform;
57use crate::scale::Scale;
58use crate::stat::Stat;
59use crate::theme::Theme;
60
61#[derive(Clone, Debug, Default)]
63pub struct Labels {
64 pub title: Option<String>,
65 pub subtitle: Option<String>,
66 pub x: Option<String>,
67 pub y: Option<String>,
68 pub caption: Option<String>,
69}
70
71pub struct Layer {
73 pub data: Option<DataFrame>,
74 pub mapping: Aes,
75 pub geom: Box<dyn Geom>,
76 pub stat: Box<dyn Stat>,
77 pub position: Box<dyn Position>,
78 pub params: GeomParams,
79 pub show_legend: Option<bool>,
80}
81
82pub struct GGPlot {
84 pub(crate) data: DataFrame,
85 pub(crate) mapping: Aes,
86 pub(crate) layers: Vec<Layer>,
87 pub(crate) scales: Vec<Box<dyn Scale>>,
88 pub(crate) coord: Box<dyn Coord>,
89 pub(crate) theme: Theme,
90 pub(crate) labels: Labels,
91 pub(crate) facet: Facet,
92 pub(crate) annotations: Vec<Annotation>,
93 pub(crate) guide_legend: crate::guide::config::GuideLegend,
94}
95
96impl GGPlot {
97 pub fn new(data: impl GGData) -> Self {
99 GGPlot {
100 data: data.into_dataframe(),
101 mapping: Aes::default(),
102 layers: Vec::new(),
103 scales: Vec::new(),
104 coord: Box::new(CoordCartesian::new()),
105 theme: Theme::default(),
106 labels: Labels::default(),
107 facet: Facet::default(),
108 annotations: Vec::new(),
109 guide_legend: crate::guide::config::GuideLegend::default(),
110 }
111 }
112
113 pub fn aes(mut self, mapping: Aes) -> Self {
115 self.mapping = mapping;
116 self
117 }
118
119 pub fn geom_point(self) -> Self {
122 self.add_geom(GeomPoint::default())
123 }
124
125 pub fn geom_point_with(self, geom: GeomPoint) -> Self {
126 self.add_geom(geom)
127 }
128
129 pub fn geom_line(self) -> Self {
130 self.add_geom(GeomLine::default())
131 }
132
133 pub fn geom_line_with(self, geom: GeomLine) -> Self {
134 self.add_geom(geom)
135 }
136
137 pub fn geom_bar(self) -> Self {
138 self.add_geom(GeomBar::default())
139 }
140
141 pub fn geom_bar_with(self, geom: GeomBar) -> Self {
142 self.add_geom(geom)
143 }
144
145 pub fn geom_histogram(self) -> Self {
146 self.add_geom(GeomHistogram::default())
147 }
148
149 pub fn geom_histogram_with(self, geom: GeomHistogram) -> Self {
150 self.add_geom(geom)
151 }
152
153 pub fn geom_boxplot(self) -> Self {
154 self.add_geom(GeomBoxplot::default())
155 }
156
157 pub fn geom_boxplot_with(self, geom: GeomBoxplot) -> Self {
158 self.add_geom(geom)
159 }
160
161 pub fn geom_smooth(self) -> Self {
162 self.add_geom(GeomSmooth::default())
163 }
164
165 pub fn geom_smooth_with(self, geom: GeomSmooth) -> Self {
166 self.add_geom(geom)
167 }
168
169 pub fn geom_col(self) -> Self {
170 self.add_geom(GeomCol::default())
171 }
172
173 pub fn geom_col_with(self, geom: GeomCol) -> Self {
174 self.add_geom(geom)
175 }
176
177 pub fn geom_hline(self, yintercept: f64) -> Self {
178 self.add_geom(GeomHline::new(yintercept))
179 }
180
181 pub fn geom_hline_with(self, geom: GeomHline) -> Self {
183 self.add_geom(geom)
184 }
185
186 pub fn geom_vline(self, xintercept: f64) -> Self {
187 self.add_geom(GeomVline::new(xintercept))
188 }
189
190 pub fn geom_vline_with(self, geom: GeomVline) -> Self {
192 self.add_geom(geom)
193 }
194
195 pub fn geom_abline(self, slope: f64, intercept: f64) -> Self {
196 self.add_geom(GeomAbline::new(slope, intercept))
197 }
198
199 pub fn geom_abline_with(self, geom: GeomAbline) -> Self {
201 self.add_geom(geom)
202 }
203
204 pub fn geom_text(self) -> Self {
205 self.add_geom(GeomText::default())
206 }
207
208 pub fn geom_text_with(self, geom: GeomText) -> Self {
209 self.add_geom(geom)
210 }
211
212 pub fn geom_label(self) -> Self {
213 self.add_geom(GeomLabel::default())
214 }
215
216 pub fn geom_label_with(self, geom: GeomLabel) -> Self {
217 self.add_geom(geom)
218 }
219
220 pub fn geom_area(self) -> Self {
221 self.add_geom(GeomArea::default())
222 }
223
224 pub fn geom_area_with(self, geom: GeomArea) -> Self {
225 self.add_geom(geom)
226 }
227
228 pub fn geom_ribbon(self) -> Self {
229 self.add_geom(GeomRibbon::default())
230 }
231
232 pub fn geom_ribbon_with(self, geom: GeomRibbon) -> Self {
233 self.add_geom(geom)
234 }
235
236 pub fn geom_errorbar(self) -> Self {
237 self.add_geom(GeomErrorbar::default())
238 }
239
240 pub fn geom_errorbar_with(self, geom: GeomErrorbar) -> Self {
241 self.add_geom(geom)
242 }
243
244 pub fn geom_segment(self) -> Self {
245 self.add_geom(GeomSegment::default())
246 }
247
248 pub fn geom_segment_with(self, geom: GeomSegment) -> Self {
249 self.add_geom(geom)
250 }
251
252 pub fn geom_density(self) -> Self {
253 self.add_geom(GeomDensity::default())
254 }
255
256 pub fn geom_density_with(self, geom: GeomDensity) -> Self {
257 self.add_geom(geom)
258 }
259
260 pub fn geom_rug(self) -> Self {
261 self.add_geom(GeomRug::default())
262 }
263
264 pub fn geom_rug_with(self, geom: GeomRug) -> Self {
265 self.add_geom(geom)
266 }
267
268 pub fn geom_jitter(self) -> Self {
269 self.add_geom(GeomJitter::default())
270 }
271
272 pub fn geom_jitter_with(self, geom: GeomJitter) -> Self {
273 self.add_geom(geom)
274 }
275
276 pub fn geom_path(self) -> Self {
277 self.add_geom(GeomPath::default())
278 }
279
280 pub fn geom_path_with(self, geom: GeomPath) -> Self {
281 self.add_geom(geom)
282 }
283
284 pub fn stat_ellipse(self) -> Self {
286 self.geom_path()
287 .stat(crate::stat::ellipse::StatEllipse::default())
288 }
289
290 pub fn stat_ellipse_level(self, level: f64) -> Self {
292 self.geom_path()
293 .stat(crate::stat::ellipse::StatEllipse::new(level))
294 }
295
296 #[cfg(feature = "regression")]
299 pub fn stat_quantile(mut self, taus: &[f64]) -> Self {
300 for &tau in taus {
301 self = self
302 .geom_path()
303 .stat(crate::stat::quantile::StatQuantile::new(tau));
304 }
305 self
306 }
307
308 #[cfg(feature = "regression")]
310 pub fn geom_quantile(self) -> Self {
311 self.stat_quantile(&[0.25, 0.5, 0.75])
312 }
313
314 pub fn geom_step(self) -> Self {
315 self.add_geom(GeomStep::default())
316 }
317
318 pub fn geom_step_with(self, geom: GeomStep) -> Self {
319 self.add_geom(geom)
320 }
321
322 pub fn geom_freqpoly(self) -> Self {
323 self.add_geom(GeomFreqpoly::default())
324 }
325
326 pub fn geom_freqpoly_with(self, geom: GeomFreqpoly) -> Self {
327 self.add_geom(geom)
328 }
329
330 pub fn geom_linerange(self) -> Self {
331 self.add_geom(GeomLinerange::default())
332 }
333
334 pub fn geom_linerange_with(self, geom: GeomLinerange) -> Self {
335 self.add_geom(geom)
336 }
337
338 pub fn geom_pointrange(self) -> Self {
339 self.add_geom(GeomPointrange::default())
340 }
341
342 pub fn geom_pointrange_with(self, geom: GeomPointrange) -> Self {
343 self.add_geom(geom)
344 }
345
346 pub fn geom_crossbar(self) -> Self {
347 self.add_geom(GeomCrossbar::default())
348 }
349
350 pub fn geom_crossbar_with(self, geom: GeomCrossbar) -> Self {
351 self.add_geom(geom)
352 }
353
354 pub fn geom_spoke(self) -> Self {
355 self.add_geom(GeomSpoke::default())
356 }
357
358 pub fn geom_spoke_with(self, geom: GeomSpoke) -> Self {
359 self.add_geom(geom)
360 }
361
362 pub fn geom_rect(self) -> Self {
363 self.add_geom(GeomRect::default())
364 }
365
366 pub fn geom_rect_with(self, geom: GeomRect) -> Self {
367 self.add_geom(geom)
368 }
369
370 pub fn geom_tile(self) -> Self {
371 self.add_geom(GeomTile::default())
372 }
373
374 pub fn geom_tile_with(self, geom: GeomTile) -> Self {
375 self.add_geom(geom)
376 }
377
378 pub fn geom_raster(self) -> Self {
380 self.add_geom(crate::geom::raster::GeomRaster::default())
381 }
382
383 pub fn geom_raster_with(self, geom: crate::geom::raster::GeomRaster) -> Self {
384 self.add_geom(geom)
385 }
386
387 pub fn geom_polygon(self) -> Self {
388 self.add_geom(GeomPolygon::default())
389 }
390
391 pub fn geom_polygon_with(self, geom: GeomPolygon) -> Self {
392 self.add_geom(geom)
393 }
394
395 pub fn geom_curve(self) -> Self {
396 self.add_geom(GeomCurve::default())
397 }
398
399 pub fn geom_curve_with(self, geom: GeomCurve) -> Self {
400 self.add_geom(geom)
401 }
402
403 pub fn geom_violin(self) -> Self {
404 self.add_geom(GeomViolin::default())
405 }
406
407 pub fn geom_violin_with(self, geom: GeomViolin) -> Self {
408 self.add_geom(geom)
409 }
410
411 pub fn geom_dotplot(self) -> Self {
412 self.add_geom(GeomDotplot::default())
413 }
414
415 pub fn geom_dotplot_with(self, geom: GeomDotplot) -> Self {
416 self.add_geom(geom)
417 }
418
419 pub fn geom_qq(self) -> Self {
420 self.add_geom(GeomQQ::default())
421 }
422
423 pub fn geom_qq_with(self, geom: GeomQQ) -> Self {
424 self.add_geom(geom)
425 }
426
427 pub fn geom_qq_line(self) -> Self {
428 self.add_geom(GeomQQLine::default())
429 }
430
431 pub fn geom_qq_line_with(self, geom: GeomQQLine) -> Self {
432 self.add_geom(geom)
433 }
434
435 pub fn geom_bin2d(self) -> Self {
436 self.add_geom(GeomBin2d::default())
437 }
438
439 pub fn geom_bin2d_with(self, geom: GeomBin2d) -> Self {
440 self.add_geom(geom)
441 }
442
443 pub fn geom_hex(self) -> Self {
444 self.add_geom(GeomHex::default())
445 }
446
447 pub fn geom_hex_with(self, geom: GeomHex) -> Self {
448 self.add_geom(geom)
449 }
450
451 pub fn geom_count(self) -> Self {
452 self.add_geom(GeomCount::default())
453 }
454
455 pub fn geom_count_with(self, geom: GeomCount) -> Self {
456 self.add_geom(geom)
457 }
458
459 pub fn geom_contour(self) -> Self {
460 self.add_geom(GeomContour::default())
461 }
462
463 pub fn geom_contour_with(self, geom: GeomContour) -> Self {
464 self.add_geom(geom)
465 }
466
467 pub fn geom_density2d(self) -> Self {
468 self.add_geom(GeomDensity2d::default())
469 }
470
471 pub fn geom_density2d_with(self, geom: GeomDensity2d) -> Self {
472 self.add_geom(geom)
473 }
474
475 pub fn geom_blank(self) -> Self {
476 self.add_geom(GeomBlank)
477 }
478
479 fn add_geom(mut self, geom: impl Geom + 'static) -> Self {
480 let stat = geom.default_stat();
481 let position = geom.default_position();
482 let params = geom.default_params();
483 self.layers.push(Layer {
484 data: None,
485 mapping: Aes::default(),
486 geom: Box::new(geom),
487 stat,
488 position,
489 params,
490 show_legend: None,
491 });
492 self
493 }
494
495 pub fn stat(mut self, stat: impl Stat + 'static) -> Self {
499 if let Some(layer) = self.layers.last_mut() {
500 layer.stat = Box::new(stat);
501 }
502 self
503 }
504
505 pub fn position(mut self, pos: impl Position + 'static) -> Self {
507 if let Some(layer) = self.layers.last_mut() {
508 layer.position = Box::new(pos);
509 }
510 self
511 }
512
513 pub fn layer_data(mut self, data: impl GGData) -> Self {
515 if let Some(layer) = self.layers.last_mut() {
516 layer.data = Some(data.into_dataframe());
517 }
518 self
519 }
520
521 pub fn layer_aes(mut self, mapping: Aes) -> Self {
523 if let Some(layer) = self.layers.last_mut() {
524 layer.mapping = mapping;
525 }
526 self
527 }
528
529 pub fn show_legend(mut self, show: bool) -> Self {
532 if let Some(layer) = self.layers.last_mut() {
533 layer.show_legend = Some(show);
534 }
535 self
536 }
537
538 pub fn scale_x_continuous(mut self, s: ScaleContinuous) -> Self {
541 let s = s.for_aesthetic(crate::aes::Aesthetic::X);
542 self.scales.push(Box::new(s));
543 self
544 }
545
546 pub fn scale_y_continuous(mut self, s: ScaleContinuous) -> Self {
547 let s = s.for_aesthetic(crate::aes::Aesthetic::Y);
548 self.scales.push(Box::new(s));
549 self
550 }
551
552 pub fn scale_x_discrete(mut self, s: crate::scale::discrete::ScaleDiscrete) -> Self {
553 let s = s.for_aesthetic(crate::aes::Aesthetic::X);
554 self.scales.push(Box::new(s));
555 self
556 }
557
558 pub fn scale_y_discrete(mut self, s: crate::scale::discrete::ScaleDiscrete) -> Self {
559 let s = s.for_aesthetic(crate::aes::Aesthetic::Y);
560 self.scales.push(Box::new(s));
561 self
562 }
563
564 pub fn scale_color(mut self, s: impl Scale + 'static) -> Self {
565 self.scales.push(Box::new(s));
566 self
567 }
568
569 pub fn scale_fill(mut self, s: impl Scale + 'static) -> Self {
570 self.scales.push(Box::new(s));
571 self
572 }
573
574 pub fn scale_color_manual(self, values: Vec<(&str, crate::scale::color::RGBAColor)>) -> Self {
575 let s = crate::scale::manual::ScaleManual::new(crate::aes::Aesthetic::Color, values);
576 self.scale_color(s)
577 }
578
579 pub fn scale_fill_manual(self, values: Vec<(&str, crate::scale::color::RGBAColor)>) -> Self {
580 let s = crate::scale::manual::ScaleManual::new(crate::aes::Aesthetic::Fill, values);
581 self.scale_fill(s)
582 }
583
584 pub fn scale_color_viridis(self) -> Self {
585 use crate::scale::color::ScaleColorDiscrete;
586 use crate::scale::palettes::PaletteName;
587 let s = ScaleColorDiscrete::new(crate::aes::Aesthetic::Color)
588 .with_named_palette(&PaletteName::Viridis);
589 self.scale_color(s)
590 }
591
592 pub fn scale_color_brewer(self, name: crate::scale::palettes::PaletteName) -> Self {
593 use crate::scale::color::ScaleColorDiscrete;
594 let s = ScaleColorDiscrete::new(crate::aes::Aesthetic::Color).with_named_palette(&name);
595 self.scale_color(s)
596 }
597
598 pub fn scale_color_gradient(
599 self,
600 low: crate::scale::color::RGBAColor,
601 high: crate::scale::color::RGBAColor,
602 ) -> Self {
603 use crate::scale::color::ScaleColorContinuous;
604 let s = ScaleColorContinuous::new(crate::aes::Aesthetic::Color).with_colors(low, high);
605 self.scale_color(s)
606 }
607
608 pub fn scale_fill_gradient(
609 self,
610 low: crate::scale::color::RGBAColor,
611 high: crate::scale::color::RGBAColor,
612 ) -> Self {
613 use crate::scale::color::ScaleColorContinuous;
614 let s = ScaleColorContinuous::new(crate::aes::Aesthetic::Fill).with_colors(low, high);
615 self.scale_fill(s)
616 }
617
618 pub fn scale_color_gradient2(
619 self,
620 low: crate::scale::color::RGBAColor,
621 mid: crate::scale::color::RGBAColor,
622 high: crate::scale::color::RGBAColor,
623 ) -> Self {
624 use crate::scale::gradient::ScaleColorGradient2;
625 let s = ScaleColorGradient2::new(crate::aes::Aesthetic::Color).with_colors(low, mid, high);
626 self.scale_color(s)
627 }
628
629 pub fn scale_fill_gradient2(
630 self,
631 low: crate::scale::color::RGBAColor,
632 mid: crate::scale::color::RGBAColor,
633 high: crate::scale::color::RGBAColor,
634 ) -> Self {
635 use crate::scale::gradient::ScaleColorGradient2;
636 let s = ScaleColorGradient2::new(crate::aes::Aesthetic::Fill).with_colors(low, mid, high);
637 self.scale_fill(s)
638 }
639
640 pub fn scale_fill_viridis(self) -> Self {
641 use crate::scale::color::ScaleColorDiscrete;
642 use crate::scale::palettes::PaletteName;
643 let s = ScaleColorDiscrete::new(crate::aes::Aesthetic::Fill)
644 .with_named_palette(&PaletteName::Viridis);
645 self.scale_fill(s)
646 }
647
648 pub fn scale_color_viridis_c(self) -> Self {
650 use crate::scale::gradient_n::ScaleColorGradientN;
651 let s = ScaleColorGradientN::viridis(crate::aes::Aesthetic::Color);
652 self.scale_color(s)
653 }
654
655 pub fn scale_fill_viridis_c(self) -> Self {
657 use crate::scale::gradient_n::ScaleColorGradientN;
658 let s = ScaleColorGradientN::viridis(crate::aes::Aesthetic::Fill);
659 self.scale_fill(s)
660 }
661
662 pub fn scale_color_gradientn(self, stops: Vec<(f64, crate::scale::color::RGBAColor)>) -> Self {
664 use crate::scale::gradient_n::ScaleColorGradientN;
665 let s = ScaleColorGradientN::new(crate::aes::Aesthetic::Color, stops);
666 self.scale_color(s)
667 }
668
669 pub fn scale_fill_gradientn(self, stops: Vec<(f64, crate::scale::color::RGBAColor)>) -> Self {
671 use crate::scale::gradient_n::ScaleColorGradientN;
672 let s = ScaleColorGradientN::new(crate::aes::Aesthetic::Fill, stops);
673 self.scale_fill(s)
674 }
675
676 pub fn scale_color_steps(
679 self,
680 low: crate::scale::color::RGBAColor,
681 high: crate::scale::color::RGBAColor,
682 n_bins: usize,
683 ) -> Self {
684 let s = crate::scale::steps::ScaleColorSteps::two(
685 crate::aes::Aesthetic::Color,
686 (low.r, low.g, low.b),
687 (high.r, high.g, high.b),
688 n_bins,
689 );
690 self.scale_color(s)
691 }
692
693 pub fn scale_color_stepsn(
695 self,
696 stops: Vec<crate::scale::color::RGBAColor>,
697 n_bins: usize,
698 ) -> Self {
699 let s = crate::scale::steps::ScaleColorSteps::new(
700 crate::aes::Aesthetic::Color,
701 stops.iter().map(|c| (c.r, c.g, c.b)).collect(),
702 n_bins,
703 );
704 self.scale_color(s)
705 }
706
707 pub fn scale_color_fermenter(
709 self,
710 name: crate::scale::palettes::PaletteName,
711 n_bins: usize,
712 ) -> Self {
713 let stops = crate::scale::palettes::palette(&name)
714 .iter()
715 .map(|c| (c.r, c.g, c.b))
716 .collect();
717 let s =
718 crate::scale::steps::ScaleColorSteps::new(crate::aes::Aesthetic::Color, stops, n_bins);
719 self.scale_color(s)
720 }
721
722 pub fn scale_fill_steps(
724 self,
725 low: crate::scale::color::RGBAColor,
726 high: crate::scale::color::RGBAColor,
727 n_bins: usize,
728 ) -> Self {
729 let s = crate::scale::steps::ScaleColorSteps::two(
730 crate::aes::Aesthetic::Fill,
731 (low.r, low.g, low.b),
732 (high.r, high.g, high.b),
733 n_bins,
734 );
735 self.scale_fill(s)
736 }
737
738 pub fn scale_fill_fermenter(
740 self,
741 name: crate::scale::palettes::PaletteName,
742 n_bins: usize,
743 ) -> Self {
744 let stops = crate::scale::palettes::palette(&name)
745 .iter()
746 .map(|c| (c.r, c.g, c.b))
747 .collect();
748 let s =
749 crate::scale::steps::ScaleColorSteps::new(crate::aes::Aesthetic::Fill, stops, n_bins);
750 self.scale_fill(s)
751 }
752
753 pub fn scale_fill_brewer(self, name: crate::scale::palettes::PaletteName) -> Self {
754 use crate::scale::color::ScaleColorDiscrete;
755 let s = ScaleColorDiscrete::new(crate::aes::Aesthetic::Fill).with_named_palette(&name);
756 self.scale_fill(s)
757 }
758
759 pub fn scale_linetype_manual(
760 self,
761 values: Vec<(&str, crate::render::backend::Linetype)>,
762 ) -> Self {
763 let s = crate::scale::linetype_manual::ScaleLinetypeManual::new(values);
764 self.scale_color(s)
765 }
766
767 pub fn scale_shape_manual(
768 self,
769 values: Vec<(&str, crate::render::backend::PointShape)>,
770 ) -> Self {
771 let s = crate::scale::shape_manual::ScaleShapeManual::new(values);
772 self.scale_color(s)
773 }
774
775 pub fn scale_color_grey(self) -> Self {
776 let s = crate::scale::grey::ScaleColorGrey::new(crate::aes::Aesthetic::Color);
777 self.scale_color(s)
778 }
779
780 pub fn scale_fill_grey(self) -> Self {
781 let s = crate::scale::grey::ScaleColorGrey::new(crate::aes::Aesthetic::Fill);
782 self.scale_fill(s)
783 }
784
785 pub fn scale_color_grey_with(self, s: crate::scale::grey::ScaleColorGrey) -> Self {
786 self.scale_color(s)
787 }
788
789 pub fn scale_fill_grey_with(self, s: crate::scale::grey::ScaleColorGrey) -> Self {
790 self.scale_fill(s)
791 }
792
793 pub fn scale_x_reverse(self) -> Self {
794 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Reverse))
795 }
796
797 pub fn scale_y_reverse(self) -> Self {
798 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Reverse))
799 }
800
801 pub fn scale_x_datetime(mut self, s: crate::scale::datetime::ScaleDateTime) -> Self {
802 let s = s.for_aesthetic(crate::aes::Aesthetic::X);
803 self.scales.push(Box::new(s));
804 self
805 }
806
807 pub fn scale_y_datetime(mut self, s: crate::scale::datetime::ScaleDateTime) -> Self {
808 let s = s.for_aesthetic(crate::aes::Aesthetic::Y);
809 self.scales.push(Box::new(s));
810 self
811 }
812
813 pub fn scale_size(mut self, s: crate::scale::size::ScaleSizeContinuous) -> Self {
814 self.scales.push(Box::new(s));
815 self
816 }
817
818 pub fn scale_alpha(mut self, s: crate::scale::alpha::ScaleAlphaContinuous) -> Self {
819 self.scales.push(Box::new(s));
820 self
821 }
822
823 pub fn xlim(self, min: f64, max: f64) -> Self {
824 self.scale_x_continuous(ScaleContinuous::new().with_limits(min, max))
825 }
826
827 pub fn ylim(self, min: f64, max: f64) -> Self {
828 self.scale_y_continuous(ScaleContinuous::new().with_limits(min, max))
829 }
830
831 pub fn scale_x_log10(self) -> Self {
832 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Log10))
833 }
834
835 pub fn scale_y_log10(self) -> Self {
836 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Log10))
837 }
838
839 pub fn scale_x_sqrt(self) -> Self {
840 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Sqrt))
841 }
842
843 pub fn scale_y_sqrt(self) -> Self {
844 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Sqrt))
845 }
846
847 pub fn scale_x_log2(self) -> Self {
848 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Log2))
849 }
850
851 pub fn scale_y_log2(self) -> Self {
852 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Log2))
853 }
854
855 pub fn scale_x_ln(self) -> Self {
856 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Ln))
857 }
858
859 pub fn scale_y_ln(self) -> Self {
860 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Ln))
861 }
862
863 pub fn scale_x_logit(self) -> Self {
865 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Logit))
866 }
867
868 pub fn scale_y_logit(self) -> Self {
869 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Logit))
870 }
871
872 pub fn scale_x_probit(self) -> Self {
874 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Probit))
875 }
876
877 pub fn scale_y_probit(self) -> Self {
878 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Probit))
879 }
880
881 pub fn scale_x_pseudo_log(self) -> Self {
883 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::PseudoLog))
884 }
885
886 pub fn scale_y_pseudo_log(self) -> Self {
887 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::PseudoLog))
888 }
889
890 pub fn scale_x_reciprocal(self) -> Self {
892 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Reciprocal))
893 }
894
895 pub fn scale_y_reciprocal(self) -> Self {
896 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Reciprocal))
897 }
898
899 pub fn scale_x_exp(self) -> Self {
901 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Exp))
902 }
903
904 pub fn scale_y_exp(self) -> Self {
905 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Exp))
906 }
907
908 pub fn scale_x_boxcox(self, lambda: f64) -> Self {
910 self.scale_x_continuous(
911 ScaleContinuous::new().with_transform(ScaleTransform::BoxCox(lambda)),
912 )
913 }
914
915 pub fn scale_y_boxcox(self, lambda: f64) -> Self {
916 self.scale_y_continuous(
917 ScaleContinuous::new().with_transform(ScaleTransform::BoxCox(lambda)),
918 )
919 }
920
921 pub fn facet_wrap(mut self, var: &str, ncol: Option<usize>) -> Self {
924 self.facet = Facet::Wrap {
925 var: var.to_string(),
926 ncol,
927 scales: FacetScales::Fixed,
928 labeller: FacetLabeller::default(),
929 };
930 self
931 }
932
933 pub fn facet_wrap_free(mut self, var: &str, ncol: Option<usize>, scales: FacetScales) -> Self {
934 self.facet = Facet::Wrap {
935 var: var.to_string(),
936 ncol,
937 scales,
938 labeller: FacetLabeller::default(),
939 };
940 self
941 }
942
943 pub fn facet_wrap_labeller(
944 mut self,
945 var: &str,
946 ncol: Option<usize>,
947 labeller: FacetLabeller,
948 ) -> Self {
949 self.facet = Facet::Wrap {
950 var: var.to_string(),
951 ncol,
952 scales: FacetScales::Fixed,
953 labeller,
954 };
955 self
956 }
957
958 pub fn facet_grid(mut self, row: Option<&str>, col: Option<&str>) -> Self {
959 self.facet = Facet::Grid {
960 row_var: row.map(String::from),
961 col_var: col.map(String::from),
962 scales: FacetScales::Fixed,
963 labeller: FacetLabeller::default(),
964 };
965 self
966 }
967
968 pub fn facet_grid_free(
969 mut self,
970 row: Option<&str>,
971 col: Option<&str>,
972 scales: FacetScales,
973 ) -> Self {
974 self.facet = Facet::Grid {
975 row_var: row.map(String::from),
976 col_var: col.map(String::from),
977 scales,
978 labeller: FacetLabeller::default(),
979 };
980 self
981 }
982
983 pub fn facet_grid_labeller(
984 mut self,
985 row: Option<&str>,
986 col: Option<&str>,
987 labeller: FacetLabeller,
988 ) -> Self {
989 self.facet = Facet::Grid {
990 row_var: row.map(String::from),
991 col_var: col.map(String::from),
992 scales: FacetScales::Fixed,
993 labeller,
994 };
995 self
996 }
997
998 pub fn coord_flip(mut self) -> Self {
1001 self.coord = Box::new(CoordFlip);
1002 self
1003 }
1004
1005 pub fn coord_fixed(mut self, ratio: f64) -> Self {
1006 self.coord = Box::new(CoordFixed::new(ratio));
1007 self
1008 }
1009
1010 pub fn coord_cartesian_zoom(
1012 mut self,
1013 xlim: Option<(f64, f64)>,
1014 ylim: Option<(f64, f64)>,
1015 ) -> Self {
1016 let mut c = CoordCartesian::new();
1017 if let Some((min, max)) = xlim {
1018 c = c.xlim(min, max);
1019 }
1020 if let Some((min, max)) = ylim {
1021 c = c.ylim(min, max);
1022 }
1023 self.coord = Box::new(c);
1024 self
1025 }
1026
1027 pub fn coord_polar(mut self) -> Self {
1028 self.coord = Box::new(CoordPolar::new());
1029 self
1030 }
1031
1032 pub fn coord_polar_with(mut self, coord: CoordPolar) -> Self {
1033 self.coord = Box::new(coord);
1034 self
1035 }
1036
1037 pub fn theme(mut self, theme: Theme) -> Self {
1040 self.theme = theme;
1041 self
1042 }
1043
1044 pub fn primary_color(mut self, color: (u8, u8, u8)) -> Self {
1048 self.theme.primary = Some(color);
1049 self
1050 }
1051
1052 pub fn theme_minimal(mut self) -> Self {
1053 self.theme = crate::theme::presets::theme_minimal();
1054 self
1055 }
1056
1057 pub fn theme_bw(mut self) -> Self {
1058 self.theme = crate::theme::presets::theme_bw();
1059 self
1060 }
1061
1062 pub fn theme_gray(mut self) -> Self {
1063 self.theme = crate::theme::presets::theme_gray();
1064 self
1065 }
1066
1067 pub fn theme_classic(mut self) -> Self {
1068 self.theme = crate::theme::presets::theme_classic();
1069 self
1070 }
1071
1072 pub fn theme_linedraw(mut self) -> Self {
1073 self.theme = crate::theme::presets::theme_linedraw();
1074 self
1075 }
1076
1077 pub fn theme_light(mut self) -> Self {
1078 self.theme = crate::theme::presets::theme_light();
1079 self
1080 }
1081
1082 pub fn theme_dark(mut self) -> Self {
1083 self.theme = crate::theme::presets::theme_dark();
1084 self
1085 }
1086
1087 pub fn theme_void(mut self) -> Self {
1088 self.theme = crate::theme::presets::theme_void();
1089 self
1090 }
1091
1092 pub fn theme_update(mut self, update: crate::theme::ThemeUpdate) -> Self {
1095 self.theme = self.theme.update(update);
1096 self
1097 }
1098
1099 pub fn guides(mut self, guide: crate::guide::config::GuideLegend) -> Self {
1103 self.guide_legend = guide;
1104 self
1105 }
1106
1107 pub fn labs(mut self, labels: Labels) -> Self {
1110 if labels.title.is_some() {
1111 self.labels.title = labels.title;
1112 }
1113 if labels.subtitle.is_some() {
1114 self.labels.subtitle = labels.subtitle;
1115 }
1116 if labels.x.is_some() {
1117 self.labels.x = labels.x;
1118 }
1119 if labels.y.is_some() {
1120 self.labels.y = labels.y;
1121 }
1122 if labels.caption.is_some() {
1123 self.labels.caption = labels.caption;
1124 }
1125 self
1126 }
1127
1128 pub fn title(mut self, title: &str) -> Self {
1129 self.labels.title = Some(title.to_string());
1130 self
1131 }
1132
1133 pub fn subtitle(mut self, subtitle: &str) -> Self {
1134 self.labels.subtitle = Some(subtitle.to_string());
1135 self
1136 }
1137
1138 pub fn xlab(mut self, label: &str) -> Self {
1139 self.labels.x = Some(label.to_string());
1140 self
1141 }
1142
1143 pub fn ylab(mut self, label: &str) -> Self {
1144 self.labels.y = Some(label.to_string());
1145 self
1146 }
1147
1148 pub fn caption(mut self, caption: &str) -> Self {
1149 self.labels.caption = Some(caption.to_string());
1150 self
1151 }
1152
1153 pub fn annotate(mut self, annotation: Annotation) -> Self {
1157 self.annotations.push(annotation);
1158 self
1159 }
1160
1161 pub fn annotate_text(self, label: &str, x: f64, y: f64) -> Self {
1163 self.annotate(Annotation::text(label, x, y))
1164 }
1165
1166 pub fn annotate_rect(self, xmin: f64, xmax: f64, ymin: f64, ymax: f64) -> Self {
1168 self.annotate(Annotation::rect(xmin, xmax, ymin, ymax))
1169 }
1170
1171 pub fn annotate_segment(self, x: f64, y: f64, xend: f64, yend: f64) -> Self {
1173 self.annotate(Annotation::segment(x, y, xend, yend))
1174 }
1175
1176 pub fn try_build(self) -> Result<crate::build::BuiltPlot, GGError> {
1180 PlotBuilder::build(self)
1181 }
1182
1183 pub fn build(self) -> crate::build::BuiltPlot {
1187 self.try_build().expect("plot build failed")
1188 }
1189
1190 pub fn save(self, path: &str) -> Result<(), GGError> {
1192 self.save_with_size(path, 800, 600)
1193 }
1194
1195 pub fn save_with_size(self, path: &str, w: u32, h: u32) -> Result<(), GGError> {
1197 let (built, layout) = self.prepare(w, h)?;
1198
1199 let ext = path.rsplit('.').next().unwrap_or("svg").to_lowercase();
1201
1202 match ext.as_str() {
1203 "svg" => {
1204 let backend = plotters::prelude::SVGBackend::new(path, (w, h));
1205 Self::render_into(backend.into_drawing_area(), &built, &layout)?;
1206 }
1207 "png" | "bmp" | "gif" | "jpeg" | "jpg" | "tiff" => {
1208 let backend = plotters::prelude::BitMapBackend::new(path, (w, h));
1209 Self::render_into(backend.into_drawing_area(), &built, &layout)?;
1210 }
1211 _ => {
1212 return Err(GGError::UnsupportedFormat(ext));
1213 }
1214 }
1215
1216 Ok(())
1217 }
1218
1219 pub fn render_svg(self) -> Result<String, GGError> {
1224 self.render_svg_with_size(800, 600)
1225 }
1226
1227 pub fn render_svg_with_size(self, w: u32, h: u32) -> Result<String, GGError> {
1229 let (built, layout) = self.prepare(w, h)?;
1230 let mut buf = String::new();
1231 {
1232 let backend = plotters::prelude::SVGBackend::with_string(&mut buf, (w, h));
1233 Self::render_into(backend.into_drawing_area(), &built, &layout)?;
1234 }
1235 Ok(buf)
1236 }
1237
1238 pub fn render_png(self) -> Result<Vec<u8>, GGError> {
1243 self.render_png_with_size(800, 600)
1244 }
1245
1246 pub fn render_png_with_size(self, w: u32, h: u32) -> Result<Vec<u8>, GGError> {
1248 let (built, layout) = self.prepare(w, h)?;
1249
1250 let mut rgb = vec![0u8; (w as usize) * (h as usize) * 3];
1253 {
1254 let backend = plotters::prelude::BitMapBackend::with_buffer(&mut rgb, (w, h));
1255 Self::render_into(backend.into_drawing_area(), &built, &layout)?;
1256 }
1257
1258 let img = image::RgbImage::from_raw(w, h, rgb).ok_or_else(|| {
1259 GGError::Render(RenderError::BackendError(
1260 "PNG buffer size mismatch".to_string(),
1261 ))
1262 })?;
1263 let mut out = std::io::Cursor::new(Vec::new());
1264 img.write_to(&mut out, image::ImageOutputFormat::Png)
1265 .map_err(|e| GGError::Render(RenderError::BackendError(format!("{:?}", e))))?;
1266 Ok(out.into_inner())
1267 }
1268
1269 fn prepare(self, w: u32, h: u32) -> Result<(crate::build::BuiltPlot, PlotLayout), GGError> {
1271 let plot = self;
1272
1273 let has_title = plot.labels.title.is_some();
1274 let has_subtitle = plot.labels.subtitle.is_some();
1275 let has_caption = plot.labels.caption.is_some();
1276 let has_legend = plot.has_legend_mapping();
1277 let x_label = plot.labels.x.clone();
1278 let y_label = plot.labels.y.clone();
1279
1280 let mut built = PlotBuilder::build(plot)?;
1281
1282 if let Some(ref label) = x_label {
1284 if let Some(s) = built.scales.get_mut(&crate::aes::Aesthetic::X) {
1285 s.set_name(label);
1286 }
1287 }
1288 if let Some(ref label) = y_label {
1289 if let Some(s) = built.scales.get_mut(&crate::aes::Aesthetic::Y) {
1290 s.set_name(label);
1291 }
1292 }
1293
1294 let layout = PlotLayout::compute_full(
1295 w as f64,
1296 h as f64,
1297 &built.theme,
1298 has_title,
1299 has_subtitle,
1300 has_caption,
1301 has_legend,
1302 );
1303
1304 Ok((built, layout))
1305 }
1306
1307 fn render_into<DB>(
1309 area: plotters::drawing::DrawingArea<DB, plotters::coord::Shift>,
1310 built: &crate::build::BuiltPlot,
1311 layout: &PlotLayout,
1312 ) -> Result<(), GGError>
1313 where
1314 DB: plotters::prelude::DrawingBackend,
1315 DB::ErrorType: 'static,
1316 {
1317 area.fill(&plotters::prelude::WHITE)
1318 .map_err(|e| GGError::Render(RenderError::BackendError(format!("{:?}", e))))?;
1319 let mut adapter = PlottersAdapter::new(&area, layout.plot_area.clone());
1320 PlotRenderer::render(built, &mut adapter).map_err(GGError::Render)?;
1321 area.present()
1322 .map_err(|e| GGError::Render(RenderError::BackendError(format!("{:?}", e))))?;
1323 Ok(())
1324 }
1325
1326 pub fn ggsave(
1328 self,
1329 path: &str,
1330 width_inches: f64,
1331 height_inches: f64,
1332 dpi: f64,
1333 ) -> Result<(), GGError> {
1334 let w = (width_inches * dpi) as u32;
1335 let h = (height_inches * dpi) as u32;
1336 self.save_with_size(path, w, h)
1337 }
1338
1339 fn has_legend_mapping(&self) -> bool {
1340 self.mapping.mappings.iter().any(|m| {
1341 matches!(
1342 m.aesthetic,
1343 crate::aes::Aesthetic::Color
1344 | crate::aes::Aesthetic::Fill
1345 | crate::aes::Aesthetic::Shape
1346 | crate::aes::Aesthetic::Linetype
1347 | crate::aes::Aesthetic::Size
1348 | crate::aes::Aesthetic::Alpha
1349 )
1350 })
1351 }
1352}
1353
1354#[derive(Debug)]
1356pub enum GGError {
1357 Render(RenderError),
1358 UnsupportedFormat(String),
1359 Io(std::io::Error),
1360 ValidationError(String),
1361}
1362
1363impl std::fmt::Display for GGError {
1364 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1365 match self {
1366 GGError::Render(e) => write!(f, "Render error: {e}"),
1367 GGError::UnsupportedFormat(ext) => write!(f, "Unsupported output format: {ext}"),
1368 GGError::Io(e) => write!(f, "IO error: {e}"),
1369 GGError::ValidationError(msg) => write!(f, "Validation error: {msg}"),
1370 }
1371 }
1372}
1373
1374impl std::error::Error for GGError {}