On Sun, 2006-06-18 at 00:05 +1000, John Pye wrote:
> Hi all,
> 
> A thought just occurred to me: I wonder if it would be useful to be able
> to 'pickle' Matplotlib plots, using the python cPickle library. This
> way, I could save my plots in a form that would allow me to load them
> back later (with just the necessary source data) and fiddle with things
> like titles and legends and so on. Would be useful perhaps in the
> context of preparing diagrams for an article or report.
> 
> Has anyone tried this? Would it be recommended/not recommended/not even
> possible?

I had a look at this a while back. It looks like the well thought out
structure of MPL should make this easy, although it would require a few
adjustments. To make a Figure object pickle-able, all the internal
objects in a Figure must also be pickle-able. Most of the innards of a
Figure are python objects which should pickle without problem. The only
parts which aren't are the "BinOps". These are custom C-coded objects
which implement 'lazy evaluation' of the transformation expressions.
They're defined in the _transforms.cxx/h files.

In theory, you can easily make these C-objects pickle-able using the
'copy_reg' module; you just register two functions, one to extracts the
object's state as a pickle-able object, the other to construct a new
instance of the object, initialised with the previously stored state.

However, I ran into a problem: there's some bug in either python or CXX
(the automatic C++ class wrapper which mpl uses for the compiled
components) which results in a segfault when I tried pickling copy_reg
enhanced BinOps. The templating techniques used by CXX are completely
beyond me so this is where things have stuck.

... but ... I just now tested this again with python-2.4.2 and
mpl-0.87.2 and it works! yeay. Thus, if every object in
matplotlib._transforms gets given a python reduction/construction
function pair and registers them with copy_reg, this *should* be enough
to make a Figure pickle-able. Unless I've missed something else...

I may try this out later this week, unless someone else tries it first.

Bryan

PS. copy_reg example follows >>>

import cPickle as pickle
import copy_reg

#let's test this on a simple 'Value' BinOp
from matplotlib._transforms import Value

def fcon(val):
    #constructor
    return Value(val)

def fred(o):
    #reduction functions
    val = o.get()
    return fcon, (val,)

#my starting object
a=Value(5)
print a, a.get()

copy_reg.pickle(type(a), fred)

data = pickle.dumps(a)

new = pickle.loads(data)
print "new", new, new.get()

> 
> Cheers
> JP




_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to