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 geom_step(self) -> Self {
285 self.add_geom(GeomStep::default())
286 }
287
288 pub fn geom_step_with(self, geom: GeomStep) -> Self {
289 self.add_geom(geom)
290 }
291
292 pub fn geom_freqpoly(self) -> Self {
293 self.add_geom(GeomFreqpoly::default())
294 }
295
296 pub fn geom_freqpoly_with(self, geom: GeomFreqpoly) -> Self {
297 self.add_geom(geom)
298 }
299
300 pub fn geom_linerange(self) -> Self {
301 self.add_geom(GeomLinerange::default())
302 }
303
304 pub fn geom_linerange_with(self, geom: GeomLinerange) -> Self {
305 self.add_geom(geom)
306 }
307
308 pub fn geom_pointrange(self) -> Self {
309 self.add_geom(GeomPointrange::default())
310 }
311
312 pub fn geom_pointrange_with(self, geom: GeomPointrange) -> Self {
313 self.add_geom(geom)
314 }
315
316 pub fn geom_crossbar(self) -> Self {
317 self.add_geom(GeomCrossbar::default())
318 }
319
320 pub fn geom_crossbar_with(self, geom: GeomCrossbar) -> Self {
321 self.add_geom(geom)
322 }
323
324 pub fn geom_spoke(self) -> Self {
325 self.add_geom(GeomSpoke::default())
326 }
327
328 pub fn geom_spoke_with(self, geom: GeomSpoke) -> Self {
329 self.add_geom(geom)
330 }
331
332 pub fn geom_rect(self) -> Self {
333 self.add_geom(GeomRect::default())
334 }
335
336 pub fn geom_rect_with(self, geom: GeomRect) -> Self {
337 self.add_geom(geom)
338 }
339
340 pub fn geom_tile(self) -> Self {
341 self.add_geom(GeomTile::default())
342 }
343
344 pub fn geom_tile_with(self, geom: GeomTile) -> Self {
345 self.add_geom(geom)
346 }
347
348 pub fn geom_polygon(self) -> Self {
349 self.add_geom(GeomPolygon::default())
350 }
351
352 pub fn geom_polygon_with(self, geom: GeomPolygon) -> Self {
353 self.add_geom(geom)
354 }
355
356 pub fn geom_curve(self) -> Self {
357 self.add_geom(GeomCurve::default())
358 }
359
360 pub fn geom_curve_with(self, geom: GeomCurve) -> Self {
361 self.add_geom(geom)
362 }
363
364 pub fn geom_violin(self) -> Self {
365 self.add_geom(GeomViolin::default())
366 }
367
368 pub fn geom_violin_with(self, geom: GeomViolin) -> Self {
369 self.add_geom(geom)
370 }
371
372 pub fn geom_dotplot(self) -> Self {
373 self.add_geom(GeomDotplot::default())
374 }
375
376 pub fn geom_dotplot_with(self, geom: GeomDotplot) -> Self {
377 self.add_geom(geom)
378 }
379
380 pub fn geom_qq(self) -> Self {
381 self.add_geom(GeomQQ::default())
382 }
383
384 pub fn geom_qq_with(self, geom: GeomQQ) -> Self {
385 self.add_geom(geom)
386 }
387
388 pub fn geom_qq_line(self) -> Self {
389 self.add_geom(GeomQQLine::default())
390 }
391
392 pub fn geom_qq_line_with(self, geom: GeomQQLine) -> Self {
393 self.add_geom(geom)
394 }
395
396 pub fn geom_bin2d(self) -> Self {
397 self.add_geom(GeomBin2d::default())
398 }
399
400 pub fn geom_bin2d_with(self, geom: GeomBin2d) -> Self {
401 self.add_geom(geom)
402 }
403
404 pub fn geom_hex(self) -> Self {
405 self.add_geom(GeomHex::default())
406 }
407
408 pub fn geom_hex_with(self, geom: GeomHex) -> Self {
409 self.add_geom(geom)
410 }
411
412 pub fn geom_count(self) -> Self {
413 self.add_geom(GeomCount::default())
414 }
415
416 pub fn geom_count_with(self, geom: GeomCount) -> Self {
417 self.add_geom(geom)
418 }
419
420 pub fn geom_contour(self) -> Self {
421 self.add_geom(GeomContour::default())
422 }
423
424 pub fn geom_contour_with(self, geom: GeomContour) -> Self {
425 self.add_geom(geom)
426 }
427
428 pub fn geom_density2d(self) -> Self {
429 self.add_geom(GeomDensity2d::default())
430 }
431
432 pub fn geom_density2d_with(self, geom: GeomDensity2d) -> Self {
433 self.add_geom(geom)
434 }
435
436 pub fn geom_blank(self) -> Self {
437 self.add_geom(GeomBlank)
438 }
439
440 fn add_geom(mut self, geom: impl Geom + 'static) -> Self {
441 let stat = geom.default_stat();
442 let position = geom.default_position();
443 let params = geom.default_params();
444 self.layers.push(Layer {
445 data: None,
446 mapping: Aes::default(),
447 geom: Box::new(geom),
448 stat,
449 position,
450 params,
451 show_legend: None,
452 });
453 self
454 }
455
456 pub fn stat(mut self, stat: impl Stat + 'static) -> Self {
460 if let Some(layer) = self.layers.last_mut() {
461 layer.stat = Box::new(stat);
462 }
463 self
464 }
465
466 pub fn position(mut self, pos: impl Position + 'static) -> Self {
468 if let Some(layer) = self.layers.last_mut() {
469 layer.position = Box::new(pos);
470 }
471 self
472 }
473
474 pub fn layer_data(mut self, data: impl GGData) -> Self {
476 if let Some(layer) = self.layers.last_mut() {
477 layer.data = Some(data.into_dataframe());
478 }
479 self
480 }
481
482 pub fn layer_aes(mut self, mapping: Aes) -> Self {
484 if let Some(layer) = self.layers.last_mut() {
485 layer.mapping = mapping;
486 }
487 self
488 }
489
490 pub fn show_legend(mut self, show: bool) -> Self {
493 if let Some(layer) = self.layers.last_mut() {
494 layer.show_legend = Some(show);
495 }
496 self
497 }
498
499 pub fn scale_x_continuous(mut self, s: ScaleContinuous) -> Self {
502 let s = s.for_aesthetic(crate::aes::Aesthetic::X);
503 self.scales.push(Box::new(s));
504 self
505 }
506
507 pub fn scale_y_continuous(mut self, s: ScaleContinuous) -> Self {
508 let s = s.for_aesthetic(crate::aes::Aesthetic::Y);
509 self.scales.push(Box::new(s));
510 self
511 }
512
513 pub fn scale_x_discrete(mut self, s: crate::scale::discrete::ScaleDiscrete) -> Self {
514 let s = s.for_aesthetic(crate::aes::Aesthetic::X);
515 self.scales.push(Box::new(s));
516 self
517 }
518
519 pub fn scale_y_discrete(mut self, s: crate::scale::discrete::ScaleDiscrete) -> Self {
520 let s = s.for_aesthetic(crate::aes::Aesthetic::Y);
521 self.scales.push(Box::new(s));
522 self
523 }
524
525 pub fn scale_color(mut self, s: impl Scale + 'static) -> Self {
526 self.scales.push(Box::new(s));
527 self
528 }
529
530 pub fn scale_fill(mut self, s: impl Scale + 'static) -> Self {
531 self.scales.push(Box::new(s));
532 self
533 }
534
535 pub fn scale_color_manual(self, values: Vec<(&str, crate::scale::color::RGBAColor)>) -> Self {
536 let s = crate::scale::manual::ScaleManual::new(crate::aes::Aesthetic::Color, values);
537 self.scale_color(s)
538 }
539
540 pub fn scale_fill_manual(self, values: Vec<(&str, crate::scale::color::RGBAColor)>) -> Self {
541 let s = crate::scale::manual::ScaleManual::new(crate::aes::Aesthetic::Fill, values);
542 self.scale_fill(s)
543 }
544
545 pub fn scale_color_viridis(self) -> Self {
546 use crate::scale::color::ScaleColorDiscrete;
547 use crate::scale::palettes::PaletteName;
548 let s = ScaleColorDiscrete::new(crate::aes::Aesthetic::Color)
549 .with_named_palette(&PaletteName::Viridis);
550 self.scale_color(s)
551 }
552
553 pub fn scale_color_brewer(self, name: crate::scale::palettes::PaletteName) -> Self {
554 use crate::scale::color::ScaleColorDiscrete;
555 let s = ScaleColorDiscrete::new(crate::aes::Aesthetic::Color).with_named_palette(&name);
556 self.scale_color(s)
557 }
558
559 pub fn scale_color_gradient(
560 self,
561 low: crate::scale::color::RGBAColor,
562 high: crate::scale::color::RGBAColor,
563 ) -> Self {
564 use crate::scale::color::ScaleColorContinuous;
565 let s = ScaleColorContinuous::new(crate::aes::Aesthetic::Color).with_colors(low, high);
566 self.scale_color(s)
567 }
568
569 pub fn scale_fill_gradient(
570 self,
571 low: crate::scale::color::RGBAColor,
572 high: crate::scale::color::RGBAColor,
573 ) -> Self {
574 use crate::scale::color::ScaleColorContinuous;
575 let s = ScaleColorContinuous::new(crate::aes::Aesthetic::Fill).with_colors(low, high);
576 self.scale_fill(s)
577 }
578
579 pub fn scale_color_gradient2(
580 self,
581 low: crate::scale::color::RGBAColor,
582 mid: crate::scale::color::RGBAColor,
583 high: crate::scale::color::RGBAColor,
584 ) -> Self {
585 use crate::scale::gradient::ScaleColorGradient2;
586 let s = ScaleColorGradient2::new(crate::aes::Aesthetic::Color).with_colors(low, mid, high);
587 self.scale_color(s)
588 }
589
590 pub fn scale_fill_gradient2(
591 self,
592 low: crate::scale::color::RGBAColor,
593 mid: crate::scale::color::RGBAColor,
594 high: crate::scale::color::RGBAColor,
595 ) -> Self {
596 use crate::scale::gradient::ScaleColorGradient2;
597 let s = ScaleColorGradient2::new(crate::aes::Aesthetic::Fill).with_colors(low, mid, high);
598 self.scale_fill(s)
599 }
600
601 pub fn scale_fill_viridis(self) -> Self {
602 use crate::scale::color::ScaleColorDiscrete;
603 use crate::scale::palettes::PaletteName;
604 let s = ScaleColorDiscrete::new(crate::aes::Aesthetic::Fill)
605 .with_named_palette(&PaletteName::Viridis);
606 self.scale_fill(s)
607 }
608
609 pub fn scale_color_viridis_c(self) -> Self {
611 use crate::scale::gradient_n::ScaleColorGradientN;
612 let s = ScaleColorGradientN::viridis(crate::aes::Aesthetic::Color);
613 self.scale_color(s)
614 }
615
616 pub fn scale_fill_viridis_c(self) -> Self {
618 use crate::scale::gradient_n::ScaleColorGradientN;
619 let s = ScaleColorGradientN::viridis(crate::aes::Aesthetic::Fill);
620 self.scale_fill(s)
621 }
622
623 pub fn scale_color_gradientn(self, stops: Vec<(f64, crate::scale::color::RGBAColor)>) -> Self {
625 use crate::scale::gradient_n::ScaleColorGradientN;
626 let s = ScaleColorGradientN::new(crate::aes::Aesthetic::Color, stops);
627 self.scale_color(s)
628 }
629
630 pub fn scale_fill_gradientn(self, stops: Vec<(f64, crate::scale::color::RGBAColor)>) -> Self {
632 use crate::scale::gradient_n::ScaleColorGradientN;
633 let s = ScaleColorGradientN::new(crate::aes::Aesthetic::Fill, stops);
634 self.scale_fill(s)
635 }
636
637 pub fn scale_fill_brewer(self, name: crate::scale::palettes::PaletteName) -> Self {
638 use crate::scale::color::ScaleColorDiscrete;
639 let s = ScaleColorDiscrete::new(crate::aes::Aesthetic::Fill).with_named_palette(&name);
640 self.scale_fill(s)
641 }
642
643 pub fn scale_linetype_manual(
644 self,
645 values: Vec<(&str, crate::render::backend::Linetype)>,
646 ) -> Self {
647 let s = crate::scale::linetype_manual::ScaleLinetypeManual::new(values);
648 self.scale_color(s)
649 }
650
651 pub fn scale_shape_manual(
652 self,
653 values: Vec<(&str, crate::render::backend::PointShape)>,
654 ) -> Self {
655 let s = crate::scale::shape_manual::ScaleShapeManual::new(values);
656 self.scale_color(s)
657 }
658
659 pub fn scale_color_grey(self) -> Self {
660 let s = crate::scale::grey::ScaleColorGrey::new(crate::aes::Aesthetic::Color);
661 self.scale_color(s)
662 }
663
664 pub fn scale_fill_grey(self) -> Self {
665 let s = crate::scale::grey::ScaleColorGrey::new(crate::aes::Aesthetic::Fill);
666 self.scale_fill(s)
667 }
668
669 pub fn scale_color_grey_with(self, s: crate::scale::grey::ScaleColorGrey) -> Self {
670 self.scale_color(s)
671 }
672
673 pub fn scale_fill_grey_with(self, s: crate::scale::grey::ScaleColorGrey) -> Self {
674 self.scale_fill(s)
675 }
676
677 pub fn scale_x_reverse(self) -> Self {
678 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Reverse))
679 }
680
681 pub fn scale_y_reverse(self) -> Self {
682 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Reverse))
683 }
684
685 pub fn scale_x_datetime(mut self, s: crate::scale::datetime::ScaleDateTime) -> Self {
686 let s = s.for_aesthetic(crate::aes::Aesthetic::X);
687 self.scales.push(Box::new(s));
688 self
689 }
690
691 pub fn scale_y_datetime(mut self, s: crate::scale::datetime::ScaleDateTime) -> Self {
692 let s = s.for_aesthetic(crate::aes::Aesthetic::Y);
693 self.scales.push(Box::new(s));
694 self
695 }
696
697 pub fn scale_size(mut self, s: crate::scale::size::ScaleSizeContinuous) -> Self {
698 self.scales.push(Box::new(s));
699 self
700 }
701
702 pub fn scale_alpha(mut self, s: crate::scale::alpha::ScaleAlphaContinuous) -> Self {
703 self.scales.push(Box::new(s));
704 self
705 }
706
707 pub fn xlim(self, min: f64, max: f64) -> Self {
708 self.scale_x_continuous(ScaleContinuous::new().with_limits(min, max))
709 }
710
711 pub fn ylim(self, min: f64, max: f64) -> Self {
712 self.scale_y_continuous(ScaleContinuous::new().with_limits(min, max))
713 }
714
715 pub fn scale_x_log10(self) -> Self {
716 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Log10))
717 }
718
719 pub fn scale_y_log10(self) -> Self {
720 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Log10))
721 }
722
723 pub fn scale_x_sqrt(self) -> Self {
724 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Sqrt))
725 }
726
727 pub fn scale_y_sqrt(self) -> Self {
728 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Sqrt))
729 }
730
731 pub fn scale_x_log2(self) -> Self {
732 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Log2))
733 }
734
735 pub fn scale_y_log2(self) -> Self {
736 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Log2))
737 }
738
739 pub fn scale_x_ln(self) -> Self {
740 self.scale_x_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Ln))
741 }
742
743 pub fn scale_y_ln(self) -> Self {
744 self.scale_y_continuous(ScaleContinuous::new().with_transform(ScaleTransform::Ln))
745 }
746
747 pub fn facet_wrap(mut self, var: &str, ncol: Option<usize>) -> Self {
750 self.facet = Facet::Wrap {
751 var: var.to_string(),
752 ncol,
753 scales: FacetScales::Fixed,
754 labeller: FacetLabeller::default(),
755 };
756 self
757 }
758
759 pub fn facet_wrap_free(mut self, var: &str, ncol: Option<usize>, scales: FacetScales) -> Self {
760 self.facet = Facet::Wrap {
761 var: var.to_string(),
762 ncol,
763 scales,
764 labeller: FacetLabeller::default(),
765 };
766 self
767 }
768
769 pub fn facet_wrap_labeller(
770 mut self,
771 var: &str,
772 ncol: Option<usize>,
773 labeller: FacetLabeller,
774 ) -> Self {
775 self.facet = Facet::Wrap {
776 var: var.to_string(),
777 ncol,
778 scales: FacetScales::Fixed,
779 labeller,
780 };
781 self
782 }
783
784 pub fn facet_grid(mut self, row: Option<&str>, col: Option<&str>) -> Self {
785 self.facet = Facet::Grid {
786 row_var: row.map(String::from),
787 col_var: col.map(String::from),
788 scales: FacetScales::Fixed,
789 labeller: FacetLabeller::default(),
790 };
791 self
792 }
793
794 pub fn facet_grid_free(
795 mut self,
796 row: Option<&str>,
797 col: Option<&str>,
798 scales: FacetScales,
799 ) -> Self {
800 self.facet = Facet::Grid {
801 row_var: row.map(String::from),
802 col_var: col.map(String::from),
803 scales,
804 labeller: FacetLabeller::default(),
805 };
806 self
807 }
808
809 pub fn facet_grid_labeller(
810 mut self,
811 row: Option<&str>,
812 col: Option<&str>,
813 labeller: FacetLabeller,
814 ) -> Self {
815 self.facet = Facet::Grid {
816 row_var: row.map(String::from),
817 col_var: col.map(String::from),
818 scales: FacetScales::Fixed,
819 labeller,
820 };
821 self
822 }
823
824 pub fn coord_flip(mut self) -> Self {
827 self.coord = Box::new(CoordFlip);
828 self
829 }
830
831 pub fn coord_fixed(mut self, ratio: f64) -> Self {
832 self.coord = Box::new(CoordFixed::new(ratio));
833 self
834 }
835
836 pub fn coord_cartesian_zoom(
838 mut self,
839 xlim: Option<(f64, f64)>,
840 ylim: Option<(f64, f64)>,
841 ) -> Self {
842 let mut c = CoordCartesian::new();
843 if let Some((min, max)) = xlim {
844 c = c.xlim(min, max);
845 }
846 if let Some((min, max)) = ylim {
847 c = c.ylim(min, max);
848 }
849 self.coord = Box::new(c);
850 self
851 }
852
853 pub fn coord_polar(mut self) -> Self {
854 self.coord = Box::new(CoordPolar::new());
855 self
856 }
857
858 pub fn coord_polar_with(mut self, coord: CoordPolar) -> Self {
859 self.coord = Box::new(coord);
860 self
861 }
862
863 pub fn theme(mut self, theme: Theme) -> Self {
866 self.theme = theme;
867 self
868 }
869
870 pub fn primary_color(mut self, color: (u8, u8, u8)) -> Self {
874 self.theme.primary = Some(color);
875 self
876 }
877
878 pub fn theme_minimal(mut self) -> Self {
879 self.theme = crate::theme::presets::theme_minimal();
880 self
881 }
882
883 pub fn theme_bw(mut self) -> Self {
884 self.theme = crate::theme::presets::theme_bw();
885 self
886 }
887
888 pub fn theme_gray(mut self) -> Self {
889 self.theme = crate::theme::presets::theme_gray();
890 self
891 }
892
893 pub fn theme_classic(mut self) -> Self {
894 self.theme = crate::theme::presets::theme_classic();
895 self
896 }
897
898 pub fn theme_linedraw(mut self) -> Self {
899 self.theme = crate::theme::presets::theme_linedraw();
900 self
901 }
902
903 pub fn theme_light(mut self) -> Self {
904 self.theme = crate::theme::presets::theme_light();
905 self
906 }
907
908 pub fn theme_dark(mut self) -> Self {
909 self.theme = crate::theme::presets::theme_dark();
910 self
911 }
912
913 pub fn theme_void(mut self) -> Self {
914 self.theme = crate::theme::presets::theme_void();
915 self
916 }
917
918 pub fn theme_update(mut self, update: crate::theme::ThemeUpdate) -> Self {
921 self.theme = self.theme.update(update);
922 self
923 }
924
925 pub fn guides(mut self, guide: crate::guide::config::GuideLegend) -> Self {
929 self.guide_legend = guide;
930 self
931 }
932
933 pub fn labs(mut self, labels: Labels) -> Self {
936 if labels.title.is_some() {
937 self.labels.title = labels.title;
938 }
939 if labels.subtitle.is_some() {
940 self.labels.subtitle = labels.subtitle;
941 }
942 if labels.x.is_some() {
943 self.labels.x = labels.x;
944 }
945 if labels.y.is_some() {
946 self.labels.y = labels.y;
947 }
948 if labels.caption.is_some() {
949 self.labels.caption = labels.caption;
950 }
951 self
952 }
953
954 pub fn title(mut self, title: &str) -> Self {
955 self.labels.title = Some(title.to_string());
956 self
957 }
958
959 pub fn subtitle(mut self, subtitle: &str) -> Self {
960 self.labels.subtitle = Some(subtitle.to_string());
961 self
962 }
963
964 pub fn xlab(mut self, label: &str) -> Self {
965 self.labels.x = Some(label.to_string());
966 self
967 }
968
969 pub fn ylab(mut self, label: &str) -> Self {
970 self.labels.y = Some(label.to_string());
971 self
972 }
973
974 pub fn caption(mut self, caption: &str) -> Self {
975 self.labels.caption = Some(caption.to_string());
976 self
977 }
978
979 pub fn annotate(mut self, annotation: Annotation) -> Self {
983 self.annotations.push(annotation);
984 self
985 }
986
987 pub fn annotate_text(self, label: &str, x: f64, y: f64) -> Self {
989 self.annotate(Annotation::text(label, x, y))
990 }
991
992 pub fn annotate_rect(self, xmin: f64, xmax: f64, ymin: f64, ymax: f64) -> Self {
994 self.annotate(Annotation::rect(xmin, xmax, ymin, ymax))
995 }
996
997 pub fn annotate_segment(self, x: f64, y: f64, xend: f64, yend: f64) -> Self {
999 self.annotate(Annotation::segment(x, y, xend, yend))
1000 }
1001
1002 pub fn try_build(self) -> Result<crate::build::BuiltPlot, GGError> {
1006 PlotBuilder::build(self)
1007 }
1008
1009 pub fn build(self) -> crate::build::BuiltPlot {
1013 self.try_build().expect("plot build failed")
1014 }
1015
1016 pub fn save(self, path: &str) -> Result<(), GGError> {
1018 self.save_with_size(path, 800, 600)
1019 }
1020
1021 pub fn save_with_size(self, path: &str, w: u32, h: u32) -> Result<(), GGError> {
1023 let (built, layout) = self.prepare(w, h)?;
1024
1025 let ext = path.rsplit('.').next().unwrap_or("svg").to_lowercase();
1027
1028 match ext.as_str() {
1029 "svg" => {
1030 let backend = plotters::prelude::SVGBackend::new(path, (w, h));
1031 Self::render_into(backend.into_drawing_area(), &built, &layout)?;
1032 }
1033 "png" | "bmp" | "gif" | "jpeg" | "jpg" | "tiff" => {
1034 let backend = plotters::prelude::BitMapBackend::new(path, (w, h));
1035 Self::render_into(backend.into_drawing_area(), &built, &layout)?;
1036 }
1037 _ => {
1038 return Err(GGError::UnsupportedFormat(ext));
1039 }
1040 }
1041
1042 Ok(())
1043 }
1044
1045 pub fn render_svg(self) -> Result<String, GGError> {
1050 self.render_svg_with_size(800, 600)
1051 }
1052
1053 pub fn render_svg_with_size(self, w: u32, h: u32) -> Result<String, GGError> {
1055 let (built, layout) = self.prepare(w, h)?;
1056 let mut buf = String::new();
1057 {
1058 let backend = plotters::prelude::SVGBackend::with_string(&mut buf, (w, h));
1059 Self::render_into(backend.into_drawing_area(), &built, &layout)?;
1060 }
1061 Ok(buf)
1062 }
1063
1064 pub fn render_png(self) -> Result<Vec<u8>, GGError> {
1069 self.render_png_with_size(800, 600)
1070 }
1071
1072 pub fn render_png_with_size(self, w: u32, h: u32) -> Result<Vec<u8>, GGError> {
1074 let (built, layout) = self.prepare(w, h)?;
1075
1076 let mut rgb = vec![0u8; (w as usize) * (h as usize) * 3];
1079 {
1080 let backend = plotters::prelude::BitMapBackend::with_buffer(&mut rgb, (w, h));
1081 Self::render_into(backend.into_drawing_area(), &built, &layout)?;
1082 }
1083
1084 let img = image::RgbImage::from_raw(w, h, rgb).ok_or_else(|| {
1085 GGError::Render(RenderError::BackendError(
1086 "PNG buffer size mismatch".to_string(),
1087 ))
1088 })?;
1089 let mut out = std::io::Cursor::new(Vec::new());
1090 img.write_to(&mut out, image::ImageOutputFormat::Png)
1091 .map_err(|e| GGError::Render(RenderError::BackendError(format!("{:?}", e))))?;
1092 Ok(out.into_inner())
1093 }
1094
1095 fn prepare(self, w: u32, h: u32) -> Result<(crate::build::BuiltPlot, PlotLayout), GGError> {
1097 let plot = self;
1098
1099 let has_title = plot.labels.title.is_some();
1100 let has_subtitle = plot.labels.subtitle.is_some();
1101 let has_caption = plot.labels.caption.is_some();
1102 let has_legend = plot.has_legend_mapping();
1103 let x_label = plot.labels.x.clone();
1104 let y_label = plot.labels.y.clone();
1105
1106 let mut built = PlotBuilder::build(plot)?;
1107
1108 if let Some(ref label) = x_label {
1110 if let Some(s) = built.scales.get_mut(&crate::aes::Aesthetic::X) {
1111 s.set_name(label);
1112 }
1113 }
1114 if let Some(ref label) = y_label {
1115 if let Some(s) = built.scales.get_mut(&crate::aes::Aesthetic::Y) {
1116 s.set_name(label);
1117 }
1118 }
1119
1120 let layout = PlotLayout::compute_full(
1121 w as f64,
1122 h as f64,
1123 &built.theme,
1124 has_title,
1125 has_subtitle,
1126 has_caption,
1127 has_legend,
1128 );
1129
1130 Ok((built, layout))
1131 }
1132
1133 fn render_into<DB>(
1135 area: plotters::drawing::DrawingArea<DB, plotters::coord::Shift>,
1136 built: &crate::build::BuiltPlot,
1137 layout: &PlotLayout,
1138 ) -> Result<(), GGError>
1139 where
1140 DB: plotters::prelude::DrawingBackend,
1141 DB::ErrorType: 'static,
1142 {
1143 area.fill(&plotters::prelude::WHITE)
1144 .map_err(|e| GGError::Render(RenderError::BackendError(format!("{:?}", e))))?;
1145 let mut adapter = PlottersAdapter::new(&area, layout.plot_area.clone());
1146 PlotRenderer::render(built, &mut adapter).map_err(GGError::Render)?;
1147 area.present()
1148 .map_err(|e| GGError::Render(RenderError::BackendError(format!("{:?}", e))))?;
1149 Ok(())
1150 }
1151
1152 pub fn ggsave(
1154 self,
1155 path: &str,
1156 width_inches: f64,
1157 height_inches: f64,
1158 dpi: f64,
1159 ) -> Result<(), GGError> {
1160 let w = (width_inches * dpi) as u32;
1161 let h = (height_inches * dpi) as u32;
1162 self.save_with_size(path, w, h)
1163 }
1164
1165 fn has_legend_mapping(&self) -> bool {
1166 self.mapping.mappings.iter().any(|m| {
1167 matches!(
1168 m.aesthetic,
1169 crate::aes::Aesthetic::Color
1170 | crate::aes::Aesthetic::Fill
1171 | crate::aes::Aesthetic::Shape
1172 | crate::aes::Aesthetic::Linetype
1173 | crate::aes::Aesthetic::Size
1174 | crate::aes::Aesthetic::Alpha
1175 )
1176 })
1177 }
1178}
1179
1180#[derive(Debug)]
1182pub enum GGError {
1183 Render(RenderError),
1184 UnsupportedFormat(String),
1185 Io(std::io::Error),
1186 ValidationError(String),
1187}
1188
1189impl std::fmt::Display for GGError {
1190 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1191 match self {
1192 GGError::Render(e) => write!(f, "Render error: {e}"),
1193 GGError::UnsupportedFormat(ext) => write!(f, "Unsupported output format: {ext}"),
1194 GGError::Io(e) => write!(f, "IO error: {e}"),
1195 GGError::ValidationError(msg) => write!(f, "Validation error: {msg}"),
1196 }
1197 }
1198}
1199
1200impl std::error::Error for GGError {}