If you are using mpl svn, please read this as it describes

some fairly major changes.

Mike Lusignan has been working on adding units support, and as a

consequence, partial support for working with arbitrary types in mpl.

The support is not complete yet, but it is basically working and

compatible with the rest of mpl, so I thought now would be a good time

to integrate it into the svn HEAD (he's been working in a branch)

and get some more eyeballs on it.

The code base is a little complicated and daunting at first, but we

are working to try and simplify it and refactor it so the main

functionality is minimally invasive into the rest of the code base.

Right now it is somewhat distributed among units, figure, axes,

artist, lines, patched, etc, but will be consolidated in the upcoming

week(s). Not all of the plotting functions support units, but the

examples show some with scatter and plot.

The documentation is in matplotlib.units. We do not assume any

particular units package, we only require that package to provide

a certain interface. Alternatively, one can use a units type that doesn't

have the required interface as long as you register some adaptors with

the figure. More on this later. Mike also provided a mockup units package

in the examples/units dir called basic_unit.py to test and demo the support.

I ran into a little problem today in trying to reconcile Eric's work

supporting multicolumn y data with the unit support for arbitrary

types. The basic tension is in _process_plot_var_args._xy_from_xy and

friends which simplfies the array column logic by forcing all inputs

to have a array.shape==2 using some conversion functions. The problem

is this strips out the units tagging Mike is relying on (in the

current implementation he needs _xorig in Line2D to be the original

data type). This is a fairly important question that

requires some thought: do we want mpl objects to store original data

objects as long as they know how to convert themselves under the hood

to something useful when requested (eg Text now supports any object

that supports '%s'%o. I think if we could support this generally,

that is the ideal, because it let's users use mpl with custom objects,

possibly from 3rd party closed src vendors, as long as the objects

expose the right interface. It's also useful for picking, where you

might want to store your custom objects and arrays in mpl and query

them later. If we lose access to the orginal data when constructing

our objects, we lose this ability. That said, we are fairly far from

achieving this goal globally.

I did a quick-and-dirty hack in process_plot_var_args for the time

being to get something everyone can chew on, which is to use the

existing approach if the data are indeed multicolumn, but use the

original x and y data otherwise. We'll come up with something more

general and elegant shortly.

backend_driver is passing in my local repository, and the units

examples are passing as well, and I thought this is sufficient

progress that it merits getting the merge done now and getting more

testers on this. I expect there will be some breakage

and performance hits, and we can fix these as they arise.

The new examples are in examples/units -- a couple of screenshot

of the example below is attached.

Thanks Mike!

JDH

import matplotlib

matplotlib.rcParams['numerix'] = 'numpy'

import basic_units as bu

import numpy as N

from pylab import figure, show

from matplotlib.cbook import iterable

cm = bu.BasicUnit('cm', 'centimeters')

inch = bu.BasicUnit('inch', 'inches')

inch.add_conversion_factor(cm, 2.54)

cm.add_conversion_factor(inch, 1/2.54)

lengths_cm = cm*N.arange(0, 10, 0.5)

# iterator test

print 'Testing iterators...'

for length in lengths_cm:

print length

print 'Iterable() = ' + `iterable(lengths_cm)`

print 'cm', lengths_cm

print 'toinch', lengths_cm.convert_to(inch)

print 'toval', lengths_cm.convert_to(inch).get_value()

fig = figure()

ax1 = fig.add_subplot(2,2,1)

ax1.plot(lengths_cm, 2.0*lengths_cm, xunits=cm, yunits=cm)

ax1.set_xlabel('in centimeters')

ax1.set_ylabel('in centimeters')

ax2 = fig.add_subplot(2,2,2)

ax2.plot(lengths_cm, lengths_cm, xunits=cm, yunits=inch)

ax2.set_xlabel('in centimeters')

ax2.set_ylabel('in inches')

ax3 = fig.add_subplot(2,2,3)

ax3.plot(lengths_cm, 2.0*lengths_cm, xunits=inch, yunits=cm)

ax3.set_xlabel('in inches')

ax3.set_ylabel('in centimeters')

ax4 = fig.add_subplot(2,2,4)

ax4.plot(lengths_cm, 2.0*lengths_cm, xunits=inch, yunits=inch)

ax4.set_xlabel('in inches')

ax4.set_ylabel('in inches')

fig.savefig('simple_conversion_plot.png')

show()