@@ -439,7 +439,7 @@ impl Axes {
439439 /// # Example
440440 ///
441441 /// ```
442- /// use matplotlib as plt;
442+ /// use matplotlib::{self as plt, colors::Tab} ;
443443 /// use ndarray::{Array1, Array2};
444444 /// let x: Array1<f64> = Array1::linspace(-1., 1., 30);
445445 /// let y: Array1<f64> = Array1::linspace(-1., 1., 30);
@@ -452,6 +452,7 @@ impl Axes {
452452 /// let (fig, [[mut ax]]) = plt::subplots()?;
453453 /// ax.contour(x.as_slice().unwrap(), y.as_slice().unwrap(), &z)
454454 /// .levels(&[0.2, 0.5, 0.8])
455+ /// .colors(&[Tab::Red, Tab::Blue, Tab::Olive])
455456 /// .plot();
456457 /// fig.save().to_file("target/contour.pdf")?;
457458 /// # Ok::<(), matplotlib::Error>(())
@@ -465,6 +466,7 @@ impl Axes {
465466 options : PlotOptions :: new ( ) ,
466467 x, y, z,
467468 levels : None ,
469+ colors : None ,
468470 }
469471 }
470472
@@ -496,6 +498,7 @@ impl Axes {
496498 n1 : 100 ,
497499 n2 : 100 ,
498500 levels : None ,
501+ colors : None ,
499502 }
500503 }
501504
@@ -883,6 +886,45 @@ macro_rules! set_contour_options { () => {
883886 self . levels = Some ( levels) ;
884887 self
885888 }
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+ }
886928} }
887929
888930#[ must_use]
@@ -893,6 +935,7 @@ pub struct Contour<'a, D> {
893935 y : D ,
894936 z : & ' a ndarray:: Array2 < f64 > ,
895937 levels : Option < & ' a [ f64 ] > ,
938+ colors : Option < Vec < [ f64 ; 4 ] > > ,
896939}
897940
898941impl < ' a , D > Contour < ' a , D >
@@ -905,11 +948,8 @@ where D: AsRef<[f64]> {
905948 let x = self . x . as_ref ( ) . to_pyarray_bound ( py) ;
906949 let y = self . y . as_ref ( ) . to_pyarray_bound ( py) ;
907950 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) ;
913953 let contours = self . axes . ax
914954 . call_method_bound ( py, intern ! ( py, "contour" ) ,
915955 ( x, y, z) ,
@@ -931,6 +971,7 @@ pub struct ContourFun<'a, F> {
931971 n1 : usize , // FIXME: want to be more versatile than an equispaced grid?
932972 n2 : usize ,
933973 levels : Option < & ' a [ f64 ] > ,
974+ colors : Option < Vec < [ f64 ; 4 ] > > ,
934975}
935976
936977impl < ' a , F > ContourFun < ' a , F >
@@ -961,11 +1002,8 @@ where F: FnMut(f64, f64) -> f64 {
9611002 let x = x. to_pyarray_bound ( py) ;
9621003 let y = y. to_pyarray_bound ( py) ;
9631004 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) ;
9691007 let contours = self . axes . ax
9701008 . call_method_bound ( py, intern ! ( py, "contour" ) ,
9711009 ( x, y, z) ,
0 commit comments