Closed
Description
Bug report
Bug summary
Suptitle and constrained layout raises an exception whenclearing-and-reusing an existing figure. Originally noticed in #11035 .
Attn @jklymak aka. our layout manager expert
Code for reproduction
import matplotlib.pyplot as plt
# Use-case: at the beginning of a session
fig, ax = plt.subplots(constrained_layout=True, num='boo')
fig.suptitle("Dummy")
plt.show()
# Use-case: later in the same session
fig, ax = plt.subplots(constrained_layout=True, num='boo', clear=True)
ax.plot(range(30))
plt.show()
#=> boom, AttributeError
Actual outcome
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-6-a852cdf04f60> in <module>()
5 plt.show()
6
----> 7 fig, ax = plt.subplots(constrained_layout=True, num='boo', clear=True)
8 ax.plot(range(30))
9 plt.show()
~/anaconda3/lib/python3.6/site-packages/matplotlib/pyplot.py in subplots(nrows, ncols, sharex, sharey, squeeze, subplot_kw, gridspec_kw, **fig_kw)
1196 subplot
1197 """
-> 1198 fig = figure(**fig_kw)
1199 axs = fig.subplots(nrows=nrows, ncols=ncols, sharex=sharex, sharey=sharey,
1200 squeeze=squeeze, subplot_kw=subplot_kw,
~/anaconda3/lib/python3.6/site-packages/matplotlib/pyplot.py in figure(num, figsize, dpi, facecolor, edgecolor, frameon, FigureClass, clear, **kwargs)
574
575 if clear:
--> 576 figManager.canvas.figure.clear()
577
578 return figManager.canvas.figure
~/anaconda3/lib/python3.6/site-packages/matplotlib/figure.py in clear(self, keep_observers)
1434 Clear the figure -- synonym for :meth:`clf`.
1435 """
-> 1436 self.clf(keep_observers=keep_observers)
1437
1438 @allow_rasterization
~/anaconda3/lib/python3.6/site-packages/matplotlib/figure.py in clf(self, keep_observers)
1427 self._suptitle = None
1428 if self.get_constrained_layout():
-> 1429 layoutbox.nonetree(self._layoutbox)
1430 self.stale = True
1431
~/anaconda3/lib/python3.6/site-packages/matplotlib/_layoutbox.py in nonetree(lb)
672 # Clear the solver. Hopefully this garbage collects.
673 lb.solver.reset()
--> 674 nonechildren(lb)
675 else:
676 nonetree(lb.parent)
~/anaconda3/lib/python3.6/site-packages/matplotlib/_layoutbox.py in nonechildren(lb)
679 def nonechildren(lb):
680 for child in lb.children:
--> 681 nonechildren(child)
682 lb.artist._layoutbox = None
683 lb = None
~/anaconda3/lib/python3.6/site-packages/matplotlib/_layoutbox.py in nonechildren(lb)
680 for child in lb.children:
681 nonechildren(child)
--> 682 lb.artist._layoutbox = None
683 lb = None
684
AttributeError: 'NoneType' object has no attribute '_layoutbox'
Expected outcome
No Exception, but a clear Figure named 'boo'.
Matplotlib version
- Operating system: Fedora 27
- Matplotlib version: master ('2.2.2.post856+g506520f30') and 2.2.2
- Matplotlib backend (
print(matplotlib.get_backend())
): Qt5Agg - Python version: 3.6 (Anaconda)
Being there
Some test snippet to put in test_constrainedlayout.py
def test_constrained_layout23():
'''
Comment in #11035: suptitle used to cause an exception when
reusing a figure w/ CL with ``clear=True``.
'''
for i in range(2):
fig, ax = plt.subplots(num="123", constrained_layout=True, clear=True)
fig.suptitle(f"Suptitle {i}".format(i))