From 7596db71009fee43d0cf53b7d225364d7b73ce52 Mon Sep 17 00:00:00 2001 From: Kent Date: Sat, 8 Jun 2019 20:02:21 -0600 Subject: [PATCH 1/7] Add force_zorder parameter --- lib/mpl_toolkits/mplot3d/axes3d.py | 43 +++++++++++++++++++----------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 44fffb740539..571082403181 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -49,7 +49,7 @@ class Axes3D(Axes): def __init__( self, fig, rect=None, *args, azim=-60, elev=30, sharez=None, proj_type='persp', - box_aspect=None, + box_aspect=None, force_zorder=False, **kwargs): """ Parameters @@ -66,6 +66,10 @@ def __init__( Other axes to share z-limits with. proj_type : {'persp', 'ortho'} The projection type, default 'persp'. + force_zorder : bool, optional + Force use of each collection and patch's zorder to determine + draw order. If this option is True, automatic draw order is + completely disabled. Defaults to False. auto_add_to_figure : bool, default: True Prior to Matplotlib 3.4 Axes3D would add themselves to their host Figure on init. Other Axes class do not @@ -84,6 +88,8 @@ def __init__( ----- .. versionadded:: 1.2.1 The *sharez* parameter. + .. versionadded:: TBD + The *force_zorder* parameter. """ if rect is None: @@ -92,6 +98,7 @@ def __init__( self.initial_azim = azim self.initial_elev = elev self.set_proj_type(proj_type) + self.force_zorder = force_zorder self.xy_viewLim = Bbox.unit() self.zz_viewLim = Bbox.unit() @@ -477,20 +484,26 @@ def do_3d_projection(artist): "%(since)s and will be removed %(removal)s.") return artist.do_3d_projection(renderer) - # Calculate projection of collections and patches and zorder them. - # Make sure they are drawn above the grids. - zorder_offset = max(axis.get_zorder() - for axis in self._get_axis_list()) + 1 - for i, col in enumerate( - sorted(self.collections, - key=do_3d_projection, - reverse=True)): - col.zorder = zorder_offset + i - for i, patch in enumerate( - sorted(self.patches, - key=do_3d_projection, - reverse=True)): - patch.zorder = zorder_offset + i + if self.force_zorder: + for col in self.collections: + col.do_3d_projection() + for patch in self.patches: + patch.do_3d_projection() + else: + # Calculate projection of collections and patches and zorder them. + # Make sure they are drawn above the grids. + zorder_offset = max(axis.get_zorder() + for axis in self._get_axis_list()) + 1 + for i, col in enumerate( + sorted(self.collections, + key=do_3d_projection, + reverse=True)): + col.zorder = zorder_offset + i + for i, patch in enumerate( + sorted(self.patches, + key=do_3d_projection, + reverse=True)): + patch.zorder = zorder_offset + i if self._axis3don: # Draw panes first From 4de1eb42744dfdddd3c82fd8fe515a679bd5044f Mon Sep 17 00:00:00 2001 From: Kent Date: Tue, 23 Feb 2021 22:00:40 -0700 Subject: [PATCH 2/7] Add force_zorder test --- .../test_mplot3d/force_zorder.png | Bin 0 -> 57032 bytes lib/mpl_toolkits/tests/test_mplot3d.py | 83 ++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 lib/mpl_toolkits/tests/baseline_images/test_mplot3d/force_zorder.png diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/force_zorder.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/force_zorder.png new file mode 100644 index 0000000000000000000000000000000000000000..887d409b72c763c39069314c8aa9cd27f1f6197c GIT binary patch literal 57032 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 Y3{n~;pTp$~2YzHFl_W~vfBO1=05Thj)c^nh literal 0 HcmV?d00001 diff --git a/lib/mpl_toolkits/tests/test_mplot3d.py b/lib/mpl_toolkits/tests/test_mplot3d.py index cfcc383db1a4..073ae33c579d 100644 --- a/lib/mpl_toolkits/tests/test_mplot3d.py +++ b/lib/mpl_toolkits/tests/test_mplot3d.py @@ -1425,3 +1425,86 @@ def test_subfigure_simple(): sf = fig.subfigures(1, 2) ax = sf[0].add_subplot(1, 1, 1, projection='3d') ax = sf[1].add_subplot(1, 1, 1, projection='3d', label='other') + + +@image_comparison(baseline_images=['force_zorder'], remove_text=True, + extensions=['png']) +def test_force_zorder(): + fig = plt.figure() + ax1 = fig.add_subplot(221, projection='3d') + ax2 = fig.add_subplot(222, projection='3d') + ax2.force_zorder = True + + # create a horizontal plane + corners = ((0, 0, 0), (0, 5, 0), (5, 5, 0), (5, 0, 0)) + for ax in (ax1, ax2): + tri = art3d.Poly3DCollection([corners], + facecolors='white', + edgecolors='black', + zorder=1) + ax.add_collection3d(tri) + + # plot a vector + ax.plot((2, 2), (2, 2), (0, 4), c='red', zorder=2) + + # plot some points + ax.scatter((3, 3), (1, 3), (1, 3), c='red', zorder=10) + + ax.set_xlim((0, 5.0)) + ax.set_ylim((0, 5.0)) + ax.set_zlim((0, 2.5)) + + ax3 = fig.add_subplot(223, projection='3d') + ax4 = fig.add_subplot(224, projection='3d') + ax4.force_zorder = True + + dim = 10 + X, Y = np.meshgrid((-dim, dim), (-dim, dim)) + Z = np.zeros((2, 2)) + + angle = 0.5 + X2, Y2 = np.meshgrid((-dim, dim), (0, dim)) + Z2 = Y2 * angle + X3, Y3 = np.meshgrid((-dim, dim), (-dim, 0)) + Z3 = Y3 * angle + + r = 7 + M = 1000 + th = np.linspace(0, 2 * np.pi, M) + x, y, z = r * np.cos(th), r * np.sin(th), angle * r * np.sin(th) + for ax in (ax3, ax4): + ax.plot_surface(X2, Y3, Z3, + color='blue', + alpha=0.5, + linewidth=0, + zorder=-1) + ax.plot(x[y < 0], y[y < 0], z[y < 0], + lw=5, + linestyle='--', + color='green', + zorder=0) + + ax.plot_surface(X, Y, Z, + color='red', + alpha=0.5, + linewidth=0, + zorder=1) + + ax.plot(r * np.sin(th), r * np.cos(th), np.zeros(M), + lw=5, + linestyle='--', + color='black', + zorder=2) + + ax.plot_surface(X2, Y2, Z2, + color='blue', + alpha=0.5, + linewidth=0, + zorder=3) + + ax.plot(x[y > 0], y[y > 0], z[y > 0], lw=5, + linestyle='--', + color='green', + zorder=4) + ax.view_init(azim=-20, elev=20) + ax.axis('off') From 61451ee7419fe35f4105ec848191e2b4bf22680c Mon Sep 17 00:00:00 2001 From: Kent Date: Thu, 25 Feb 2021 22:14:40 -0700 Subject: [PATCH 3/7] Change kwarg to computed_zorder --- lib/mpl_toolkits/mplot3d/axes3d.py | 39 +++++++++--------- .../{force_zorder.png => computed_zorder.png} | Bin lib/mpl_toolkits/tests/test_mplot3d.py | 8 ++-- 3 files changed, 24 insertions(+), 23 deletions(-) rename lib/mpl_toolkits/tests/baseline_images/test_mplot3d/{force_zorder.png => computed_zorder.png} (100%) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 571082403181..8cbc2479cef9 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -49,7 +49,7 @@ class Axes3D(Axes): def __init__( self, fig, rect=None, *args, azim=-60, elev=30, sharez=None, proj_type='persp', - box_aspect=None, force_zorder=False, + box_aspect=None, computed_zorder=True, **kwargs): """ Parameters @@ -66,10 +66,10 @@ def __init__( Other axes to share z-limits with. proj_type : {'persp', 'ortho'} The projection type, default 'persp'. - force_zorder : bool, optional - Force use of each collection and patch's zorder to determine - draw order. If this option is True, automatic draw order is - completely disabled. Defaults to False. + computed_zorder : bool, optional + If this option is True, draw order is computed automatically. + Otherwise, each collection and patch's zorder is used to determine + draw order. Defaults to True. auto_add_to_figure : bool, default: True Prior to Matplotlib 3.4 Axes3D would add themselves to their host Figure on init. Other Axes class do not @@ -89,7 +89,7 @@ def __init__( .. versionadded:: 1.2.1 The *sharez* parameter. .. versionadded:: TBD - The *force_zorder* parameter. + The *computed_zorder* parameter. """ if rect is None: @@ -98,7 +98,7 @@ def __init__( self.initial_azim = azim self.initial_elev = elev self.set_proj_type(proj_type) - self.force_zorder = force_zorder + self.computed_zorder = computed_zorder self.xy_viewLim = Bbox.unit() self.zz_viewLim = Bbox.unit() @@ -484,26 +484,26 @@ def do_3d_projection(artist): "%(since)s and will be removed %(removal)s.") return artist.do_3d_projection(renderer) - if self.force_zorder: - for col in self.collections: - col.do_3d_projection() - for patch in self.patches: - patch.do_3d_projection() - else: - # Calculate projection of collections and patches and zorder them. - # Make sure they are drawn above the grids. + if self.computed_zorder: + # Calculate projection of collections and patches and zorder + # them. Make sure they are drawn above the grids. zorder_offset = max(axis.get_zorder() for axis in self._get_axis_list()) + 1 for i, col in enumerate( sorted(self.collections, - key=do_3d_projection, - reverse=True)): + key=do_3d_projection, + reverse=True)): col.zorder = zorder_offset + i for i, patch in enumerate( sorted(self.patches, - key=do_3d_projection, - reverse=True)): + key=do_3d_projection, + reverse=True)): patch.zorder = zorder_offset + i + else: + for col in self.collections: + col.do_3d_projection() + for patch in self.patches: + patch.do_3d_projection() if self._axis3don: # Draw panes first @@ -3518,6 +3518,7 @@ def stem(self, x, y, z, *, linefmt='C0-', markerfmt='C0o', basefmt='C3-', stem3D = stem + docstring.interpd.update(Axes3D_kwdoc=artist.kwdoc(Axes3D)) docstring.dedent_interpd(Axes3D.__init__) diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/force_zorder.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/computed_zorder.png similarity index 100% rename from lib/mpl_toolkits/tests/baseline_images/test_mplot3d/force_zorder.png rename to lib/mpl_toolkits/tests/baseline_images/test_mplot3d/computed_zorder.png diff --git a/lib/mpl_toolkits/tests/test_mplot3d.py b/lib/mpl_toolkits/tests/test_mplot3d.py index 073ae33c579d..1fcb5b500069 100644 --- a/lib/mpl_toolkits/tests/test_mplot3d.py +++ b/lib/mpl_toolkits/tests/test_mplot3d.py @@ -1427,13 +1427,13 @@ def test_subfigure_simple(): ax = sf[1].add_subplot(1, 1, 1, projection='3d', label='other') -@image_comparison(baseline_images=['force_zorder'], remove_text=True, +@image_comparison(baseline_images=['computed_zorder'], remove_text=True, extensions=['png']) -def test_force_zorder(): +def test_computed_zorder(): fig = plt.figure() ax1 = fig.add_subplot(221, projection='3d') ax2 = fig.add_subplot(222, projection='3d') - ax2.force_zorder = True + ax2.computed_zorder = False # create a horizontal plane corners = ((0, 0, 0), (0, 5, 0), (5, 5, 0), (5, 0, 0)) @@ -1456,7 +1456,7 @@ def test_force_zorder(): ax3 = fig.add_subplot(223, projection='3d') ax4 = fig.add_subplot(224, projection='3d') - ax4.force_zorder = True + ax4.computed_zorder = False dim = 10 X, Y = np.meshgrid((-dim, dim), (-dim, dim)) From 3e8c9a4e8a8da739bc08d1fa598c172b72d24112 Mon Sep 17 00:00:00 2001 From: Kent Date: Fri, 26 Feb 2021 01:00:53 -0700 Subject: [PATCH 4/7] Remove 'versionadded' notes --- lib/mpl_toolkits/mplot3d/axes3d.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 8cbc2479cef9..2bfd7c8c91cb 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -83,13 +83,6 @@ def __init__( Other optional keyword arguments: %(Axes3D_kwdoc)s - - Notes - ----- - .. versionadded:: 1.2.1 - The *sharez* parameter. - .. versionadded:: TBD - The *computed_zorder* parameter. """ if rect is None: From 27588320b4cc7aa95b1cdce9bbf832d0a0dd33da Mon Sep 17 00:00:00 2001 From: kentcr Date: Fri, 26 Feb 2021 01:17:25 -0700 Subject: [PATCH 5/7] Improve computed_zorder description Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> --- lib/mpl_toolkits/mplot3d/axes3d.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 2bfd7c8c91cb..09201c5ef66a 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -66,10 +66,15 @@ def __init__( Other axes to share z-limits with. proj_type : {'persp', 'ortho'} The projection type, default 'persp'. - computed_zorder : bool, optional - If this option is True, draw order is computed automatically. - Otherwise, each collection and patch's zorder is used to determine - draw order. Defaults to True. + computed_zorder : bool, default: True + If True, the draw order is computed based on the average position + of the `.Artist`\s along the view direction. + Set to False if you want to manually control the order in which Artists + are drawn on top of each other using their *zorder* attribute. This + can be used for fine-tuning if the automatic order does not produce + the desired result. Note however, that a manual zorder will only be + correct for a limited view angle. If the figure is rotated by the user, + it will look wrong from certain angles. auto_add_to_figure : bool, default: True Prior to Matplotlib 3.4 Axes3D would add themselves to their host Figure on init. Other Axes class do not From 4ee377fa814561f3c42335883047958682941486 Mon Sep 17 00:00:00 2001 From: Kent Date: Fri, 26 Feb 2021 01:45:56 -0700 Subject: [PATCH 6/7] Add "What's new" entry --- doc/users/next_whats_new/axes3d_computed_zorder.rst | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 doc/users/next_whats_new/axes3d_computed_zorder.rst diff --git a/doc/users/next_whats_new/axes3d_computed_zorder.rst b/doc/users/next_whats_new/axes3d_computed_zorder.rst new file mode 100644 index 000000000000..d40d9334988b --- /dev/null +++ b/doc/users/next_whats_new/axes3d_computed_zorder.rst @@ -0,0 +1,6 @@ +Axes3D now allows manual control of draw order +---------------------------------------------- + +The :class:`~mpl_toolkits.mplot3d.axes3d.Axes3D` class now has +``computed_zorder`` parameter. When set to False, Artists are drawn using their +``zorder`` attribute. From a65c7b8dce1bae3006e7f3408d92bffaa36cb2c0 Mon Sep 17 00:00:00 2001 From: Kent Date: Fri, 26 Feb 2021 01:52:54 -0700 Subject: [PATCH 7/7] Fix flake8 violations in new description --- lib/mpl_toolkits/mplot3d/axes3d.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 09201c5ef66a..9060e4543aae 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -68,13 +68,13 @@ def __init__( The projection type, default 'persp'. computed_zorder : bool, default: True If True, the draw order is computed based on the average position - of the `.Artist`\s along the view direction. - Set to False if you want to manually control the order in which Artists - are drawn on top of each other using their *zorder* attribute. This - can be used for fine-tuning if the automatic order does not produce - the desired result. Note however, that a manual zorder will only be - correct for a limited view angle. If the figure is rotated by the user, - it will look wrong from certain angles. + of the `.Artist`s along the view direction. + Set to False if you want to manually control the order in which + Artists are drawn on top of each other using their *zorder* + attribute. This can be used for fine-tuning if the automatic order + does not produce the desired result. Note however, that a manual + zorder will only be correct for a limited view angle. If the figure + is rotated by the user, it will look wrong from certain angles. auto_add_to_figure : bool, default: True Prior to Matplotlib 3.4 Axes3D would add themselves to their host Figure on init. Other Axes class do not