如何改善matplotlib中的曲线拟合?

时间:2017-07-23 16:10:49

标签: python numpy matplotlib

我有一组数据,y是角度方向,x是y每个点的时间戳。

整个数据集有许多用于角度方向的分段。为了进行曲线拟合,我将数据拆分为各自的段,将每个段存储为numpy数组。

然后我使用numpy.polyfit找到多项式拟合,以找到适合每个数据段的曲线。但是因为我的数据纯粹是实验性的,所以我不知道numpy.polyfit使用哪个多项式度数,因此我迭代一系列多项式度,直到找到最高的多项式度。

这是我的代码:

 pip3 install --upgrade pip

这就是我的情节。图中心是一个部分。

黑线表示尝试的曲线拟合,红点表示实验点。 enter image description here

如图所示,黑色曲线拟合线并不能很好地拟合数据点。我感兴趣的区域是该区域的中间区域,但是尽管使用了最高的多项式度,该区域也不能很好地拟合。

任何人都可以向我提供任何补充技术,或者更适合数据的替代代码吗?

1 个答案:

答案 0 :(得分:1)

立方插值

数据的三次插值怎么样?

import numpy as np
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt

x = np.linspace(6, 13, num=40)
y = 3 + 2.*x+np.sin(x)/2.+np.sin(4*x)/3.+ np.random.rand(len(x))/3.

fig, ax = plt.subplots()
ax.scatter(x,y, s=5, c="crimson")

f = interp1d(x, y, kind='cubic')
xdens = np.linspace(6, 13, num=400)
ydens = f(xdens)

ax.plot(xdens, ydens, label="interpolation")
ax.legend()
ax2 = ax.twinx()
yderiv =  np.diff(ydens)/np.diff(xdens)
ax2.plot(xdens[:-1],yderiv, color="C2", label="derivative")

ax2.legend()
plt.show()

enter image description here

样条插值

使用样条插值可以实现相同的效果。优点是scipy.interpolate.splrep允许使用参数s来平滑结果,并且还允许直接评估样条的导数。

import numpy as np
import scipy.interpolate
import matplotlib.pyplot as plt

x = np.linspace(6, 13, num=40)
y = 3 + 2.*x+np.sin(x)/2.+np.sin(4*x)/3.+ np.random.rand(len(x))/3.

fig, ax = plt.subplots()
ax.scatter(x,y, s=5, c="crimson")

tck = scipy.interpolate.splrep(x, y, s=0.4)
xdens = np.linspace(6, 13, num=400)
ydens = scipy.interpolate.splev(xdens, tck, der=0)

ax.plot(xdens, ydens, label="spline interpolation")
ax.legend(loc=2)

ax2 = ax.twinx()
yderiv = scipy.interpolate.splev(xdens, tck, der=1)
ax2.plot(xdens, yderiv, color="C2", label="derivative")

ax2.legend(loc=4)
plt.show()

enter image description here