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
Cannot properly reload figure that was previously pickled #3483
Dear all,
I just figure out that matplotlib does not have apparently a simple way to save interactive plots as MATLAB "fig" figures. I sincerely hope the "experimental" pickling will be soon consolidated because it would be of great benefit for users imho.
It seems that I am able to pickle the figure indeed, but not to reload it properly.
This is what I get:
Traceback (most recent call last):
File "/usr/lib64/python2.7/site-packages/matplotlib/backends/backend_qt4.py", line 299, in resizeEvent
self.draw()
File "/usr/lib64/python2.7/site-packages/matplotlib/backends/backend_qt4agg.py", line 154, in draw
FigureCanvasAgg.draw(self)
File "/usr/lib64/python2.7/site-packages/matplotlib/backends/backend_agg.py", line 451, in draw
self.figure.draw(self.renderer)
File "/usr/lib64/python2.7/site-packages/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib64/python2.7/site-packages/matplotlib/figure.py", line 1031, in draw
dsu = [row for row in dsu if not row[1].get_animated()]
File "/usr/lib64/python2.7/site-packages/matplotlib/artist.py", line 612, in get_animated
return self._animated
AttributeError: 'AxesSubplot' object has no attribute '_animated'
Any suggestion? Shall I bother about this?
I am using matplotlib 1.3.1 on Fedora 20 with QtAgg backend.
The bug occurs when the pickle is loaded with mpl in interactive mode, and not otherwise, at least in my limited testing. I think the problem is that in interactive mode, draw() commands are triggered before the unpickling is complete. Conceptually, this could be solved if draw_if_interactive() had a way of knowing that unpickling is in progress; equivalently, a solution would be for the unpickling process to turn off interactive mode until it has finished. Offhand, I don't know how to implement either of these solutions. Does pickle.load set a global variable that serves as a flag to show when loading is in progress?
If not, then maybe we need to have a pickle.load wrapper in mpl, and tell people to use that instead of raw pickling. As a step beyond that, we could have a pickle.save wrapper, and potentially add metadata to the file.
@mdepitta in the meantime, a workaround for you is manually turn interactive mode off (plt.ioff()) before loading your pickle, and restore it (plt.ion(), if you were indeed in interactive mode) at the end.
Or, instead of a wrapper around pickle.load(), how about a context manager?
On Sun, Sep 7, 2014 at 4:06 PM, Eric Firing [email protected]
wrote:
The bug occurs when the pickle is loaded with mpl in interactive mode, and
not otherwise, at least in my limited testing. I think the problem is that
in interactive mode, draw() commands are triggered before the unpickling
is complete. Conceptually, this could be solved if draw_if_interactive()
had a way of knowing that unpickling is in progress; equivalently, a
solution would be for the unpickling process to turn off interactive mode
until it has finished. Offhand, I don't know how to implement either of
these solutions. Does pickle.load set a global variable that serves as a
flag to show when loading is in progress?
If not, then maybe we need to have a pickle.load wrapper in mpl, and tell
people to use that instead of raw pickling. As a step beyond that, we could
have a pickle.save wrapper, and potentially add metadata to the file.
@WeatherGod Yes, a context manager would work. A disadvantage is that context managers are relatively new features of Python, and not something a beginner or casual user (or perhaps an old-timer like myself) is likely to have at their fingertips. With a pair of wrappers we could provide a simple function interface with memorable names (really, if you were a beginner, would you think of using the term "pickle" for saving a plot?), and with the ability to improve functionality via metadata and error handling. In fact, we could add the pickling capability to the savefig method and function, and then add a restorefig function, or something like that.
I've never been a fan of this general approach; instead I've always advocated using scripts to save code and data as needed to recreate plots. Nevertheless, we have the pickle capability, and there is always demand for this style, so we are stuck with it. Might as well try to make it easy to use.
An argument to the contrary would be that because pickles only work for short-term storage when one can be sure of restoring into the same environment as that from which one saved, we should let our pickle capability remain obscure; otherwise we might be inundated with complaints that "I can't load the pickle I saved last year." So, maybe we are better off just providing a context manager in pyplot.
I'm undecided.
Wow, I'm so behind on my notifications! Thanks for raising this @mdepitta. Can you provide a SSCCE (Short, Self Contained, Correct , Example) to allow us to reproduce? This will dramatically speed up the development of a fix for this issue.
Activity
efiring commentedon Sep 7, 2014
The bug occurs when the pickle is loaded with mpl in interactive mode, and not otherwise, at least in my limited testing. I think the problem is that in interactive mode,
draw()commands are triggered before the unpickling is complete. Conceptually, this could be solved ifdraw_if_interactive()had a way of knowing that unpickling is in progress; equivalently, a solution would be for the unpickling process to turn off interactive mode until it has finished. Offhand, I don't know how to implement either of these solutions. Doespickle.loadset a global variable that serves as a flag to show when loading is in progress?If not, then maybe we need to have a
pickle.loadwrapper in mpl, and tell people to use that instead of raw pickling. As a step beyond that, we could have apickle.savewrapper, and potentially add metadata to the file.@mdepitta in the meantime, a workaround for you is manually turn interactive mode off (
plt.ioff()) before loading your pickle, and restore it (plt.ion(), if you were indeed in interactive mode) at the end.WeatherGod commentedon Sep 7, 2014
Or, instead of a wrapper around pickle.load(), how about a context manager?
On Sun, Sep 7, 2014 at 4:06 PM, Eric Firing [email protected]
wrote:
efiring commentedon Sep 7, 2014
@WeatherGod Yes, a context manager would work. A disadvantage is that context managers are relatively new features of Python, and not something a beginner or casual user (or perhaps an old-timer like myself) is likely to have at their fingertips. With a pair of wrappers we could provide a simple function interface with memorable names (really, if you were a beginner, would you think of using the term "pickle" for saving a plot?), and with the ability to improve functionality via metadata and error handling. In fact, we could add the pickling capability to the
savefigmethod and function, and then add arestorefigfunction, or something like that.I've never been a fan of this general approach; instead I've always advocated using scripts to save code and data as needed to recreate plots. Nevertheless, we have the pickle capability, and there is always demand for this style, so we are stuck with it. Might as well try to make it easy to use.
An argument to the contrary would be that because pickles only work for short-term storage when one can be sure of restoring into the same environment as that from which one saved, we should let our pickle capability remain obscure; otherwise we might be inundated with complaints that "I can't load the pickle I saved last year." So, maybe we are better off just providing a context manager in pyplot.
I'm undecided.
tacaswell commentedon Sep 8, 2014
I would advocate against pushing the use of pickle to store/share plots due to the security issues associated with them.
This will hopefully be addressed by the effort to serialize figures to json.
pelson commentedon Feb 6, 2015
Wow, I'm so behind on my notifications! Thanks for raising this @mdepitta. Can you provide a SSCCE (Short, Self Contained, Correct , Example) to allow us to reproduce? This will dramatically speed up the development of a fix for this issue.
Thanks!
fix matplotlib#3483
Revert "fix matplotlib#3483"
fix matplotlib#3483
efiring commentedon Feb 28, 2015
Given the "won't fix" decision, I'm going to close this.