Plot data from custom class

Out of the box matplotlib works great with Numeric and numarray data
types. However, I have my own custom class which contains data members,
methods and an array of data (underlying C array). Is there a way to
expose the C array data to the plot() routines? For example I would
like to be able to use plot(X) where X is an instantiated object of
type MyClass.

Thanks,

-Simon

One approach that I've used recently is to simply provide functionality
for the operator (done by implementing the __getslice__ member
function) that accesses the data according to standard slicing rules.
Then, you can use plot() directly.

Glen

···

On Fri, Mar 02, 2007 at 09:41:03AM -0500, Simon Wood wrote:

Out of the box matplotlib works great with Numeric and numarray data types.
However, I have my own custom class which contains data members, methods and
an array of data (underlying C array). Is there a way to expose the C array
data to the plot() routines? For example I would like to be able to use
plot(X) where X is an instantiated object of type MyClass.

P.S. You may also need to implement functions like __len__; if these
concepts are well-defined for your class, then it should be a very
straightforward process.

Glen

···

On Fri, Mar 02, 2007 at 08:44:02AM -0600, Glen W. Mabey wrote:

One approach that I've used recently is to simply provide functionality
for the operator (done by implementing the __getslice__ member
function) that accesses the data according to standard slicing rules.
Then, you can use plot() directly.

But the problem is (if your experience is similar to mine) that then
you'll want to implement __iter__ too, and you'll start liking this
combination of python, numpy, and matplotlib *way* too much.

Glen

···

On Fri, Mar 02, 2007 at 08:46:24AM -0600, Glen W. Mabey wrote:

P.S. You may also need to implement functions like __len__; if these
concepts are well-defined for your class, then it should be a very
straightforward process.

python > Out of the box matplotlib works great with Numeric and
numarray data types.

However, I have my own custom class which contains data members, methods and
an array of data (underlying C array). Is there a way to expose the C array
data to the plot() routines? For example I would like to be able to use
plot(X) where X is an instantiated object of type MyClass.

My initial response was if your object supports iteration, it will
work with matplotlib But I just tested this and found it to be false.

class C:
    def __init__(self):
        self._data = (1,2,3,4,5)

    def __iter__(self):
        for i in self._data:
            yield i
        return

    def __len__(self):
        return len(self._data)

c = C()
for i in c:
    print i

But numpy.asarray, which is what mpl uses to convert inputs to arrays,
fails with this object.

In [16]: c = C()
In [17]: numpy.asarray(c)
Out[17]: array(<__main__.C instance at 0x8d04f6c>, dtype=object)

because it treats it as an object array (but list(c) works as
expected). What is the minimum interface for an object to be
converted to a numpy sequence via as array?

Setting up your object to work with the numpy asarray conversion
facility is probably your best bet pending answers to the question
above. But, if your object doesn't expose the proper interface, and
for some reason you cannot modify or wrap your objects to expose it,
we have a branch of svn to handle plotting of types with unit
information, but this branch will also support plotting of arbitrary
user types. One can register their type with a set of converter
functions, and then do

  >>> plot(myobj)

myobj does not need to expose any particular interface, as long as you
have registered a converter with matplotlib -- the converter maps
object type to classes that know how to convert your object to. This
enable you to use custom objects (usually coming from 3rd part
extension code that you do not want to wrap or modify) with
matplotlib. Some basic examples are in examples/units and the
documentation is in lib/matplotlib/units.py

Michael, can you point Simon to a minimal example in the unit's branch
that would show him how to use the new units registry for a custom
object? Just to be clear, he doesn't need the unit handling, so would
just need the default locator and formatter, but he would need the
to_array conversion and object type registry. I think this will be an
important use case for this code that was not part of the original
plan. I think the basic idea is that an important use case will be
one where the user doesn't care about units or tagged values or
locators and formatters, and we should provide a base converter than
encapsulates all this for them, and then all the need to do is derive
from this class and register with the figure. It also suggests we may
want to rename register_default_unit_conversion to
register_default_conversion.

The svn branch lives in

svn checkout matplotlib download | SourceForge.net mplunits

JDH

···

On 3/2/07, Simon Wood <sgwoodjr@...287...> wrote:

John Hunter wrote:

But numpy.asarray, which is what mpl uses to convert inputs to
arrays,

The whole idea of asarray, is that it should be able to convert properly
defined objects without even copying the data.

my own custom class which contains data members, methods and an array
of data (underlying C array)

This sounds like EXACTLY the type of object that the array interface is supposed to support. So what you need to do is give your object an array interface:

http://numpy.scipy.org/array_interface.shtml

once you've done that, asarray() should "just work" and therefore all of MPL should just work.

However, I would post a question about this to the numpy list -- there is an effort at the moment to have an n-d buffer protocol defined for Python 3.0.

http://projects.scipy.org/mailman/listinfo/numpy-discussion

I'm not sure at this point whether you'd be best off implementing the above interface or the new buffer protocol that's being discussed:

http://projects.scipy.org/scipy/numpy/browser/trunk/numpy/doc/pep_buffer.txt

The numpy folks will be able to help.

By the way, this is a good example why the above PEP is a good idea!

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@...259...

I still am not able to make my mock-up custom python class work as I
would like with asarray (though it works with "list"). What am I
missing? The way I read it this appears to be in support of extension
code that wants to expose the array interface, but I have a python
object that acts like a sequence (am I missing some important method)
that wants to work properly with numpy.asarray

class C:
    def __init__(self):
        self._data = (1,2,3,4,5)

    def __iter__(self):
        for i in self._data:
            yield i
        return

    def __getitem__(self, i):
        return self._data[i]

    def __getslice__(self, i, j):
        return self._data[i:j]

    def __len__(self):
        return len(self._data)

    def __array_interface__(self):
        return dict(
            shape=(len(self._data),),
            typestr='f',
            version=3)

import numpy
c = C()
print numpy.asarray(c)
#for i in c:
# print i

···

On 3/2/07, Christopher Barker <Chris.Barker@...259...> wrote:

This sounds like EXACTLY the type of object that the array interface is
supposed to support. So what you need to do is give your object an array
interface:

http://numpy.scipy.org/array_interface.shtml

John,
Why wouldn't you use the numpy.core.ma implementation of masked arrays as a
source of inspiration ? After all, what (I think) you're doing is pretty
close to how masked arrays were initially implemented, as a class on its own,
not derived from ndarray.
Basically, that would amount to define a __array__() method that would return
the numpy equivalent of your object.

Or you can try to use Pyrex for your new class. That works well if you don't
try to subclass ndarray.

···

On Friday 02 March 2007 14:12:24 John Hunter wrote:

I still am not able to make my mock-up custom python class work as I
would like with asarray (though it works with "list"). What am I
missing? The way I read it this appears to be in support of extension
code that wants to expose the array interface, but I have a python
object that acts like a sequence (am I missing some important method)
that wants to work properly with numpy.asarray