[英]Interpolation over 2d unstructured grid data
我有一些數據 (x,y,z)放在一個非結構化的網格上,我想對這些數據進行插值以用於可視化目的。
我已經嘗試過scipy.interpolate.griddata
,插值在所有地方都假定為相同的值。 之后,我嘗試了scipy.interpolate.Rbf
,但是這使我遇到了內存錯誤(請參見下面的代碼)。
是否有其他方法或其他選項可以改善結果?
結果->
我的密碼
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata, Rbf
x, y, z = np.loadtxt('stackoverflow_example-data')
# griddata
points = np.reshape(np.array([x, y]),(z.size, 2))
grid_x, grid_y = np.mgrid[x.min():x.max():1000j,y.min():y.max():1000j]
counts_I_grid_1 = griddata(points, z, (grid_x, grid_y), method='nearest')
counts_I_grid_2 = griddata(points, z, (grid_x, grid_y), method='linear', fill_value=0)
counts_I_grid_3 = griddata(points, z, (grid_x, grid_y), method='cubic', fill_value=0)
# Rbf -- fails due to memory error
#rbf = Rbf(x,y,z)
#counts_I_Rbf = rbf(grid_x,grid_y)
追溯(最近一次通話最近):文件“ /path/code.py”,第14行,在rbf = Rbf(x,y,z)中文件“ /[...]/python3.4/site-packages/scipy /initpolate/rbf.py”,第198行, init r = self._call_norm(self.xi,self.xi)文件“ /[...]/python3.4/site-packages/scipy/interpolate/rbf。 py”,第222行,_call_norm中返回self.norm(x1,x2)文件“ /[...]/python3.4/site-packages/scipy/interpolate/rbf.py”,第114行,_euclidean_norm中返回sqrt ((((x1-x2)** 2).sum(axis = 0))MemoryError
# plot the result
fig = plt.figure()
ax1 = plt.subplot(2,2,1)
plt.title('Data')
plt.gca().set_aspect((x.max() - x.min()) / (y.max() - y.min()))
plt.scatter(x, y, c=z, s=2, edgecolor='', marker=',')
plt.colorbar(ax=ax1)
plt.xlim(x.min(), x.max())
plt.ylim(y.min(), y.max())
plt.xticks([20.7,20.9,21.1,21.3])
plt.ticklabel_format(useOffset=False)
ax2 = plt.subplot(2,2,2)
plt.title('nearest')
plt.imshow(counts_I_grid_1.T, origin='lower',
extent=(x.min(), x.max(), y.min(), y.max()),
aspect=(x.max() - x.min()) / (y.max() - y.min()),
vmin=0,vmax=36)
plt.colorbar(ax=ax2)
plt.xticks([20.7,20.9,21.1,21.3])
plt.ticklabel_format(useOffset=False)
ax2 = plt.subplot(2,2,3)
plt.title('linear')
plt.imshow(counts_I_grid_2.T, origin='lower',
extent=(x.min(), x.max(), y.min(), y.max()),
aspect=(x.max() - x.min()) / (y.max() - y.min()),
vmin=0,vmax=36)
plt.colorbar(ax=ax2)
plt.xticks([20.7,20.9,21.1,21.3])
plt.ticklabel_format(useOffset=False)
ax2 = plt.subplot(2,2,4)
plt.title('cubic')
plt.imshow(counts_I_grid_3.T, origin='lower',
extent=(x.min(), x.max(), y.min(), y.max()),
aspect=(x.max() - x.min()) / (y.max() - y.min()),
vmin=0,vmax=36)
plt.colorbar(ax=ax2)
plt.xticks([20.7,20.9,21.1,21.3])
plt.ticklabel_format(useOffset=False)
plt.tight_layout()
plt.show()
您的問題是由於一個微小的錯誤而引起的,這個錯誤非常危險,我認為值得給出完整的答案。
考慮這一行:
points = np.reshape(np.array([x, y]),(z.size, 2))
由於您的輸入數組為1d,因此您試圖將[x,y]
轉換為形狀“(something,2)”。 請注意,說出來是正確的
points = np.reshape(np.array([x, y]),(-1, 2))
讓numpy為您推斷缺少的尺寸,而這仍然不是您想要的。 當您構建2D數組時
np.array([x, y])
您正在逐行定義矩陣,從而創建形狀為“(2,something)”的數組。 當您在其上調用reshape
時,默認情況下它將逐行讀取元素,因為numpy以行優先的順序存儲數組(如C / C ++,並且與fortran和MATLAB不同)。 這意味着生成的兩列數組將首先包含所有x
值,然后包含所有y
值,而不是在每行中包含成對的(x,y)
。
您實際上想做的是交換陣列的尺寸,而不用改變其結構。 這意味着您必須轉置矩陣。 這意味着您必須使用
points = np.array([x, y]).T
# or np.transpose([x,y])
代替。 請注意,雖然它的shape
與原始shape
相同,但其元素的順序正確:
In [320]: np.reshape(np.array([x,y]),(-1,2))
Out[320]:
array([[ 20.7 , 20.702 ],
[ 20.704 , 20.706 ],
[ 20.708 , 20.71 ],
...,
[ 852.356964, 852.356964],
[ 852.356964, 852.356964],
[ 852.356964, 852.356964]])
In [321]: np.array([x,y]).T
Out[321]:
array([[ 20.7 , 852.357235],
[ 20.702 , 852.357235],
[ 20.704 , 852.357235],
...,
[ 21.296 , 852.356964],
[ 21.298 , 852.356964],
[ 21.3 , 852.356964]])
這將解決您的樣本x/y
點與z
之間的不一致,並產生預期的結果。 以我的經驗, reshape
幾乎從未被要求。 通常,您需要將ndarray
展平為1d
數組,但是最好使用給定數組的ndarray
ravel()
方法。
結果證明:左,您的原件帶有三次插值; 正確, points
固定的版本:
請注意,正如@MaxNoe建議的那樣 ,我將您的插值網格尺寸減小為200x200。 正如他們所暗示的那樣, Rbf
的內存錯誤很可能源於大量的插值點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.