FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Added code information to Poly3DCollection by cwebster2 · Pull Request #4793 · matplotlib/matplotlib · GitHub

Repository navigation

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .pdf  (1) .png  (1) .py  (3) .rst  (1) .svg  (1) All 5 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
10 changes: 10 additions & 0 deletions doc/users/whats_new/plotting.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,13 @@ points are contoured as usual. If the ``corner_mask`` keyword argument is not
specified, the default value is taken from rcParams.

.. plot:: mpl_examples/pylab_examples/contour_corner_mask.py

Fixed 3D filled contour plot polygon rendering
``````````````````````````````````````````````

Certain cases of 3D filled contour plots that produce polygons with multiple
holes produced improper rendering due to a loss of path information between
:class:`~matplotlib.collections.PolyCollection` and
:class:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection`. A function
:func:`~matplotlib.collections.PolyCollection.set_verts_and_codes` was
added to allow path information to be retained for proper rendering.
13 changes: 13 additions & 0 deletions lib/matplotlib/collections.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,19 @@ def set_verts(self, verts, closed=True):

set_paths = set_verts

def set_verts_and_codes(self, verts, codes):
'''This allows one to initialize vertices with path codes.'''
if (len(verts) != len(codes)):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Will need a docstring

raise ValueError("'codes' must be a 1D list or array "
"with the same length of 'verts'")
self._paths = []
for xy, cds in zip(verts, codes):
if len(xy):
self._paths.append(mpath.Path(xy, cds))
else:
self._paths.append(mpath.Path(xy))
self.stale = True

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

still missing the self.stale = True.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I caught that after I pushed the last commit. I have it in my local branch and I'll push it once I have the testcase figured out (trying to find a simplest case than my 40x40 data that reproduces the error)


Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Should add a self.stale = True here.

class BrokenBarHCollection(PolyCollection):
"""
Expand Down
67 changes: 57 additions & 10 deletions lib/mpl_toolkits/mplot3d/art3d.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,37 @@ def paths_to_3d_segments(paths, zs=0, zdir='z'):
segments.append(path_to_3d_segment(path, pathz, zdir))
return segments

def path_to_3d_segment_with_codes(path, zs=0, zdir='z'):
'''Convert a path to a 3D segment with path codes.'''

if not iterable(zs):
zs = np.ones(len(path)) * zs

seg = []
codes = []
pathsegs = path.iter_segments(simplify=False, curves=False)
for (((x, y), code), z) in zip(pathsegs, zs):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

If you use izip_longest here, you don't need to allocate a large array of ones in zs first.

seg.append((x, y, z))
codes.append(code)
seg3d = [juggle_axes(x, y, z, zdir) for (x, y, z) in seg]
return seg3d, codes

def paths_to_3d_segments_with_codes(paths, zs=0, zdir='z'):
'''
Convert paths from a collection object to 3D segments with path codes.
'''

if not iterable(zs):
zs = np.ones(len(paths)) * zs

segments = []
codes_list = []
for path, pathz in zip(paths, zs):
segs, codes = path_to_3d_segment_with_codes(path, pathz, zdir)
segments.append(segs)
codes_list.append(codes)
return segments, codes_list

class Line3DCollection(LineCollection):
'''
A collection of 3D lines.
Expand Down Expand Up @@ -487,6 +518,7 @@ def __init__(self, verts, *args, **kwargs):
zsort = kwargs.pop('zsort', True)
PolyCollection.__init__(self, verts, *args, **kwargs)
self.set_zsort(zsort)
self._codes3d = None

_zsort_functions = {
'average': np.average,
Expand Down Expand Up @@ -545,6 +577,14 @@ def set_verts(self, verts, closed=True):
# 2D verts will be updated at draw time
PolyCollection.set_verts(self, [], closed)

def set_verts_and_codes(self, verts, codes):
'''Sets 3D vertices with path codes'''
# set vertices with closed=False to prevent PolyCollection from
# setting path codes
self.set_verts(verts, closed=False)
# and set our own codes instead.
self._codes3d = codes

def set_3d_properties(self):
# Force the collection to initialize the face and edgecolors
# just in case it is a scalarmappable with a colormap.
Expand All @@ -571,8 +611,8 @@ def do_3d_projection(self, renderer):
self._facecolors3d = self._facecolors

txs, tys, tzs = proj3d.proj_transform_vec(self._vec, renderer.M)
xyzlist = [(txs[si:ei], tys[si:ei], tzs[si:ei]) \
for si, ei in self._segis]
xyzlist = [(txs[si:ei], tys[si:ei], tzs[si:ei])
for si, ei in self._segis]

# This extra fuss is to re-order face / edge colors
cface = self._facecolors3d
Expand All @@ -586,18 +626,24 @@ def do_3d_projection(self, renderer):

# if required sort by depth (furthest drawn first)
if self._zsort:
z_segments_2d = [(self._zsortfunc(zs), list(zip(xs, ys)), fc, ec) for
(xs, ys, zs), fc, ec in zip(xyzlist, cface, cedge)]
indices = range(len(xyzlist))
z_segments_2d = [(self._zsortfunc(zs), list(zip(xs, ys)), fc, ec,
idx) for (xs, ys, zs), fc, ec, idx in
zip(xyzlist, cface, cedge, indices)]
z_segments_2d.sort(key=lambda x: x[0], reverse=True)
else:
raise ValueError("whoops")

segments_2d = [s for z, s, fc, ec in z_segments_2d]
PolyCollection.set_verts(self, segments_2d)
segments_2d = [s for z, s, fc, ec, idx in z_segments_2d]
if self._codes3d is not None:
codes = [self._codes3d[idx] for z, s, fc, ec, idx in z_segments_2d]
PolyCollection.set_verts_and_codes(self, segments_2d, codes)
else:
PolyCollection.set_verts(self, segments_2d)

self._facecolors2d = [fc for z, s, fc, ec in z_segments_2d]
self._facecolors2d = [fc for z, s, fc, ec, idx in z_segments_2d]
if len(self._edgecolors3d) == len(cface):
self._edgecolors2d = [ec for z, s, fc, ec in z_segments_2d]
self._edgecolors2d = [ec for z, s, fc, ec, idx in z_segments_2d]
else:
self._edgecolors2d = self._edgecolors3d

Expand Down Expand Up @@ -663,9 +709,10 @@ def draw(self, renderer):

def poly_collection_2d_to_3d(col, zs=0, zdir='z'):
"""Convert a PolyCollection to a Poly3DCollection object."""
segments_3d = paths_to_3d_segments(col.get_paths(), zs, zdir)
segments_3d, codes = paths_to_3d_segments_with_codes(col.get_paths(),
zs, zdir)
col.__class__ = Poly3DCollection
col.set_verts(segments_3d)
col.set_verts_and_codes(segments_3d, codes)
col.set_3d_properties()

def juggle_axes(xs, ys, zs, zdir):
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Viewer requires iframe.
Loading

Back | FazBrowse Home | New Git URL