【问题标题】:date2num , ValueError: ordinal must be >= 1date2num , ValueError: ordinal must be >= 1
【发布时间】:2011-06-10 02:33:12
【问题描述】:

我正在使用 matplotlib 烛台模块,它需要将时间作为浮点日格式传递。我正在使用 date2num 转换它,之前:

这是我的代码:

import csv
import sys
import math
import numpy as np
import datetime
from optparse import OptionParser
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
import matplotlib.mlab as mlab
import matplotlib.dates as mdates
from matplotlib.finance import candlestick
from matplotlib.dates import date2num

datafile = 'historical_data/AUD_Q10_1D_500.csv'
print 'loading', datafile
r = mlab.csv2rec(datafile, delimiter=';')
quotes = [date2num(r['date']),r['open'],r['close'],r['max'],r['min']]


candlestick(ax, quotes, width=0.6)

plt.show()

(这里是 csv 文件:http://db.tt/MIOqFA0)

这就是文档所说的:

烛台(斧头,报价, 宽度=0.20000000000000001, colorup='k', colordown='r', alpha=1.0) 引号是(时间,打开, close, high, low, ...) 元组。作为 只要前 5 个元素 元组是这些值,元组 可以随心所欲(例如,它可能 存储量)。 时间必须采用浮点天数格式 - 请参阅 date2num

这是完整的错误日志:

Traceback (most recent call last):
File
"/usr/lib/python2.6/site-packages/matplotlib/backends/backend_qt4agg.py",
line 83, in paintEvent
FigureCanvasAgg.draw(self) File
"/usr/lib/python2.6/site-packages/matplotlib/backends/backend_agg.py",
line 394, in draw
self.figure.draw(self.renderer) File
"/usr/lib/python2.6/site-packages/matplotlib/artist.py",
line 55, in draw_wrapper draw(artist,
renderer, *args, **kwargs) File
"/usr/lib/python2.6/site-packages/matplotlib/figure.py",
line 798, in draw func(*args) File
"/usr/lib/python2.6/site-packages/matplotlib/artist.py",
line 55, in draw_wrapper draw(artist,
renderer, *args, **kwargs) File
"/usr/lib/python2.6/site-packages/matplotlib/axes.py", line 1946, in draw a.draw(renderer)
File
"/usr/lib/python2.6/site-packages/matplotlib/artist.py",
line 55, in draw_wrapper draw(artist,
renderer, *args, **kwargs) File
"/usr/lib/python2.6/site-packages/matplotlib/axis.py", line 971, in draw tick_tups = [ t for
t in self.iter_ticks()] File
"/usr/lib/python2.6/site-packages/matplotlib/axis.py", line 904, in iter_ticks majorLocs =
self.major.locator() File
"/usr/lib/python2.6/site-packages/matplotlib/dates.py",
line 743, in __call__ self.refresh()
File
"/usr/lib/python2.6/site-packages/matplotlib/dates.py",
line 752, in refresh dmin, dmax =
self.viewlim_to_dt() File
"/usr/lib/python2.6/site-packages/matplotlib/dates.py",
line 524, in viewlim_to_dt return
num2date(vmin, self.tz),
num2date(vmax, self.tz) File
"/usr/lib/python2.6/site-packages/matplotlib/dates.py",
line 289, in num2date if not
cbook.iterable(x): return
_from_ordinalf(x, tz) File "/usr/lib/python2.6/site-packages/matplotlib/dates.py",
line 203, in _from_ordinalf dt =
datetime.datetime.fromordinal(ix)
ValueError: ordinal must be >= 1

如果我跑得快:

for x in r['date']:
    print str(x) + "is :" + str(date2num(x))

它输出类似:

2010-06-12is :733935.0
2010-07-12is :733965.0
2010-08-12is :733996.0

对我来说听起来不错:)

【问题讨论】:

  • 日期的格式是否总是正确的? AAAA/MM/DD hh:mm:ss
  • 是的,日期已按 YYYY-MM-DD 排序

标签: python numpy matplotlib


【解决方案1】:

请仔细阅读文档字符串 :)

quotes 是 (time, open, close, high, low, ...) 元组的列表。

发生的情况是它期望quotes 的每个项目 是(时间、开盘、收盘、高点、低点)的序列。

您传入 5 个长数组,它需要 5 个项目的长序列。

你只需要zip你的输入。

import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
from matplotlib.finance import candlestick
from matplotlib.dates import date2num

datafile = 'Downloads/AUD_Q10_1D_500.csv'
r = mlab.csv2rec(datafile, delimiter=';')

quotes = zip(date2num(r['date']),r['open'],r['close'],r['max'],r['min'])

fig, ax = plt.subplots()
candlestick(ax, quotes, width=0.6)

plt.show()

【讨论】:

    【解决方案2】:

    好像你在传递一个浮点数。在您提供的错误消息中(请下次完整消息!)看来 matplotlib 只是将转换委托给datetime.datetime.fromordinal。

    我没有安装 Python 3 来测试它,但是当我尝试在 2.6 中使用 datetime.datetime.fromordinal 将浮点数转换为 datetime 对象时,我收到了弃用警告。然后我在ideone 上试了一下,得到了这个:

    Traceback (most recent call last):
      File "prog.py", line 2, in <module>
        print(datetime.datetime.fromordinal(5.5))
    TypeError: integer argument expected, got float
    

    所以也许它在漂浮物上窒息。

    【讨论】:

    • 我想我应该更好地改写问题,让我编辑问题
    【解决方案3】:

    我认为你的问题在这里:

    r = mlab.csv2rec(datafile, delimiter=';')
    

    你需要跳过csv的第一行,这意味着你需要:

    r = mlab.csv2rec(datafile, delimiter=';', skiprows=1)
    

    从技术上讲这是不正确的,Ubuntu 有一个旧版本的库,OP 的版本有以下两行,但这是我原来的答案

    我会确保您使用的是最新版本的 matplotlib。

    为了重现这个问题,我下载并安装了最新版本,我注意到违规代码的行号已更改为 179。我还注意到该值在 fromordinal 之前立即转换为 int被调用(这为 senderle 的回答提供了很多可信度)。

    (Ubuntu 存储库中最新 matplotlib 的第 178-179 行)

    ix = int(x)
    dt = datetime.datetime.fromordinal(ix)
    

    如果升级不是一个选项,那么你应该先转换为 int。

    【讨论】:

    • 我正在使用 matplotlib 1.0.1 和 nump 1.6.0,让我将问题编辑得更清楚
    • 但是如果我添加skirows,我的记录数组中就不会有字段名称了?
    • @Julz 看起来你是对的。我没有意识到 process_skiprows 在第 2003 行和第 2129 行被调用。
    • 如果静态填充quotes会发生什么?
    • 奇怪,我输入这个:quotes = [733965.0,r['open'],r['close'],r['max'],r['min']],然后错误消息是“TypeError: 'float' object is unsubscriptable”,尽管我认为它应该将浮点数作为参数
    猜你喜欢
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 2017-01-27
    • 2022-09-03
    • 2022-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多