1414from  six .moves  import  zip 
1515
1616from  matplotlib  import  lines , text  as  mtext , path  as  mpath , colors  as  mcolors 
17+ from  matplotlib  import  artist 
1718from  matplotlib .collections  import  Collection , LineCollection , \
1819        PolyCollection , PatchCollection , PathCollection 
1920from  matplotlib .cm  import  ScalarMappable 
@@ -310,9 +311,14 @@ def __init__(self, *args, **kwargs):
310311        :class:`~matplotlib.collections.PatchCollection`. In addition, 
311312        keywords *zs=0* and *zdir='z'* are available. 
312313
314+         Also, the keyword argument "depthshade" is available to 
315+         indicate whether or not to shade the patches in order to 
316+         give the appearance of depth (default is *True*). 
317+         This is typically desired in scatter plots. 
313318        """ 
314319        zs  =  kwargs .pop ('zs' , 0 )
315320        zdir  =  kwargs .pop ('zdir' , 'z' )
321+         self ._depthshade  =  kwargs .pop ('depthshade' , True )
316322        PatchCollection .__init__ (self , * args , ** kwargs )
317323        self ._old_draw  =  lambda  x : PatchCollection .draw (self , x )
318324        self .set_3d_properties (zs , zdir )
@@ -339,10 +345,16 @@ def set_3d_properties(self, zs, zdir):
339345    def  do_3d_projection (self , renderer ):
340346        xs , ys , zs  =  self ._offsets3d 
341347        vxs , vys , vzs , vis  =  proj3d .proj_transform_clip (xs , ys , zs , renderer .M )
342-         #FIXME: mpl allows us no way to unset the collection alpha value 
343-         self ._alpha  =  None 
344-         self .set_facecolors (zalpha (self ._facecolor3d , vzs ))
345-         self .set_edgecolors (zalpha (self ._edgecolor3d , vzs ))
348+ 
349+         fcs  =  (zalpha (self ._facecolor3d , vzs ) if  self ._depthshade  else 
350+                self ._facecolor3d )
351+         fcs  =  mcolors .colorConverter .to_rgba_array (fcs , self ._alpha )
352+         self .set_facecolors (fcs )
353+ 
354+         ecs  =  (zalpha (self ._edgecolor3d , vzs ) if  self ._depthshade  else 
355+                self ._edgecolor3d )
356+         ecs  =  mcolors .colorConverter .to_rgba_array (ecs , self ._alpha )
357+         self .set_edgecolors (ecs )
346358        super (self .__class__ , self ).set_offsets (list (zip (vxs , vys )))
347359
348360        if  vzs .size  >  0  :
@@ -362,9 +374,22 @@ class Path3DCollection(Collection3D, PathCollection):
362374    pass 
363375
364376
365- def  patch_collection_2d_to_3d (col , zs = 0 , zdir = 'z' ):
366-     """Convert a PatchCollection to a Patch3DCollection object.""" 
377+ def  patch_collection_2d_to_3d (col , zs = 0 , zdir = 'z' , depthshade = True ):
378+     """ 
379+     Convert a :class:`~matplotlib.collections.PatchCollection` into a 
380+     :class:`Patch3DCollection` object 
381+     (or a :class:`~matplotlib.collections.PathCollection` into a 
382+     :class:`Path3DCollection` object). 
383+ 
384+     Keywords: 
385+     *za*            The location or locations to place the patches in the 
386+                     collection along the *zdir* axis. Defaults to 0. 
387+     *zdir*          The axis in which to place the patches. Default is "z". 
388+     *depthshade*    Whether to shade the patches to give a sense of depth. 
389+                     Defaults to *True*. 
390+      
367391
392+     """ 
368393    # The tricky part here is that there are several classes that are 
369394    # derived from PatchCollection. We need to use the right draw method. 
370395    col ._old_draw  =  col .draw 
@@ -373,6 +398,7 @@ def patch_collection_2d_to_3d(col, zs=0, zdir='z'):
373398        col .__class__  =  Path3DCollection 
374399    elif  isinstance (col , PatchCollection ):
375400        col .__class__  =  Patch3DCollection 
401+     col ._depthshade  =  depthshade 
376402    col .set_3d_properties (zs , zdir )
377403
378404class  Poly3DCollection (PolyCollection ):
@@ -461,6 +487,7 @@ def set_3d_properties(self):
461487        self .set_zsort (True )
462488        self ._facecolors3d  =  PolyCollection .get_facecolors (self )
463489        self ._edgecolors3d  =  PolyCollection .get_edgecolors (self )
490+         self ._alpha3d  =  PolyCollection .get_alpha (self )
464491
465492    def  set_sort_zpos (self ,val ):
466493        '''Set the position to use for z-sorting.''' 
@@ -529,6 +556,30 @@ def set_edgecolor(self, colors):
529556        self ._edgecolors3d  =  PolyCollection .get_edgecolor (self )
530557    set_edgecolors  =  set_edgecolor 
531558
559+     def  set_alpha (self , alpha ):
560+         """ 
561+         Set the alpha tranparencies of the collection.  *alpha* must be 
562+         a float or *None*. 
563+ 
564+         ACCEPTS: float or None 
565+         """ 
566+         if  alpha  is  not   None :
567+             try :
568+                 float (alpha )
569+             except  TypeError :
570+                 raise  TypeError ('alpha must be a float or None' )
571+         artist .Artist .set_alpha (self , alpha )
572+         try :
573+             self ._facecolors  =  mcolors .colorConverter .to_rgba_array (
574+                 self ._facecolors3d , self ._alpha )
575+         except  (AttributeError , TypeError , IndexError ):
576+             pass 
577+         try :
578+             self ._edgecolors  =  mcolors .colorConverter .to_rgba_array (
579+                     self ._edgecolors3d , self ._alpha )
580+         except  (AttributeError , TypeError , IndexError ):
581+             pass 
582+ 
532583    def  get_facecolors (self ):
533584        return  self ._facecolors2d 
534585    get_facecolor  =  get_facecolors 
0 commit comments