Description
Summary
Units are inconsistent and only partially functional, particularly when combined with duck-typing array types.
Proposed fix
Matplotlib has had support for units for many years. There have been two main uses for this functionality,
- to convert data objects to numpy arrays
- to allow the units to change on an axis (
ax.xaxis.set_units('feet')
).
The first functionality generally works, and works well. However the second is only supported by plot
. That is because plot
retains the unit information, and Line2d
reevaluates it at draw time. Unfortunately, no other plotting methods do this.
Here we propose to back this out of Line2D
and instead convert at the beginning. So at the beginning of any plotting routine we will call x = ax.xaxis.convert_units(x)
. If xaxis
already has a unit converter, that will get called with x
as an argument. If not, then the units registry will be consulted and the unit converter added to xaxis
. Data will always be stored as a numpy array with some base units. So if we have 'feet', 'miles', 'meters', we would convert and store x
in units of meters (or whatever the converter
prefers).
This leaves dealing with changing the units on the axis, which works for plot
/Line2D
but not other artists. This can be done one of two ways
- Just change the axis
Locator
andFormatter
to the new units. This is currently whatdates.py
does already for different date resolutions. This has the benefit of keeping the data units the same as the numpy values stored by the Artist - The more complicated method would be via another transform going from internal data to display data
Overall, I think 1) is the easiest, but it does require folks with unit converters writing more flexible locators and formatters.
I note that this is the opposite direction being suggested by recent proposals to pipe the raw object all the way to the draw stage. But I'm not sure if that will end up successful, so thought I'd make this alternate suggestion.