plotlars/plots/array2dplot.rs
1use bon::bon;
2
3use plotly::{image::ColorModel, Image as ImagePlotly, Layout as LayoutPlotly, Trace};
4
5use serde::Serialize;
6
7use crate::{
8 common::{Layout, PlotHelper},
9 components::{Axis, Rgb, Text},
10};
11
12/// A structure representing a 2D array plot.
13///
14/// The `Array2dPlot` struct allows for visualizing 2D arrays of RGB color values as images or heatmaps.
15/// Each element in the 2D array corresponds to a pixel, with its color defined by an `[u8; 3]` RGB triplet.
16/// This struct supports customizable titles, axis labels, and axis configurations for better presentation.
17///
18/// # Arguments
19///
20/// * `data` - A 2D vector of RGB triplets (`&[Vec<[u8; 3]>]`) representing pixel colors for the plot.
21/// * `plot_title` - An optional `Text` struct specifying the title of the plot.
22/// * `x_title` - An optional `Text` struct specifying the title of the x-axis.
23/// * `y_title` - An optional `Text` struct specifying the title of the y-axis.
24/// * `x_axis` - An optional reference to an `Axis` struct for customizing the x-axis.
25/// * `y_axis` - An optional reference to an `Axis` struct for customizing the y-axis.
26///
27/// # Example
28///
29/// ## Basic 2D Array Plot
30///
31/// ```rust
32/// use plotlars::{Array2dPlot, Plot, Text};
33///
34/// let data = vec![
35/// vec![[255, 0, 0], [0, 255, 0], [0, 0, 255]],
36/// vec![[0, 0, 255], [255, 0, 0], [0, 255, 0]],
37/// vec![[0, 255, 0], [0, 0, 255], [255, 0, 0]],
38/// ];
39///
40/// Array2dPlot::builder()
41/// .data(&data)
42/// .plot_title(
43/// Text::from("Array2D Plot")
44/// .font("Arial")
45/// .size(18)
46/// )
47/// .build()
48/// .plot();
49/// ```
50///
51/// 
52#[derive(Clone, Serialize)]
53pub struct Array2dPlot {
54 traces: Vec<Box<dyn Trace + 'static>>,
55 layout: LayoutPlotly,
56}
57
58#[bon]
59impl Array2dPlot {
60 #[builder(on(String, into), on(Text, into))]
61 pub fn new(
62 data: &[Vec<[u8; 3]>],
63 plot_title: Option<Text>,
64 x_title: Option<Text>,
65 y_title: Option<Text>,
66 x_axis: Option<&Axis>,
67 y_axis: Option<&Axis>,
68 ) -> Self {
69 let z_title = None;
70 let legend_title = None;
71 let z_axis = None;
72 let legend = None;
73 let y2_title = None;
74 let y2_axis = None;
75
76 let layout = Self::create_layout(
77 plot_title,
78 x_title,
79 y_title,
80 y2_title,
81 z_title,
82 legend_title,
83 x_axis,
84 y_axis,
85 y2_axis,
86 z_axis,
87 legend,
88 );
89
90 let mut traces = vec![];
91
92 let trace = Self::create_trace(data);
93
94 traces.push(trace);
95
96 Self { traces, layout }
97 }
98
99 fn create_trace(data: &[Vec<[u8; 3]>]) -> Box<dyn Trace + 'static> {
100 let pixels = data
101 .iter()
102 .map(|row| {
103 row.iter()
104 .map(|&rgb| Rgb(rgb[0], rgb[1], rgb[2]).to_plotly())
105 .collect::<Vec<_>>()
106 })
107 .collect::<Vec<_>>();
108
109 ImagePlotly::new(pixels).color_model(ColorModel::RGB)
110 }
111}
112
113impl Layout for Array2dPlot {}
114
115impl PlotHelper for Array2dPlot {
116 fn get_layout(&self) -> &LayoutPlotly {
117 &self.layout
118 }
119
120 fn get_traces(&self) -> &Vec<Box<dyn Trace + 'static>> {
121 &self.traces
122 }
123}