Date2num, ValueError: serial number must be> = 1

I use the matplotlib candlestick module, which requires the time to be passed as a floating-point day format. I use date2num to convert it before:

This is my code:

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() 

(here is the csv file: http://db.tt/MIOqFA0 )

Here is what doc says:

candlestick (ax, quotation marks, width = +0,20000000000000001, colorup = 'k', colordown = 'r', alpha = 1.0) quotation marks are a list (time, opening, close, high, low, ...) tuples. In the view, since the first 5 elements of these tuples are values, the tuple can be as long as you want (for example, it can store volume). time should be in float days format - see date2num

Here is the complete error log:

 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 

If I run fast:

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

something like:

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

which sounds ok to me :)

+4
source share
3 answers

Read the docstring a little more carefully :)

quotes - list (time, opening, closing, high, low, ...) tuples.

What happens is that each quotes element must be a sequence (time, open, close, high, low).

You pass 5 long arrays, it expects a long sequence of 5 elements.

You just need to zip enter your input.

 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() 

enter image description here

+6
source

Looks like you're passing him a float. And in the error message that you provide (full message next time, please!), It seems that matplotlib just delegates the conversion to datetime.datetime.fromordinal .

I do not have Python 3 installed to verify this, but when I tried to convert the float to a datetime object using datetime.datetime.fromordinal in 2.6, I got an obsolescence warning. Then I tried this on ideone and got the following:

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

So maybe he is choking on the float.

+2
source

I think your problem is here:

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

You need to skip the first line of csv, which means you need:

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

This is technically wrong, Ubuntu has an older version of the library, and the OP version has two lines below, but that was my original answer

I would make sure that you are using the latest version of matplotlib.

So that I can reproduce this problem, I downloaded and installed the latest version, and I noticed that the line number of the damaging piece of code was changed to 179. I also noticed that the value is passed to int immediately before (this gives a lot of confidence in the senderle answer).

(line 178-179 from the last matplotlib in the Ubuntu repository)

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

If updating is not an option, you should first port to int.

0
source

All Articles