Skip to content

Reusing cleared figure with suptitle and constrained layout raises an exception #11115

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
afvincent opened this issue Apr 24, 2018 · 1 comment
Labels
topic: geometry manager LayoutEngine, Constrained layout, Tight layout

Comments

@afvincent
Copy link
Contributor

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))
@afvincent afvincent added the topic: geometry manager LayoutEngine, Constrained layout, Tight layout label Apr 24, 2018
@afvincent
Copy link
Contributor Author

Closing as it actually seems to be related to the issue in #11035 and will very likely be fixed by this PR too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: geometry manager LayoutEngine, Constrained layout, Tight layout
Projects
None yet
Development

No branches or pull requests

1 participant