diff --git a/doc/api/next_api_changes/deprecations/22418-AL.rst b/doc/api/next_api_changes/deprecations/22418-AL.rst new file mode 100644 index 000000000000..8e7fb763223b --- /dev/null +++ b/doc/api/next_api_changes/deprecations/22418-AL.rst @@ -0,0 +1,6 @@ +Auto-removal of overlapping Axes by ``plt.subplot`` and ``plt.subplot2grid`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Previously, `.pyplot.subplot` and `.pyplot.subplot2grid` would automatically +remove preexisting Axes that overlap with the newly added Axes. This behavior +was deemed confusing, and is now deprecated. Explicitly call ``ax.remove()`` +on Axes that need to be removed. diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 66885c2216b0..49f833085015 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -1303,13 +1303,13 @@ def subplot(*args, **kwargs): fig.sca(ax) - bbox = ax.bbox - axes_to_delete = [] - for other_ax in fig.axes: - if other_ax == ax: - continue - if bbox.fully_overlaps(other_ax.bbox): - axes_to_delete.append(other_ax) + axes_to_delete = [other for other in fig.axes + if other != ax and ax.bbox.fully_overlaps(other.bbox)] + if axes_to_delete: + _api.warn_deprecated( + "3.6", message="Auto-removal of overlapping axes is deprecated " + "since %(since)s and will be removed %(removal)s; explicitly call " + "ax.remove() as needed.") for ax_to_del in axes_to_delete: delaxes(ax_to_del) @@ -1596,13 +1596,14 @@ def subplot2grid(shape, loc, rowspan=1, colspan=1, fig=None, **kwargs): subplotspec = gs.new_subplotspec(loc, rowspan=rowspan, colspan=colspan) ax = fig.add_subplot(subplotspec, **kwargs) - bbox = ax.bbox - axes_to_delete = [] - for other_ax in fig.axes: - if other_ax == ax: - continue - if bbox.fully_overlaps(other_ax.bbox): - axes_to_delete.append(other_ax) + + axes_to_delete = [other for other in fig.axes + if other != ax and ax.bbox.fully_overlaps(other.bbox)] + if axes_to_delete: + _api.warn_deprecated( + "3.6", message="Auto-removal of overlapping axes is deprecated " + "since %(since)s and will be removed %(removal)s; explicitly call " + "ax.remove() as needed.") for ax_to_del in axes_to_delete: delaxes(ax_to_del) diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index a5f5ddad93c4..2f5bf4c528f8 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -442,6 +442,8 @@ def test_inverted_cla(): assert not ax.xaxis_inverted() assert ax.yaxis_inverted() + for ax in fig.axes: + ax.remove() # 5. two shared axes. Inverting the leader axis should invert the shared # axes; clearing the leader axis should bring axes in shared # axes back to normal. diff --git a/lib/matplotlib/tests/test_pyplot.py b/lib/matplotlib/tests/test_pyplot.py index 25c52ae9967c..13bfcbeafa15 100644 --- a/lib/matplotlib/tests/test_pyplot.py +++ b/lib/matplotlib/tests/test_pyplot.py @@ -206,8 +206,8 @@ def test_subplot_replace_projection(): ax = plt.subplot(1, 2, 1) ax1 = plt.subplot(1, 2, 1) ax2 = plt.subplot(1, 2, 2) - # This will delete ax / ax1 as they fully overlap - ax3 = plt.subplot(1, 2, 1, projection='polar') + with pytest.warns(MatplotlibDeprecationWarning): + ax3 = plt.subplot(1, 2, 1, projection='polar') ax4 = plt.subplot(1, 2, 1, projection='polar') assert ax is not None assert ax1 is ax @@ -228,6 +228,7 @@ def test_subplot_kwarg_collision(): ax1 = plt.subplot(projection='polar', theta_offset=0) ax2 = plt.subplot(projection='polar', theta_offset=0) assert ax1 is ax2 + ax1.remove() ax3 = plt.subplot(projection='polar', theta_offset=1) assert ax1 is not ax3 assert ax1 not in plt.gcf().axes @@ -274,6 +275,8 @@ def test_subplot_projection_reuse(): assert ax1 is plt.gca() # make sure we get it back if we ask again assert ax1 is plt.subplot(111) + # remove it + ax1.remove() # create a polar plot ax2 = plt.subplot(111, projection='polar') assert ax2 is plt.gca() @@ -281,6 +284,7 @@ def test_subplot_projection_reuse(): assert ax1 not in plt.gcf().axes # assert we get it back if no extra parameters passed assert ax2 is plt.subplot(111) + ax2.remove() # now check explicitly setting the projection to rectilinear # makes a new axes ax3 = plt.subplot(111, projection='rectilinear') @@ -302,15 +306,19 @@ def test_subplot_polar_normalization(): def test_subplot_change_projection(): + created_axes = set() ax = plt.subplot() + created_axes.add(ax) projections = ('aitoff', 'hammer', 'lambert', 'mollweide', 'polar', 'rectilinear', '3d') for proj in projections: - ax_next = plt.subplot(projection=proj) - assert ax_next is plt.subplot() - assert ax_next.name == proj - assert ax is not ax_next - ax = ax_next + ax.remove() + ax = plt.subplot(projection=proj) + assert ax is plt.subplot() + assert ax.name == proj + created_axes.add(ax) + # Check that each call created a new Axes. + assert len(created_axes) == 1 + len(projections) def test_polar_second_call(): pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy