Pre-existing bug — reproduces identically on main, not caused by #698. Filing it because #698 is what gives this state a named owner (SubplotManager), which makes it the natural place to fix.
Repro
import ultraplot as uplt
fig, axs = uplt.subplots(nrows=1, ncols=2)
fig.clear()
print(fig.axes) # [] <- matplotlib cleaned up
print(list(fig._subplots.subplot_dict)) # [1, 2] <- stale, dead axes
print(len(fig.subplotgrid)) # 2 <- hands them back to the user
print(fig.gridspec) # GridSpec(nrows=1, ncols=2) <- stale
print(fig._subplots.counter) # 2 <- never reset
Figure.clear() goes through matplotlib and empties fig.axes, but nothing resets the subplot bookkeeping. So after a clear():
fig.subplotgrid returns axes that are no longer in the figure,
fig._get_subplot(n) resolves to a dead axes,
fig.gridspec still points at the old gridspec,
- the label counter keeps climbing.
(On main the same thing happens via fig._subplot_dict / fig._gridspec / fig._subplot_counter — this is a faithful description of long-standing behaviour, not something the refactor introduced.)
Suggested fix
Give SubplotManager a reset() that clears subplot_dict, zeroes counter, and drops _gridspec, and have Figure.clear() call it. Add a regression test — there is currently no test covering figure state after clear(), which is why this survived.
Pre-existing bug — reproduces identically on
main, not caused by #698. Filing it because #698 is what gives this state a named owner (SubplotManager), which makes it the natural place to fix.Repro
Figure.clear()goes through matplotlib and emptiesfig.axes, but nothing resets the subplot bookkeeping. So after aclear():fig.subplotgridreturns axes that are no longer in the figure,fig._get_subplot(n)resolves to a dead axes,fig.gridspecstill points at the old gridspec,(On
mainthe same thing happens viafig._subplot_dict/fig._gridspec/fig._subplot_counter— this is a faithful description of long-standing behaviour, not something the refactor introduced.)Suggested fix
Give
SubplotManagerareset()that clearssubplot_dict, zeroescounter, and drops_gridspec, and haveFigure.clear()call it. Add a regression test — there is currently no test covering figure state afterclear(), which is why this survived.