簡體   English   中英

二維非結構化網格數據的插值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM