4

I am trying to plot a custom chart with datetime axis. My understanding is that matplotlib requires a float format which is days since epoch. So, I want to convert a numpy array to the float epoch as required by matplotlib.

The datetime values are stored in a numpy array called t:

In [235]: t
Out[235]: array(['2008-12-01T00:00:59.000000000-0800',
                 '2008-12-01T00:00:59.000000000-0800',
                 '2008-12-01T00:00:59.000000000-0800',
                 '2008-12-01T00:09:26.000000000-0800',
                 '2008-12-01T00:09:41.000000000-0800'], dtype='datetime64[ns]')

Apparently, matplotlib.dates.date2num only accepts a sequence of python datetimes as input (not numpy datetimes arrays):

import matplotlib.dates as dates
plt_dates = dates.date2num(t)

raises AttributeError: 'numpy.datetime64' object has no attribute 'toordinal'

How should I resolve this issue? I hope to have a solution that works for all types of numpy.datetime like object.

My best workaround (which I am not sure to be correct) is not to use date2num at all. Instead, I try to use the following:

z = np.array([0]).astype(t.dtype)
plt_dates = (t - z)/ np.timedelta64(1,'D')

Even, if this solution is correct, it is nicer to use library functions, instead of manual adhoc workarounds.

  • 2
    The problem is because numpy has the type datetime64, whereas the matplotlib library is expecting the type datetime. This makes the question a close-to-duplicate of this one. Your workaround should work and is very similar to the accepted answer there. – J Richard Snape Jan 17 '16 at 22:21
  • 2
    Importing pandas may make the datetime64 axes 'just work'. – tacaswell Jan 18 '16 at 4:03
  • @JRichardSnape: Not sure :S! In my case this seems to happen to plot_date(df.index,....) that worked before upgrading anaconda, plus using plot_date(df.index.values.astype(datetime.datetime),... does not work either :S... (conversion works, plotting breaks...) – ntg Nov 24 '17 at 9:37
6

For a quick fix, use:

import matplotlib.dates as dates
plt_dates = dates.date2num(t.to_pydatetime())

or:

import matplotlib.dates as dates
plt_dates = dates.date2num(list(t))

It seems the latest (matplotlib.__version__ '2.1.0') does not like numpy arrays... Edit: In my case, after checking the source code, the problem seems to be that the latest matplotlib.cbook cannot create an iterable from the numpy array and thinks the array is a number.

For similar but a bit more complex problems, check http://stackoverflow.com/questions/13703720/converting-between-datetime-timestamp-and-datetime64, possibly Why do I get "python int too large to convert to C long" errors when I use matplotlib's DateFormatter to format dates on the x axis?, and maybe matplotlib plot_date AttributeError: 'numpy.datetime64' object has no attribute 'toordinal' (if someone answers) Edit: someone answered, his code using to_pydatetime() seems best, also: pandas 0.21.0 Timestamp compatibility issue with matplotlib, though that did not work in my case (because of python 2???)

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.