0

只是想看看其他人是否认为 matplotlib 中的以下行为plot_date是错误的,或者这只是我应该忍受的。

我设置了一个多面板图,sharex以便在所有轴上进行缩放/平移,并在两个面板中绘制时间序列数据。但是,在第二个面板中,所有数据恰好都是无效的(在这个例子中我屏蔽了它)。

from matplotlib.pyplot import figure,show
from datetime import datetime,timedelta
from numpy import sin,cos,linspace,pi,ma,array

fig=figure(figsize=(16,9))
ax1=fig.add_subplot(211)
ax2=fig.add_subplot(212,sharex=ax1)

# xdata is seconds
xdata=linspace(0,9999,10000)
tdata=array([datetime(2000,1,1)+timedelta(seconds=ss) for ss in xdata])
data1=ma.masked_array(sin(pi*xdata/300),mask=False)
data2=ma.masked_array(cos(pi*xdata/300),mask=True)

ax1.plot_date(tdata,data1,marker='',color='r')
ax2.plot_date(tdata,data2,marker='',color='b')
show()

我希望(更喜欢)它只是显示一个空白面板,而不是失败并给我一个长期无用的回溯。这是预期的行为吗?

笔记:

  • 如果我使用ax.plot(...)而不是,此脚本也会失败ax.plot_date(...)
  • 如果我只是针对xdata而不是 datetime 数组tsdata(但我必须使用它ax1.set_xlim(xdata[0],xdata[-1])来显示一个合理的域),它可以正常工作(即给我一个空面板):
   ax1.plot(xdata,data1,marker='',color='r')
   ax2.plot(xdata,data2,marker='',color='b')
   ax1.set_xlim(xdata[0],xdata[-1])
   show()
  • 我刚刚意识到我可以通过在命令ax2之前强制限制来挽救上述情节。show()我仍然认为主要示例中的失败是不优雅的:
   ax2.set_xlim(tdata[0],tdata[-1])
   show()

专家们怎么看?

谢谢!

仅供参考,这是在 matplotlib 1.1.0 上,从我的 PC 上的源代码编译而来。

这是我得到的回溯:

Traceback (most recent call last):
 File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/backendsbackend_gtk.py", line 395, in expose_even
self._render_figure(self._pixmap, w, h)
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/backends/backend_gtkagg.py", line 75, in _render_f
FigureCanvasAgg.draw(self)
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/backends/backend_agg.py", line 401, in draw
self.figure.draw(self.renderer)
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/figure.py", line 884, in draw
func(*args)
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/axes.py", line 1983, in draw
a.draw(renderer)
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/axis.py", line 1036, in draw
ticks_to_draw = self._update_ticks(renderer)
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/axis.py", line 926, in _update_ticks
tick_tups = [ t for t in self.iter_ticks()]
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/axis.py", line 873, in iter_ticks
majorLocs = self.major.locator()
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/dates.py", line 749, in __call__
self.refresh()
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/dates.py", line 758, in refresh
dmin, dmax = self.viewlim_to_dt()
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/dates.py", line 530, in viewlim_to_dt
return num2date(vmin, self.tz), num2date(vmax, self.tz)
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/dates.py", line 289, in num2date
if not cbook.iterable(x): return _from_ordinalf(x, tz)
  File "/home/tchubb/local/lib/python2.7/site-packages/matplotlib/dates.py", line 203, in _from_ordinalf
dt = datetime.datetime.fromordinal(ix)
ValueError: ordinal must be >= 1
If you suspect this is an IPython bug, please report it at:
https://github.com/ipython/ipython/issues
or send an email to the mailing list at ipython-dev@scipy.org
4

1 回答 1

2

是的,我认为这是一个错误,或者至少是一个看起来已经修复的疏忽(通过@ali_m https://github.com/matplotlib/matplotlib/issues/162)。

我遇到了这个异常,但那是从 6 月开始的 1.3.x 版本(我的错,以为我在这台计算机上有更新的版本)。当前的 master 没有这个问题,@ali_m 报告说它也适用于 1.2.1 和 1.3.0,所以我怀疑修复是升级你的matplotlib.

看起来正在发生的事情是,代码中没有检查来确定放置刻度的位置,也没有检查以确保您提供了非空数据。

明确设置限制以防止错误的原因是代码从不尝试找出空数据的范围。

请为此创建一个 github 问题(并在问题中包含回溯)。

In [7]: Traceback (most recent call last):
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/backends/backend_qt4.py", line 366, in idle_draw
    self.draw()
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/backends/backend_qt4agg.py", line 148, in draw
    FigureCanvasAgg.draw(self)
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/backends/backend_agg.py", line 440, in draw
    self.figure.draw(self.renderer)
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/artist.py", line 54, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/figure.py", line 1027, in draw
    func(*args)
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/artist.py", line 54, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/axes.py", line 2088, in draw
    a.draw(renderer)
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/artist.py", line 54, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/axis.py", line 1076, in draw
    ticks_to_draw = self._update_ticks(renderer)
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/axis.py", line 938, in _update_ticks
    tick_tups = [t for t in self.iter_ticks()]
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/axis.py", line 882, in iter_ticks
    majorLocs = self.major.locator()
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/dates.py", line 785, in __call__
    self.refresh()
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/dates.py", line 794, in refresh
    dmin, dmax = self.viewlim_to_dt()
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/dates.py", line 560, in viewlim_to_dt
    return num2date(vmin, self.tz), num2date(vmax, self.tz)
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/dates.py", line 305, in num2date
    return _from_ordinalf(x, tz)
  File "/home/tcaswell/local_installs/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/dates.py", line 208, in _from_ordinalf
    dt = datetime.datetime.fromordinal(ix)
ValueError: ordinal must be >= 1
于 2013-10-07T01:19:01.910 回答