落在 meshgrid 之外的数据点被插值,而 meshgrid 肯定覆盖这些点
Data points falling outside the meshgrid being interpolated over, while the meshgrid certainly covers those points
我正在尝试在网格上插入稀疏数据,但我观察到一些相当奇怪的行为。白点正是我有值的地方,我依靠线性插值算法尽可能地填充其他网格。我认识到由于明显缺乏数据,这种类型的插值并不完美,但是为什么我有数据的一些点落在我插值的网格之外?这是普遍现象吗?即使我使网格更粗糙,这也不会改变。
我希望能深入了解为什么会发生这种情况(可能是线性插值的工作原理),或者是否有任何方法可以解决此问题。例如见下图中的红圈部分:
为插值提供的数据点落在插值的网格之外
以下是生成网格化数据的插值代码。
#mesh grid
xg = np.linspace(-130, -60, num=70)
yg = np.linspace(20,50,num=30)
Xg,Yg = np.meshgrid(xg,yg)
zg1 = griddata(points1, df2['tempratio'], (Xg, Yg), method = 'linear')
from mpl_toolkits.basemap import Basemap
lon_0 = xg.mean()
lat_0 = yg.mean()
m = Basemap(width=5000000, height=3500000,
resolution='l', projection='stere',\
lat_ts=40, lat_0=lat_0, lon_0=lon_0)
xm, ym = m(Xg, Yg)
cs = m.pcolormesh(xm,ym,zg1,shading='flat',cmap=plt.cm.Reds)
griddata
为网格的顶点赋值,所以 70x30 点。 pcolormesh
不为顶点着色,而是为中间的矩形着色。给定的顶点只有 69x29 的矩形。因此,zg1
的一行和一列将被删除。为了解决这个问题,可以在坐标中添加额外的行和额外的列,并在每个方向上移动半个矩形。
它仍然没有强制 griddata 包含所有给定的点,而是朝着预期的结果迈出了一步。更密集的网格也有帮助。 (选择 'nearest' 而不是 'linear' 插值将填满整个网格。)
下面是一些代码来说明正在发生的事情:
import numpy as np
from scipy.interpolate import griddata
from matplotlib import pyplot as plt
def extend_range(x):
dx = (x[1] - x[0]) / 2
return np.append( x - dx, x[-1] + dx)
N = 10
points1 = np.vstack([np.random.randint(-130, -60, N), np.random.randint(20, 50, N)]).T
tempratio = np.random.randint(0, 20, N)
xg = np.linspace(-130, -60, num=15)
yg = np.linspace(20, 50, num=10)
Xg, Yg = np.meshgrid(xg, yg)
zg1 = griddata(points1, tempratio, (Xg, Yg), method='linear')
fig, axs = plt.subplots(ncols=2, figsize=(12, 4))
for ax in axs:
ax.scatter(Xg, Yg, c=zg1, cmap='coolwarm', ec='g', s=80, zorder=2, label='griddata')
ax.scatter(points1[:,0], points1[:,1], c=tempratio, cmap='coolwarm', ec='black', s=150, zorder=3, label='given data')
if ax == axs[0]:
ax.pcolormesh(xg, yg, zg1, shading='flat', cmap='coolwarm')
ax.set_title('given x and y ranges')
else:
#todo: convert xg and yg to map coordinates
ax.pcolormesh(extend_range(xg), extend_range(yg), zg1, shading='flat', cmap='coolwarm')
ax.set_title('extended x and y ranges')
ax.legend()
plt.show()
我正在尝试在网格上插入稀疏数据,但我观察到一些相当奇怪的行为。白点正是我有值的地方,我依靠线性插值算法尽可能地填充其他网格。我认识到由于明显缺乏数据,这种类型的插值并不完美,但是为什么我有数据的一些点落在我插值的网格之外?这是普遍现象吗?即使我使网格更粗糙,这也不会改变。
我希望能深入了解为什么会发生这种情况(可能是线性插值的工作原理),或者是否有任何方法可以解决此问题。例如见下图中的红圈部分:
为插值提供的数据点落在插值的网格之外
以下是生成网格化数据的插值代码。
#mesh grid
xg = np.linspace(-130, -60, num=70)
yg = np.linspace(20,50,num=30)
Xg,Yg = np.meshgrid(xg,yg)
zg1 = griddata(points1, df2['tempratio'], (Xg, Yg), method = 'linear')
from mpl_toolkits.basemap import Basemap
lon_0 = xg.mean()
lat_0 = yg.mean()
m = Basemap(width=5000000, height=3500000,
resolution='l', projection='stere',\
lat_ts=40, lat_0=lat_0, lon_0=lon_0)
xm, ym = m(Xg, Yg)
cs = m.pcolormesh(xm,ym,zg1,shading='flat',cmap=plt.cm.Reds)
griddata
为网格的顶点赋值,所以 70x30 点。 pcolormesh
不为顶点着色,而是为中间的矩形着色。给定的顶点只有 69x29 的矩形。因此,zg1
的一行和一列将被删除。为了解决这个问题,可以在坐标中添加额外的行和额外的列,并在每个方向上移动半个矩形。
它仍然没有强制 griddata 包含所有给定的点,而是朝着预期的结果迈出了一步。更密集的网格也有帮助。 (选择 'nearest' 而不是 'linear' 插值将填满整个网格。)
下面是一些代码来说明正在发生的事情:
import numpy as np
from scipy.interpolate import griddata
from matplotlib import pyplot as plt
def extend_range(x):
dx = (x[1] - x[0]) / 2
return np.append( x - dx, x[-1] + dx)
N = 10
points1 = np.vstack([np.random.randint(-130, -60, N), np.random.randint(20, 50, N)]).T
tempratio = np.random.randint(0, 20, N)
xg = np.linspace(-130, -60, num=15)
yg = np.linspace(20, 50, num=10)
Xg, Yg = np.meshgrid(xg, yg)
zg1 = griddata(points1, tempratio, (Xg, Yg), method='linear')
fig, axs = plt.subplots(ncols=2, figsize=(12, 4))
for ax in axs:
ax.scatter(Xg, Yg, c=zg1, cmap='coolwarm', ec='g', s=80, zorder=2, label='griddata')
ax.scatter(points1[:,0], points1[:,1], c=tempratio, cmap='coolwarm', ec='black', s=150, zorder=3, label='given data')
if ax == axs[0]:
ax.pcolormesh(xg, yg, zg1, shading='flat', cmap='coolwarm')
ax.set_title('given x and y ranges')
else:
#todo: convert xg and yg to map coordinates
ax.pcolormesh(extend_range(xg), extend_range(yg), zg1, shading='flat', cmap='coolwarm')
ax.set_title('extended x and y ranges')
ax.legend()
plt.show()