Skip to main content

Aes

Struct Aes 

Source
pub struct Aes {
    pub mappings: Vec<AesMapping>,
}
Expand description

Builder for aesthetic mappings.

Fields§

§mappings: Vec<AesMapping>

Implementations§

Source§

impl Aes

Source

pub fn new() -> Self

Examples found in repository?
examples/bar_chart.rs (line 11)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    let df = df! {
6        "fruit" => ["Apple", "Apple", "Apple", "Banana", "Banana",
7                     "Cherry", "Cherry", "Cherry", "Cherry", "Date"],
8    }?;
9
10    GGPlot::new(df)
11        .aes(Aes::new().x("fruit"))
12        .geom_bar()
13        .title("Fruit Counts")
14        .xlab("Fruit")
15        .ylab("Count")
16        .save("bar_chart.svg")?;
17
18    println!("Saved bar_chart.svg");
19    Ok(())
20}
More examples
Hide additional examples
examples/coord_flip.rs (line 12)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    let df = df! {
6        "language" => ["Rust", "Python", "JavaScript", "Go", "TypeScript", "Java", "C++"],
7        "satisfaction" => [92.0, 88.0, 85.0, 78.0, 82.0, 70.0, 75.0],
8    }?;
9
10    // Horizontal bar chart using coord_flip
11    GGPlot::new(df)
12        .aes(Aes::new().x("language").y("satisfaction"))
13        .geom_col()
14        .coord_flip()
15        .title("Developer Satisfaction by Language")
16        .xlab("Language")
17        .ylab("Satisfaction Score")
18        .save("coord_flip.svg")?;
19
20    println!("Saved coord_flip.svg");
21    Ok(())
22}
examples/gallery.rs (line 47)
35fn scatter() -> Result<(), Box<dyn std::error::Error>> {
36    let n = 150;
37    let x: Vec<f64> = (0..n).map(|i| 4.5 + i as f64 * 0.02).collect();
38    let y: Vec<f64> = (0..n)
39        .map(|i| 2.5 + (i as f64 * 0.15).sin() + (i % 3) as f64 * 0.6)
40        .collect();
41    let species: Vec<&str> = (0..n)
42        .map(|i| ["setosa", "versicolor", "virginica"][i % 3])
43        .collect();
44
45    let df = df! { "x" => x, "y" => y, "species" => species }?;
46    GGPlot::new(df)
47        .aes(Aes::new().x("x").y("y").color("species"))
48        .geom_point()
49        .scale_color_brewer(PaletteName::Set1)
50        .title("Grouped Scatter")
51        .xlab("Sepal Length")
52        .ylab("Sepal Width")
53        .theme_minimal()
54        .save_with_size(&out("scatter"), W, H)?;
55    Ok(())
56}
57
58/// Points overlaid with a LOESS trend line and confidence band.
59fn smooth() -> Result<(), Box<dyn std::error::Error>> {
60    let n = 120;
61    let x: Vec<f64> = (0..n).map(|i| i as f64 * 0.1).collect();
62    let y: Vec<f64> = (0..n)
63        .map(|i| {
64            let t = i as f64 * 0.1;
65            (t * 0.6).sin() * 3.0 + t * 0.2 + ((i * 7919 % 100) as f64 / 100.0 - 0.5) * 1.5
66        })
67        .collect();
68
69    let df = df! { "x" => x, "y" => y }?;
70    GGPlot::new(df)
71        .aes(Aes::new().x("x").y("y"))
72        .geom_point()
73        .geom_smooth_with(GeomSmooth {
74            method: SmoothMethod::Loess { span: 0.5 },
75            ..Default::default()
76        })
77        .title("LOESS Smoothing")
78        .xlab("x")
79        .ylab("y")
80        .theme_bw()
81        .save_with_size(&out("smooth"), W, H)?;
82    Ok(())
83}
84
85/// Histogram of an approximately-normal sample.
86fn histogram() -> Result<(), Box<dyn std::error::Error>> {
87    let values: Vec<f64> = (0..1500)
88        .map(|i: i32| {
89            let r: f64 = (0..6)
90                .map(|k| ((i * (1237 + k * 311) + 5678) % 1000) as f64 / 1000.0)
91                .sum();
92            (r - 3.0) * 2.0
93        })
94        .collect();
95
96    let df = df! { "measurement" => values }?;
97    GGPlot::new(df)
98        .aes(Aes::new().x("measurement"))
99        .geom_histogram_with(GeomHistogram {
100            bins: 30,
101            ..Default::default()
102        })
103        .title("Histogram")
104        .xlab("Value")
105        .ylab("Count")
106        .theme_minimal()
107        .save_with_size(&out("histogram"), W, H)?;
108    Ok(())
109}
110
111/// Bar chart of category counts with a fill palette.
112fn bar() -> Result<(), Box<dyn std::error::Error>> {
113    let mut fruit: Vec<&str> = Vec::new();
114    for (f, c) in [
115        ("Apple", 8),
116        ("Banana", 5),
117        ("Cherry", 11),
118        ("Date", 3),
119        ("Elder", 7),
120    ] {
121        for _ in 0..c {
122            fruit.push(f);
123        }
124    }
125    let df = df! { "fruit" => fruit }?;
126    GGPlot::new(df)
127        .aes(Aes::new().x("fruit").fill("fruit"))
128        .geom_bar()
129        .scale_fill_brewer(PaletteName::Set2)
130        .title("Bar Chart")
131        .xlab("Fruit")
132        .ylab("Count")
133        .theme_minimal()
134        .save_with_size(&out("bar"), W, H)?;
135    Ok(())
136}
137
138/// Grouped boxplots.
139fn boxplot() -> Result<(), Box<dyn std::error::Error>> {
140    let n = 240;
141    let group: Vec<&str> = (0..n).map(|i| ["A", "B", "C", "D"][i % 4]).collect();
142    let value: Vec<f64> = (0..n)
143        .map(|i| {
144            let base = (i % 4) as f64 * 1.5;
145            base + (i as f64 * 0.4).sin() * 1.2 + ((i * 6151 % 100) as f64 / 100.0 - 0.5) * 2.0
146        })
147        .collect();
148
149    let df = df! { "group" => group, "value" => value }?;
150    GGPlot::new(df)
151        .aes(Aes::new().x("group").y("value"))
152        .geom_boxplot_with(GeomBoxplot {
153            fill: (70, 130, 180),
154            ..Default::default()
155        })
156        .title("Boxplot")
157        .xlab("Group")
158        .ylab("Value")
159        .theme_bw()
160        .save_with_size(&out("boxplot"), W, H)?;
161    Ok(())
162}
163
164/// Violin plots of grouped distributions.
165fn violin() -> Result<(), Box<dyn std::error::Error>> {
166    let n = 360;
167    let group: Vec<&str> = (0..n).map(|i| ["X", "Y", "Z"][i % 3]).collect();
168    let value: Vec<f64> = (0..n)
169        .map(|i| {
170            let g = (i % 3) as f64;
171            g * 2.0 + (i as f64 * 0.5).sin() * 1.5 + ((i * 4231 % 100) as f64 / 100.0 - 0.5) * 2.5
172        })
173        .collect();
174
175    let df = df! { "group" => group, "value" => value }?;
176    GGPlot::new(df)
177        .aes(Aes::new().x("group").y("value").fill("group"))
178        .geom_violin()
179        .scale_fill_brewer(PaletteName::Accent)
180        .title("Violin")
181        .xlab("Group")
182        .ylab("Value")
183        .theme_minimal()
184        .save_with_size(&out("violin"), W, H)?;
185    Ok(())
186}
187
188/// Spiral scatter coloured by a continuous variable (viridis).
189fn continuous_color() -> Result<(), Box<dyn std::error::Error>> {
190    let n = 400;
191    let x: Vec<f64> = (0..n)
192        .map(|i| {
193            let t = i as f64 * 0.05;
194            t.cos() * (1.0 + t * 0.12)
195        })
196        .collect();
197    let y: Vec<f64> = (0..n)
198        .map(|i| {
199            let t = i as f64 * 0.05;
200            t.sin() * (1.0 + t * 0.12)
201        })
202        .collect();
203    let z: Vec<f64> = (0..n).map(|i| i as f64 * 0.05).collect();
204
205    let df = df! { "x" => x, "y" => y, "z" => z }?;
206    GGPlot::new(df)
207        .aes(Aes::new().x("x").y("y").color("z"))
208        .geom_point()
209        .scale_color_viridis_c()
210        .title("Continuous Color (viridis)")
211        .xlab("x")
212        .ylab("y")
213        .theme_minimal()
214        .save_with_size(&out("continuous_color"), W, H)?;
215    Ok(())
216}
217
218/// Faceted scatter, one panel per group.
219fn facet() -> Result<(), Box<dyn std::error::Error>> {
220    let n = 180;
221    let x: Vec<f64> = (0..n).map(|i| (i as f64 * 0.1).cos() * 3.0).collect();
222    let y: Vec<f64> = (0..n)
223        .map(|i| (i as f64 * 0.1).sin() * 3.0 + (i % 3) as f64)
224        .collect();
225    let species: Vec<&str> = (0..n)
226        .map(|i| ["setosa", "versicolor", "virginica"][i % 3])
227        .collect();
228
229    let df = df! { "x" => x, "y" => y, "species" => species }?;
230    GGPlot::new(df)
231        .aes(Aes::new().x("x").y("y").color("species"))
232        .geom_point()
233        .facet_wrap("species", Some(3))
234        .scale_color_brewer(PaletteName::Set1)
235        .title("Facet Wrap")
236        .xlab("x")
237        .ylab("y")
238        .theme_bw()
239        .save_with_size(&out("facet"), W, H)?;
240    Ok(())
241}
242
243/// Overlapping density curves by group.
244fn density() -> Result<(), Box<dyn std::error::Error>> {
245    let n = 600;
246    let group: Vec<&str> = (0..n).map(|i| ["Group 1", "Group 2"][i % 2]).collect();
247    let value: Vec<f64> = (0..n)
248        .map(|i| {
249            let shift = (i % 2) as f64 * 2.5;
250            let t = i as f64 * 0.05;
251            shift + (t.sin() + (t * 1.7).cos()) + ((i * 3319 % 100) as f64 / 100.0 - 0.5) * PI
252        })
253        .collect();
254
255    let df = df! { "value" => value, "group" => group }?;
256    GGPlot::new(df)
257        .aes(Aes::new().x("value").fill("group").color("group"))
258        .geom_density()
259        .scale_fill_brewer(PaletteName::Set1)
260        .scale_color_brewer(PaletteName::Set1)
261        .title("Density by Group")
262        .xlab("Value")
263        .ylab("Density")
264        .theme_minimal()
265        .save_with_size(&out("density"), W, H)?;
266    Ok(())
267}
examples/annotations.rs (line 17)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    // Sales data with a notable spike
6    let month: Vec<f64> = (1..=12).map(|i| i as f64).collect();
7    let sales = vec![
8        120.0, 135.0, 150.0, 180.0, 210.0, 310.0, 280.0, 250.0, 190.0, 170.0, 155.0, 140.0,
9    ];
10
11    let df = df! {
12        "month" => month,
13        "sales" => sales,
14    }?;
15
16    GGPlot::new(df)
17        .aes(Aes::new().x("month").y("sales"))
18        .geom_line()
19        .geom_point()
20        // Highlight the peak region
21        .annotate_rect(4.5, 7.5, 100.0, 320.0)
22        // Label the peak
23        .annotate_text("Summer Peak", 6.0, 330.0)
24        // Draw an arrow-like segment pointing to the max
25        .annotate_segment(7.5, 330.0, 6.2, 312.0)
26        .title("Monthly Sales with Annotations")
27        .xlab("Month")
28        .ylab("Sales ($)")
29        .save("annotations.svg")?;
30
31    println!("Saved annotations.svg");
32    Ok(())
33}
examples/density.rs (line 27)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    // Generate two overlapping distributions using deterministic pseudo-random values
6    let value: Vec<f64> = (0..200_u64)
7        .map(|i| {
8            let r = ((i.wrapping_mul(1103515245).wrapping_add(12345)) % (1 << 16)) as f64
9                / (1u64 << 16) as f64;
10            if i < 100 {
11                3.0 + r * 4.0
12            } else {
13                5.0 + r * 4.0
14            }
15        })
16        .collect();
17    let group: Vec<&str> = (0..200)
18        .map(|i| if i < 100 { "Group A" } else { "Group B" })
19        .collect();
20
21    let df = df! {
22        "value" => value,
23        "group" => group,
24    }?;
25
26    GGPlot::new(df)
27        .aes(Aes::new().x("value").color("group"))
28        .geom_density()
29        .title("Density Plot by Group")
30        .xlab("Value")
31        .ylab("Density")
32        .save("density.svg")?;
33
34    println!("Saved density.svg");
35    Ok(())
36}
examples/scatter.rs (line 25)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    let sepal_length: Vec<f64> = (0..50).map(|i| 4.5 + i as f64 * 0.05).collect();
6    let sepal_width: Vec<f64> = (0..50)
7        .map(|i| 2.0 + (i as f64 * 0.3).sin() + i as f64 * 0.02)
8        .collect();
9    let species: Vec<&str> = (0..50)
10        .map(|i| match i % 3 {
11            0 => "setosa",
12            1 => "versicolor",
13            _ => "virginica",
14        })
15        .collect();
16
17    let df = df! {
18        "sepal_length" => sepal_length,
19        "sepal_width" => sepal_width,
20        "species" => species,
21    }?;
22
23    GGPlot::new(df)
24        .aes(
25            Aes::new()
26                .x("sepal_length")
27                .y("sepal_width")
28                .color("species"),
29        )
30        .geom_point()
31        .title("Iris Scatter Plot")
32        .xlab("Sepal Length")
33        .ylab("Sepal Width")
34        .save("scatter.svg")?;
35
36    println!("Saved scatter.svg");
37    Ok(())
38}
Source

pub fn x(self, col: &str) -> Self

Examples found in repository?
examples/bar_chart.rs (line 11)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    let df = df! {
6        "fruit" => ["Apple", "Apple", "Apple", "Banana", "Banana",
7                     "Cherry", "Cherry", "Cherry", "Cherry", "Date"],
8    }?;
9
10    GGPlot::new(df)
11        .aes(Aes::new().x("fruit"))
12        .geom_bar()
13        .title("Fruit Counts")
14        .xlab("Fruit")
15        .ylab("Count")
16        .save("bar_chart.svg")?;
17
18    println!("Saved bar_chart.svg");
19    Ok(())
20}
More examples
Hide additional examples
examples/coord_flip.rs (line 12)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    let df = df! {
6        "language" => ["Rust", "Python", "JavaScript", "Go", "TypeScript", "Java", "C++"],
7        "satisfaction" => [92.0, 88.0, 85.0, 78.0, 82.0, 70.0, 75.0],
8    }?;
9
10    // Horizontal bar chart using coord_flip
11    GGPlot::new(df)
12        .aes(Aes::new().x("language").y("satisfaction"))
13        .geom_col()
14        .coord_flip()
15        .title("Developer Satisfaction by Language")
16        .xlab("Language")
17        .ylab("Satisfaction Score")
18        .save("coord_flip.svg")?;
19
20    println!("Saved coord_flip.svg");
21    Ok(())
22}
examples/gallery.rs (line 47)
35fn scatter() -> Result<(), Box<dyn std::error::Error>> {
36    let n = 150;
37    let x: Vec<f64> = (0..n).map(|i| 4.5 + i as f64 * 0.02).collect();
38    let y: Vec<f64> = (0..n)
39        .map(|i| 2.5 + (i as f64 * 0.15).sin() + (i % 3) as f64 * 0.6)
40        .collect();
41    let species: Vec<&str> = (0..n)
42        .map(|i| ["setosa", "versicolor", "virginica"][i % 3])
43        .collect();
44
45    let df = df! { "x" => x, "y" => y, "species" => species }?;
46    GGPlot::new(df)
47        .aes(Aes::new().x("x").y("y").color("species"))
48        .geom_point()
49        .scale_color_brewer(PaletteName::Set1)
50        .title("Grouped Scatter")
51        .xlab("Sepal Length")
52        .ylab("Sepal Width")
53        .theme_minimal()
54        .save_with_size(&out("scatter"), W, H)?;
55    Ok(())
56}
57
58/// Points overlaid with a LOESS trend line and confidence band.
59fn smooth() -> Result<(), Box<dyn std::error::Error>> {
60    let n = 120;
61    let x: Vec<f64> = (0..n).map(|i| i as f64 * 0.1).collect();
62    let y: Vec<f64> = (0..n)
63        .map(|i| {
64            let t = i as f64 * 0.1;
65            (t * 0.6).sin() * 3.0 + t * 0.2 + ((i * 7919 % 100) as f64 / 100.0 - 0.5) * 1.5
66        })
67        .collect();
68
69    let df = df! { "x" => x, "y" => y }?;
70    GGPlot::new(df)
71        .aes(Aes::new().x("x").y("y"))
72        .geom_point()
73        .geom_smooth_with(GeomSmooth {
74            method: SmoothMethod::Loess { span: 0.5 },
75            ..Default::default()
76        })
77        .title("LOESS Smoothing")
78        .xlab("x")
79        .ylab("y")
80        .theme_bw()
81        .save_with_size(&out("smooth"), W, H)?;
82    Ok(())
83}
84
85/// Histogram of an approximately-normal sample.
86fn histogram() -> Result<(), Box<dyn std::error::Error>> {
87    let values: Vec<f64> = (0..1500)
88        .map(|i: i32| {
89            let r: f64 = (0..6)
90                .map(|k| ((i * (1237 + k * 311) + 5678) % 1000) as f64 / 1000.0)
91                .sum();
92            (r - 3.0) * 2.0
93        })
94        .collect();
95
96    let df = df! { "measurement" => values }?;
97    GGPlot::new(df)
98        .aes(Aes::new().x("measurement"))
99        .geom_histogram_with(GeomHistogram {
100            bins: 30,
101            ..Default::default()
102        })
103        .title("Histogram")
104        .xlab("Value")
105        .ylab("Count")
106        .theme_minimal()
107        .save_with_size(&out("histogram"), W, H)?;
108    Ok(())
109}
110
111/// Bar chart of category counts with a fill palette.
112fn bar() -> Result<(), Box<dyn std::error::Error>> {
113    let mut fruit: Vec<&str> = Vec::new();
114    for (f, c) in [
115        ("Apple", 8),
116        ("Banana", 5),
117        ("Cherry", 11),
118        ("Date", 3),
119        ("Elder", 7),
120    ] {
121        for _ in 0..c {
122            fruit.push(f);
123        }
124    }
125    let df = df! { "fruit" => fruit }?;
126    GGPlot::new(df)
127        .aes(Aes::new().x("fruit").fill("fruit"))
128        .geom_bar()
129        .scale_fill_brewer(PaletteName::Set2)
130        .title("Bar Chart")
131        .xlab("Fruit")
132        .ylab("Count")
133        .theme_minimal()
134        .save_with_size(&out("bar"), W, H)?;
135    Ok(())
136}
137
138/// Grouped boxplots.
139fn boxplot() -> Result<(), Box<dyn std::error::Error>> {
140    let n = 240;
141    let group: Vec<&str> = (0..n).map(|i| ["A", "B", "C", "D"][i % 4]).collect();
142    let value: Vec<f64> = (0..n)
143        .map(|i| {
144            let base = (i % 4) as f64 * 1.5;
145            base + (i as f64 * 0.4).sin() * 1.2 + ((i * 6151 % 100) as f64 / 100.0 - 0.5) * 2.0
146        })
147        .collect();
148
149    let df = df! { "group" => group, "value" => value }?;
150    GGPlot::new(df)
151        .aes(Aes::new().x("group").y("value"))
152        .geom_boxplot_with(GeomBoxplot {
153            fill: (70, 130, 180),
154            ..Default::default()
155        })
156        .title("Boxplot")
157        .xlab("Group")
158        .ylab("Value")
159        .theme_bw()
160        .save_with_size(&out("boxplot"), W, H)?;
161    Ok(())
162}
163
164/// Violin plots of grouped distributions.
165fn violin() -> Result<(), Box<dyn std::error::Error>> {
166    let n = 360;
167    let group: Vec<&str> = (0..n).map(|i| ["X", "Y", "Z"][i % 3]).collect();
168    let value: Vec<f64> = (0..n)
169        .map(|i| {
170            let g = (i % 3) as f64;
171            g * 2.0 + (i as f64 * 0.5).sin() * 1.5 + ((i * 4231 % 100) as f64 / 100.0 - 0.5) * 2.5
172        })
173        .collect();
174
175    let df = df! { "group" => group, "value" => value }?;
176    GGPlot::new(df)
177        .aes(Aes::new().x("group").y("value").fill("group"))
178        .geom_violin()
179        .scale_fill_brewer(PaletteName::Accent)
180        .title("Violin")
181        .xlab("Group")
182        .ylab("Value")
183        .theme_minimal()
184        .save_with_size(&out("violin"), W, H)?;
185    Ok(())
186}
187
188/// Spiral scatter coloured by a continuous variable (viridis).
189fn continuous_color() -> Result<(), Box<dyn std::error::Error>> {
190    let n = 400;
191    let x: Vec<f64> = (0..n)
192        .map(|i| {
193            let t = i as f64 * 0.05;
194            t.cos() * (1.0 + t * 0.12)
195        })
196        .collect();
197    let y: Vec<f64> = (0..n)
198        .map(|i| {
199            let t = i as f64 * 0.05;
200            t.sin() * (1.0 + t * 0.12)
201        })
202        .collect();
203    let z: Vec<f64> = (0..n).map(|i| i as f64 * 0.05).collect();
204
205    let df = df! { "x" => x, "y" => y, "z" => z }?;
206    GGPlot::new(df)
207        .aes(Aes::new().x("x").y("y").color("z"))
208        .geom_point()
209        .scale_color_viridis_c()
210        .title("Continuous Color (viridis)")
211        .xlab("x")
212        .ylab("y")
213        .theme_minimal()
214        .save_with_size(&out("continuous_color"), W, H)?;
215    Ok(())
216}
217
218/// Faceted scatter, one panel per group.
219fn facet() -> Result<(), Box<dyn std::error::Error>> {
220    let n = 180;
221    let x: Vec<f64> = (0..n).map(|i| (i as f64 * 0.1).cos() * 3.0).collect();
222    let y: Vec<f64> = (0..n)
223        .map(|i| (i as f64 * 0.1).sin() * 3.0 + (i % 3) as f64)
224        .collect();
225    let species: Vec<&str> = (0..n)
226        .map(|i| ["setosa", "versicolor", "virginica"][i % 3])
227        .collect();
228
229    let df = df! { "x" => x, "y" => y, "species" => species }?;
230    GGPlot::new(df)
231        .aes(Aes::new().x("x").y("y").color("species"))
232        .geom_point()
233        .facet_wrap("species", Some(3))
234        .scale_color_brewer(PaletteName::Set1)
235        .title("Facet Wrap")
236        .xlab("x")
237        .ylab("y")
238        .theme_bw()
239        .save_with_size(&out("facet"), W, H)?;
240    Ok(())
241}
242
243/// Overlapping density curves by group.
244fn density() -> Result<(), Box<dyn std::error::Error>> {
245    let n = 600;
246    let group: Vec<&str> = (0..n).map(|i| ["Group 1", "Group 2"][i % 2]).collect();
247    let value: Vec<f64> = (0..n)
248        .map(|i| {
249            let shift = (i % 2) as f64 * 2.5;
250            let t = i as f64 * 0.05;
251            shift + (t.sin() + (t * 1.7).cos()) + ((i * 3319 % 100) as f64 / 100.0 - 0.5) * PI
252        })
253        .collect();
254
255    let df = df! { "value" => value, "group" => group }?;
256    GGPlot::new(df)
257        .aes(Aes::new().x("value").fill("group").color("group"))
258        .geom_density()
259        .scale_fill_brewer(PaletteName::Set1)
260        .scale_color_brewer(PaletteName::Set1)
261        .title("Density by Group")
262        .xlab("Value")
263        .ylab("Density")
264        .theme_minimal()
265        .save_with_size(&out("density"), W, H)?;
266    Ok(())
267}
examples/annotations.rs (line 17)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    // Sales data with a notable spike
6    let month: Vec<f64> = (1..=12).map(|i| i as f64).collect();
7    let sales = vec![
8        120.0, 135.0, 150.0, 180.0, 210.0, 310.0, 280.0, 250.0, 190.0, 170.0, 155.0, 140.0,
9    ];
10
11    let df = df! {
12        "month" => month,
13        "sales" => sales,
14    }?;
15
16    GGPlot::new(df)
17        .aes(Aes::new().x("month").y("sales"))
18        .geom_line()
19        .geom_point()
20        // Highlight the peak region
21        .annotate_rect(4.5, 7.5, 100.0, 320.0)
22        // Label the peak
23        .annotate_text("Summer Peak", 6.0, 330.0)
24        // Draw an arrow-like segment pointing to the max
25        .annotate_segment(7.5, 330.0, 6.2, 312.0)
26        .title("Monthly Sales with Annotations")
27        .xlab("Month")
28        .ylab("Sales ($)")
29        .save("annotations.svg")?;
30
31    println!("Saved annotations.svg");
32    Ok(())
33}
examples/density.rs (line 27)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    // Generate two overlapping distributions using deterministic pseudo-random values
6    let value: Vec<f64> = (0..200_u64)
7        .map(|i| {
8            let r = ((i.wrapping_mul(1103515245).wrapping_add(12345)) % (1 << 16)) as f64
9                / (1u64 << 16) as f64;
10            if i < 100 {
11                3.0 + r * 4.0
12            } else {
13                5.0 + r * 4.0
14            }
15        })
16        .collect();
17    let group: Vec<&str> = (0..200)
18        .map(|i| if i < 100 { "Group A" } else { "Group B" })
19        .collect();
20
21    let df = df! {
22        "value" => value,
23        "group" => group,
24    }?;
25
26    GGPlot::new(df)
27        .aes(Aes::new().x("value").color("group"))
28        .geom_density()
29        .title("Density Plot by Group")
30        .xlab("Value")
31        .ylab("Density")
32        .save("density.svg")?;
33
34    println!("Saved density.svg");
35    Ok(())
36}
examples/scatter.rs (line 26)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    let sepal_length: Vec<f64> = (0..50).map(|i| 4.5 + i as f64 * 0.05).collect();
6    let sepal_width: Vec<f64> = (0..50)
7        .map(|i| 2.0 + (i as f64 * 0.3).sin() + i as f64 * 0.02)
8        .collect();
9    let species: Vec<&str> = (0..50)
10        .map(|i| match i % 3 {
11            0 => "setosa",
12            1 => "versicolor",
13            _ => "virginica",
14        })
15        .collect();
16
17    let df = df! {
18        "sepal_length" => sepal_length,
19        "sepal_width" => sepal_width,
20        "species" => species,
21    }?;
22
23    GGPlot::new(df)
24        .aes(
25            Aes::new()
26                .x("sepal_length")
27                .y("sepal_width")
28                .color("species"),
29        )
30        .geom_point()
31        .title("Iris Scatter Plot")
32        .xlab("Sepal Length")
33        .ylab("Sepal Width")
34        .save("scatter.svg")?;
35
36    println!("Saved scatter.svg");
37    Ok(())
38}
Source

pub fn y(self, col: &str) -> Self

Examples found in repository?
examples/coord_flip.rs (line 12)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    let df = df! {
6        "language" => ["Rust", "Python", "JavaScript", "Go", "TypeScript", "Java", "C++"],
7        "satisfaction" => [92.0, 88.0, 85.0, 78.0, 82.0, 70.0, 75.0],
8    }?;
9
10    // Horizontal bar chart using coord_flip
11    GGPlot::new(df)
12        .aes(Aes::new().x("language").y("satisfaction"))
13        .geom_col()
14        .coord_flip()
15        .title("Developer Satisfaction by Language")
16        .xlab("Language")
17        .ylab("Satisfaction Score")
18        .save("coord_flip.svg")?;
19
20    println!("Saved coord_flip.svg");
21    Ok(())
22}
More examples
Hide additional examples
examples/gallery.rs (line 47)
35fn scatter() -> Result<(), Box<dyn std::error::Error>> {
36    let n = 150;
37    let x: Vec<f64> = (0..n).map(|i| 4.5 + i as f64 * 0.02).collect();
38    let y: Vec<f64> = (0..n)
39        .map(|i| 2.5 + (i as f64 * 0.15).sin() + (i % 3) as f64 * 0.6)
40        .collect();
41    let species: Vec<&str> = (0..n)
42        .map(|i| ["setosa", "versicolor", "virginica"][i % 3])
43        .collect();
44
45    let df = df! { "x" => x, "y" => y, "species" => species }?;
46    GGPlot::new(df)
47        .aes(Aes::new().x("x").y("y").color("species"))
48        .geom_point()
49        .scale_color_brewer(PaletteName::Set1)
50        .title("Grouped Scatter")
51        .xlab("Sepal Length")
52        .ylab("Sepal Width")
53        .theme_minimal()
54        .save_with_size(&out("scatter"), W, H)?;
55    Ok(())
56}
57
58/// Points overlaid with a LOESS trend line and confidence band.
59fn smooth() -> Result<(), Box<dyn std::error::Error>> {
60    let n = 120;
61    let x: Vec<f64> = (0..n).map(|i| i as f64 * 0.1).collect();
62    let y: Vec<f64> = (0..n)
63        .map(|i| {
64            let t = i as f64 * 0.1;
65            (t * 0.6).sin() * 3.0 + t * 0.2 + ((i * 7919 % 100) as f64 / 100.0 - 0.5) * 1.5
66        })
67        .collect();
68
69    let df = df! { "x" => x, "y" => y }?;
70    GGPlot::new(df)
71        .aes(Aes::new().x("x").y("y"))
72        .geom_point()
73        .geom_smooth_with(GeomSmooth {
74            method: SmoothMethod::Loess { span: 0.5 },
75            ..Default::default()
76        })
77        .title("LOESS Smoothing")
78        .xlab("x")
79        .ylab("y")
80        .theme_bw()
81        .save_with_size(&out("smooth"), W, H)?;
82    Ok(())
83}
84
85/// Histogram of an approximately-normal sample.
86fn histogram() -> Result<(), Box<dyn std::error::Error>> {
87    let values: Vec<f64> = (0..1500)
88        .map(|i: i32| {
89            let r: f64 = (0..6)
90                .map(|k| ((i * (1237 + k * 311) + 5678) % 1000) as f64 / 1000.0)
91                .sum();
92            (r - 3.0) * 2.0
93        })
94        .collect();
95
96    let df = df! { "measurement" => values }?;
97    GGPlot::new(df)
98        .aes(Aes::new().x("measurement"))
99        .geom_histogram_with(GeomHistogram {
100            bins: 30,
101            ..Default::default()
102        })
103        .title("Histogram")
104        .xlab("Value")
105        .ylab("Count")
106        .theme_minimal()
107        .save_with_size(&out("histogram"), W, H)?;
108    Ok(())
109}
110
111/// Bar chart of category counts with a fill palette.
112fn bar() -> Result<(), Box<dyn std::error::Error>> {
113    let mut fruit: Vec<&str> = Vec::new();
114    for (f, c) in [
115        ("Apple", 8),
116        ("Banana", 5),
117        ("Cherry", 11),
118        ("Date", 3),
119        ("Elder", 7),
120    ] {
121        for _ in 0..c {
122            fruit.push(f);
123        }
124    }
125    let df = df! { "fruit" => fruit }?;
126    GGPlot::new(df)
127        .aes(Aes::new().x("fruit").fill("fruit"))
128        .geom_bar()
129        .scale_fill_brewer(PaletteName::Set2)
130        .title("Bar Chart")
131        .xlab("Fruit")
132        .ylab("Count")
133        .theme_minimal()
134        .save_with_size(&out("bar"), W, H)?;
135    Ok(())
136}
137
138/// Grouped boxplots.
139fn boxplot() -> Result<(), Box<dyn std::error::Error>> {
140    let n = 240;
141    let group: Vec<&str> = (0..n).map(|i| ["A", "B", "C", "D"][i % 4]).collect();
142    let value: Vec<f64> = (0..n)
143        .map(|i| {
144            let base = (i % 4) as f64 * 1.5;
145            base + (i as f64 * 0.4).sin() * 1.2 + ((i * 6151 % 100) as f64 / 100.0 - 0.5) * 2.0
146        })
147        .collect();
148
149    let df = df! { "group" => group, "value" => value }?;
150    GGPlot::new(df)
151        .aes(Aes::new().x("group").y("value"))
152        .geom_boxplot_with(GeomBoxplot {
153            fill: (70, 130, 180),
154            ..Default::default()
155        })
156        .title("Boxplot")
157        .xlab("Group")
158        .ylab("Value")
159        .theme_bw()
160        .save_with_size(&out("boxplot"), W, H)?;
161    Ok(())
162}
163
164/// Violin plots of grouped distributions.
165fn violin() -> Result<(), Box<dyn std::error::Error>> {
166    let n = 360;
167    let group: Vec<&str> = (0..n).map(|i| ["X", "Y", "Z"][i % 3]).collect();
168    let value: Vec<f64> = (0..n)
169        .map(|i| {
170            let g = (i % 3) as f64;
171            g * 2.0 + (i as f64 * 0.5).sin() * 1.5 + ((i * 4231 % 100) as f64 / 100.0 - 0.5) * 2.5
172        })
173        .collect();
174
175    let df = df! { "group" => group, "value" => value }?;
176    GGPlot::new(df)
177        .aes(Aes::new().x("group").y("value").fill("group"))
178        .geom_violin()
179        .scale_fill_brewer(PaletteName::Accent)
180        .title("Violin")
181        .xlab("Group")
182        .ylab("Value")
183        .theme_minimal()
184        .save_with_size(&out("violin"), W, H)?;
185    Ok(())
186}
187
188/// Spiral scatter coloured by a continuous variable (viridis).
189fn continuous_color() -> Result<(), Box<dyn std::error::Error>> {
190    let n = 400;
191    let x: Vec<f64> = (0..n)
192        .map(|i| {
193            let t = i as f64 * 0.05;
194            t.cos() * (1.0 + t * 0.12)
195        })
196        .collect();
197    let y: Vec<f64> = (0..n)
198        .map(|i| {
199            let t = i as f64 * 0.05;
200            t.sin() * (1.0 + t * 0.12)
201        })
202        .collect();
203    let z: Vec<f64> = (0..n).map(|i| i as f64 * 0.05).collect();
204
205    let df = df! { "x" => x, "y" => y, "z" => z }?;
206    GGPlot::new(df)
207        .aes(Aes::new().x("x").y("y").color("z"))
208        .geom_point()
209        .scale_color_viridis_c()
210        .title("Continuous Color (viridis)")
211        .xlab("x")
212        .ylab("y")
213        .theme_minimal()
214        .save_with_size(&out("continuous_color"), W, H)?;
215    Ok(())
216}
217
218/// Faceted scatter, one panel per group.
219fn facet() -> Result<(), Box<dyn std::error::Error>> {
220    let n = 180;
221    let x: Vec<f64> = (0..n).map(|i| (i as f64 * 0.1).cos() * 3.0).collect();
222    let y: Vec<f64> = (0..n)
223        .map(|i| (i as f64 * 0.1).sin() * 3.0 + (i % 3) as f64)
224        .collect();
225    let species: Vec<&str> = (0..n)
226        .map(|i| ["setosa", "versicolor", "virginica"][i % 3])
227        .collect();
228
229    let df = df! { "x" => x, "y" => y, "species" => species }?;
230    GGPlot::new(df)
231        .aes(Aes::new().x("x").y("y").color("species"))
232        .geom_point()
233        .facet_wrap("species", Some(3))
234        .scale_color_brewer(PaletteName::Set1)
235        .title("Facet Wrap")
236        .xlab("x")
237        .ylab("y")
238        .theme_bw()
239        .save_with_size(&out("facet"), W, H)?;
240    Ok(())
241}
examples/annotations.rs (line 17)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    // Sales data with a notable spike
6    let month: Vec<f64> = (1..=12).map(|i| i as f64).collect();
7    let sales = vec![
8        120.0, 135.0, 150.0, 180.0, 210.0, 310.0, 280.0, 250.0, 190.0, 170.0, 155.0, 140.0,
9    ];
10
11    let df = df! {
12        "month" => month,
13        "sales" => sales,
14    }?;
15
16    GGPlot::new(df)
17        .aes(Aes::new().x("month").y("sales"))
18        .geom_line()
19        .geom_point()
20        // Highlight the peak region
21        .annotate_rect(4.5, 7.5, 100.0, 320.0)
22        // Label the peak
23        .annotate_text("Summer Peak", 6.0, 330.0)
24        // Draw an arrow-like segment pointing to the max
25        .annotate_segment(7.5, 330.0, 6.2, 312.0)
26        .title("Monthly Sales with Annotations")
27        .xlab("Month")
28        .ylab("Sales ($)")
29        .save("annotations.svg")?;
30
31    println!("Saved annotations.svg");
32    Ok(())
33}
examples/scatter.rs (line 27)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    let sepal_length: Vec<f64> = (0..50).map(|i| 4.5 + i as f64 * 0.05).collect();
6    let sepal_width: Vec<f64> = (0..50)
7        .map(|i| 2.0 + (i as f64 * 0.3).sin() + i as f64 * 0.02)
8        .collect();
9    let species: Vec<&str> = (0..50)
10        .map(|i| match i % 3 {
11            0 => "setosa",
12            1 => "versicolor",
13            _ => "virginica",
14        })
15        .collect();
16
17    let df = df! {
18        "sepal_length" => sepal_length,
19        "sepal_width" => sepal_width,
20        "species" => species,
21    }?;
22
23    GGPlot::new(df)
24        .aes(
25            Aes::new()
26                .x("sepal_length")
27                .y("sepal_width")
28                .color("species"),
29        )
30        .geom_point()
31        .title("Iris Scatter Plot")
32        .xlab("Sepal Length")
33        .ylab("Sepal Width")
34        .save("scatter.svg")?;
35
36    println!("Saved scatter.svg");
37    Ok(())
38}
examples/loess_smooth.rs (line 22)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    // Generate noisy sine wave data
6    let x: Vec<f64> = (0..80).map(|i| (i as f64) * 0.1).collect();
7    let y: Vec<f64> = (0..80)
8        .map(|i| {
9            let xv = (i as f64) * 0.1;
10            let noise = ((i * 17 + 3) % 11) as f64 / 11.0 - 0.5; // deterministic pseudo-noise
11            (xv * 0.8).sin() * 2.0 + noise * 1.5
12        })
13        .collect();
14
15    let df = df! {
16        "x" => &x,
17        "y" => &y,
18    }?;
19
20    // Linear smooth (default)
21    GGPlot::new(df.clone())
22        .aes(Aes::new().x("x").y("y"))
23        .geom_point()
24        .geom_smooth()
25        .title("Linear Smooth (method = lm)")
26        .save("smooth_lm.svg")?;
27
28    println!("Saved smooth_lm.svg");
29
30    // LOESS smooth
31    GGPlot::new(df)
32        .aes(Aes::new().x("x").y("y"))
33        .geom_point()
34        .geom_smooth_with(GeomSmooth::default().loess(0.3))
35        .title("LOESS Smooth (span = 0.3)")
36        .save("smooth_loess.svg")?;
37
38    println!("Saved smooth_loess.svg");
39    Ok(())
40}
examples/log_scale.rs (line 22)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    // Exponential growth data (e.g., population, bacteria count)
6    let year: Vec<f64> = (0..30).map(|i| 1990.0 + i as f64).collect();
7    let count: Vec<f64> = (0..30)
8        .map(|i| {
9            let base = 100.0 * (1.15_f64).powi(i); // 15% growth per year
10            let noise = ((i * 37 + 7) % 13) as f64 / 13.0 * 0.2 + 0.9;
11            base * noise
12        })
13        .collect();
14
15    let df = df! {
16        "year" => &year,
17        "count" => &count,
18    }?;
19
20    // Linear scale — exponential curve
21    GGPlot::new(df.clone())
22        .aes(Aes::new().x("year").y("count"))
23        .geom_point()
24        .geom_line()
25        .title("Exponential Growth (Linear Scale)")
26        .xlab("Year")
27        .ylab("Count")
28        .save("log_scale_linear.svg")?;
29
30    println!("Saved log_scale_linear.svg");
31
32    // Log10 y-axis — should appear roughly linear
33    GGPlot::new(df)
34        .aes(Aes::new().x("year").y("count"))
35        .geom_point()
36        .geom_line()
37        .scale_y_log10()
38        .title("Exponential Growth (Log10 Y Scale)")
39        .xlab("Year")
40        .ylab("Count (log10)")
41        .save("log_scale_log10.svg")?;
42
43    println!("Saved log_scale_log10.svg");
44    Ok(())
45}
Source

pub fn color(self, col: &str) -> Self

Examples found in repository?
examples/gallery.rs (line 47)
35fn scatter() -> Result<(), Box<dyn std::error::Error>> {
36    let n = 150;
37    let x: Vec<f64> = (0..n).map(|i| 4.5 + i as f64 * 0.02).collect();
38    let y: Vec<f64> = (0..n)
39        .map(|i| 2.5 + (i as f64 * 0.15).sin() + (i % 3) as f64 * 0.6)
40        .collect();
41    let species: Vec<&str> = (0..n)
42        .map(|i| ["setosa", "versicolor", "virginica"][i % 3])
43        .collect();
44
45    let df = df! { "x" => x, "y" => y, "species" => species }?;
46    GGPlot::new(df)
47        .aes(Aes::new().x("x").y("y").color("species"))
48        .geom_point()
49        .scale_color_brewer(PaletteName::Set1)
50        .title("Grouped Scatter")
51        .xlab("Sepal Length")
52        .ylab("Sepal Width")
53        .theme_minimal()
54        .save_with_size(&out("scatter"), W, H)?;
55    Ok(())
56}
57
58/// Points overlaid with a LOESS trend line and confidence band.
59fn smooth() -> Result<(), Box<dyn std::error::Error>> {
60    let n = 120;
61    let x: Vec<f64> = (0..n).map(|i| i as f64 * 0.1).collect();
62    let y: Vec<f64> = (0..n)
63        .map(|i| {
64            let t = i as f64 * 0.1;
65            (t * 0.6).sin() * 3.0 + t * 0.2 + ((i * 7919 % 100) as f64 / 100.0 - 0.5) * 1.5
66        })
67        .collect();
68
69    let df = df! { "x" => x, "y" => y }?;
70    GGPlot::new(df)
71        .aes(Aes::new().x("x").y("y"))
72        .geom_point()
73        .geom_smooth_with(GeomSmooth {
74            method: SmoothMethod::Loess { span: 0.5 },
75            ..Default::default()
76        })
77        .title("LOESS Smoothing")
78        .xlab("x")
79        .ylab("y")
80        .theme_bw()
81        .save_with_size(&out("smooth"), W, H)?;
82    Ok(())
83}
84
85/// Histogram of an approximately-normal sample.
86fn histogram() -> Result<(), Box<dyn std::error::Error>> {
87    let values: Vec<f64> = (0..1500)
88        .map(|i: i32| {
89            let r: f64 = (0..6)
90                .map(|k| ((i * (1237 + k * 311) + 5678) % 1000) as f64 / 1000.0)
91                .sum();
92            (r - 3.0) * 2.0
93        })
94        .collect();
95
96    let df = df! { "measurement" => values }?;
97    GGPlot::new(df)
98        .aes(Aes::new().x("measurement"))
99        .geom_histogram_with(GeomHistogram {
100            bins: 30,
101            ..Default::default()
102        })
103        .title("Histogram")
104        .xlab("Value")
105        .ylab("Count")
106        .theme_minimal()
107        .save_with_size(&out("histogram"), W, H)?;
108    Ok(())
109}
110
111/// Bar chart of category counts with a fill palette.
112fn bar() -> Result<(), Box<dyn std::error::Error>> {
113    let mut fruit: Vec<&str> = Vec::new();
114    for (f, c) in [
115        ("Apple", 8),
116        ("Banana", 5),
117        ("Cherry", 11),
118        ("Date", 3),
119        ("Elder", 7),
120    ] {
121        for _ in 0..c {
122            fruit.push(f);
123        }
124    }
125    let df = df! { "fruit" => fruit }?;
126    GGPlot::new(df)
127        .aes(Aes::new().x("fruit").fill("fruit"))
128        .geom_bar()
129        .scale_fill_brewer(PaletteName::Set2)
130        .title("Bar Chart")
131        .xlab("Fruit")
132        .ylab("Count")
133        .theme_minimal()
134        .save_with_size(&out("bar"), W, H)?;
135    Ok(())
136}
137
138/// Grouped boxplots.
139fn boxplot() -> Result<(), Box<dyn std::error::Error>> {
140    let n = 240;
141    let group: Vec<&str> = (0..n).map(|i| ["A", "B", "C", "D"][i % 4]).collect();
142    let value: Vec<f64> = (0..n)
143        .map(|i| {
144            let base = (i % 4) as f64 * 1.5;
145            base + (i as f64 * 0.4).sin() * 1.2 + ((i * 6151 % 100) as f64 / 100.0 - 0.5) * 2.0
146        })
147        .collect();
148
149    let df = df! { "group" => group, "value" => value }?;
150    GGPlot::new(df)
151        .aes(Aes::new().x("group").y("value"))
152        .geom_boxplot_with(GeomBoxplot {
153            fill: (70, 130, 180),
154            ..Default::default()
155        })
156        .title("Boxplot")
157        .xlab("Group")
158        .ylab("Value")
159        .theme_bw()
160        .save_with_size(&out("boxplot"), W, H)?;
161    Ok(())
162}
163
164/// Violin plots of grouped distributions.
165fn violin() -> Result<(), Box<dyn std::error::Error>> {
166    let n = 360;
167    let group: Vec<&str> = (0..n).map(|i| ["X", "Y", "Z"][i % 3]).collect();
168    let value: Vec<f64> = (0..n)
169        .map(|i| {
170            let g = (i % 3) as f64;
171            g * 2.0 + (i as f64 * 0.5).sin() * 1.5 + ((i * 4231 % 100) as f64 / 100.0 - 0.5) * 2.5
172        })
173        .collect();
174
175    let df = df! { "group" => group, "value" => value }?;
176    GGPlot::new(df)
177        .aes(Aes::new().x("group").y("value").fill("group"))
178        .geom_violin()
179        .scale_fill_brewer(PaletteName::Accent)
180        .title("Violin")
181        .xlab("Group")
182        .ylab("Value")
183        .theme_minimal()
184        .save_with_size(&out("violin"), W, H)?;
185    Ok(())
186}
187
188/// Spiral scatter coloured by a continuous variable (viridis).
189fn continuous_color() -> Result<(), Box<dyn std::error::Error>> {
190    let n = 400;
191    let x: Vec<f64> = (0..n)
192        .map(|i| {
193            let t = i as f64 * 0.05;
194            t.cos() * (1.0 + t * 0.12)
195        })
196        .collect();
197    let y: Vec<f64> = (0..n)
198        .map(|i| {
199            let t = i as f64 * 0.05;
200            t.sin() * (1.0 + t * 0.12)
201        })
202        .collect();
203    let z: Vec<f64> = (0..n).map(|i| i as f64 * 0.05).collect();
204
205    let df = df! { "x" => x, "y" => y, "z" => z }?;
206    GGPlot::new(df)
207        .aes(Aes::new().x("x").y("y").color("z"))
208        .geom_point()
209        .scale_color_viridis_c()
210        .title("Continuous Color (viridis)")
211        .xlab("x")
212        .ylab("y")
213        .theme_minimal()
214        .save_with_size(&out("continuous_color"), W, H)?;
215    Ok(())
216}
217
218/// Faceted scatter, one panel per group.
219fn facet() -> Result<(), Box<dyn std::error::Error>> {
220    let n = 180;
221    let x: Vec<f64> = (0..n).map(|i| (i as f64 * 0.1).cos() * 3.0).collect();
222    let y: Vec<f64> = (0..n)
223        .map(|i| (i as f64 * 0.1).sin() * 3.0 + (i % 3) as f64)
224        .collect();
225    let species: Vec<&str> = (0..n)
226        .map(|i| ["setosa", "versicolor", "virginica"][i % 3])
227        .collect();
228
229    let df = df! { "x" => x, "y" => y, "species" => species }?;
230    GGPlot::new(df)
231        .aes(Aes::new().x("x").y("y").color("species"))
232        .geom_point()
233        .facet_wrap("species", Some(3))
234        .scale_color_brewer(PaletteName::Set1)
235        .title("Facet Wrap")
236        .xlab("x")
237        .ylab("y")
238        .theme_bw()
239        .save_with_size(&out("facet"), W, H)?;
240    Ok(())
241}
242
243/// Overlapping density curves by group.
244fn density() -> Result<(), Box<dyn std::error::Error>> {
245    let n = 600;
246    let group: Vec<&str> = (0..n).map(|i| ["Group 1", "Group 2"][i % 2]).collect();
247    let value: Vec<f64> = (0..n)
248        .map(|i| {
249            let shift = (i % 2) as f64 * 2.5;
250            let t = i as f64 * 0.05;
251            shift + (t.sin() + (t * 1.7).cos()) + ((i * 3319 % 100) as f64 / 100.0 - 0.5) * PI
252        })
253        .collect();
254
255    let df = df! { "value" => value, "group" => group }?;
256    GGPlot::new(df)
257        .aes(Aes::new().x("value").fill("group").color("group"))
258        .geom_density()
259        .scale_fill_brewer(PaletteName::Set1)
260        .scale_color_brewer(PaletteName::Set1)
261        .title("Density by Group")
262        .xlab("Value")
263        .ylab("Density")
264        .theme_minimal()
265        .save_with_size(&out("density"), W, H)?;
266    Ok(())
267}
More examples
Hide additional examples
examples/density.rs (line 27)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    // Generate two overlapping distributions using deterministic pseudo-random values
6    let value: Vec<f64> = (0..200_u64)
7        .map(|i| {
8            let r = ((i.wrapping_mul(1103515245).wrapping_add(12345)) % (1 << 16)) as f64
9                / (1u64 << 16) as f64;
10            if i < 100 {
11                3.0 + r * 4.0
12            } else {
13                5.0 + r * 4.0
14            }
15        })
16        .collect();
17    let group: Vec<&str> = (0..200)
18        .map(|i| if i < 100 { "Group A" } else { "Group B" })
19        .collect();
20
21    let df = df! {
22        "value" => value,
23        "group" => group,
24    }?;
25
26    GGPlot::new(df)
27        .aes(Aes::new().x("value").color("group"))
28        .geom_density()
29        .title("Density Plot by Group")
30        .xlab("Value")
31        .ylab("Density")
32        .save("density.svg")?;
33
34    println!("Saved density.svg");
35    Ok(())
36}
examples/scatter.rs (line 28)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    let sepal_length: Vec<f64> = (0..50).map(|i| 4.5 + i as f64 * 0.05).collect();
6    let sepal_width: Vec<f64> = (0..50)
7        .map(|i| 2.0 + (i as f64 * 0.3).sin() + i as f64 * 0.02)
8        .collect();
9    let species: Vec<&str> = (0..50)
10        .map(|i| match i % 3 {
11            0 => "setosa",
12            1 => "versicolor",
13            _ => "virginica",
14        })
15        .collect();
16
17    let df = df! {
18        "sepal_length" => sepal_length,
19        "sepal_width" => sepal_width,
20        "species" => species,
21    }?;
22
23    GGPlot::new(df)
24        .aes(
25            Aes::new()
26                .x("sepal_length")
27                .y("sepal_width")
28                .color("species"),
29        )
30        .geom_point()
31        .title("Iris Scatter Plot")
32        .xlab("Sepal Length")
33        .ylab("Sepal Width")
34        .save("scatter.svg")?;
35
36    println!("Saved scatter.svg");
37    Ok(())
38}
examples/continuous_color.rs (line 28)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    // Generate scatter data with a continuous variable for color
6    let x: Vec<f64> = (0..200)
7        .map(|i| {
8            let t = i as f64 * 0.05;
9            t.cos() * (1.0 + t * 0.3)
10        })
11        .collect();
12    let y: Vec<f64> = (0..200)
13        .map(|i| {
14            let t = i as f64 * 0.05;
15            t.sin() * (1.0 + t * 0.3)
16        })
17        .collect();
18    let z: Vec<f64> = (0..200).map(|i| i as f64 * 0.05).collect();
19
20    let df = df! {
21        "x" => &x,
22        "y" => &y,
23        "z" => &z,
24    }?;
25
26    // Default blue-to-red gradient
27    GGPlot::new(df.clone())
28        .aes(Aes::new().x("x").y("y").color("z"))
29        .geom_point()
30        .title("Continuous Color (default gradient)")
31        .xlab("X")
32        .ylab("Y")
33        .save("continuous_color.svg")?;
34
35    println!("Saved continuous_color.svg");
36
37    // Custom gradient: dark blue to yellow
38    GGPlot::new(df)
39        .aes(Aes::new().x("x").y("y").color("z"))
40        .geom_point()
41        .scale_color_gradient(RGBAColor::new(10, 30, 100), RGBAColor::new(255, 230, 50))
42        .title("Continuous Color (custom gradient)")
43        .xlab("X")
44        .ylab("Y")
45        .save("continuous_color_custom.svg")?;
46
47    println!("Saved continuous_color_custom.svg");
48    Ok(())
49}
examples/supplier_leadtime.rs (line 263)
246fn compare(rows: &[Po]) -> Result<(), Box<dyn std::error::Error>> {
247    let lead: Vec<Value> = rows
248        .iter()
249        .filter(|p| p.attributable)
250        .map(|p| Value::Float(p.lead))
251        .collect();
252    let supplier: Vec<Value> = rows
253        .iter()
254        .filter(|p| p.attributable)
255        .map(|p| Value::Str(p.supplier.to_string()))
256        .collect();
257    let data: Vec<(String, Vec<Value>)> = vec![
258        ("lead".to_string(), lead),
259        ("supplier".to_string(), supplier),
260    ];
261
262    GGPlot::new(data)
263        .aes(Aes::new().x("lead").fill("supplier").color("supplier"))
264        .geom_density_with(GeomDensity {
265            alpha: 0.35,
266            line_width: 1.2,
267            ..Default::default()
268        })
269        .geom_vline_with(GeomVline {
270            xintercept: CONTRACT,
271            color: CONTRACT_RED,
272            width: 1.2,
273            linetype: Linetype::Dashed,
274            alpha: 1.0,
275        })
276        .scale_fill_brewer(PaletteName::Dark2)
277        .scale_color_brewer(PaletteName::Dark2)
278        .annotate_text("contract", CONTRACT + 1.0, 0.005)
279        .title("Lead-time distributions by supplier")
280        .subtitle("attributable deliveries; dashed line = contracted lead time")
281        .xlab("Actual lead time (days)")
282        .ylab("Density")
283        .theme_minimal()
284        .save_with_size(&out("supplier_leadtime_compare"), W, H)?;
285    Ok(())
286}
examples/faceted.rs (line 36)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    // Generate data with two grouping variables
6    let sepal_length: Vec<f64> = (0..120)
7        .map(|i| 4.0 + (i as f64) * 0.04 + (i as f64 * 0.5).sin() * 0.3)
8        .collect();
9    let sepal_width: Vec<f64> = (0..120)
10        .map(|i| 2.0 + (i as f64) * 0.015 + (i as f64 * 0.3).cos() * 0.4)
11        .collect();
12    let species: Vec<&str> = (0..120)
13        .map(|i| match i % 3 {
14            0 => "setosa",
15            1 => "versicolor",
16            _ => "virginica",
17        })
18        .collect();
19    let region: Vec<&str> = (0..120)
20        .map(|i| if i % 2 == 0 { "North" } else { "South" })
21        .collect();
22
23    let df = df! {
24        "sepal_length" => sepal_length,
25        "sepal_width" => sepal_width,
26        "species" => species,
27        "region" => region,
28    }?;
29
30    // facet_wrap: one variable, automatic grid layout
31    GGPlot::new(df.clone())
32        .aes(
33            Aes::new()
34                .x("sepal_length")
35                .y("sepal_width")
36                .color("species"),
37        )
38        .geom_point()
39        .facet_wrap("species", Some(2))
40        .title("Facet Wrap by Species")
41        .xlab("Sepal Length")
42        .ylab("Sepal Width")
43        .save("facet_wrap.svg")?;
44
45    println!("Saved facet_wrap.svg");
46
47    // facet_grid: two variables, row ~ col layout
48    GGPlot::new(df)
49        .aes(
50            Aes::new()
51                .x("sepal_length")
52                .y("sepal_width")
53                .color("species"),
54        )
55        .geom_point()
56        .facet_grid(Some("region"), Some("species"))
57        .title("Facet Grid: Region ~ Species")
58        .xlab("Sepal Length")
59        .ylab("Sepal Width")
60        .save("facet_grid.svg")?;
61
62    println!("Saved facet_grid.svg");
63    Ok(())
64}
Source

pub fn fill(self, col: &str) -> Self

Examples found in repository?
examples/gallery.rs (line 127)
112fn bar() -> Result<(), Box<dyn std::error::Error>> {
113    let mut fruit: Vec<&str> = Vec::new();
114    for (f, c) in [
115        ("Apple", 8),
116        ("Banana", 5),
117        ("Cherry", 11),
118        ("Date", 3),
119        ("Elder", 7),
120    ] {
121        for _ in 0..c {
122            fruit.push(f);
123        }
124    }
125    let df = df! { "fruit" => fruit }?;
126    GGPlot::new(df)
127        .aes(Aes::new().x("fruit").fill("fruit"))
128        .geom_bar()
129        .scale_fill_brewer(PaletteName::Set2)
130        .title("Bar Chart")
131        .xlab("Fruit")
132        .ylab("Count")
133        .theme_minimal()
134        .save_with_size(&out("bar"), W, H)?;
135    Ok(())
136}
137
138/// Grouped boxplots.
139fn boxplot() -> Result<(), Box<dyn std::error::Error>> {
140    let n = 240;
141    let group: Vec<&str> = (0..n).map(|i| ["A", "B", "C", "D"][i % 4]).collect();
142    let value: Vec<f64> = (0..n)
143        .map(|i| {
144            let base = (i % 4) as f64 * 1.5;
145            base + (i as f64 * 0.4).sin() * 1.2 + ((i * 6151 % 100) as f64 / 100.0 - 0.5) * 2.0
146        })
147        .collect();
148
149    let df = df! { "group" => group, "value" => value }?;
150    GGPlot::new(df)
151        .aes(Aes::new().x("group").y("value"))
152        .geom_boxplot_with(GeomBoxplot {
153            fill: (70, 130, 180),
154            ..Default::default()
155        })
156        .title("Boxplot")
157        .xlab("Group")
158        .ylab("Value")
159        .theme_bw()
160        .save_with_size(&out("boxplot"), W, H)?;
161    Ok(())
162}
163
164/// Violin plots of grouped distributions.
165fn violin() -> Result<(), Box<dyn std::error::Error>> {
166    let n = 360;
167    let group: Vec<&str> = (0..n).map(|i| ["X", "Y", "Z"][i % 3]).collect();
168    let value: Vec<f64> = (0..n)
169        .map(|i| {
170            let g = (i % 3) as f64;
171            g * 2.0 + (i as f64 * 0.5).sin() * 1.5 + ((i * 4231 % 100) as f64 / 100.0 - 0.5) * 2.5
172        })
173        .collect();
174
175    let df = df! { "group" => group, "value" => value }?;
176    GGPlot::new(df)
177        .aes(Aes::new().x("group").y("value").fill("group"))
178        .geom_violin()
179        .scale_fill_brewer(PaletteName::Accent)
180        .title("Violin")
181        .xlab("Group")
182        .ylab("Value")
183        .theme_minimal()
184        .save_with_size(&out("violin"), W, H)?;
185    Ok(())
186}
187
188/// Spiral scatter coloured by a continuous variable (viridis).
189fn continuous_color() -> Result<(), Box<dyn std::error::Error>> {
190    let n = 400;
191    let x: Vec<f64> = (0..n)
192        .map(|i| {
193            let t = i as f64 * 0.05;
194            t.cos() * (1.0 + t * 0.12)
195        })
196        .collect();
197    let y: Vec<f64> = (0..n)
198        .map(|i| {
199            let t = i as f64 * 0.05;
200            t.sin() * (1.0 + t * 0.12)
201        })
202        .collect();
203    let z: Vec<f64> = (0..n).map(|i| i as f64 * 0.05).collect();
204
205    let df = df! { "x" => x, "y" => y, "z" => z }?;
206    GGPlot::new(df)
207        .aes(Aes::new().x("x").y("y").color("z"))
208        .geom_point()
209        .scale_color_viridis_c()
210        .title("Continuous Color (viridis)")
211        .xlab("x")
212        .ylab("y")
213        .theme_minimal()
214        .save_with_size(&out("continuous_color"), W, H)?;
215    Ok(())
216}
217
218/// Faceted scatter, one panel per group.
219fn facet() -> Result<(), Box<dyn std::error::Error>> {
220    let n = 180;
221    let x: Vec<f64> = (0..n).map(|i| (i as f64 * 0.1).cos() * 3.0).collect();
222    let y: Vec<f64> = (0..n)
223        .map(|i| (i as f64 * 0.1).sin() * 3.0 + (i % 3) as f64)
224        .collect();
225    let species: Vec<&str> = (0..n)
226        .map(|i| ["setosa", "versicolor", "virginica"][i % 3])
227        .collect();
228
229    let df = df! { "x" => x, "y" => y, "species" => species }?;
230    GGPlot::new(df)
231        .aes(Aes::new().x("x").y("y").color("species"))
232        .geom_point()
233        .facet_wrap("species", Some(3))
234        .scale_color_brewer(PaletteName::Set1)
235        .title("Facet Wrap")
236        .xlab("x")
237        .ylab("y")
238        .theme_bw()
239        .save_with_size(&out("facet"), W, H)?;
240    Ok(())
241}
242
243/// Overlapping density curves by group.
244fn density() -> Result<(), Box<dyn std::error::Error>> {
245    let n = 600;
246    let group: Vec<&str> = (0..n).map(|i| ["Group 1", "Group 2"][i % 2]).collect();
247    let value: Vec<f64> = (0..n)
248        .map(|i| {
249            let shift = (i % 2) as f64 * 2.5;
250            let t = i as f64 * 0.05;
251            shift + (t.sin() + (t * 1.7).cos()) + ((i * 3319 % 100) as f64 / 100.0 - 0.5) * PI
252        })
253        .collect();
254
255    let df = df! { "value" => value, "group" => group }?;
256    GGPlot::new(df)
257        .aes(Aes::new().x("value").fill("group").color("group"))
258        .geom_density()
259        .scale_fill_brewer(PaletteName::Set1)
260        .scale_color_brewer(PaletteName::Set1)
261        .title("Density by Group")
262        .xlab("Value")
263        .ylab("Density")
264        .theme_minimal()
265        .save_with_size(&out("density"), W, H)?;
266    Ok(())
267}
More examples
Hide additional examples
examples/supplier_leadtime.rs (line 263)
246fn compare(rows: &[Po]) -> Result<(), Box<dyn std::error::Error>> {
247    let lead: Vec<Value> = rows
248        .iter()
249        .filter(|p| p.attributable)
250        .map(|p| Value::Float(p.lead))
251        .collect();
252    let supplier: Vec<Value> = rows
253        .iter()
254        .filter(|p| p.attributable)
255        .map(|p| Value::Str(p.supplier.to_string()))
256        .collect();
257    let data: Vec<(String, Vec<Value>)> = vec![
258        ("lead".to_string(), lead),
259        ("supplier".to_string(), supplier),
260    ];
261
262    GGPlot::new(data)
263        .aes(Aes::new().x("lead").fill("supplier").color("supplier"))
264        .geom_density_with(GeomDensity {
265            alpha: 0.35,
266            line_width: 1.2,
267            ..Default::default()
268        })
269        .geom_vline_with(GeomVline {
270            xintercept: CONTRACT,
271            color: CONTRACT_RED,
272            width: 1.2,
273            linetype: Linetype::Dashed,
274            alpha: 1.0,
275        })
276        .scale_fill_brewer(PaletteName::Dark2)
277        .scale_color_brewer(PaletteName::Dark2)
278        .annotate_text("contract", CONTRACT + 1.0, 0.005)
279        .title("Lead-time distributions by supplier")
280        .subtitle("attributable deliveries; dashed line = contracted lead time")
281        .xlab("Actual lead time (days)")
282        .ylab("Density")
283        .theme_minimal()
284        .save_with_size(&out("supplier_leadtime_compare"), W, H)?;
285    Ok(())
286}
Source

pub fn size(self, col: &str) -> Self

Source

pub fn shape(self, col: &str) -> Self

Source

pub fn alpha(self, col: &str) -> Self

Source

pub fn group(self, col: &str) -> Self

Source

pub fn ymin(self, col: &str) -> Self

Source

pub fn ymax(self, col: &str) -> Self

Source

pub fn label(self, col: &str) -> Self

Source

pub fn weight(self, col: &str) -> Self

Source

pub fn xend(self, col: &str) -> Self

Source

pub fn yend(self, col: &str) -> Self

Source

pub fn xmin(self, col: &str) -> Self

Source

pub fn xmax(self, col: &str) -> Self

Source

pub fn angle(self, col: &str) -> Self

Source

pub fn radius(self, col: &str) -> Self

Source

pub fn linetype(self, col: &str) -> Self

Source

pub fn after_stat_y(self, col: &str) -> Self

Map a stat-computed column to the y aesthetic (e.g., after_stat_y("density")).

Source

pub fn after_stat_x(self, col: &str) -> Self

Map a stat-computed column to the x aesthetic.

Source

pub fn after_stat_fill(self, col: &str) -> Self

Map a stat-computed column to the fill aesthetic.

Source

pub fn after_stat_color(self, col: &str) -> Self

Map a stat-computed column to the color aesthetic.

Source

pub fn after_stat_size(self, col: &str) -> Self

Map a stat-computed column to the size aesthetic.

Source

pub fn after_stat_alpha(self, col: &str) -> Self

Map a stat-computed column to the alpha aesthetic.

Source

pub fn get_mapping(&self, aes: &Aesthetic) -> Option<&str>

Get the column mapped to a specific aesthetic.

Source

pub fn merge(&self, other: &Aes) -> Aes

Merge another Aes into this one. The other’s mappings override on conflict.

Trait Implementations§

Source§

impl Clone for Aes

Source§

fn clone(&self) -> Aes

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Aes

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Aes

Source§

fn default() -> Aes

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Aes

§

impl RefUnwindSafe for Aes

§

impl Send for Aes

§

impl Sync for Aes

§

impl Unpin for Aes

§

impl UnsafeUnpin for Aes

§

impl UnwindSafe for Aes

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V