scatterpolar/
scatterpolar.rs

1use plotlars::{Fill, Legend, Line, Mode, Plot, Rgb, ScatterPolar, Shape, Text};
2use polars::prelude::*;
3
4fn main() {
5    // Example 1: Basic scatter polar plot with markers only
6    basic_scatter_polar();
7
8    // Example 2: Lines and markers with custom styling
9    styled_scatter_polar();
10
11    // Example 3: Grouped data with multiple traces
12    grouped_scatter_polar();
13
14    // Example 4: Filled area polar plot
15    filled_scatter_polar();
16}
17
18fn basic_scatter_polar() {
19    // Create sample data - wind direction and speed
20    let directions = vec![0., 45., 90., 135., 180., 225., 270., 315., 360.];
21    let speeds = vec![5.0, 7.5, 10.0, 8.5, 6.0, 4.5, 3.0, 2.5, 5.0];
22
23    let dataset = DataFrame::new(vec![
24        Column::new("direction".into(), directions),
25        Column::new("speed".into(), speeds),
26    ])
27    .unwrap();
28
29    ScatterPolar::builder()
30        .data(&dataset)
31        .theta("direction")
32        .r("speed")
33        .mode(Mode::Markers)
34        .color(Rgb(65, 105, 225))
35        .shape(Shape::Circle)
36        .size(10)
37        .plot_title(Text::from("Wind Speed by Direction").font("Arial").size(20))
38        .build()
39        .plot();
40}
41
42fn styled_scatter_polar() {
43    // Create sample data - radar chart style
44    let categories = vec![0., 72., 144., 216., 288., 360.];
45    let performance = vec![8.0, 6.5, 7.0, 9.0, 5.5, 8.0];
46
47    let dataset = DataFrame::new(vec![
48        Column::new("category".into(), categories),
49        Column::new("performance".into(), performance),
50    ])
51    .unwrap();
52
53    ScatterPolar::builder()
54        .data(&dataset)
55        .theta("category")
56        .r("performance")
57        .mode(Mode::LinesMarkers)
58        .color(Rgb(255, 0, 0))
59        .shape(Shape::Diamond)
60        .line(Line::Solid)
61        .width(3.0)
62        .size(12)
63        .opacity(0.8)
64        .plot_title(
65            Text::from("Performance Radar Chart")
66                .font("Arial")
67                .size(22)
68                .x(0.5),
69        )
70        .build()
71        .plot();
72}
73
74fn grouped_scatter_polar() {
75    // Create sample data - comparing two products across multiple metrics
76    let angles = vec![
77        0., 60., 120., 180., 240., 300., 360., // Product A
78        0., 60., 120., 180., 240., 300., 360., // Product B
79    ];
80    let values = vec![
81        7.0, 8.5, 6.0, 5.5, 9.0, 8.0, 7.0, // Product A values
82        6.0, 7.0, 8.0, 9.0, 6.5, 7.5, 6.0, // Product B values
83    ];
84    let products = vec![
85        "Product A",
86        "Product A",
87        "Product A",
88        "Product A",
89        "Product A",
90        "Product A",
91        "Product A",
92        "Product B",
93        "Product B",
94        "Product B",
95        "Product B",
96        "Product B",
97        "Product B",
98        "Product B",
99    ];
100
101    let dataset = DataFrame::new(vec![
102        Column::new("angle".into(), angles),
103        Column::new("score".into(), values),
104        Column::new("product".into(), products),
105    ])
106    .unwrap();
107
108    ScatterPolar::builder()
109        .data(&dataset)
110        .theta("angle")
111        .r("score")
112        .group("product")
113        .mode(Mode::LinesMarkers)
114        .colors(vec![
115            Rgb(255, 99, 71),  // Tomato red
116            Rgb(60, 179, 113), // Medium sea green
117        ])
118        .shapes(vec![Shape::Circle, Shape::Square])
119        .lines(vec![Line::Solid, Line::Dash])
120        .width(2.5)
121        .size(8)
122        .plot_title(Text::from("Product Comparison").font("Arial").size(24))
123        .legend_title(Text::from("Products").font("Arial").size(14))
124        .legend(&Legend::new().x(0.85).y(0.95))
125        .build()
126        .plot();
127}
128
129fn filled_scatter_polar() {
130    // Create sample data - filled area chart
131    let angles: Vec<f64> = (0..=360).step_by(10).map(|x| x as f64).collect();
132    let radii: Vec<f64> = angles
133        .iter()
134        .map(|&angle| 5.0 + 3.0 * (angle * std::f64::consts::PI / 180.0).sin())
135        .collect();
136
137    let dataset = DataFrame::new(vec![
138        Column::new("angle".into(), angles),
139        Column::new("radius".into(), radii),
140    ])
141    .unwrap();
142
143    ScatterPolar::builder()
144        .data(&dataset)
145        .theta("angle")
146        .r("radius")
147        .mode(Mode::Lines)
148        .fill(Fill::ToSelf)
149        .color(Rgb(135, 206, 250))
150        .line(Line::Solid)
151        .width(2.0)
152        .opacity(0.6)
153        .plot_title(Text::from("Filled Polar Area Chart").font("Arial").size(20))
154        .build()
155        .plot();
156}