Alex
Alex

Reputation: 12943

Interpolation of datetimes for smooth matplotlib plot in python

I have lists of datetimes and values like this:

import datetime
x = [datetime.datetime(2016, 9, 26, 0, 0), datetime.datetime(2016, 9, 27, 0, 0), 
     datetime.datetime(2016, 9, 28, 0, 0), datetime.datetime(2016, 9, 29, 0, 0),
     datetime.datetime(2016, 9, 30, 0, 0), datetime.datetime(2016, 10, 1, 0, 0)]
y = [26060, 23243, 22834, 22541, 22441, 23248]

And can plot them like this:

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

I would like to be able to plot a smooth version using more x-points. So first I do this:

delta_t = max(x) - min(x)
N_points = 300
xnew = [min(x) + i*delta_t/N_points for i in range(N_points)]

Then attempting a spline fit with scipy:

from scipy.interpolate import spline
ynew = spline(x, y, xnew)

TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'

What is the best way to proceed? I am open to solutions involving other libraries such as pandas or plotly.

Upvotes: 0

Views: 1777

Answers (2)

Alex
Alex

Reputation: 12943

Figured something out:

x_ts = [x_.timestamp() for x_ in x]
xnew_ts = [x_.timestamp() for x_ in xnew]

ynew = spline(x_ts, y, xnew_ts)
plt.plot(xnew, ynew)

This works very nicely, but I'm still open to ideas for simpler methods.

Upvotes: 1

rofls
rofls

Reputation: 5125

You're trying to pass a list of datetimes to the spline function, which are Python objects (hence dtype('O')). You need to convert the datetimes to a numeric format first, and then convert them back if you wish:

int_x = [i.total_seconds() for i in x]
ynew = spline(int_x, y, xnew)

Edit: total_seconds() is actually a timedelta method, not for datetimes. However it looks like you sorted it out so I'll leave this answer as is.

Upvotes: 1

Related Questions