@@ -439,7 +439,7 @@ impl Axes {
439
439
/// # Example
440
440
///
441
441
/// ```
442
- /// use matplotlib as plt;
442
+ /// use matplotlib::{self as plt, colors::Tab} ;
443
443
/// use ndarray::{Array1, Array2};
444
444
/// let x: Array1<f64> = Array1::linspace(-1., 1., 30);
445
445
/// let y: Array1<f64> = Array1::linspace(-1., 1., 30);
@@ -452,6 +452,7 @@ impl Axes {
452
452
/// let (fig, [[mut ax]]) = plt::subplots()?;
453
453
/// ax.contour(x.as_slice().unwrap(), y.as_slice().unwrap(), &z)
454
454
/// .levels(&[0.2, 0.5, 0.8])
455
+ /// .colors(&[Tab::Red, Tab::Blue, Tab::Olive])
455
456
/// .plot();
456
457
/// fig.save().to_file("target/contour.pdf")?;
457
458
/// # Ok::<(), matplotlib::Error>(())
@@ -465,6 +466,7 @@ impl Axes {
465
466
options : PlotOptions :: new ( ) ,
466
467
x, y, z,
467
468
levels : None ,
469
+ colors : None ,
468
470
}
469
471
}
470
472
@@ -496,6 +498,7 @@ impl Axes {
496
498
n1 : 100 ,
497
499
n2 : 100 ,
498
500
levels : None ,
501
+ colors : None ,
499
502
}
500
503
}
501
504
@@ -883,6 +886,45 @@ macro_rules! set_contour_options { () => {
883
886
self . levels = Some ( levels) ;
884
887
self
885
888
}
889
+
890
+ pub fn colors<C : Color >( mut self , colors: impl AsRef <[ C ] >) -> Self {
891
+ let colors = colors. as_ref( ) ;
892
+ let mut rgbas = Vec :: with_capacity( colors. len( ) ) ;
893
+ for c in colors {
894
+ rgbas. push( c. rgba( ) ) ;
895
+ }
896
+ self . colors = Some ( rgbas) ;
897
+ self
898
+ }
899
+
900
+ fn update_dict( & self , d: & mut Bound <PyDict >) {
901
+ let py = d. py( ) ;
902
+ if let Some ( levels) = self . levels {
903
+ let n = levels. len( ) ;
904
+ let levels = levels. to_pyarray_bound( py) ;
905
+ d. set_item( "levels" , levels) . unwrap( ) ;
906
+
907
+ if let Some ( colors) = & self . colors {
908
+ if colors. len( ) >= n {
909
+ let colors = PyList :: new_bound( py, colors) ;
910
+ d. set_item( "colors" , colors) . unwrap( ) ;
911
+ } else {
912
+ let default = self . options. color. unwrap_or( [ 0. , 0. , 0. , 1. ] ) ;
913
+ let mut colors = colors. clone( ) ;
914
+ for _ in 0 .. n - colors. len( ) {
915
+ colors. push( default ) ;
916
+ }
917
+ let colors = PyList :: new_bound( py, colors) ;
918
+ d. set_item( "colors" , colors) . unwrap( ) ;
919
+ }
920
+ } else if let Some ( color) = self . options. color {
921
+ // let colors = std::iter::repeat_n(color, n);
922
+ let colors = vec![ color; n] ;
923
+ let colors = PyList :: new_bound( py, colors) ;
924
+ d. set_item( "colors" , colors) . unwrap( ) ;
925
+ }
926
+ }
927
+ }
886
928
} }
887
929
888
930
#[ must_use]
@@ -893,6 +935,7 @@ pub struct Contour<'a, D> {
893
935
y : D ,
894
936
z : & ' a ndarray:: Array2 < f64 > ,
895
937
levels : Option < & ' a [ f64 ] > ,
938
+ colors : Option < Vec < [ f64 ; 4 ] > > ,
896
939
}
897
940
898
941
impl < ' a , D > Contour < ' a , D >
@@ -905,11 +948,8 @@ where D: AsRef<[f64]> {
905
948
let x = self . x . as_ref ( ) . to_pyarray_bound ( py) ;
906
949
let y = self . y . as_ref ( ) . to_pyarray_bound ( py) ;
907
950
let z = self . z . to_pyarray_bound ( py) ;
908
- let opt = self . options . kwargs ( py) ;
909
- if let Some ( levels) = self . levels {
910
- let levels = levels. to_pyarray_bound ( py) ;
911
- opt. set_item ( "levels" , levels) . unwrap ( ) ;
912
- }
951
+ let mut opt = self . options . kwargs ( py) ;
952
+ self . update_dict ( & mut opt) ;
913
953
let contours = self . axes . ax
914
954
. call_method_bound ( py, intern ! ( py, "contour" ) ,
915
955
( x, y, z) ,
@@ -931,6 +971,7 @@ pub struct ContourFun<'a, F> {
931
971
n1 : usize , // FIXME: want to be more versatile than an equispaced grid?
932
972
n2 : usize ,
933
973
levels : Option < & ' a [ f64 ] > ,
974
+ colors : Option < Vec < [ f64 ; 4 ] > > ,
934
975
}
935
976
936
977
impl < ' a , F > ContourFun < ' a , F >
@@ -961,11 +1002,8 @@ where F: FnMut(f64, f64) -> f64 {
961
1002
let x = x. to_pyarray_bound ( py) ;
962
1003
let y = y. to_pyarray_bound ( py) ;
963
1004
let z = z. to_pyarray_bound ( py) ;
964
- let opt = self . options . kwargs ( py) ;
965
- if let Some ( levels) = self . levels {
966
- let levels = levels. to_pyarray_bound ( py) ;
967
- opt. set_item ( "levels" , levels) . unwrap ( ) ;
968
- }
1005
+ let mut opt = self . options . kwargs ( py) ;
1006
+ self . update_dict ( & mut opt) ;
969
1007
let contours = self . axes . ax
970
1008
. call_method_bound ( py, intern ! ( py, "contour" ) ,
971
1009
( x, y, z) ,
0 commit comments