from matplotlib.cbook import iterable import matplotlib.units as units import matplotlib.ticker as ticker import matplotlib.pyplot as plt
classFoo(object): def__init__(self, val, unit=1.0): self.unit = unit self._val = val * unit
defvalue(self, unit): if unit isNone: unit = self.unit returnself._val / unit
classFooConverter(object): @staticmethod defaxisinfo(unit, axis): 'return the Foo AxisInfo' if unit == 1.0or unit == 2.0: return units.AxisInfo( majloc=ticker.IndexLocator(8, 0), majfmt=ticker.FormatStrFormatter("VAL: %s"), label='foo', )
else: returnNone
@staticmethod defconvert(obj, unit, axis): """ convert obj using unit. If obj is a sequence, return the converted sequence """ if units.ConversionInterface.is_numlike(obj): return obj
if iterable(obj): return [o.value(unit) for o in obj] else: return obj.value(unit)
@staticmethod defdefault_units(x, axis): 'return the default unit for x or None' if iterable(x): for thisx in x: return thisx.unit else: return x.unit
units.registry[Foo] = FooConverter()
# create some Foos x = [] for val inrange(0, 50, 2): x.append(Foo(val, 1.0))
# and some arbitrary y data y = [i for i inrange(len(x))]
# plot specifying units ax2.plot(x, y, 'o', xunits=2.0) ax2.set_title("xunits = 2.0") plt.setp(ax2.get_xticklabels(), rotation=30, ha='right')
# plot without specifying units; will use the None branch for axisinfo ax1.plot(x, y) # uses default units ax1.set_title('default units') plt.setp(ax1.get_xticklabels(), rotation=30, ha='right')