You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: get_backend() clears figures from Gcf.figs if they were created under rc_context #23298
calling matplotlib.get_backend() removes all figures from Gcf if the first figure in Gcf.figs was created in an rc_context.
Code for reproduction
importmatplotlib.pyplotaspltfrommatplotlibimportget_backend, rc_context# fig1 = plt.figure() # <- UNCOMMENT THIS LINE AND IT WILL WORK# plt.ion() # <- ALTERNATIVELY, UNCOMMENT THIS LINE AND IT WILL ALSO WORKwithrc_context():
fig2=plt.figure()
before=f'{id(plt._pylab_helpers.Gcf)}{plt._pylab_helpers.Gcf.figs!r}'get_backend()
after=f'{id(plt._pylab_helpers.Gcf)}{plt._pylab_helpers.Gcf.figs!r}'assertbefore==after, '\n'+before+'\n'+after
Actual outcome
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-1-fa4d099aa289> in <cell line: 11>()
9 after = f'{id(plt._pylab_helpers.Gcf)} {plt._pylab_helpers.Gcf.figs!r}'
10
---> 11 assert before == after, '\n' + before + '\n' + after
12
AssertionError:
94453354309744 OrderedDict([(1, <matplotlib.backends.backend_qt.FigureManagerQT object at 0x7fb33e26c220>)])
94453354309744 OrderedDict()
Expected outcome
The figure should not be missing from Gcf. Consequences of this are, e.g, plt.close(fig2) doesn't work because Gcf.destroy_fig() can't find it.
I encountered this bug when using matplotlib (3.5.2) indirectly via seaborn. Before my environment is updated with matplotlib 3.6, what would you recommend as a workaround for this bug? The workaround should preferably have as little side effect as possible.
I think seaborn can turn the layout off (fig.set_tight_layout(False)). I guess if you want it to turn back on, you could save the old state and toggle it back on.
I guess philosophically I don't think of rcParams as something downstream libraries should be changing, but rather defaults that the user sets. However I appreciate that there is a counter current in the project of thinking of rcParams as a global state for the library that gets manipulated at will, and I can see how the context manager helps encourage that. However, I'm just not convinced it is a good idea given the number of weird side effects it can produce.
The rcParams very much are "a global state that can be manipulated at will" so if doing so can produce "weird side effects", it seems important for matplotlib to clearly document them.
Activity
tacaswell commentedon Jun 18, 2022
My knee-jerk guess is that :
rcParams['backend']in the auto-sentinelget_backend()re-resolves the backend which because it changes the backend it closes all of the figuresThis is probably been a long standing latent bug, but was brought to the front when we made the backend resolution lazier.
tacaswell commentedon Jun 18, 2022
That is indeed the problem. I do not see an easy way to fix this that we can backport to 3.5.x, PR coming with a way to fix this for 3.6....
ENH/FIX: Allow rc_context to ignore keys on reset
FIX/API: Do not reset rcParams['backend'] in rc_context
kailizcatman commentedon Jul 23, 2022
I encountered this bug when using matplotlib (3.5.2) indirectly via seaborn. Before my environment is updated with matplotlib 3.6, what would you recommend as a workaround for this bug? The workaround should preferably have as little side effect as possible.
tacaswell commentedon Jul 24, 2022
Adding
should force the backend resolution to work around this issue and have no other side effects. This only needs to be done once per process.
kailizcatman commentedon Jul 24, 2022
Thank you.
jklymak commentedon Jul 24, 2022
But also seaborn need not use a context manager here?
mwaskom commentedon Jul 30, 2022
?
jklymak commentedon Jul 30, 2022
I think seaborn can turn the layout off (
fig.set_tight_layout(False)). I guess if you want it to turn back on, you could save the old state and toggle it back on.I guess philosophically I don't think of rcParams as something downstream libraries should be changing, but rather defaults that the user sets. However I appreciate that there is a counter current in the project of thinking of rcParams as a global state for the library that gets manipulated at will, and I can see how the context manager helps encourage that. However, I'm just not convinced it is a good idea given the number of weird side effects it can produce.
mwaskom commentedon Jul 30, 2022
The rcParams very much are "a global state that can be manipulated at will" so if doing so can produce "weird side effects", it seems important for matplotlib to clearly document them.
FIX/API: Do not reset rcParams['backend'] in rc_context
FIX/API: Do not reset rcParams['backend'] in rc_context