扩展我之前的评论:
发生的事情是由于您的a
-values 的绝对值比x
andy
值大约 10 倍。
在求解适当的权重时,这会导致数值稳定性问题。Scipy 可能应该做一些健全性检查并“白化”(又名重新缩放)输入数据,但它没有。
由于权重不正确,插值低于最小输入a
值(线性 RBF 不应该发生这种情况)。正如@user1767344 所注意到的,这会导致您指定vmin
的值“剪切”网格。vmax
我在下面显示“未剪辑”版本,但如果您指定类似的vmin
and vmax
,您将看到与原始示例相同的结果。
举个例子:
import numpy as np
import scipy.interpolate
import matplotlib.pyplot as plt
def main():
x = np.array([0, 0, 2, 2])
y = np.array([0, 2, 0, 2])
a = np.array([23.4, 23.7, 23.4, 23.7])
xi, yi = np.mgrid[x.min():x.max():500j, y.min():y.max():500j]
a_orig = normal_interp(x, y, a, xi, yi)
a_rescale = rescaled_interp(x, y, a, xi, yi)
plot(x, y, a, a_orig, 'Not Rescaled')
plot(x, y, a, a_rescale, 'Rescaled')
plt.show()
def normal_interp(x, y, a, xi, yi):
rbf = scipy.interpolate.Rbf(x, y, a)
ai = rbf(xi, yi)
return ai
def rescaled_interp(x, y, a, xi, yi):
a_rescaled = (a - a.min()) / a.ptp()
ai = normal_interp(x, y, a_rescaled, xi, yi)
ai = a.ptp() * ai + a.min()
return ai
def plot(x, y, a, ai, title):
fig, ax = plt.subplots()
im = ax.imshow(ai.T, origin='lower',
extent=[x.min(), x.max(), y.min(), y.max()])
ax.scatter(x, y, c=a)
ax.set(xlabel='X', ylabel='Y', title=title)
fig.colorbar(im)
main()
两者之间的唯一区别只是a
在 0 和 1 之间线性重新调整输入和输出值:
def normal_interp(x, y, a, xi, yi):
rbf = scipy.interpolate.Rbf(x, y, a)
ai = rbf(xi, yi)
return ai
def rescaled_interp(x, y, a, xi, yi):
a_rescaled = (a - a.min()) / a.ptp()
ai = normal_interp(x, y, a_rescaled, xi, yi)
ai = a.ptp() * ai + a.min()
return ai
因为它是一种 2D 插值方法,所以结果并不完全“像颜色条”。如果您愿意,您可以使用一维插值并平铺结果。或者,在这种情况下,简单的三角插值方法(例如griddata
)是一个不错的选择,并且应该给出与一维结果相同的结果。(缺点是在其他情况下它不会“平滑”,但这总是一个权衡。)