不均匀间隔点之间的直观插值

Jon*_*nny 4 python interpolation matplotlib scipy

我有以下图表,我想使用Python和Matplotlib将数字化为高质量的出版物等级数字:

在此输入图像描述

我使用数字化程序从3个数据集中的一个中获取一些样本:

x_data = np.array([
1,
1.2371,
1.6809,
2.89151,
5.13304,
9.23238,
])

y_data = np.array([
0.0688824,
0.0490012,
0.0332843,
0.0235889,
0.0222304,
0.0245952,
])
Run Code Online (Sandbox Code Playgroud)

我已经尝试了3种不同的方法来拟合这些数据点的曲线.第一种方法是使用通过点绘制样条曲线scipy.interpolate import spline

这导致(将实际数据点绘制为蓝色标记):

在此输入图像描述

这显然没有好处.

我的第二次尝试是使用一系列不同的顺序polinimials绘制曲线拟合scipy.optimize import curve_fit.即使是四阶多项式,答案也是无用的(较低阶的更无用):

在此输入图像描述

最后,我曾经scipy.interpolate import interp1d尝试在数据点之间进行插值.线性插值显然会产生预期的结果,但线条是直的,本练习的目的是获得一条漂亮的平滑曲线:

在此输入图像描述

如果我然后使用三次插值我得到一个rubish结果,但是二次插值会产生稍微好一点的结果:

在此输入图像描述

但它还没有完全存在,我认为interp1d不能进行更高阶的插值.

有没有人有一个很好的方法这样做?也许我会尝试在IPE或其他什么方面做得更好?

谢谢!

tom*_*m10 8

标准三次样条曲线在非常不均匀间隔的数据点之间的合理外观上并不是很好.幸运的是,还有很多其他插值算法,Scipy提供了许多插值算法.以下是一些适用于您的数据:

在此输入图像描述

import numpy as np
from scipy.interpolate import spline, UnivariateSpline, Akima1DInterpolator, PchipInterpolator
import matplotlib.pyplot as plt

x_data = np.array([1, 1.2371, 1.6809, 2.89151, 5.13304, 9.23238])

y_data = np.array([0.0688824, 0.0490012, 0.0332843, 0.0235889, 0.0222304, 0.0245952])

x_data_smooth = np.linspace(min(x_data), max(x_data), 1000)
fig, ax = plt.subplots(1,1)

spl = UnivariateSpline(x_data, y_data, s=0, k=2)
y_data_smooth = spl(x_data_smooth)
ax.plot(x_data_smooth, y_data_smooth, 'b')

bi = Akima1DInterpolator(x_data, y_data)
y_data_smooth = bi(x_data_smooth)
ax.plot(x_data_smooth, y_data_smooth, 'g')

bi = PchipInterpolator(x_data, y_data)
y_data_smooth = bi(x_data_smooth)
ax.plot(x_data_smooth, y_data_smooth, 'k')

ax.plot(x_data_smooth, y_data_smooth)
ax.scatter(x_data, y_data)

plt.show()
Run Code Online (Sandbox Code Playgroud)

我建议仔细研究这些,以及其他几个,并找到一个与你认为正确相符的东西.但是,您可能还需要多点几点.例如,我认为PCHIP算法希望保持数据点之间的拟合单调,因此将最小点数字化将是有用的(无论您使用何种算法,这可能都是一个好主意).