@@ -2746,7 +2746,7 @@ def calc_arrow(uvw, angle=15):
2746
2746
2747
2747
quiver3D = quiver
2748
2748
2749
- def voxels (self , filled , color = None , ** kwargs ):
2749
+ def voxels (self , filled , ** kwargs ):
2750
2750
"""
2751
2751
Plot a set of filled voxels
2752
2752
@@ -2762,13 +2762,13 @@ def voxels(self, filled, color=None, **kwargs):
2762
2762
A 3d array of values, with truthy values indicating which voxels
2763
2763
to fill
2764
2764
2765
- color : array_like
2766
- The color to draw the faces of the voxels. This parameter can be:
2765
+ facecolors, edgecolors : array_like
2766
+ The color to draw the faces and edges of the voxels. This parameter
2767
+ can be:
2767
2768
2768
2769
- A single color value, to color all voxels the same color. This
2769
2770
can be either a string, or a 1D rgb/rgba array
2770
- - ``None``, indicating the above with the next color in the
2771
- sequence
2771
+ - ``None``, indicating to use the default
2772
2772
- A 3D ndarray of color names, with each item the color for the
2773
2773
corresponding voxel. The size must match the voxels.
2774
2774
- A 4D ndarray of rgb/rgba data, with the components along the
@@ -2796,21 +2796,29 @@ def voxels(self, filled, color=None, **kwargs):
2796
2796
if filled .ndim != 3 :
2797
2797
raise ValueError ("Argument filled must be 3-dimensional" )
2798
2798
2799
- # handle the color argument
2800
- if color is None :
2801
- color = self ._get_patches_for_fill .get_next_color ()
2802
- if np .ndim (color ) in (0 , 1 ):
2803
- # single color, like "red" or [1, 0, 0]
2804
- color = broadcast_to (color , filled .shape + np .shape (color ))
2805
- elif np .ndim (color ) in (3 , 4 ):
2806
- # 3D array of strings, or 4D array with last axis rgb
2807
- if np .shape (color )[:3 ] != filled .shape :
2808
- raise ValueError (
2809
- "When multidimensional, color must match the shape of "
2810
- "filled" )
2811
- else :
2812
- raise ValueError ("Invalid color argument" )
2799
+ def _broadcast_color_arg (color , name ):
2800
+ if np .ndim (color ) in (0 , 1 ):
2801
+ # single color, like "red" or [1, 0, 0]
2802
+ return broadcast_to (color , filled .shape + np .shape (color ))
2803
+ elif np .ndim (color ) in (3 , 4 ):
2804
+ # 3D array of strings, or 4D array with last axis rgb
2805
+ if np .shape (color )[:3 ] != filled .shape :
2806
+ raise ValueError (
2807
+ "When multidimensional, {} must match the shape of "
2808
+ "filled" .format (name ))
2809
+ return color
2810
+ else :
2811
+ raise ValueError ("Invalid {} argument" .format (name ))
2812
+
2813
+ # intercept the facecolors, handling defaults and broacasting
2814
+ facecolors = kwargs .pop ('facecolors' , None )
2815
+ if facecolors is None :
2816
+ facecolors = self ._get_patches_for_fill .get_next_color ()
2817
+ facecolors = _broadcast_color_arg (facecolors , 'facecolors' )
2813
2818
2819
+ # broadcast but no default on edgecolors
2820
+ edgecolors = kwargs .pop ('edgecolors' , None )
2821
+ edgecolors = _broadcast_color_arg (edgecolors , 'edgecolors' )
2814
2822
2815
2823
# always scale to the full array, even if the data is only in the center
2816
2824
self .auto_scale_xyz (
@@ -2884,7 +2892,8 @@ def permutation_matrices(n):
2884
2892
polygons = {}
2885
2893
for coord , faces in voxel_faces .items ():
2886
2894
poly = art3d .Poly3DCollection (faces ,
2887
- facecolors = color [coord ],
2895
+ facecolors = facecolors [coord ],
2896
+ edgecolors = edgecolors [coord ],
2888
2897
** kwargs
2889
2898
)
2890
2899
self .add_collection3d (poly )
0 commit comments