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()