【发布时间】:2019-05-05 18:42:03
【问题描述】:
我正在尝试使我的课程与matplotlib's units 兼容并面临意外行为。
这是我的自定义类的简化版本,它不是 numpy 的 ndarray 的子类:
import numpy as np
import matplotlib
import matplotlib.units as units
class Toto:
def __init__(self, value_like, unit_like):
self.value_like = value_like # typically a scalar or array
self.unit_like = unit_like # a string describing the unit
def __array__(self, *args, **kwargs):
return np.array(self.value_like, *args, **kwargs)
# To test if plot as expected, without units handling
arr_x = Toto(np.arange(5), "meter")
arr_y = Toto(np.arange(5), "second")
plt.plot(arr_x, arr_y)
请注意,我添加了一个 __array__ 方法,以便使用 matplotlib 使其“可绘制”(如果没有,当 numpy 尝试使用 array(toto_instance, float) 投射 Toto 时,我得到一个 TypeError: float() argument must be a string or a number, not 'Toto' 异常)。我怀疑我的问题实际上来自这种方法,但我不知道为什么/如何。无论如何,继续解决实际问题:
现在我按照example in the doc 为我的 Toto 课程制作了一个转换接口:
class TotoConverter(units.ConversionInterface):
@staticmethod
def convert(value, unit, axis):
'Convert a toto object value to a scalar or array'
old_toto_unit = axis.get_unit()
# stupid computation to determine new_unit (simpler for a MWE)
new_unit = old_toto_unit
new_toto = Toto(value, new_unit)
return new_toto.value_like
@staticmethod
def axisinfo(unit, axis):
return units.AxisInfo(label=str(unit))
@staticmethod
def default_units(x, axis):
'Return the default unit for x or None'
return getattr(x, 'unit_like', None)
最后,我将我的类的转换接口添加到matplotlib的转换接口注册表中:
units.registry[Toto] = TotoConverter()
那么问题来了: 此时,我应该在绘制 Toto 实例时获得标签上的单位,但我得到的结果与定义和注册我的单位转换接口之前相同。这是为什么 ?
我怀疑转换对象从未被调用,因为我的 Toto 实例被转换为 ndarray 但我不确定
干杯
【问题讨论】:
标签: python numpy matplotlib multidimensional-array