-
-
Notifications
You must be signed in to change notification settings - Fork 7.8k
[MNT]: Lifetime of pyplot figures #29849
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
Comments
I have some old code that is basically for fig in [fig1, fig2]:
ax = fig.add_subplot(3, 3, plot_num)
plt.sca(ax)
... plot stuff ... I likely would not write it using It might be nice if |
Good point, that way (or generally by passing a Figure instance While it's currently prohibited, I don't think there would be a fundamental problem whith registering an already-existing figure. Actually making is possible to add/remove figures from pyplot tracking would make the pyplot code less entangled. Edit: Actually, we already can attach an existing figure to pyplot and use that for unpickling Figure: matplotlib/lib/matplotlib/figure.py Lines 3305 to 3314 in 90385b4
|
Slightly tangential, but I also just quite like the idea that you could decide after the fact that you want your figure in a gui. my_fig = matplotlib.figure.Figure(...)
ax = my_fig.subplots()
... add artists ...
plt.figure(my_fig)
plt.show() |
I have a prototype working for this 😄 |
It may be fundamentally nice not to have to create the figure though pyplot to be able to use it in pyplot afterwards. You can now do ``` from matplotlib.figure import Figure import matplotlib.pyplot as plt fig = Figure() fig.subplots().plot([1, 3, 2]) plt.figure(fig) # fig is now tracked in pyplot plt.show() ``` This also opens up the possibility to more dynamically track and untrack figures in pyplot, which opens up the road to optimized figure tracking in pyplot (matplotlib#29849)
It may be fundamentally nice not to have to create the figure though pyplot to be able to use it in pyplot afterwards. You can now do ``` from matplotlib.figure import Figure import matplotlib.pyplot as plt fig = Figure() fig.subplots().plot([1, 3, 2]) plt.figure(fig) # fig is now tracked in pyplot plt.show() ``` This also opens up the possibility to more dynamically track and untrack figures in pyplot, which opens up the road to optimized figure tracking in pyplot (matplotlib#29849)
It may be fundamentally nice not to have to create the figure though pyplot to be able to use it in pyplot afterwards. You can now do ``` from matplotlib.figure import Figure import matplotlib.pyplot as plt fig = Figure() fig.subplots().plot([1, 3, 2]) plt.figure(fig) # fig is now tracked in pyplot plt.show() ``` This also opens up the possibility to more dynamically track and untrack figures in pyplot, which opens up the road to optimized figure tracking in pyplot (matplotlib#29849)
I think this will also break the case where you do not care how your figures are tracked, but want to show them all together. This is probably quite common. for ds, name in zip(my_datasets, dataset_names):
fig, ax = plt.subplots()
ax.plot(ds, ...)
ax.set_title(name)
plt.show() |
This example breaks my assumption that you need to somehow be able to retrieve an individual figure again. The two variants with/wo the last show are possible and common: for ds, name in zip(my_datasets, dataset_names):
fig, ax = plt.subplots()
ax.plot(ds, ...)
ax.set_title(name)
plt.savefig(f"{name}.png")
plt.show() # Comment or uncomment We can at no time know whether the figure is still needed because there could always be a We cannot just be clever and auto-clean while keeping full backward-compatibility for relevant use cases. One could still think about the reasonable lifetime for pyplot figure management, but there would be breaking changes at least for some usage scenarios, which makes it much less attractive. |
Summary
Inspired by but technically orthogonal to the recent discussions #29782, #29836: Can we change the lifetime behavior so that (1) users have to care/know less about how pyplot manages the figure - ideally no
close()
is needed - and (2) we do not break typical existing usage patterns?Proposed fix
Observations / Questions:
pyplot
has to keep a figure reference?This combination tells me there is a space for criterions to auto-delete figures:
One interpretation could be: a figure is not needed anymore if all of the following apply:
This would effectively mean that you only have muliple figures tracked in pyplot if either they are currently shown or they have explicit user-created fignums. Conversely, figures without user-created fignums are auto-deleted when appropriate.
IMHO this is a very reasonable logic and removes the need to understand pyplot tracking or use of
close
for almost all users.There's only one minor use case I can imagine that would get broken by this: Users relying on the implictly created fignumbers for changing the active figure:
But this behavior is brittle anyway because you have to know that you're in a fresh interpreter. There are three mitigation strategies:
The text was updated successfully, but these errors were encountered: