在Python中,如何在绘图时用平滑线连接点?

9

我想使用样条函数绘制平滑曲线并标出一些点,但是这条曲线会在某些点“超过”实际数据点,例如在以下代码中,“超过”了0.85这个点。

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

x=np.array([0.1, 0.3, 0.5, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.9, 2])
y=np.array([0.57,0.85,0.66,0.84,0.59,0.55,0.61,0.76,0.54,0.55,0.48])

x_new = np.linspace(x.min(), x.max(),500)
y_smooth = spline(x, y, x_new)

plt.plot (x_new,y_smooth)
plt.scatter (x, y)

我该怎么修复它?


单调插值不会超出范围,例如pchip。但是现在不太清楚你需要什么。 - sascha
1
可能是使用PyPlot绘制平滑线的重复问题 - Calder White
@CalderWhite 不是这样的...他有一个额外的要求/问题,那里接受的答案正是他所使用的,并且他描述了他的问题所在。 - sascha
2个回答

15

你可以尝试在scipy.interpolate中使用interp1d:


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

x=np.array([0.1, 0.3, 0.5, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.9, 2])
y=np.array([0.57,0.85,0.66,0.84,0.59,0.55,0.61,0.76,0.54,0.55,0.48])

x_new = np.linspace(x.min(), x.max(),500)

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

plt.plot (x_new,y_smooth)
plt.scatter (x, y)

得到的结果为:

输入图像描述

关于kind参数的一些其他选项详见文档:

kind:str或int,可选。指定插值类型的字符串('linear'、'nearest'、'zero'、'slinear'、'quadratic'、'cubic',其中'zero'、'slinear'、'quadratic'和'cubic'分别表示零阶、一阶、二阶或三阶样条插值)或作为整数指定要使用的样条插值器的顺序。默认为'linear'。


0

您也可以尝试使用scipy中的径向基函数插值来进行薄板样条

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

x = np.array([0.1, 0.3, 0.5, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.9, 2])
y = np.array([0.57,0.85,0.66,0.84,0.59,0.55,0.61,0.76,0.54,0.55,0.48])

x_new = np.linspace(x.min(), x.max(), 500)

rbf = Rbf(x, y, function = 'thin_plate', smooth = 0.001)
y_smooth = rbf(x_new)

plt.plot(x_new, y_smooth)
plt.scatter (x, y);

enter image description here

通过变化 smooth 参数,可能会得到更好的数据近似。

考虑替代的 function 参数值包括 'multiquadric'、'inverse'、'gaussian'、'linear'、'cubic' 和 'quintic'。在考虑 function 值时,我通常先尝试 'thin_plate',然后再尝试 'cubic'。

请查看 scipy.interpolate.Rbf 文档 中的其他 Rbf 选项。


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