Skip to content
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

Can't dump_session with inline plots #4

Closed
niallrobinson opened this issue Sep 18, 2013 · 23 comments
Closed

Can't dump_session with inline plots #4

niallrobinson opened this issue Sep 18, 2013 · 23 comments

Comments

@niallrobinson
Copy link

dump_session() seems to fail when used with ipython notebook set up for inline plots. When the %matplotlib inline magic is used you get a traceback resulting in
PicklingError: Can't pickle 'RendererAgg' object: <RendererAgg object at 0x42a2bb8>
and when using the --pylab=inline option at start up you get a traceback resulting in
PicklingError: Can't pickle <class 'matplotlib.axes.AxesSubplot'>: it's not found as matplotlib.axes.AxesSubplot

Using Dill 0.2a.dev, ipython 1.1.0

@mmckerns
Copy link
Member

@niallrobinson: This is a known issue for pickling of matplotlib objects. Several years ago, at a scipy sprint, I tried see how far dill could go with pickling matplotlib objects, and ran into issues on the objects you list above. There's some "tricky" things that are being done in matplotlib with weakrefs and the like that make the objects unpicklable, even with dill, for the moment. I'd need to talk to the matplotlib team. In many cases, it's just a matter of moving a line of code (say an import) to another level in the object hierarchy.

ipython is a good use case for why matplotlib objects should be picklable... also it could allow matplotlib to be sped up by doing parallel computing on each of the different graphics layers. The good news is that once it would work with matplotlib objects, then it'd work in ipython. This will take some time, however, and someone on the matplotlib team's interest in getting it done. It looks like the right guys to ping about this initially are @ivanov and @fperez. There are some things that I can do in dill to help it out, but it's really a case of dev in matplotlib... and that means it be a big help if someone there is interested in it happening.

@fperez
Copy link

fperez commented Sep 19, 2013

This one is really for the matplotlib core team, pinging @mdboom so he can pitch in or relay it to the others. I'm not active in the core of mpl to the level this requires, I'm afraid.

As @mmckerns says, once the necessary support goes in for matplotlib, it will just work transparently in IPython.

@mdboom
Copy link

mdboom commented Sep 19, 2013

What version of matplotlib are you on? For 1.3.0, @pelson added a great deal of support for pickling... But I haven't tried what you describe to confirm.

@mmckerns
Copy link
Member

@mdboom: Last I tried was in version 1.1.0 and 1.2.0. So, I'm a few months off the current one. I will update to 1.3.0 and give it a try. I'm not sure about what version of matplotlib the reporter @niallrobinson is on.

If you want to test pickling anything with dill, all you have to do is type:
import dill.
Pickle's API is a subset of dill's, and the code above loads dill's known types into pickle's registry...
so you can then go about using pickle if your code is pickling with pickle and not with cPickle.

Install dill from the github site, if you want to give it a try. It's a very small pure python package with no dependencies.

@pelson
Copy link

pelson commented Sep 19, 2013

For 1.3.0, @pelson added a great deal of support for pickling

Yep. I think we labelled it "experimental" in the what's new, but certainly anything that isn't too fruity can be pickled in v1.3.0. Anything that remains is an oversight and can be considered a bug, so please fire away bug reports to the mpl tracker and I'll get on to them.

@niallrobinson
Copy link
Author

I'm currently on 1.2.0rc2, so I'll see if 1.3 sorts any of the problems.

@niallrobinson
Copy link
Author

Unfortunately I get the same behaviour with matplotlib 1.3

@mmckerns
Copy link
Member

@niallrobinson: This should probably move over to matplotlib's issue tracker -- please bug report your issue there. However, I'd appreciate keeping me in the loop... I may be able to help with the serialization. I'll update and try myself (and I may want to link the related mpl issue from here).

@pelson
Copy link

pelson commented Sep 19, 2013

We don't store the RenderAgg object when pickling figures (in fact, one of the cool features is that you can pickle a figure from one backend, and re-attach it to another, that is probably news to even @mdboom 😉) so I think there is probably some deep inspection of all objects which exist in the current session which is being a little too deep, it's uncertain to me where that inspection lies: it could be IPython or it could be dill...

@mmckerns
Copy link
Member

@pelson: So the issue that started this thread is that one of the things that dill provides is a serialization of an entire active interpreter session, where you can start a new interpreter and then resume the pickled session where you left off. That means, if you have an Agg object in the interpreter session (esp. in __main__), dill's going to try to serialize it. So, even if matplotlib doesn't need to use the Agg object to pickle a plot, requiring the Agg object be available in __main__ creates an issue for anyone that's going to try to save the current session... something desirable in IPython. Maybe that might be a focus of discussion going forward. Dill has special handlers for a very few of the IPython objects (e.g. the "exit" singleton) that need to be in __main__ for IPython, but don't need to be serialized to save the state of the interpreter. With the Agg, we may be in a similar boat. The thing to try is to create a plot, and then do:

import dill
dill.dump_session('mpl_test.pkl')

That will show what needs work for an interpreter session with a plot to be serialized.

I have a debug flag that can be turned on with dill._trace(True), but it's the same strings that would be seen in the traceback when something fails.

@mmckerns
Copy link
Member

I'll be investigating as soon as I can.

@niallrobinson
Copy link
Author

Does anyone know if anyone has had a chance to look at this? Not meaning to pester, just thought I'd ask in case I'd missed it.

@mmckerns
Copy link
Member

mmckerns commented Nov 7, 2013

@niallrobinson: I have not looked at it yet. I've been tied up for a few weeks, but should get to it soon.

@qkhhly
Copy link

qkhhly commented Oct 3, 2014

Hi, @mmckerns, how is this issuing coming along? I recently tried dill.dump_session() in a ipython notebook and still got the same error. I am using ipython 2.1 and matplotlib 1.4. As you mentioned, the ability to serialize entire active interpreter session and then resume the pickled session later is a big plus for ipython notebook. I'd like to know if there is workarounds or alternatives I can try!

@mmckerns
Copy link
Member

mmckerns commented Oct 3, 2014

@jianlingzh: It would be a very cool feature for IPython... however, this issue is still very much open, and to be honest, I haven't touched it in a long while. It'd take digging into the guts of both matplotlib (and possibly how IPython handles matplotlib)… and I've not done it.

@qkhhly
Copy link

qkhhly commented Oct 5, 2014

Thanks, @mmckerns! Is there any way to work around this currently? Like ask dill to ignore certain matplotlib objects when dumping the session?

@mmckerns
Copy link
Member

mmckerns commented Oct 5, 2014

I don't know of any current workaround, but having a list or dict of objects-to-ignore in dump_session is an interesting idea. Hmm.

@pelson
Copy link

pelson commented Oct 8, 2014

I wasn't able to reproduce this with mpl v1.3.1, IPython 2.2, and dill 0.2.1 - @jianlingzh, could you produce a notebook which I can run to reproduce the problem exactly? (a gist would be great)

@qkhhly
Copy link

qkhhly commented Oct 8, 2014

@pelson, this isn't hard for me to reproduce. Just a couple of lines:

a = range(10)
dill.dump_session('test.pkl')

will show the error that started this thread. I tried matplotlib 1.4.0, dill 0.2.1 on both IPython 2.1 and 2.2, both created the error. Did you have the pylab = 'inline' config in your ipython notebook config file?

c.IPKernelApp.pylab = 'inline'

@mmckerns
Copy link
Member

mmckerns commented Oct 8, 2014

I have added a bunch of pickling error detection and introspection methods since this thread started -- in dill.detect. If you are going to do some poking around, they are good tools. See also the complimentary use of objgraph (#58).

@pelson
Copy link

pelson commented Oct 9, 2014

Did you have the pylab = 'inline' config in your ipython notebook config file?

No! This is the reason... I never use pylab, I cannot recommend highly enough just using the proper namespaces. i.e.:

from numpy import np
from matplotlib.pyplot import plt

That said, to reproduce this without IPython (or pylab):

$> python -c "import matplotlib; matplotlib.use('tkagg'); import matplotlib.pyplot as plt; import dill; s = plt.subplot(1, 2, 1); plt.draw(); r = dill.dumps(s);"

That's:

import matplotlib
matplotlib.use('tkagg')
import matplotlib.pyplot as plt
import dill
s = plt.subplot(1, 2, 1)

# Put the renderer on the figure.
plt.draw()

r = dill.dumps(s)

And the error:

pickle.PicklingError: Can't pickle 'RendererAgg' object: <RendererAgg object at 0xxxxxxx>

Essentially, I can reproduce this with Pickle alone, so this isn't a IPython or a Dill issue - I'll go ahead and create an issue on matplotlib, and we can close this one.

P.S. The dill.detect module looks really useful! Thanks for the pointer.

@mmckerns
Copy link
Member

mmckerns commented Oct 9, 2014

@pelson: The above issue is really out of scope for dill, however, if you do find any issues that you are having in trying to do the above, please either report here or in a new ticket. Also anything pickling-related you want to ping me about, please do.

@mmckerns
Copy link
Member

FYI: this likely has become a lot easier as of #101.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants