基于点创建平滑线

时间:2017-10-01 13:31:35

标签: python

我有以下数据集:

x = [1, 6, 11, 21, 101]
y = [5, 4, 3, 2, 1]

我的目标是创建一条如下所示的平滑曲线: enter image description here

有没有办法在Python中实现?

我尝试使用here中显示的方法,以下是代码:

from scipy.interpolate import spline

import matplotlib.pyplot as plt
import numpy as np

x = [1, 6, 11, 21, 101]
y = [5, 4, 3, 2, 1]

xnew = np.linspace(min(x), max(x), 100)

y_smooth = spline(x, y, xnew)

plt.plot(xnew, y_smooth)
plt.show()

但输出显示奇怪的一行。 enter image description here

1 个答案:

答案 0 :(得分:3)

首先,interpolate.spline() has been deprecated,所以你可能不应该使用它。而是使用interpolate.splrep()interpolate.splev()。这不是一个困难的转换:

y_smooth = interpolate.spline(x, y, xnew)

变为

tck = interpolate.splrep(x, y)
y_smooth = interpolate.splev(xnew, tck)

但是,这不是真正的问题。默认情况下,scipy会尝试将3度多项式拟合到您的数据中,这与您的数据不相符。但由于点数太少,它可以很好地适应您的数据,即使它是非直观的近似值。您可以设置它尝试适合k=...参数splrep()的多项式次数。但即使是2阶多项式也是如此;它试图拟合抛物线,你的数据可能适合抛物线,中间有一个弓(这就是它现在所做的,因为斜率在开始时是如此陡峭,中间没有数据点)。 / p>

在您的情况下,您的数据更准确地表示为指数,因此最适合指数。我建议使用scipy.optimize.curve_fit()。它允许您指定自己的拟合函数,其中包含参数并且它适合您的参数:

from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import numpy as np

x = [1, 6, 11, 21, 101]
y = [5, 4, 3, 2, 1]

xnew = np.linspace(min(x), max(x), 100)

def expfunc(x, a, b, c):
    return a * np.exp(-b * x) + c

popt, pcov = curve_fit(expfunc, x, y)
plt.plot(xnew, expfunc(xnew, *popt))
plt.show()

Fitted plot