在绘图中三个点之间的平滑曲线

3

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

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

我希望有一条曲线,起点是 (1,0),到达最高点 (3,5),然后结束于 (5,0)。

我认为需要使用插值,但不确定如何使用。如果我使用 scipy 中的 spline,就像这样:

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) 点之前获得了最高分,但看起来不平衡:

enter image description here

你必须使用bokeh吗? - pylang
@pylang 是的,但我必须使用 Bokeh。 - Claudiu Creanga
你可以总是使用二次多项式进行拟合。 - JohanL
1
做与你所做的完全相同,但使用matplotlib绘制它(无法工作,因为p未定义)会给我一个完美对称的图形。 - Nathan
2
@Nathan:这很奇怪,因为我看到的不是这样。我得到了一个不对称的图形,就像OP一样。这与spline的工作方式有关,而不是bokeh/matplotlib。 - JohanL
显示剩余2条评论
3个回答

9
问题是由于没有额外参数的 spline 是3阶的。这意味着您没有足够的点/方程来获得样条曲线(这表现为病态矩阵的警告)。您需要应用一个低阶的样条,比如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 类:
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):

enter image description here

可以看到,CubicSplineorder=2spline完全相同。


4

使用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")

结果为:

这是图片描述


(注意:这里的“这是图片描述”需要替换成实际的图片描述内容)

对于我的实际目的,pchip 提供了最佳结果。 - Aroc

2

您可以使用二次插值法。这可以通过使用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()

请查看文档获取更多详细信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接