Skip to content

Cannot properly reload figure that was previously pickled #3483

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
mdepitta opened this issue Sep 7, 2014 · 6 comments
Closed

Cannot properly reload figure that was previously pickled #3483

mdepitta opened this issue Sep 7, 2014 · 6 comments

Comments

@mdepitta
Copy link

mdepitta commented Sep 7, 2014

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.

Briefly, I followed the simple procedure outlined here in order to pickle and reload figures:
http://stackoverflow.com/questions/7290370/store-and-reload-matplotlib-pyplot-object

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.

Thanks for your time,

Maurizio

@tacaswell tacaswell added this to the v1.4.x milestone Sep 7, 2014
@efiring
Copy link
Member

efiring commented 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 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.

@WeatherGod
Copy link
Member

Or, instead of a wrapper around pickle.load(), how about a context manager?

On Sun, Sep 7, 2014 at 4:06 PM, Eric Firing notifications@github.com
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.

@mdepitta https://github.com/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.


Reply to this email directly or view it on GitHub
#3483 (comment)
.

@efiring
Copy link
Member

efiring commented 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 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.

@tacaswell
Copy link
Member

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
Copy link
Member

pelson commented 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!

dvijpatel pushed a commit to dvijpatel/matplotlib that referenced this issue Feb 23, 2015
dvijpatel pushed a commit to dvijpatel/matplotlib that referenced this issue Feb 23, 2015
This reverts commit fdb66ae.
dvijpatel pushed a commit to dvijpatel/matplotlib that referenced this issue Feb 23, 2015
@dvijpatel dvijpatel mentioned this issue Feb 23, 2015
@efiring
Copy link
Member

efiring commented Feb 28, 2015

Given the "won't fix" decision, I'm going to close this.

@efiring efiring closed this as completed Feb 28, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants