图中 3 点之间的平滑曲线

Smooth curved line between 3 points in plot

我在 x 轴上有 3 个数据点,在 y 轴上有 3 个数据点:

x = [1,3,5]
y=[0,5,0]

我想要一条曲线,从 (1,0) 开始,到最高点 (3,5),然后在 (5,0) 结束

我想我需要使用插值法,但不确定如何使用。如果我像这样使用 scipy 中的样条曲线:

import bokeh.plotting as bk
from scipy.interpolate import spline
p = bk.figure()
xvals=np.linspace(1, 5, 10)
y_smooth = spline(x,y,xvals)
p.line(xvals, y_smooth)

bk.show(p)

我在(3,5)之前得到最高点,看起来不平衡:

您可以使用二次插值法。这可以通过使用 scipy.interpolate.interp1d.

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



x = [1, 3, 5]
y = [0, 5, 0]

f = interp1d(x, y, kind='quadratic')

x_interpol = np.linspace(1, 5, 1000)
y_interpol = f(x_interpol)

plt.plot(x_interpol, y_interpol)
plt.show()

查看 documentation 了解更多详情。

使用pchip_interpolate():

import numpy as np
from scipy import interpolate

x = [1,3,5]
y=[0,5,0]

x2 = np.linspace(x[0], x[-1], 100)
y2 = interpolate.pchip_interpolate(x, y, x2)
pl.plot(x2, y2)
pl.plot(x, y, "o")

结果:

问题是由于没有额外参数的 spline 是 3 阶的。这意味着您没有足够的 points/equations 来获得样条曲线(这表现为警告ill-conditioned 矩阵)。您需要应用低阶样条,例如 2 阶的三次样条:

import bokeh.plotting as bk
from scipy.interpolate import spline
p = bk.figure()
xvals=np.linspace(1, 5, 10)
y_smooth = spline(x,y,xvals, order=2) # This fixes your immediate problem
p.line(xvals, y_smooth)

bk.show(p)

此外,spline 在 SciPy 中已弃用,因此您最好不要使用它,即使可能。更好的解决方案是使用 CubicSpline class:

import bokeh.plotting as bk
from scipy.interpolate import CubicSpline
p = bk.figure()
xvals=np.linspace(1, 5, 10)
spl = CubicSpline(x, y) # First generate spline function
y_smooth = spl(xvals) # then evalute for your interpolated points
p.line(xvals, y_smooth)

bk.show(p)

只是为了显示差异(使用 pyplot):

可以看出,CubicSplineorder=2

spline相同