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()
···
On Sun, 2006-06-18 at 00:05 +1000, John Pye wrote:
Cheers
JP