Skip to main content

plotkit_core/charts/
scatter.rs

1//! Scatter chart builder methods.
2//!
3//! This module extends [`ScatterArtist`] with a fluent API for configuring
4//! scatter plot properties. Since [`Axes::scatter`] returns
5//! `Result<&mut ScatterArtist>`, these builder methods can be chained
6//! directly on the return value:
7//!
8//! ```ignore
9//! ax.scatter(&x, &y)?
10//!     .color(Color::TAB_ORANGE)
11//!     .marker(Marker::Diamond)
12//!     .size(8.0)
13//!     .label("Observations")
14//!     .alpha(0.7);
15//! ```
16
17use crate::artist::ScatterArtist;
18use crate::colormap::Colormap;
19use crate::primitives::Color;
20use crate::theme::Marker;
21
22impl ScatterArtist {
23    /// Sets the marker color.
24    ///
25    /// Applies the given [`Color`] to every marker rendered by this artist,
26    /// unless per-point colors have been set via [`colors`](Self::colors).
27    ///
28    /// # Arguments
29    ///
30    /// * `color` - The [`Color`] to fill each marker with.
31    ///
32    /// # Examples
33    ///
34    /// ```ignore
35    /// artist.color(Color::TAB_RED);
36    /// ```
37    pub fn color(&mut self, color: Color) -> &mut Self {
38        self.color = color;
39        self
40    }
41
42    /// Sets the marker shape.
43    ///
44    /// The [`Marker`] enum defines the available shapes (circle, square,
45    /// triangle, diamond, plus, cross, star, point). The default is
46    /// [`Marker::Circle`].
47    ///
48    /// # Arguments
49    ///
50    /// * `marker` - The [`Marker`] variant to use for every data point.
51    ///
52    /// # Examples
53    ///
54    /// ```ignore
55    /// artist.marker(Marker::Triangle);
56    /// ```
57    pub fn marker(&mut self, marker: Marker) -> &mut Self {
58        self.marker = marker;
59        self
60    }
61
62    /// Sets the marker size in pixels.
63    ///
64    /// This controls the diameter of each marker glyph. Larger values
65    /// produce more prominent data points; smaller values suit dense
66    /// scatter plots.
67    ///
68    /// # Arguments
69    ///
70    /// * `size` - The marker diameter in device-independent pixels.
71    ///
72    /// # Examples
73    ///
74    /// ```ignore
75    /// artist.size(10.0);
76    /// ```
77    pub fn size(&mut self, size: f64) -> &mut Self {
78        self.size = size;
79        self
80    }
81
82    /// Sets the legend label for this scatter series.
83    ///
84    /// When a label is set, the scatter series will appear in the legend
85    /// if one is displayed on the axes. Pass an empty string or omit this
86    /// call to exclude the series from the legend.
87    ///
88    /// # Arguments
89    ///
90    /// * `label` - A string slice that will be stored as the legend entry.
91    ///
92    /// # Examples
93    ///
94    /// ```ignore
95    /// artist.label("Measurements");
96    /// ```
97    pub fn label(&mut self, label: &str) -> &mut Self {
98        self.label = Some(label.to_string());
99        self
100    }
101
102    /// Sets the opacity (0.0 = fully transparent, 1.0 = fully opaque).
103    ///
104    /// The value is clamped to the `[0.0, 1.0]` range. The default opacity
105    /// is determined by the active theme (typically `0.8`).
106    ///
107    /// # Arguments
108    ///
109    /// * `alpha` - The desired opacity level.
110    ///
111    /// # Examples
112    ///
113    /// ```ignore
114    /// artist.alpha(0.5); // 50% transparent
115    /// ```
116    pub fn alpha(&mut self, alpha: f64) -> &mut Self {
117        self.alpha = alpha.clamp(0.0, 1.0);
118        self
119    }
120
121    /// Sets per-point colors, overriding the single uniform color.
122    ///
123    /// When set, each data point is rendered with its corresponding color
124    /// from the vector. The length of `colors` must equal the number of
125    /// data points (`x.len()` and `y.len()`). This is commonly used to
126    /// map a third variable to a colormap.
127    ///
128    /// Calling [`color`](Self::color) after this method does not clear the
129    /// per-point colors; the per-point colors take precedence during
130    /// rendering.
131    ///
132    /// # Arguments
133    ///
134    /// * `colors` - A vector of [`Color`] values, one per data point.
135    ///
136    /// # Examples
137    ///
138    /// ```ignore
139    /// artist.colors(vec![Color::TAB_BLUE, Color::TAB_RED, Color::TAB_GREEN]);
140    /// ```
141    pub fn colors(&mut self, colors: Vec<Color>) -> &mut Self {
142        self.colors = Some(colors);
143        self
144    }
145
146    /// Sets per-point scalar values for colormap-driven coloring.
147    ///
148    /// When combined with [`cmap`](Self::cmap), each scalar value is mapped
149    /// through the colormap to produce a per-point color. The length of `c`
150    /// must equal the number of data points. This takes precedence over
151    /// both the uniform [`color`](Self::color) and [`colors`](Self::colors).
152    ///
153    /// # Arguments
154    ///
155    /// * `c` - A vector of scalar values, one per data point.
156    ///
157    /// # Examples
158    ///
159    /// ```ignore
160    /// artist.c(vec![0.0, 0.5, 1.0]).cmap(Colormap::Viridis);
161    /// ```
162    pub fn c(&mut self, c: Vec<f64>) -> &mut Self {
163        self.c = Some(c);
164        self
165    }
166
167    /// Sets the colormap used to map `c` values to colors.
168    ///
169    /// Must be used together with [`c`](Self::c) to have any effect. When
170    /// both are set, the scatter plot renders each point with a color
171    /// determined by mapping its `c` value through the given colormap.
172    ///
173    /// # Arguments
174    ///
175    /// * `cmap` - The [`Colormap`] variant to use.
176    ///
177    /// # Examples
178    ///
179    /// ```ignore
180    /// artist.c(values).cmap(Colormap::Plasma);
181    /// ```
182    pub fn cmap(&mut self, cmap: Colormap) -> &mut Self {
183        self.cmap = Some(cmap);
184        self
185    }
186}