1
- use crate :: style:: { HSLColor , RGBAColor , RGBColor } ;
1
+ use crate :: style:: { HSLColor , RGBAColor , RGBColor } ;
2
2
3
- use num_traits:: { Float , ToPrimitive , FromPrimitive } ;
3
+ use num_traits:: { Float , FromPrimitive , ToPrimitive } ;
4
4
5
- pub trait ColorMap < ColorType : crate :: prelude:: Color , FloatType =f32 >
5
+ /// Converts scalar values to colors.
6
+ pub trait ColorMap < ColorType : crate :: prelude:: Color , FloatType = f32 >
6
7
where
7
8
FloatType : Float ,
8
9
{
10
+ /// Takes a scalar value 0.0 <= h <= 1.0 and returns the corresponding color.
11
+ /// Typically color-scales are named according to which color-type they return.
12
+ /// To use upper and lower bounds with ths function see [get_color_normalized](ColorMap::get_color_normalized).
9
13
fn get_color ( & self , h : FloatType ) -> ColorType {
10
14
self . get_color_normalized ( h, FloatType :: zero ( ) , FloatType :: one ( ) )
11
15
}
12
16
17
+ /// A slight abstraction over [get_color](ColorMap::get_color) function where lower and upper bound can be specified.
13
18
fn get_color_normalized ( & self , h : FloatType , min : FloatType , max : FloatType ) -> ColorType ;
14
19
}
15
20
16
-
17
21
/// This struct is used to dynamically construct colormaps by giving it a slice of colors.
18
22
/// It can then be used when being intantiated, but not with associated functions.
19
23
/// ```
20
24
/// use plotters::prelude::{BLACK,BLUE,WHITE,DerivedColorMap,ColorMap};
21
- ///
25
+ ///
22
26
/// let derived_colormap = DerivedColorMap::new(
23
27
/// &[BLACK,
24
28
/// BLUE,
25
29
/// WHITE]
26
30
/// );
27
- ///
31
+ ///
28
32
/// assert_eq!(derived_colormap.get_color(0.0), BLACK);
29
33
/// assert_eq!(derived_colormap.get_color(0.5), BLUE);
30
34
/// assert_eq!(derived_colormap.get_color(1.0), WHITE);
@@ -33,20 +37,22 @@ pub struct DerivedColorMap<ColorType> {
33
37
colors : Vec < ColorType > ,
34
38
}
35
39
36
-
37
40
impl < ColorType : crate :: style:: Color + Clone > DerivedColorMap < ColorType > {
41
+ /// This function lets the user define a new colormap by simply specifying colors in the correct order.
42
+ /// For calculation of the color values, the colors will be spaced evenly apart.
38
43
pub fn new ( colors : & [ ColorType ] ) -> Self {
39
- DerivedColorMap { colors : colors. iter ( ) . map ( |color| color. clone ( ) ) . collect :: < Vec < _ > > ( ) }
44
+ DerivedColorMap {
45
+ colors : colors. iter ( ) . map ( |color| color. clone ( ) ) . collect :: < Vec < _ > > ( ) ,
46
+ }
40
47
}
41
48
}
42
49
43
-
44
50
macro_rules! calculate_new_color_value(
45
51
( $relative_difference: expr, $colors: expr, $index_upper: expr, $index_lower: expr, RGBColor ) => {
46
52
RGBColor (
47
53
// These equations are a very complicated way of writing a simple linear extrapolation with lots of casting between numerical values
48
54
// In principle every cast should be safe which is why we choose to unwrap
49
- // (1.0 - r) * color_value_1 + r * color_value_2
55
+ // (1.0 - r) * color_value_1 + r * color_value_2
50
56
( ( FloatType :: one( ) - $relative_difference) * FloatType :: from_u8( $colors[ $index_upper] . 0 ) . unwrap( ) + $relative_difference * FloatType :: from_u8( $colors[ $index_lower] . 0 ) . unwrap( ) ) . round( ) . to_u8( ) . unwrap( ) ,
51
57
( ( FloatType :: one( ) - $relative_difference) * FloatType :: from_u8( $colors[ $index_upper] . 1 ) . unwrap( ) + $relative_difference * FloatType :: from_u8( $colors[ $index_lower] . 1 ) . unwrap( ) ) . round( ) . to_u8( ) . unwrap( ) ,
52
58
( ( FloatType :: one( ) - $relative_difference) * FloatType :: from_u8( $colors[ $index_upper] . 2 ) . unwrap( ) + $relative_difference * FloatType :: from_u8( $colors[ $index_lower] . 2 ) . unwrap( ) ) . round( ) . to_u8( ) . unwrap( )
@@ -56,7 +62,7 @@ macro_rules! calculate_new_color_value(
56
62
RGBAColor (
57
63
// These equations are a very complicated way of writing a simple linear extrapolation with lots of casting between numerical values
58
64
// In principle every cast should be safe which is why we choose to unwrap
59
- // (1.0 - r) * color_value_1 + r * color_value_2
65
+ // (1.0 - r) * color_value_1 + r * color_value_2
60
66
( ( FloatType :: one( ) - $relative_difference) * FloatType :: from_u8( $colors[ $index_upper] . 0 ) . unwrap( ) + $relative_difference * FloatType :: from_u8( $colors[ $index_lower] . 0 ) . unwrap( ) ) . round( ) . to_u8( ) . unwrap( ) ,
61
67
( ( FloatType :: one( ) - $relative_difference) * FloatType :: from_u8( $colors[ $index_upper] . 1 ) . unwrap( ) + $relative_difference * FloatType :: from_u8( $colors[ $index_lower] . 1 ) . unwrap( ) ) . round( ) . to_u8( ) . unwrap( ) ,
62
68
( ( FloatType :: one( ) - $relative_difference) * FloatType :: from_u8( $colors[ $index_upper] . 2 ) . unwrap( ) + $relative_difference * FloatType :: from_u8( $colors[ $index_lower] . 2 ) . unwrap( ) ) . round( ) . to_u8( ) . unwrap( ) ,
@@ -67,7 +73,7 @@ macro_rules! calculate_new_color_value(
67
73
HSLColor (
68
74
// These equations are a very complicated way of writing a simple linear extrapolation with lots of casting between numerical values
69
75
// In principle every cast should be safe which is why we choose to unwrap
70
- // (1.0 - r) * color_value_1 + r * color_value_2
76
+ // (1.0 - r) * color_value_1 + r * color_value_2
71
77
( ( FloatType :: one( ) - $relative_difference) * FloatType :: from_f64( $colors[ $index_upper] . 0 ) . unwrap( ) + $relative_difference * FloatType :: from_f64( $colors[ $index_lower] . 0 ) . unwrap( ) ) . to_f64( ) . unwrap( ) ,
72
78
( ( FloatType :: one( ) - $relative_difference) * FloatType :: from_f64( $colors[ $index_upper] . 1 ) . unwrap( ) + $relative_difference * FloatType :: from_f64( $colors[ $index_lower] . 1 ) . unwrap( ) ) . to_f64( ) . unwrap( ) ,
73
79
( ( FloatType :: one( ) - $relative_difference) * FloatType :: from_f64( $colors[ $index_upper] . 2 ) . unwrap( ) + $relative_difference * FloatType :: from_f64( $colors[ $index_lower] . 2 ) . unwrap( ) ) . to_f64( ) . unwrap( ) ,
@@ -113,22 +119,26 @@ macro_rules! implement_color_scale_for_derived_color_map{
113
119
self . colors. len( )
114
120
) ;
115
121
// Interpolate the final color linearly
116
- calculate_new_color_value!( relative_difference, self . colors, index_upper, index_lower, $color_type)
122
+ calculate_new_color_value!(
123
+ relative_difference,
124
+ self . colors,
125
+ index_upper,
126
+ index_lower,
127
+ $color_type
128
+ )
117
129
}
118
130
}
119
131
) +
120
132
}
121
133
}
122
134
123
- implement_color_scale_for_derived_ColorMap ! { RGBAColor , RGBColor , HSLColor }
124
-
135
+ implement_color_scale_for_derived_color_map ! { RGBAColor , RGBColor , HSLColor }
125
136
126
137
macro_rules! count {
127
138
( ) => ( 0usize ) ;
128
139
( $x: tt $( $xs: tt) * ) => ( 1usize + count!( $( $xs) * ) ) ;
129
140
}
130
141
131
-
132
142
macro_rules! define_colors_from_list_of_values_or_directly{
133
143
( $color_type: ident, $( ( $( $color_value: expr) ,+) ) ,+) => {
134
144
[ $( $color_type( $( $color_value) ,+) ) ,+]
@@ -160,28 +170,49 @@ macro_rules! implement_linear_interpolation_color_map {
160
170
Self :: COLORS . len( )
161
171
) ;
162
172
// Interpolate the final color linearly
163
- calculate_new_color_value!( relative_difference, Self :: COLORS , index_upper, index_lower, $color_type)
173
+ calculate_new_color_value!(
174
+ relative_difference,
175
+ Self :: COLORS ,
176
+ index_upper,
177
+ index_lower,
178
+ $color_type
179
+ )
164
180
}
165
181
}
166
182
167
183
impl $color_scale_name {
168
- pub fn get_color<FloatType : std:: fmt:: Debug + Float + FromPrimitive + ToPrimitive >( h: FloatType ) -> $color_type {
184
+ #[ doc = "Get color value from `" ]
185
+ #[ doc = stringify!( $color_scale_name) ]
186
+ #[ doc = "` by supplying a parameter 0.0 <= h <= 1.0" ]
187
+ pub fn get_color<FloatType : std:: fmt:: Debug + Float + FromPrimitive + ToPrimitive >(
188
+ h: FloatType ,
189
+ ) -> $color_type {
169
190
let color_scale = $color_scale_name { } ;
170
191
color_scale. get_color( h)
171
192
}
172
193
173
- pub fn get_color_normalized<FloatType : std:: fmt:: Debug + Float + FromPrimitive + ToPrimitive >( h: FloatType , min: FloatType , max: FloatType ) -> $color_type {
194
+ #[ doc = "Get color value from `" ]
195
+ #[ doc = stringify!( $color_scale_name) ]
196
+ #[ doc = "` by supplying lower and upper bounds min, max and a parameter h where min <= h <= max" ]
197
+ pub fn get_color_normalized<
198
+ FloatType : std:: fmt:: Debug + Float + FromPrimitive + ToPrimitive ,
199
+ >(
200
+ h: FloatType ,
201
+ min: FloatType ,
202
+ max: FloatType ,
203
+ ) -> $color_type {
174
204
let color_scale = $color_scale_name { } ;
175
205
color_scale. get_color_normalized( h, min, max)
176
206
}
177
207
}
178
- }
208
+ } ;
179
209
}
180
210
181
-
182
211
#[ macro_export]
212
+ /// Macro to create a new colormap with evenly spaced colors at compile-time.
183
213
macro_rules! define_linear_interpolation_color_map{
184
- ( $color_scale_name: ident, $color_type: ident, $( ( $( $color_value: expr) ,+) ) ,* ) => {
214
+ ( $color_scale_name: ident, $color_type: ident, $doc: expr, $( ( $( $color_value: expr) ,+) ) ,* ) => {
215
+ #[ doc = $doc]
185
216
pub struct $color_scale_name { }
186
217
187
218
impl $color_scale_name {
@@ -192,7 +223,8 @@ macro_rules! define_linear_interpolation_color_map{
192
223
193
224
implement_linear_interpolation_color_map!{ $color_scale_name, $color_type}
194
225
} ;
195
- ( $color_scale_name: ident, $color_type: ident, $( $color_complete: tt) ,+) => {
226
+ ( $color_scale_name: ident, $color_type: ident, $doc: expr, $( $color_complete: tt) ,+) => {
227
+ #[ doc = $doc]
196
228
pub struct $color_scale_name { }
197
229
198
230
impl $color_scale_name {
@@ -203,10 +235,12 @@ macro_rules! define_linear_interpolation_color_map{
203
235
}
204
236
}
205
237
206
-
207
- define_linear_interpolation_color_map ! {
238
+ define_linear_interpolation_color_map ! {
208
239
ViridisRGBA ,
209
240
RGBAColor ,
241
+ "A colormap optimized for visually impaired people (RGBA format).
242
+ It is currently the default colormap also used by [matplotlib](https://matplotlib.org/stable/tutorials/colors/colormaps.html).
243
+ Read more in this [paper](https://doi.org/10.1371/journal.pone.0199239)" ,
210
244
( 68 , 1 , 84 , 1.0 ) ,
211
245
( 70 , 50 , 127 , 1.0 ) ,
212
246
( 54 , 92 , 141 , 1.0 ) ,
@@ -217,10 +251,12 @@ define_linear_interpolation_color_map!{
217
251
( 254 , 232 , 37 , 1.0 )
218
252
}
219
253
220
-
221
- define_linear_interpolation_color_map ! {
254
+ define_linear_interpolation_color_map ! {
222
255
ViridisRGB ,
223
256
RGBColor ,
257
+ "A colormap optimized for visually impaired people (RGB Format).
258
+ It is currently the default colormap also used by [matplotlib](https://matplotlib.org/stable/tutorials/colors/colormaps.html).
259
+ Read more in this [paper](https://doi.org/10.1371/journal.pone.0199239)" ,
224
260
( 68 , 1 , 84 ) ,
225
261
( 70 , 50 , 127 ) ,
226
262
( 54 , 92 , 141 ) ,
@@ -231,44 +267,44 @@ define_linear_interpolation_color_map!{
231
267
( 254 , 232 , 37 )
232
268
}
233
269
234
-
235
- define_linear_interpolation_color_map ! {
270
+ define_linear_interpolation_color_map ! {
236
271
BlackWhite ,
237
272
RGBColor ,
273
+ "Simple chromatic colormap from black to white." ,
238
274
( 0 , 0 , 0 ) ,
239
275
( 255 , 255 , 255 )
240
276
}
241
277
242
-
243
- define_linear_interpolation_color_map ! {
278
+ define_linear_interpolation_color_map ! {
244
279
MandelbrotHSL ,
245
280
HSLColor ,
281
+ "Colormap created to replace the one used in the mandelbrot example." ,
246
282
( 0.0 , 1.0 , 0.5 ) ,
247
283
( 1.0 , 1.0 , 0.5 )
248
284
}
249
285
250
-
251
- define_linear_interpolation_color_map ! {
286
+ define_linear_interpolation_color_map ! {
252
287
VulcanoHSL ,
253
288
HSLColor ,
289
+ "A vulcanic colormap that display red/orange and black colors" ,
254
290
( 2.0 /3.0 , 1.0 , 0.7 ) ,
255
291
( 0.0 , 1.0 , 0.7 )
256
292
}
257
293
258
-
259
294
use super :: full_palette:: * ;
260
- define_linear_interpolation_color_map ! {
295
+ define_linear_interpolation_color_map ! {
261
296
Bone ,
262
297
RGBColor ,
298
+ "Dark colormap going from black over blue to white." ,
263
299
BLACK ,
264
300
BLUE ,
265
301
WHITE
266
302
}
267
303
268
-
269
- define_linear_interpolation_color_map ! {
304
+ define_linear_interpolation_color_map ! {
270
305
Copper ,
271
306
RGBColor ,
307
+ "Friendly black to brown colormap." ,
272
308
BLACK ,
273
309
BROWN ,
274
310
ORANGE
0 commit comments