diff --git a/lib/mpl_toolkits/mplot3d/art3d.py b/lib/mpl_toolkits/mplot3d/art3d.py index 6c7a97b75cc1..9856138b2758 100644 --- a/lib/mpl_toolkits/mplot3d/art3d.py +++ b/lib/mpl_toolkits/mplot3d/art3d.py @@ -866,15 +866,21 @@ def do_3d_projection(self, renderer=None): else: cedge = cedge.repeat(len(xyzlist), axis=0) - # sort by depth (furthest drawn first) - z_segments_2d = sorted( - ((self._zsortfunc(zs), np.column_stack([xs, ys]), fc, ec, idx) - for idx, ((xs, ys, zs), fc, ec) - in enumerate(zip(xyzlist, cface, cedge))), - key=lambda x: x[0], reverse=True) - - zzs, segments_2d, self._facecolors2d, self._edgecolors2d, idxs = \ - zip(*z_segments_2d) + if xyzlist: + # sort by depth (furthest drawn first) + z_segments_2d = sorted( + ((self._zsortfunc(zs), np.column_stack([xs, ys]), fc, ec, idx) + for idx, ((xs, ys, zs), fc, ec) + in enumerate(zip(xyzlist, cface, cedge))), + key=lambda x: x[0], reverse=True) + + _, segments_2d, self._facecolors2d, self._edgecolors2d, idxs = \ + zip(*z_segments_2d) + else: + segments_2d = [] + self._facecolors2d = np.empty((0, 4)) + self._edgecolors2d = np.empty((0, 4)) + idxs = [] if self._codes3d is not None: codes = [self._codes3d[idx] for idx in idxs] diff --git a/lib/mpl_toolkits/tests/test_mplot3d.py b/lib/mpl_toolkits/tests/test_mplot3d.py index 89c3ba63acd0..990509c2c4b4 100644 --- a/lib/mpl_toolkits/tests/test_mplot3d.py +++ b/lib/mpl_toolkits/tests/test_mplot3d.py @@ -233,6 +233,8 @@ def test_scatter3d(): x = y = z = np.arange(10, 20) ax.scatter(x, y, z, c='b', marker='^') z[-1] = 0 # Check that scatter() copies the data. + # Ensure empty scatters do not break. + ax.scatter([], [], [], c='r', marker='X') @mpl3d_image_comparison(['scatter3d_color.png']) @@ -625,6 +627,14 @@ def test_poly_collection_2d_to_3d_empty(): assert isinstance(poly, art3d.Poly3DCollection) assert poly.get_paths() == [] + fig, ax = plt.subplots(subplot_kw=dict(projection='3d')) + ax.add_artist(poly) + minz = poly.do_3d_projection() + assert np.isnan(minz) + + # Ensure drawing actually works. + fig.canvas.draw() + @mpl3d_image_comparison(['poly3dcollection_alpha.png']) def test_poly3dcollection_alpha():