plotlars/plots/
piechart.rs

1use bon::bon;
2
3use plotly::{
4    Layout as LayoutPlotly,
5    Pie,
6    Trace,
7};
8
9use polars::frame::DataFrame;
10use serde::Serialize;
11
12use crate::{
13    common::{Layout, PlotHelper, Polar},
14    components::Text,
15};
16
17/// A structure representing a pie chart.
18///
19/// The `PieChart` struct allows for the creation and customization of pie charts, supporting
20/// features such as labels, hole size for donut-style charts, slice pulling, rotation, and customizable plot titles.
21/// It is ideal for visualizing proportions and distributions in categorical data.
22///
23/// # Arguments
24///
25/// * `data` - A reference to the `DataFrame` containing the data to be plotted.
26/// * `labels` - A string slice specifying the column name to be used for slice labels.
27/// * `hole` - An optional `f64` value specifying the size of the hole in the center of the pie chart.
28///   A value of `0.0` creates a full pie chart, while a value closer to `1.0` creates a thinner ring.
29/// * `pull` - An optional `f64` value specifying the fraction by which each slice should be pulled out from the center.
30/// * `rotation` - An optional `f64` value specifying the starting angle (in degrees) of the first slice.
31/// * `plot_title` - An optional `Text` struct specifying the title of the plot.
32///
33/// # Example
34///
35/// ## Basic Pie Chart with Customization
36///
37/// ```rust
38/// use plotlars::{PieChart, Plot, Text};
39///
40/// let dataset = LazyCsvReader::new("data/penguins.csv")
41///     .finish()
42///     .unwrap()
43///     .select([
44///         col("species"),
45///     ])
46///     .collect()
47///     .unwrap();
48///
49/// PieChart::builder()
50///     .data(&dataset)
51///     .labels("species")
52///     .hole(0.4)
53///     .pull(0.01)
54///     .rotation(20.0)
55///     .plot_title(
56///         Text::from("Pie Chart")
57///             .font("Arial")
58///             .size(18)
59///     )
60///     .build()
61///     .plot();
62/// ```
63///
64/// ![Example](https://imgur.com/jE70hYS.png)
65#[derive(Clone, Serialize)]
66pub struct PieChart {
67    traces: Vec<Box<dyn Trace + 'static>>,
68    layout: LayoutPlotly,
69}
70
71#[bon]
72impl PieChart {
73    #[builder(on(String, into), on(Text, into))]
74    pub fn new(
75        data: &DataFrame,
76        labels: &str,
77        hole: Option<f64>,
78        pull: Option<f64>,
79        rotation: Option<f64>,
80        plot_title: Option<Text>,
81    ) -> Self {
82        let x_title = None;
83        let y_title = None;
84        let z_title = None;
85        let legend_title = None;
86        let x_axis = None;
87        let y_axis = None;
88        let z_axis = None;
89        let legend = None;
90
91        let layout = Self::create_layout(
92            plot_title,
93            x_title,
94            y_title,
95            None, // y2_title,
96            z_title,
97            legend_title,
98            x_axis,
99            y_axis,
100            None, // y2_axis,
101            z_axis,
102            legend,
103        );
104
105        let mut traces = vec![];
106
107        let trace = Self::create_trace(data, labels, hole, pull, rotation);
108
109        traces.push(trace);
110
111        Self { traces, layout }
112    }
113
114    fn create_trace(
115        data: &DataFrame,
116        labels: &str,
117        hole: Option<f64>,
118        pull: Option<f64>,
119        rotation: Option<f64>,
120    ) -> Box<dyn Trace + 'static> {
121        let labels = Self::get_string_column(data, labels)
122            .iter()
123            .filter_map(|s| {
124                if s.is_some() {
125                    Some(s.clone().unwrap().to_owned())
126                } else {
127                    None
128                }
129            })
130            .collect::<Vec<String>>();
131
132        let mut trace = Pie::<u32>::from_labels(&labels);
133
134        if let Some(hole) = hole {
135            trace = trace.hole(hole);
136        }
137
138        if let Some(pull) = pull {
139            trace = trace.pull(pull);
140        }
141
142        if let Some(rotation) = rotation {
143            trace = trace.rotation(rotation);
144        }
145
146        trace
147    }
148}
149
150impl Layout for PieChart {}
151impl Polar for PieChart {}
152
153impl PlotHelper for PieChart {
154    fn get_layout(&self) -> &LayoutPlotly {
155        &self.layout
156    }
157
158    fn get_traces(&self) -> &Vec<Box<dyn Trace + 'static>> {
159        &self.traces
160    }
161}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy