Skip to main content

ggplot_rs/position/
jitter.rs

1use rand::Rng;
2
3use crate::data::{DataFrame, Value};
4
5use super::{Position, PositionParams};
6
7/// Add random noise to x and y positions to reduce overplotting.
8pub struct PositionJitter {
9    pub width: f64,
10    pub height: f64,
11}
12
13impl Default for PositionJitter {
14    fn default() -> Self {
15        PositionJitter {
16            width: 0.4,
17            height: 0.4,
18        }
19    }
20}
21
22impl Position for PositionJitter {
23    fn compute(&self, data: &mut DataFrame, _params: &PositionParams) {
24        let mut rng = rand::thread_rng();
25
26        if let Some(x_col) = data.column_mut("x") {
27            for v in x_col.iter_mut() {
28                if let Some(x) = v.as_f64() {
29                    let jitter = rng.gen_range(-self.width..self.width);
30                    *v = Value::Float(x + jitter);
31                }
32            }
33        }
34
35        if self.height > 0.0 {
36            if let Some(y_col) = data.column_mut("y") {
37                for v in y_col.iter_mut() {
38                    if let Some(y) = v.as_f64() {
39                        let jitter = rng.gen_range(-self.height..self.height);
40                        *v = Value::Float(y + jitter);
41                    }
42                }
43            }
44        }
45    }
46
47    fn name(&self) -> &str {
48        "jitter"
49    }
50}