8000 Merge pull request #3211 from WeatherGod/mplot3d/depthshade · matplotlib/matplotlib@0d54829 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0d54829

Browse files
committed
Merge pull request #3211 from WeatherGod/mplot3d/depthshade
Mplot3d/depthshade
2 parents 2d43258 + 923272f commit 0d54829

File tree

2 files changed

+65
-8
lines changed

2 files changed

+65
-8
lines changed

lib/mpl_toolkits/mplot3d/art3d.py

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from six.moves import zip
1515

1616
from matplotlib import lines, text as mtext, path as mpath, colors as mcolors
17+
from matplotlib import artist
1718
from matplotlib.collections import Collection, LineCollection, \
1819
PolyCollection, PatchCollection, PathCollection
1920
from 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

378404
class 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+
67F4 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

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2176,7 +2176,8 @@ def add_collection3d(self, col, zs=0, zdir='z'):
21762176

21772177
Axes.add_collection(self, col)
21782178

2179-
def scatter(self, xs, ys, zs=0, zdir='z', s=20, c='b', *args, **kwargs):
2179+
def scatter(self, xs, ys, zs=0, zdir='z', s=20, c='b', depthshade=True,
2180+
*args, **kwargs):
21802181
'''
21812182
Create a scatter plot.
21822183
@@ -2200,6 +2201,10 @@ def scatter(self, xs, ys, zs=0, zdir='z', s=20, c='b', *args, **kwargs):
22002201
sequence because that is indistinguishable from an array
22012202
of values to be colormapped. *c* can be a 2-D array in
22022203
which the rows are RGB or RGBA, however.
2204+
2205+
*depthshade*
2206+
Whether or not to shade the scatter markers to give the
2207+
appearance of depth. Default is *True*.
22032208
========== ==========================================================
22042209
22052210
Keyword arguments are passed on to
@@ -2238,7 +2243,8 @@ def scatter(self, xs, ys, zs=0, zdir='z', s=20, c='b', *args, **kwargs):
22382243
zs = np.ones(len(xs)) * zs
22392244
else:
22402245
is_2d = False
2241-
art3d.patch_collection_2d_to_3d(patches, zs=zs, zdir=zdir)
2246+
art3d.patch_collection_2d_to_3d(patches, zs=zs, zdir=zdir,
2247+
depthshade=depthshade)
22422248

22432249
if self._zmargin < 0.05 and xs.size > 0:
22442250
self.set_zmargin(0.05)

0 commit comments

Comments
 (0)
0