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, FacetSpace};
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 pub tag: Option<String>,
71}
72
73pub struct Layer {
75 pub data: Option<DataFrame>,
76 pub mapping: Aes,
77 pub geom: Box<dyn Geom>,
78 pub stat: Box<dyn Stat>,
79 pub position: Box<dyn Position>,
80 pub params: GeomParams,
81 pub show_legend: Option<bool>,
82}
83
84pub struct GGPlot {
86 pub(crate) data: DataFrame,
87 pub(crate) mapping: Aes,
88 pub(crate) layers: Vec<Layer>,
89 pub(crate) scales: Vec<Box<dyn Scale>>,
90 pub(crate) coord: Box<dyn Coord>,
91 pub(crate) theme: Theme,
92 pub(crate) labels: Labels,
93 pub(crate) facet: Facet,
94 pub(crate) annotations: Vec<Annotation>,
95 pub(crate) guide_legend: crate::guide::config::GuideLegend,
96}
97
98impl GGPlot {
99 pub fn new(data: impl GGData) -> Self {
101 GGPlot {
102 data: data.into_dataframe(),
103 mapping: Aes::default(),
104 layers: Vec::new(),
105 scales: Vec::new(),
106 coord: Box::new(CoordCartesian::new()),
107 theme: Theme::default(),
108 labels: Labels::default(),
109 facet: Facet::default(),
110 annotations: Vec::new(),
111 guide_legend: crate::guide::config::GuideLegend::default(),
112 }
113 }
114
115 pub fn aes(mut self, mapping: Aes) -> Self {
117 self.mapping = mapping;
118 self
119 }
120
121 pub fn geom_point(self) -> Self {
124 self.add_geom(GeomPoint::default())
125 }
126
127 pub fn geom_point_with(self, geom: GeomPoint) -> Self {
128 self.add_geom(geom)
129 }
130
131 pub fn geom_line(self) -> Self {
132 self.add_geom(GeomLine::default())
133 }
134
135 pub fn geom_line_with(self, geom: GeomLine) -> Self {
136 self.add_geom(geom)
137 }
138
139 pub fn geom_bar(self) -> Self {
140 self.add_geom(GeomBar::default())
141 }
142
143 pub fn geom_bar_with(self, geom: GeomBar) -> Self {
144 self.add_geom(geom)
145 }
146
147 pub fn geom_histogram(self) -> Self {
148 self.add_geom(GeomHistogram::default())
149 }
150
151 pub fn geom_histogram_with(self, geom: GeomHistogram) -> Self {
152 self.add_geom(geom)
153 }
154
155 pub fn geom_boxplot(self) -> Self {
156 self.add_geom(GeomBoxplot::default())
157 }
158
159 pub fn geom_boxplot_with(self, geom: GeomBoxplot) -> Self {
160 self.add_geom(geom)
161 }
162
163 pub fn geom_smooth(self) -> Self {
164 self.add_geom(GeomSmooth::default())
165 }
166
167 pub fn geom_smooth_with(self, geom: GeomSmooth) -> Self {
168 self.add_geom(geom)
169 }
170
171 pub fn geom_col(self) -> Self {
172 self.add_geom(GeomCol::default())
173 }
174
175 pub fn geom_col_with(self, geom: GeomCol) -> Self {
176 self.add_geom(geom)
177 }
178
179 pub fn geom_hline(self, yintercept: f64) -> Self {
180 self.add_geom(GeomHline::new(yintercept))
181 }
182
183 pub fn geom_hline_with(self, geom: GeomHline) -> Self {
185 self.add_geom(geom)
186 }
187
188 pub fn geom_vline(self, xintercept: f64) -> Self {
189 self.add_geom(GeomVline::new(xintercept))
190 }
191
192 pub fn geom_vline_with(self, geom: GeomVline) -> Self {
194 self.add_geom(geom)
195 }
196
197 pub fn geom_abline(self, slope: f64, intercept: f64) -> Self {
198 self.add_geom(GeomAbline::new(slope, intercept))
199 }
200
201 pub fn geom_abline_with(self, geom: GeomAbline) -> Self {
203 self.add_geom(geom)
204 }
205
206 pub fn geom_text(self) -> Self {
207 self.add_geom(GeomText::default())
208 }
209
210 pub fn geom_text_with(self, geom: GeomText) -> Self {
211 self.add_geom(geom)
212 }
213
214 pub fn geom_label(self) -> Self {
215 self.add_geom(GeomLabel::default())
216 }
217
218 pub fn geom_label_with(self, geom: GeomLabel) -> Self {
219 self.add_geom(geom)
220 }
221
222 pub fn geom_area(self) -> Self {
223 self.add_geom(GeomArea::default())
224 }
225
226 pub fn geom_area_with(self, geom: GeomArea) -> Self {
227 self.add_geom(geom)
228 }
229
230 pub fn geom_ribbon(self) -> Self {
231 self.add_geom(GeomRibbon::default())
232 }
233
234 pub fn geom_ribbon_with(self, geom: GeomRibbon) -> Self {
235 self.add_geom(geom)
236 }
237
238 pub fn geom_errorbar(self) -> Self {
239 self.add_geom(GeomErrorbar::default())
240 }
241
242 pub fn geom_errorbar_with(self, geom: GeomErrorbar) -> Self {
243 self.add_geom(geom)
244 }
245
246 pub fn geom_segment(self) -> Self {
247 self.add_geom(GeomSegment::default())
248 }
249
250 pub fn geom_segment_with(self, geom: GeomSegment) -> Self {
251 self.add_geom(geom)
252 }
253
254 pub fn geom_density(self) -> Self {
255 self.add_geom(GeomDensity::default())
256 }
257
258 pub fn geom_density_with(self, geom: GeomDensity) -> Self {
259 self.add_geom(geom)
260 }
261
262 pub fn geom_rug(self) -> Self {
263 self.add_geom(GeomRug::default())
264 }
265
266 pub fn geom_rug_with(self, geom: GeomRug) -> Self {
267 self.add_geom(geom)
268 }
269
270 pub fn geom_jitter(self) -> Self {
271 self.add_geom(GeomJitter::default())
272 }
273
274 pub fn geom_jitter_with(self, geom: GeomJitter) -> Self {
275 self.add_geom(geom)
276 }
277
278 pub fn geom_path(self) -> Self {
279 self.add_geom(GeomPath::default())
280 }
281
282 pub fn geom_path_with(self, geom: GeomPath) -> Self {
283 self.add_geom(geom)
284 }
285
286 pub fn stat_ellipse(self) -> Self {
288 self.geom_path()
289 .stat(crate::stat::ellipse::StatEllipse::default())
290 }
291
292 pub fn stat_ellipse_level(self, level: f64) -> Self {
294 self.geom_path()
295 .stat(crate::stat::ellipse::StatEllipse::new(level))
296 }
297
298 #[cfg(feature = "regression")]
301 pub fn stat_quantile(mut self, taus: &[f64]) -> Self {
302 for &tau in taus {
303 self = self
304 .geom_path()
305 .stat(crate::stat::quantile::StatQuantile::new(tau));
306 }
307 self
308 }
309
310 #[cfg(feature = "regression")]
312 pub fn geom_quantile(self) -> Self {
313 self.stat_quantile(&[0.25, 0.5, 0.75])
314 }
315
316 pub fn geom_step(self) -> Self {
317 self.add_geom(GeomStep::default())
318 }
319
320 pub fn geom_step_with(self, geom: GeomStep) -> Self {
321 self.add_geom(geom)
322 }
323
324 pub fn geom_freqpoly(self) -> Self {
325 self.add_geom(GeomFreqpoly::default())
326 }
327
328 pub fn geom_freqpoly_with(self, geom: GeomFreqpoly) -> Self {
329 self.add_geom(geom)
330 }
331
332 pub fn geom_linerange(self) -> Self {
333 self.add_geom(GeomLinerange::default())
334 }
335
336 pub fn geom_linerange_with(self, geom: GeomLinerange) -> Self {
337 self.add_geom(geom)
338 }
339
340 pub fn geom_pointrange(self) -> Self {
341 self.add_geom(GeomPointrange::default())
342 }
343
344 pub fn geom_pointrange_with(self, geom: GeomPointrange) -> Self {
345 self.add_geom(geom)
346 }
347
348 pub fn geom_crossbar(self) -> Self {
349 self.add_geom(GeomCrossbar::default())
350 }
351
352 pub fn geom_crossbar_with(self, geom: GeomCrossbar) -> Self {
353 self.add_geom(geom)
354 }
355
356 pub fn geom_spoke(self) -> Self {
357 self.add_geom(GeomSpoke::default())
358 }
359
360 pub fn geom_spoke_with(self, geom: GeomSpoke) -> Self {
361 self.add_geom(geom)
362 }
363
364 pub fn geom_rect(self) -> Self {
365 self.add_geom(GeomRect::default())
366 }
367
368 pub fn geom_rect_with(self, geom: GeomRect) -> Self {
369 self.add_geom(geom)
370 }
371
372 pub fn geom_tile(self) -> Self {
373 self.add_geom(GeomTile::default())
374 }
375
376 pub fn geom_tile_with(self, geom: GeomTile) -> Self {
377 self.add_geom(geom)
378 }
379
380 pub fn geom_raster(self) -> Self {
382 self.add_geom(crate::geom::raster::GeomRaster::default())
383 }
384
385 pub fn geom_raster_with(self, geom: crate::geom::raster::GeomRaster) -> Self {
386 self.add_geom(geom)
387 }
388
389 pub fn geom_polygon(self) -> Self {
390 self.add_geom(GeomPolygon::default())
391 }
392
393 pub fn geom_polygon_with(self, geom: GeomPolygon) -> Self {
394 self.add_geom(geom)
395 }
396
397 pub fn geom_curve(self) -> Self {
398 self.add_geom(GeomCurve::default())
399 }
400
401 pub fn geom_curve_with(self, geom: GeomCurve) -> Self {
402 self.add_geom(geom)
403 }
404
405 pub fn geom_violin(self) -> Self {
406 self.add_geom(GeomViolin::default())
407 }
408
409 pub fn geom_violin_with(self, geom: GeomViolin) -> Self {
410 self.add_geom(geom)
411 }
412
413 pub fn geom_dotplot(self) -> Self {
414 self.add_geom(GeomDotplot::default())
415 }
416
417 pub fn geom_dotplot_with(self, geom: GeomDotplot) -> Self {
418 self.add_geom(geom)
419 }
420
421 pub fn geom_qq(self) -> Self {
422 self.add_geom(GeomQQ::default())
423 }
424
425 pub fn geom_qq_with(self, geom: GeomQQ) -> Self {
426 self.add_geom(geom)
427 }
428
429 pub fn geom_qq_line(self) -> Self {
430 self.add_geom(GeomQQLine::default())
431 }
432
433 pub fn geom_qq_line_with(self, geom: GeomQQLine) -> Self {
434 self.add_geom(geom)
435 }
436
437 pub fn geom_bin2d(self) -> Self {
438 self.add_geom(GeomBin2d::default())
439 }
440
441 pub fn geom_bin2d_with(self, geom: GeomBin2d) -> Self {
442 self.add_geom(geom)
443 }
444
445 pub fn geom_hex(self) -> Self {
446 self.add_geom(GeomHex::default())
447 }
448
449 pub fn geom_hex_with(self, geom: GeomHex) -> Self {
450 self.add_geom(geom)
451 }
452
453 pub fn geom_count(self) -> Self {
454 self.add_geom(GeomCount::default())
455 }
456
457 pub fn geom_count_with(self, geom: GeomCount) -> Self {
458 self.add_geom(geom)
459 }
460
461 pub fn geom_contour(self) -> Self {
462 self.add_geom(GeomContour::default())
463 }
464
465 pub fn geom_contour_with(self, geom: GeomContour) -> Self {
466 self.add_geom(geom)
467 }
468
469 pub fn geom_contour_filled(self) -> Self {
472 self.add_geom(GeomPolygon {
473 line_width: 0.0,
474 alpha: 1.0,
475 ..GeomPolygon::default()
476 })
477 .stat(crate::stat::contour_filled::StatContourFilled::default())
478 }
479
480 pub fn geom_density2d(self) -> Self {
481 self.add_geom(GeomDensity2d::default())
482 }
483
484 pub fn geom_density2d_with(self, geom: GeomDensity2d) -> Self {
485 self.add_geom(geom)
486 }
487
488 pub fn geom_blank(self) -> Self {
489 self.add_geom(GeomBlank)
490 }
491
492 fn add_geom(mut self, geom: impl Geom + 'static) -> Self {
493 let stat = geom.default_stat();
494 let position = geom.default_position();
495 let params = geom.default_params();
496 self.layers.push(Layer {
497 data: None,
498 mapping: Aes::default(),
499 geom: Box::new(geom),
500 stat,
501 position,
502 params,
503 show_legend: None,
504 });
505 self
506 }
507
508 pub fn stat(mut self, stat: impl Stat + 'static) -> Self {
512 if let Some(layer) = self.layers.last_mut() {
513 layer.stat = Box::new(stat);
514 }
515 self
516 }
517
518 pub fn position(mut self, pos: impl Position + 'static) -> Self {
520 if let Some(layer) = self.layers.last_mut() {
521 layer.position = Box::new(pos);
522 }
523 self
524 }
525
526 pub fn layer_data(mut self, data: impl GGData) -> Self {
528 if let Some(layer) = self.layers.last_mut() {
529 layer.data = Some(data.into_dataframe());
530 }
531 self
532 }
533
534 pub fn layer_aes(mut self, mapping: Aes) -> Self {
536 if let Some(layer) = self.layers.last_mut() {
537 layer.mapping = mapping;
538 }
539 self
540 }
541
542 pub fn show_legend(mut self, show: bool) -> Self {
545 if let Some(layer) = self.layers.last_mut() {
546 layer.show_legend = Some(show);
547 }
548 self
549 }
550
551 pub fn scale_x_continuous(mut self, s: ScaleContinuous) -> Self {
554 let s = s.for_aesthetic(crate::aes::Aesthetic::X);
555 self.scales.push(Box::new(s));
556 self
557 }
558
559 pub fn scale_y_continuous(mut self, s: ScaleContinuous) -> Self {
560 let s = s.for_aesthetic(crate::aes::Aesthetic::Y);
561 self.scales.push(Box::new(s));
562 self
563 }
564
565 pub fn scale_x_discrete(mut self, s: crate::scale::discrete::ScaleDiscrete) -> Self {
566 let s = s.for_aesthetic(crate::aes::Aesthetic::X);
567 self.scales.push(Box::new(s));
568 self
569 }
570
571 pub fn scale_y_discrete(mut self, s: crate::scale::discrete::ScaleDiscrete) -> Self {
572 let s = s.for_aesthetic(crate::aes::Aesthetic::Y);
573 self.scales.push(Box::new(s));
574 self
575 }
576
577 pub fn scale_color(mut self, s: impl Scale + 'static) -> Self {
578 self.scales.push(Box::new(s));
579 self
580 }
581
582 pub fn scale_fill(mut self, s: impl Scale + 'static) -> Self {
583 self.scales.push(Box::new(s));
584 self
585 }
586
587 pub fn scale_color_manual(self, values: Vec<(&str, crate::scale::color::RGBAColor)>) -> Self {
588 let s = crate::scale::manual::ScaleManual::new(crate::aes::Aesthetic::Color, values);
589 self.scale_color(s)
590 }
591
592 pub fn scale_fill_manual(self, values: Vec<(&str, crate::scale::color::RGBAColor)>) -> Self {
593 let s = crate::scale::manual::ScaleManual::new(crate::aes::Aesthetic::Fill, values);
594 self.scale_fill(s)
595 }
596
597 pub fn scale_color_viridis(self) -> Self {
598 use crate::scale::color::ScaleColorDiscrete;
599 use crate::scale::palettes::PaletteName;
600 let s = ScaleColorDiscrete::new(crate::aes::Aesthetic::Color)
601 .with_named_palette(&PaletteName::Viridis);
602 self.scale_color(s)
603 }
604
605 pub fn scale_color_brewer(self, name: crate::scale::palettes::PaletteName) -> Self {
606 use crate::scale::color::ScaleColorDiscrete;
607 let s = ScaleColorDiscrete::new(crate::aes::Aesthetic::Color).with_named_palette(&name);
608 self.scale_color(s)
609 }
610
611 pub fn scale_color_gradient(
612 self,
613 low: crate::scale::color::RGBAColor,
614 high: crate::scale::color::RGBAColor,
615 ) -> Self {
616 use crate::scale::color::ScaleColorContinuous;
617 let s = ScaleColorContinuous::new(crate::aes::Aesthetic::Color).with_colors(low, high);
618 self.scale_color(s)
619 }
620
621 pub fn scale_fill_gradient(
622 self,
623 low: crate::scale::color::RGBAColor,
624 high: crate::scale::color::RGBAColor,
625 ) -> Self {
626 use crate::scale::color::ScaleColorContinuous;
627 let s = ScaleColorContinuous::new(crate::aes::Aesthetic::Fill).with_colors(low, high);
628 self.scale_fill(s)
629 }
630
631 pub fn scale_color_gradient2(
632 self,
633 low: crate::scale::color::RGBAColor,
634 mid: crate::scale::color::RGBAColor,
635 high: crate::scale::color::RGBAColor,
636 ) -> Self {
637 use crate::scale::gradient::ScaleColorGradient2;
638 let s = ScaleColorGradient2::new(crate::aes::Aesthetic::Color).with_colors(low, mid, high);
639 self.scale_color(s)
640 }
641
642 pub fn scale_fill_gradient2(
643 self,
644 low: crate::scale::color::RGBAColor,
645 mid: crate::scale::color::RGBAColor,
646 high: crate::scale::color::RGBAColor,
647 ) -> Self {
648 use crate::scale::gradient::ScaleColorGradient2;
649 let s = ScaleColorGradient2::new(crate::aes::Aesthetic::Fill).with_colors(low, mid, high);
650 self.scale_fill(s)
651 }
652
653 pub fn scale_fill_viridis(self) -> Self {
654 use crate::scale::color::ScaleColorDiscrete;
655 use crate::scale::palettes::PaletteName;
656 let s = ScaleColorDiscrete::new(crate::aes::Aesthetic::Fill)
657 .with_named_palette(&PaletteName::Viridis);
658 self.scale_fill(s)
659 }
660
661 pub fn scale_color_viridis_c(self) -> Self {
663 use crate::scale::gradient_n::ScaleColorGradientN;
664 let s = ScaleColorGradientN::viridis(crate::aes::Aesthetic::Color);
665 self.scale_color(s)
666 }
667
668 pub fn scale_fill_viridis_c(self) -> Self {
670 use crate::scale::gradient_n::ScaleColorGradientN;
671 let s = ScaleColorGradientN::viridis(crate::aes::Aesthetic::Fill);
672 self.scale_fill(s)
673 }
674
675 pub fn scale_color_gradientn(self, stops: Vec<(f64, crate::scale::color::RGBAColor)>) -> Self {
677 use crate::scale::gradient_n::ScaleColorGradientN;
678 let s = ScaleColorGradientN::new(crate::aes::Aesthetic::Color, stops);
679 self.scale_color(s)
680 }
681
682 pub fn scale_fill_gradientn(self, stops: Vec<(f64, crate::scale::color::RGBAColor)>) -> Self {
684 use crate::scale::gradient_n::ScaleColorGradientN;
685 let s = ScaleColorGradientN::new(crate::aes::Aesthetic::Fill, stops);
686 self.scale_fill(s)
687 }
688
689 pub fn scale_color_steps(
692 self,
693 low: crate::scale::color::RGBAColor,
694 high: crate::scale::color::RGBAColor,
695 n_bins: usize,
696 ) -> Self {
697 let s = crate::scale::steps::ScaleColorSteps::two(
698 crate::aes::Aesthetic::Color,
699 (low.r, low.g, low.b),
700 (high.r, high.g, high.b),
701 n_bins,
702 );
703 self.scale_color(s)
704 }
705
706 pub fn scale_color_stepsn(
708 self,
709 stops: Vec<crate::scale::color::RGBAColor>,
710 n_bins: usize,
711 ) -> Self {
712 let s = crate::scale::steps::ScaleColorSteps::new(
713 crate::aes::Aesthetic::Color,
714 stops.iter().map(|c| (c.r, c.g, c.b)).collect(),
715 n_bins,
716 );
717 self.scale_color(s)
718 }
719
720 pub fn scale_color_fermenter(
722 self,
723 name: crate::scale::palettes::PaletteName,
724 n_bins: usize,
725 ) -> Self {
726 let stops = crate::scale::palettes::palette(&name)
727 .iter()
728 .map(|c| (c.r, c.g, c.b))
729 .collect();
730 let s =
731 crate::scale::steps::ScaleColorSteps::new(crate::aes::Aesthetic::Color, stops, n_bins);
732 self.scale_color(s)
733 }
734
735 pub fn scale_fill_steps(
737 self,
738 low: crate::scale::color::RGBAColor,
739 high: crate::scale::color::RGBAColor,
740 n_bins: usize,
741 ) -> Self {
742 let s = crate::scale::steps::ScaleColorSteps::two(
743 crate::aes::Aesthetic::Fill,
744 (low.r, low.g, low.b),
745 (high.r, high.g, high.b),
746 n_bins,
747 );
748 self.scale_fill(s)
749 }
750
751 pub fn scale_fill_fermenter(
753 self,
754 name: crate::scale::palettes::PaletteName,
755 n_bins: usize,
756 ) -> Self {
757 let stops = crate::scale::palettes::palette(&name)
758 .iter()
759 .map(|c| (c.r, c.g, c.b))
760 .collect();
761 let s =
762 crate::scale::steps::ScaleColorSteps::new(crate::aes::Aesthetic::Fill, stops, n_bins);
763 self.scale_fill(s)
764 }
765
766 pub fn scale_fill_brewer(self, name: crate::scale::palettes::PaletteName) -> Self {
767 use crate::scale::color::ScaleColorDiscrete;
768 let s = ScaleColorDiscrete::new(crate::aes::Aesthetic::Fill).with_named_palette(&name);
769 self.scale_fill(s)
770 }
771
772 pub fn scale_linetype_manual(
773 self,
774 values: Vec<(&str, crate::render::backend::Linetype)>,
775 ) -> Self {
776 let s = crate::scale::linetype_manual::ScaleLinetypeManual::new(values);
777 self.scale_color(s)
778 }
779
780 pub fn scale_shape_manual(
781 self,
782 values: Vec<(&str, crate::render::backend::PointShape)>,
783 ) -> Self {
784 let s = crate::scale::shape_manual::ScaleShapeManual::new(values);
785 self.scale_color(s)
786 }
787
788 pub fn scale_color_grey(self) -> Self {
789 let s = crate::scale::grey::ScaleColorGrey::new(crate::aes::Aesthetic::Color);
790 self.scale_color(s)
791 }
792
793 pub fn scale_fill_grey(self) -> Self {
794 let s = crate::scale::grey::ScaleColorGrey::new(crate::aes::Aesthetic::Fill);
795 self.scale_fill(s)
796 }
797
798 pub fn scale_color_grey_with(self, s: crate::scale::grey::ScaleColorGrey) -> Self {
799 self.scale_color(s)
800 }
801
802 pub fn scale_fill_grey_with(self, s: crate::scale::grey::ScaleColorGrey) -> Self {
803 self.scale_fill(s)
804 }
805
806 pub fn scale_x_reverse(self) -> Self {
807 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Reverse))
808 }
809
810 pub fn scale_y_reverse(self) -> Self {
811 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Reverse))
812 }
813
814 pub fn scale_x_datetime(mut self, s: crate::scale::datetime::ScaleDateTime) -> Self {
815 let s = s.for_aesthetic(crate::aes::Aesthetic::X);
816 self.scales.push(Box::new(s));
817 self
818 }
819
820 pub fn scale_y_datetime(mut self, s: crate::scale::datetime::ScaleDateTime) -> Self {
821 let s = s.for_aesthetic(crate::aes::Aesthetic::Y);
822 self.scales.push(Box::new(s));
823 self
824 }
825
826 pub fn scale_size(mut self, s: crate::scale::size::ScaleSizeContinuous) -> Self {
827 self.scales.push(Box::new(s));
828 self
829 }
830
831 pub fn scale_alpha(mut self, s: crate::scale::alpha::ScaleAlphaContinuous) -> Self {
832 self.scales.push(Box::new(s));
833 self
834 }
835
836 pub fn xlim(self, min: f64, max: f64) -> Self {
837 self.scale_x_continuous(ScaleContinuous::new().with_limits(min, max))
838 }
839
840 pub fn ylim(self, min: f64, max: f64) -> Self {
841 self.scale_y_continuous(ScaleContinuous::new().with_limits(min, max))
842 }
843
844 pub fn scale_x_log10(self) -> Self {
845 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Log10))
846 }
847
848 pub fn scale_y_log10(self) -> Self {
849 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Log10))
850 }
851
852 pub fn scale_x_sqrt(self) -> Self {
853 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Sqrt))
854 }
855
856 pub fn scale_y_sqrt(self) -> Self {
857 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Sqrt))
858 }
859
860 pub fn scale_x_log2(self) -> Self {
861 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Log2))
862 }
863
864 pub fn scale_y_log2(self) -> Self {
865 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Log2))
866 }
867
868 pub fn scale_x_ln(self) -> Self {
869 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Ln))
870 }
871
872 pub fn scale_y_ln(self) -> Self {
873 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Ln))
874 }
875
876 pub fn scale_x_logit(self) -> Self {
878 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Logit))
879 }
880
881 pub fn scale_y_logit(self) -> Self {
882 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Logit))
883 }
884
885 pub fn scale_x_probit(self) -> Self {
887 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Probit))
888 }
889
890 pub fn scale_y_probit(self) -> Self {
891 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Probit))
892 }
893
894 pub fn scale_x_pseudo_log(self) -> Self {
896 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::PseudoLog))
897 }
898
899 pub fn scale_y_pseudo_log(self) -> Self {
900 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::PseudoLog))
901 }
902
903 pub fn scale_x_reciprocal(self) -> Self {
905 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Reciprocal))
906 }
907
908 pub fn scale_y_reciprocal(self) -> Self {
909 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Reciprocal))
910 }
911
912 pub fn scale_x_exp(self) -> Self {
914 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Exp))
915 }
916
917 pub fn scale_y_exp(self) -> Self {
918 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Exp))
919 }
920
921 pub fn scale_x_boxcox(self, lambda: f64) -> Self {
923 self.scale_x_continuous(
924 ScaleContinuous::new().with_transform(ScaleTransform::BoxCox(lambda)),
925 )
926 }
927
928 pub fn scale_y_boxcox(self, lambda: f64) -> Self {
929 self.scale_y_continuous(
930 ScaleContinuous::new().with_transform(ScaleTransform::BoxCox(lambda)),
931 )
932 }
933
934 pub fn facet_wrap(mut self, var: &str, ncol: Option<usize>) -> Self {
937 self.facet = Facet::Wrap {
938 var: var.to_string(),
939 ncol,
940 scales: FacetScales::Fixed,
941 labeller: FacetLabeller::default(),
942 };
943 self
944 }
945
946 pub fn facet_wrap_free(mut self, var: &str, ncol: Option<usize>, scales: FacetScales) -> Self {
947 self.facet = Facet::Wrap {
948 var: var.to_string(),
949 ncol,
950 scales,
951 labeller: FacetLabeller::default(),
952 };
953 self
954 }
955
956 pub fn facet_wrap_labeller(
957 mut self,
958 var: &str,
959 ncol: Option<usize>,
960 labeller: FacetLabeller,
961 ) -> Self {
962 self.facet = Facet::Wrap {
963 var: var.to_string(),
964 ncol,
965 scales: FacetScales::Fixed,
966 labeller,
967 };
968 self
969 }
970
971 pub fn facet_grid(mut self, row: Option<&str>, col: Option<&str>) -> Self {
972 self.facet = Facet::Grid {
973 row_var: row.map(String::from),
974 col_var: col.map(String::from),
975 scales: FacetScales::Fixed,
976 labeller: FacetLabeller::default(),
977 space: FacetSpace::Fixed,
978 };
979 self
980 }
981
982 pub fn facet_grid_free(
983 mut self,
984 row: Option<&str>,
985 col: Option<&str>,
986 scales: FacetScales,
987 ) -> Self {
988 self.facet = Facet::Grid {
989 row_var: row.map(String::from),
990 col_var: col.map(String::from),
991 scales,
992 labeller: FacetLabeller::default(),
993 space: FacetSpace::Fixed,
994 };
995 self
996 }
997
998 pub fn facet_grid_multi(
1002 mut self,
1003 row: Option<&str>,
1004 cols: &[&str],
1005 scales: FacetScales,
1006 space: FacetSpace,
1007 ) -> Self {
1008 let col_var = if cols.len() > 1 {
1009 let n = self.data.nrows();
1011 let mut combined = Vec::with_capacity(n);
1012 for i in 0..n {
1013 let parts: Vec<String> = cols
1014 .iter()
1015 .map(|c| {
1016 self.data
1017 .column(c)
1018 .and_then(|col| col.get(i))
1019 .map(|v| v.to_group_key())
1020 .unwrap_or_default()
1021 })
1022 .collect();
1023 combined.push(crate::data::Value::Str(parts.join(" . ")));
1024 }
1025 let name = "__facet_cols__".to_string();
1026 self.data.add_column(name.clone(), combined);
1027 Some(name)
1028 } else {
1029 cols.first().map(|s| s.to_string())
1030 };
1031 self.facet = Facet::Grid {
1032 row_var: row.map(String::from),
1033 col_var,
1034 scales,
1035 labeller: FacetLabeller::default(),
1036 space,
1037 };
1038 self
1039 }
1040
1041 pub fn facet_grid_space(
1044 mut self,
1045 row: Option<&str>,
1046 col: Option<&str>,
1047 scales: FacetScales,
1048 space: FacetSpace,
1049 ) -> Self {
1050 self.facet = Facet::Grid {
1051 row_var: row.map(String::from),
1052 col_var: col.map(String::from),
1053 scales,
1054 labeller: FacetLabeller::default(),
1055 space,
1056 };
1057 self
1058 }
1059
1060 pub fn facet_grid_labeller(
1061 mut self,
1062 row: Option<&str>,
1063 col: Option<&str>,
1064 labeller: FacetLabeller,
1065 ) -> Self {
1066 self.facet = Facet::Grid {
1067 row_var: row.map(String::from),
1068 col_var: col.map(String::from),
1069 scales: FacetScales::Fixed,
1070 labeller,
1071 space: FacetSpace::Fixed,
1072 };
1073 self
1074 }
1075
1076 pub fn coord_flip(mut self) -> Self {
1079 self.coord = Box::new(CoordFlip);
1080 self
1081 }
1082
1083 pub fn coord_fixed(mut self, ratio: f64) -> Self {
1084 self.coord = Box::new(CoordFixed::new(ratio));
1085 self
1086 }
1087
1088 pub fn coord_trans(mut self, x: Option<ScaleTransform>, y: Option<ScaleTransform>) -> Self {
1093 self.coord = Box::new(crate::coord::trans::CoordTrans::new(x, y));
1094 self
1095 }
1096
1097 pub fn coord_trans_y(self, y: ScaleTransform) -> Self {
1099 self.coord_trans(None, Some(y))
1100 }
1101
1102 pub fn coord_trans_x(self, x: ScaleTransform) -> Self {
1104 self.coord_trans(Some(x), None)
1105 }
1106
1107 pub fn coord_cartesian_zoom(
1109 mut self,
1110 xlim: Option<(f64, f64)>,
1111 ylim: Option<(f64, f64)>,
1112 ) -> Self {
1113 let mut c = CoordCartesian::new();
1114 if let Some((min, max)) = xlim {
1115 c = c.xlim(min, max);
1116 }
1117 if let Some((min, max)) = ylim {
1118 c = c.ylim(min, max);
1119 }
1120 self.coord = Box::new(c);
1121 self
1122 }
1123
1124 pub fn coord_polar(mut self) -> Self {
1125 self.coord = Box::new(CoordPolar::new());
1126 self
1127 }
1128
1129 pub fn coord_polar_with(mut self, coord: CoordPolar) -> Self {
1130 self.coord = Box::new(coord);
1131 self
1132 }
1133
1134 pub fn theme(mut self, theme: Theme) -> Self {
1137 self.theme = theme;
1138 self
1139 }
1140
1141 pub fn axis_text_x_angle(mut self, degrees: f64) -> Self {
1145 self.theme.axis_text_x.angle = degrees;
1146 self
1147 }
1148
1149 pub fn axis_text_y_angle(mut self, degrees: f64) -> Self {
1151 self.theme.axis_text_y.angle = degrees;
1152 self
1153 }
1154
1155 pub fn axis_text_x_dodge(mut self, n: usize) -> Self {
1158 self.theme.axis_text_x_dodge = n.max(1);
1159 self
1160 }
1161
1162 pub fn legend_position_inside(mut self, x: f64, y: f64) -> Self {
1169 self.theme.legend_position = crate::theme::LegendPosition::Inside(x, y);
1170 self
1171 }
1172
1173 pub fn primary_color(mut self, color: (u8, u8, u8)) -> Self {
1174 self.theme.primary = Some(color);
1175 self
1176 }
1177
1178 pub fn theme_minimal(mut self) -> Self {
1179 self.theme = crate::theme::presets::theme_minimal();
1180 self
1181 }
1182
1183 pub fn theme_bw(mut self) -> Self {
1184 self.theme = crate::theme::presets::theme_bw();
1185 self
1186 }
1187
1188 pub fn theme_gray(mut self) -> Self {
1189 self.theme = crate::theme::presets::theme_gray();
1190 self
1191 }
1192
1193 pub fn theme_classic(mut self) -> Self {
1194 self.theme = crate::theme::presets::theme_classic();
1195 self
1196 }
1197
1198 pub fn theme_linedraw(mut self) -> Self {
1199 self.theme = crate::theme::presets::theme_linedraw();
1200 self
1201 }
1202
1203 pub fn theme_light(mut self) -> Self {
1204 self.theme = crate::theme::presets::theme_light();
1205 self
1206 }
1207
1208 pub fn theme_dark(mut self) -> Self {
1209 self.theme = crate::theme::presets::theme_dark();
1210 self
1211 }
1212
1213 pub fn theme_void(mut self) -> Self {
1214 self.theme = crate::theme::presets::theme_void();
1215 self
1216 }
1217
1218 pub fn theme_update(mut self, update: crate::theme::ThemeUpdate) -> Self {
1221 self.theme = self.theme.update(update);
1222 self
1223 }
1224
1225 pub fn guides(mut self, guide: crate::guide::config::GuideLegend) -> Self {
1229 self.guide_legend = guide;
1230 self
1231 }
1232
1233 pub fn labs(mut self, labels: Labels) -> Self {
1236 if labels.title.is_some() {
1237 self.labels.title = labels.title;
1238 }
1239 if labels.subtitle.is_some() {
1240 self.labels.subtitle = labels.subtitle;
1241 }
1242 if labels.x.is_some() {
1243 self.labels.x = labels.x;
1244 }
1245 if labels.y.is_some() {
1246 self.labels.y = labels.y;
1247 }
1248 if labels.caption.is_some() {
1249 self.labels.caption = labels.caption;
1250 }
1251 if labels.tag.is_some() {
1252 self.labels.tag = labels.tag;
1253 }
1254 self
1255 }
1256
1257 pub fn title(mut self, title: &str) -> Self {
1258 self.labels.title = Some(title.to_string());
1259 self
1260 }
1261
1262 pub fn tag(mut self, tag: &str) -> Self {
1265 self.labels.tag = Some(tag.to_string());
1266 self
1267 }
1268
1269 pub fn subtitle(mut self, subtitle: &str) -> Self {
1270 self.labels.subtitle = Some(subtitle.to_string());
1271 self
1272 }
1273
1274 pub fn xlab(mut self, label: &str) -> Self {
1275 self.labels.x = Some(label.to_string());
1276 self
1277 }
1278
1279 pub fn ylab(mut self, label: &str) -> Self {
1280 self.labels.y = Some(label.to_string());
1281 self
1282 }
1283
1284 pub fn caption(mut self, caption: &str) -> Self {
1285 self.labels.caption = Some(caption.to_string());
1286 self
1287 }
1288
1289 pub fn annotate(mut self, annotation: Annotation) -> Self {
1293 self.annotations.push(annotation);
1294 self
1295 }
1296
1297 pub fn annotate_text(self, label: &str, x: f64, y: f64) -> Self {
1299 self.annotate(Annotation::text(label, x, y))
1300 }
1301
1302 pub fn annotate_rect(self, xmin: f64, xmax: f64, ymin: f64, ymax: f64) -> Self {
1304 self.annotate(Annotation::rect(xmin, xmax, ymin, ymax))
1305 }
1306
1307 pub fn annotate_segment(self, x: f64, y: f64, xend: f64, yend: f64) -> Self {
1309 self.annotate(Annotation::segment(x, y, xend, yend))
1310 }
1311
1312 pub fn try_build(self) -> Result<crate::build::BuiltPlot, GGError> {
1316 PlotBuilder::build(self)
1317 }
1318
1319 pub fn build(self) -> crate::build::BuiltPlot {
1323 self.try_build().expect("plot build failed")
1324 }
1325
1326 pub fn save(self, path: &str) -> Result<(), GGError> {
1328 self.save_with_size(path, 800, 600)
1329 }
1330
1331 pub fn save_with_size(self, path: &str, w: u32, h: u32) -> Result<(), GGError> {
1333 let (built, layout) = self.prepare(w, h)?;
1334
1335 let ext = path.rsplit('.').next().unwrap_or("svg").to_lowercase();
1337
1338 match ext.as_str() {
1339 "svg" => {
1340 let backend = plotters::prelude::SVGBackend::new(path, (w, h));
1341 Self::render_into(backend.into_drawing_area(), &built, &layout)?;
1342 }
1343 "png" | "bmp" | "gif" | "jpeg" | "jpg" | "tiff" => {
1344 let backend = plotters::prelude::BitMapBackend::new(path, (w, h));
1345 Self::render_into(backend.into_drawing_area(), &built, &layout)?;
1346 }
1347 _ => {
1348 return Err(GGError::UnsupportedFormat(ext));
1349 }
1350 }
1351
1352 Ok(())
1353 }
1354
1355 pub fn render_svg(self) -> Result<String, GGError> {
1360 self.render_svg_with_size(800, 600)
1361 }
1362
1363 pub fn render_svg_with_size(self, w: u32, h: u32) -> Result<String, GGError> {
1365 let (built, layout) = self.prepare(w, h)?;
1366 let mut buf = String::new();
1367 {
1368 let backend = plotters::prelude::SVGBackend::with_string(&mut buf, (w, h));
1369 Self::render_into(backend.into_drawing_area(), &built, &layout)?;
1370 }
1371 Ok(buf)
1372 }
1373
1374 pub fn render_png(self) -> Result<Vec<u8>, GGError> {
1379 self.render_png_with_size(800, 600)
1380 }
1381
1382 pub fn render_png_with_size(self, w: u32, h: u32) -> Result<Vec<u8>, GGError> {
1384 let (built, layout) = self.prepare(w, h)?;
1385
1386 let mut rgb = vec![0u8; (w as usize) * (h as usize) * 3];
1389 {
1390 let backend = plotters::prelude::BitMapBackend::with_buffer(&mut rgb, (w, h));
1391 Self::render_into(backend.into_drawing_area(), &built, &layout)?;
1392 }
1393
1394 let img = image::RgbImage::from_raw(w, h, rgb).ok_or_else(|| {
1395 GGError::Render(RenderError::BackendError(
1396 "PNG buffer size mismatch".to_string(),
1397 ))
1398 })?;
1399 let mut out = std::io::Cursor::new(Vec::new());
1400 img.write_to(&mut out, image::ImageOutputFormat::Png)
1401 .map_err(|e| GGError::Render(RenderError::BackendError(format!("{:?}", e))))?;
1402 Ok(out.into_inner())
1403 }
1404
1405 fn prepare(self, w: u32, h: u32) -> Result<(crate::build::BuiltPlot, PlotLayout), GGError> {
1407 let plot = self;
1408
1409 let has_title = plot.labels.title.is_some();
1410 let has_subtitle = plot.labels.subtitle.is_some();
1411 let has_caption = plot.labels.caption.is_some();
1412 let has_legend = plot.has_legend_mapping();
1413 let x_label = plot.labels.x.clone();
1414 let y_label = plot.labels.y.clone();
1415
1416 let mut built = PlotBuilder::build(plot)?;
1417
1418 if let Some(ref label) = x_label {
1420 if let Some(s) = built.scales.get_mut(&crate::aes::Aesthetic::X) {
1421 s.set_name(label);
1422 }
1423 }
1424 if let Some(ref label) = y_label {
1425 if let Some(s) = built.scales.get_mut(&crate::aes::Aesthetic::Y) {
1426 s.set_name(label);
1427 }
1428 }
1429
1430 let x_axis_top = built
1431 .scales
1432 .get(&crate::aes::Aesthetic::X)
1433 .map(|s| s.axis_position_opposite())
1434 .unwrap_or(false);
1435
1436 let layout = PlotLayout::compute_full(
1437 w as f64,
1438 h as f64,
1439 &built.theme,
1440 has_title,
1441 has_subtitle,
1442 has_caption,
1443 has_legend,
1444 x_axis_top,
1445 );
1446
1447 Ok((built, layout))
1448 }
1449
1450 fn render_into<DB>(
1452 area: plotters::drawing::DrawingArea<DB, plotters::coord::Shift>,
1453 built: &crate::build::BuiltPlot,
1454 layout: &PlotLayout,
1455 ) -> Result<(), GGError>
1456 where
1457 DB: plotters::prelude::DrawingBackend,
1458 DB::ErrorType: 'static,
1459 {
1460 area.fill(&plotters::prelude::WHITE)
1461 .map_err(|e| GGError::Render(RenderError::BackendError(format!("{:?}", e))))?;
1462 let mut adapter = PlottersAdapter::new(&area, layout.plot_area.clone());
1463 PlotRenderer::render(built, &mut adapter).map_err(GGError::Render)?;
1464 area.present()
1465 .map_err(|e| GGError::Render(RenderError::BackendError(format!("{:?}", e))))?;
1466 Ok(())
1467 }
1468
1469 pub fn ggsave(
1471 self,
1472 path: &str,
1473 width_inches: f64,
1474 height_inches: f64,
1475 dpi: f64,
1476 ) -> Result<(), GGError> {
1477 let w = (width_inches * dpi) as u32;
1478 let h = (height_inches * dpi) as u32;
1479 self.save_with_size(path, w, h)
1480 }
1481
1482 fn has_legend_mapping(&self) -> bool {
1483 self.mapping.mappings.iter().any(|m| {
1484 matches!(
1485 m.aesthetic,
1486 crate::aes::Aesthetic::Color
1487 | crate::aes::Aesthetic::Fill
1488 | crate::aes::Aesthetic::Shape
1489 | crate::aes::Aesthetic::Linetype
1490 | crate::aes::Aesthetic::Size
1491 | crate::aes::Aesthetic::Alpha
1492 )
1493 })
1494 }
1495}
1496
1497#[derive(Debug)]
1499pub enum GGError {
1500 Render(RenderError),
1501 UnsupportedFormat(String),
1502 Io(std::io::Error),
1503 ValidationError(String),
1504}
1505
1506impl std::fmt::Display for GGError {
1507 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1508 match self {
1509 GGError::Render(e) => write!(f, "Render error: {e}"),
1510 GGError::UnsupportedFormat(ext) => write!(f, "Unsupported output format: {ext}"),
1511 GGError::Io(e) => write!(f, "IO error: {e}"),
1512 GGError::ValidationError(msg) => write!(f, "Validation error: {msg}"),
1513 }
1514 }
1515}
1516
1517impl std::error::Error for GGError {}