我想用numpy和matplotlib绘制一个时间序列,使用标记来标记精确的点,并使用插值。基本上是这样的(数据是虚拟的,但功能是相同的,注意时间点之间的距离可能会变化):
import numpy as np
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt
T = [
np.datetime64('2020-01-01T00:00:00.000000000'),
np.datetime64('2020-01-02T00:00:00.000000000'),
np.datetime64('2020-01-03T00:00:00.000000000'),
np.datetime64('2020-01-05T00:00:00.000000000'),
np.datetime64('2020-01-06T00:00:00.000000000'),
np.datetime64('2020-01-09T00:00:00.000000000'),
np.datetime64('2020-01-13T00:00:00.000000000'),
]
Z = [543, 234, 435, 765, 564, 235, 345]
fig = plt.figure(figsize=(8,6))
ax = fig.add_subplot()
ax.plot(T, Z, 'o-')
然而,这里所做的插值只是连接点。我想使用scipy的interp1d来包括样条插值和其他类型的插值。因此,我尝试用以下代码替换最后一行:
ax.plot(T,Z, 'o')
ax.plot(T,interp1d(T, Z)(T), '-')
我得到了以下错误:
UFuncTypeError: ufunc 'true_divide' cannot use operands with types dtype('float64') and dtype('<m8[ns]')
阅读this answer时,我看到在插值过程中,我应该将T
除以np.timedelta64(1, 's')
,如下所示:
ax.plot(T,Z, 'o')
ax.plot(T,interp1d(T/np.timedelta64(1, 's'))(T), '-')
然而,我得到了一个更奇怪错误:
ufunc 'true_divide' cannot use operands with types dtype('<M8[ns]') and dtype('<m8[s]')
我该怎么办?
1条答案
按热度按时间g0czyy6m1#
T
中任何元素的数据类型都是np.datetime64
,而不是np.timedelta64
。因此,通过创建一个数据类型为
m
的numpy数组,将T的所有元素的dtype转换为np.timedelta64
:然后,正如the documentation所建议的,我们必须将可转换为float类值的
x
和y
传递给scipy.interpolate.interp1d
,以获得插值函数。我们将使用answer中建议的方法来实现这一点:最后,我们可以使用如下插值函数进行绘图:
将所有内容结合起来,我们将得到以下输出:
可以重现图像的代码: