【问题标题】:matplotlib inherit from datetime class plotmatplotlib 继承自 datetime 类图
【发布时间】:2012-05-01 14:41:02
【问题描述】:

所以情况是这样的。假设我们有:

class Test(datetime):
    def a(self):
        return '{0:02d}{1:02d}{2:02d}{3:02d}'.format(self.year % 100, self.month, self.day, self.hour)
x = [Test(2010, 05, 02, 06), Test(2010, 05, 02, 12)]
y = [0, 1]

现在尝试使用:

import matplotlib.pyplot as plt
plt.plot(x, y)

给出一个空白图和以下错误:

/usr/local/lib/python2.7/dist-packages/matplotlib/pyplot.py in plot(*args, **kwargs)
   2456         ax.hold(hold)
   2457     try:
-> 2458         ret = ax.plot(*args, **kwargs)
   2459         draw_if_interactive()
   2460     finally:
/usr/local/lib/python2.7/dist-packages/matplotlib/axes.pyc in plot(self, *args, **kwargs)
   3847 
   3848         for line in self._get_lines(*args, **kwargs):
-> 3849             self.add_line(line)
   3850             lines.append(line)
   3851 
/usr/local/lib/python2.7/dist-packages/matplotlib/axes.pyc in add_line(self, line)
   1441             line.set_clip_path(self.patch)
   1442 
-> 1443         self._update_line_limits(line)
   1444         if not line.get_label():
   1445             line.set_label('_line%d'%len(self.lines))
/usr/local/lib/python2.7/dist-packages/matplotlib/axes.pyc in _update_line_limits(self, line)
   1449 
   1450     def _update_line_limits(self, line):
-> 1451         p = line.get_path()
   1452         if p.vertices.size > 0:
   1453             self.dataLim.update_from_path(p, self.ignore_existing_data_limits,
/usr/local/lib/python2.7/dist-packages/matplotlib/lines.pyc in get_path(self)
    642         """
    643         if self._invalidy or self._invalidx:
--> 644             self.recache()
    645         return self._path
    646 
/usr/local/lib/python2.7/dist-packages/matplotlib/lines.pyc in recache(self, always)
    390                 x = ma.asarray(xconv, np.float_)
    391             else:
--> 392                 x = np.asarray(xconv, np.float_)
    393             x = x.ravel()
    394         else:
/usr/local/lib/python2.7/dist-packages/numpy/core/numeric.pyc in asarray(a, dtype, order)
    233 
    234     """
--> 235     return array(a, dtype, copy=False, order=order)
    236 
    237 def asanyarray(a, dtype=None, order=None):
TypeError: float() argument must be a string or a number

你们有谁知道发生了什么事吗?是的,我知道有一个 date2num 可以在 x 上使用,但如果可能的话,我想了解这里错误的原因。

【问题讨论】:

    标签: python datetime inheritance matplotlib base-class


    【解决方案1】:

    Matplotlib 使用对象的__class__ 属性来确定如何处理它。您的 Test 课程与 datetime 课程不同:

    >>> from datetime import datetime
    >>> class Test(datetime):
    ...   def a(self):
    ...     return '{0:02d}{1:02d}{2:02d}{3:02d}'.format(self.year % 100, self.month, self.day, self.hour)
    ...
    >>>
    >>> t = Test(2010, 05, 02, 06)
    >>> d = datetime(2010, 05, 02, 06)
    >>>
    >>> getattr(t, '__class__')
    <class '__main__.Test'>
    >>> getattr(d, '__class__')
    <type 'datetime.datetime'>
    

    所以 matplotlib 无法将您的 Test 类识别为 datetime

    这是一个丑陋的 hack,它通过注册 Test 类来解决这个问题,这样它的处理方式与 datetime 的处理方式相同。查看matplotlib.units 文档以获取更多信息。不保证此代码适用于未来版本的 matplotlib:

    >>> import matplotlib.pyplot as plt
    >>> import matplotlib.units, matplotlib.dates
    >>> import datetime
    >>>
    >>> class Test(datetime.datetime):
    ...   def a(self):
    ...     return '{0:02d}{1:02d}{2:02d}{3:02d}'.format(self.year % 100, self.month, self.day, self.hour)
    ...
    >>> matplotlib.units.registry[Test] = matplotlib.dates.DateConverter()
    >>>
    >>> x = [Test(2010, 05, 02, 06), Test(2010, 05, 02, 12)]
    >>> y = [0, 1]
    >>> plt.plot(x, y)
    [<matplotlib.lines.Line2D object at 0x02F6E730>]
    

    (我在 Windows 上使用 python 2.7.2 和 matplotlib 1.1.0 对此进行了测试)

    【讨论】:

    • 嗯,我认为可能会发生这样的事情,我只是不知道在哪里寻找进一步的说明。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多