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 5b95065

Browse filesBrowse files
committed
FIX: restore creating new axes via plt.subplot with different kwargs
This adds a small amount of additional state to the Axes created via Figure.add_axes and Figure.add_subplot (which the other Axes creation methods eventually funnel through) to track the projection class and processed kwargs. We then use that state in `pyplot.subplot` to determine if we should re-use an Axes found at a given position or create a new one (and implicitly destroy the existing one). closes #19432
1 parent 56d9e7c commit 5b95065
Copy full SHA for 5b95065

File tree

Expand file treeCollapse file tree

3 files changed

+32
-12
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+32
-12
lines changed

‎lib/matplotlib/figure.py

Copy file name to clipboardExpand all lines: lib/matplotlib/figure.py
+13-7Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ def add_axes(self, *args, **kwargs):
568568

569569
if isinstance(args[0], Axes):
570570
a = args[0]
571+
key = getattr(a, '_projection_init', ())
571572
if a.get_figure() is not self:
572573
raise ValueError(
573574
"The Axes must have been created in the present figure")
@@ -576,12 +577,13 @@ def add_axes(self, *args, **kwargs):
576577
if not np.isfinite(rect).all():
577578
raise ValueError('all entries in rect must be finite '
578579
'not {}'.format(rect))
579-
projection_class, kwargs = self._process_projection_requirements(
580+
projection_class, pkw = self._process_projection_requirements(
580581
*args, **kwargs)
581582

582583
# create the new axes using the axes class given
583-
a = projection_class(self, rect, **kwargs)
584-
return self._add_axes_internal(a)
584+
a = projection_class(self, rect, **pkw)
585+
key = (projection_class, pkw)
586+
return self._add_axes_internal(a, key)
585587

586588
@docstring.dedent_interpd
587589
def add_subplot(self, *args, **kwargs):
@@ -694,6 +696,7 @@ def add_subplot(self, *args, **kwargs):
694696

695697
if len(args) == 1 and isinstance(args[0], SubplotBase):
696698
ax = args[0]
699+
key = getattr(ax, '_projection_init', ())
697700
if ax.get_figure() is not self:
698701
raise ValueError("The Subplot must have been created in "
699702
"the present figure")
@@ -706,17 +709,20 @@ def add_subplot(self, *args, **kwargs):
706709
if (len(args) == 1 and isinstance(args[0], Integral)
707710
and 100 <= args[0] <= 999):
708711
args = tuple(map(int, str(args[0])))
709-
projection_class, kwargs = self._process_projection_requirements(
712+
projection_class, pkw = self._process_projection_requirements(
710713
*args, **kwargs)
711-
ax = subplot_class_factory(projection_class)(self, *args, **kwargs)
712-
return self._add_axes_internal(ax)
714+
ax = subplot_class_factory(projection_class)(self, *args, **pkw)
715+
key = (projection_class, pkw)
716+
return self._add_axes_internal(ax, key)
713717

714-
def _add_axes_internal(self, ax):
718+
def _add_axes_internal(self, ax, key):
715719
"""Private helper for `add_axes` and `add_subplot`."""
716720
self._axstack.push(ax)
717721
self._localaxes.push(ax)
718722
self.sca(ax)
719723
ax._remove_method = self.delaxes
724+
# this is to support plt.subplot's re-selection logic
725+
ax._projection_init = key
720726
self.stale = True
721727
ax.stale_callback = _stale_figure_callback
722728
return ax

‎lib/matplotlib/pyplot.py

Copy file name to clipboardExpand all lines: lib/matplotlib/pyplot.py
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,8 +1229,9 @@ def subplot(*args, **kwargs):
12291229
if hasattr(ax, 'get_subplotspec') and ax.get_subplotspec() == key),
12301230
None)
12311231

1232-
# If no existing axes match, then create a new one.
1233-
if ax is None:
1232+
key = fig._process_projection_requirements(*args, **kwargs)
1233+
# If no existing axes matches, then create a new one.
1234+
if ax is None or getattr(ax, '_projection_init', ()) != key:
12341235
ax = fig.add_subplot(*args, **kwargs)
12351236

12361237
bbox = ax.bbox

‎lib/matplotlib/tests/test_figure.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_figure.py
+16-3Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,18 +1010,27 @@ def test_axes_kwargs():
10101010
plt.close()
10111011

10121012
# plt.subplot() searches for axes with the same subplot spec, and if one
1013-
# exists, returns it, regardless of whether the axes kwargs were the same.
1013+
# exists, and the kwargs match returns it, create a new one if they do not
10141014
fig = plt.figure()
10151015
ax = plt.subplot(1, 2, 1)
10161016
ax1 = plt.subplot(1, 2, 1)
10171017
ax2 = plt.subplot(1, 2, 2)
1018+
# This will delete ax / ax1 as they fully overlap
10181019
ax3 = plt.subplot(1, 2, 1, projection='polar')
1020+
ax4 = plt.subplot(1, 2, 1, projection='polar')
10191021
assert ax is not None
10201022
assert ax1 is ax
10211023
assert ax2 is not ax
1022-
assert ax3 is ax
1024+
assert ax3 is not ax
1025+
assert ax3 is ax4
1026+
1027+
assert ax not in fig.axes
1028+
assert ax2 in fig.axes
1029+
assert ax3 in fig.axes
1030+
10231031
assert ax.name == 'rectilinear'
1024-
assert ax3.name == 'rectilinear'
1032+
assert ax2.name == 'rectilinear'
1033+
assert ax3.name == 'polar'
10251034
plt.close()
10261035

10271036
# plt.gca() returns an existing axes, unless there were no axes.
@@ -1055,3 +1064,7 @@ def test_axes_kwargs():
10551064
assert ax1 is ax
10561065
assert ax1.name == 'rectilinear'
10571066
plt.close()
1067+
1068+
ax1 = plt.subplot(111, projection='polar')
1069+
ax2 = plt.subplot(111, polar=True)
1070+
assert ax1 is ax2

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.