是否有一种现成的方法可以从网格中心位置(红点)外推网格角位置(蓝点)?
我正在使用的网格不是矩形,因此常规的双线性插值似乎不是最好的方法;但是,这只是为了我的情节我的数据使用pyplot.pcolormesh()
,所以也许这并不重要。
示例网格数据:
import numpy as np
lons = np.array([[ 109.93299681, 109.08091365, 108.18301276, 107.23602539],
[ 108.47911382, 107.60397996, 106.68325946, 105.71386119],
[ 107.06790187, 106.17259769, 105.23214707, 104.2436463 ],
[ 105.69908292, 104.78633156, 103.82905363, 102.82453812]])
lats = np.array([[ 83.6484245 , 83.81088466, 83.97177823, 84.13098916],
[ 83.55459198, 83.71460466, 83.87294803, 84.02950188],
[ 83.4569054 , 83.61444708, 83.77022192, 83.92410637],
[ 83.35554612, 83.51060313, 83.6638013 , 83.81501464]])
答案 0 :(得分:4)
我不知道有任何强大的matplotlib技术可以满足您的要求,但我可能有不同的解决方案。我经常需要填充/推断我缺少信息的网格区域。为此,我使用Fortran程序,我使用F2PY(随numpy一起提供)编译,将其创建为python模块。假设您使用的是英特尔Fortran编译器,请使用以下命令对其进行编译:{{1}}。您可以使用python调用该程序(参见here获取完整示例):
f2py --verbose --fcompiler=intelem -c -m extrapolate fill.f90
该程序通过迭代方法在RECTANGULAR坐标中解决具有Neumann边界条件(dA / dn = 0)的拉普拉斯方程,以在包含诸如" undef"之类的值的网格点处填充合理的值。这对我很有用,也许你会发现它很有用。该程序可在我的github帐户here上找到。
答案 1 :(得分:2)
我使用pyproj
首先计算点之间的距离和方位角(使用pyproj.Geod.inv
,然后用必要距离内插/外推该角度,这是一种不那么优雅的方法(使用pyproj.Geod.fwd
)到psi位置。
<强>码强>:
def calc_psi_coords(lons, lats):
''' Calcuate psi points from centered grid points'''
import numpy as np
import pyproj
# Create Geod object with WGS84 ellipsoid
g = pyproj.Geod(ellps='WGS84')
# Get grid field dimensions
ydim, xdim = lons.shape
# Create empty coord arrays
lons_psi = np.zeros((ydim+1, xdim+1))
lats_psi = np.zeros((ydim+1, xdim+1))
# Calculate internal points
#--------------------------
for j in range(ydim-1):
for i in range(xdim-1):
lon1 = lons[j,i] # top left point
lat1 = lats[j,i]
lon2 = lons[j+1,i+1] # bottom right point
lat2 = lats[j+1,i+1]
# Calc distance between points, find position at half of dist
fwd_az, bck_az, dist = g.inv(lon1,lat1,lon2,lat2)
lon_psi, lat_psi, bck_az = g.fwd(lon1,lat1,fwd_az,dist*0.5)
# Assign to psi interior positions
lons_psi[j+1,i+1] = lon_psi
lats_psi[j+1,i+1] = lat_psi
# Caclulate external points (not corners)
#----------------------------------------
for j in range(ydim):
# Left external points
#~~~~~~~~~~~~~~~~~~~~~
lon1 = lons_psi[j+1,2] # left inside point
lat1 = lats_psi[j+1,2]
lon2 = lons_psi[j+1,1] # left outside point
lat2 = lats_psi[j+1,1]
# Calc dist between points, find position at dist*2 from pos1
fwd_az, bck_az, dist = g.inv(lon1,lat1,lon2,lat2)
lon_psi, lat_psi, bck_az = g.fwd(lon1,lat1,fwd_az,dist*2.)
lons_psi[j+1,0] = lon_psi
lats_psi[j+1,0] = lat_psi
# Right External points
#~~~~~~~~~~~~~~~~~~~~~~
lon1 = lons_psi[j+1,-3] # right inside point
lat1 = lats_psi[j+1,-3]
lon2 = lons_psi[j+1,-2] # right outside point
lat2 = lats_psi[j+1,-2]
# Calc dist between points, find position at dist*2 from pos1
fwd_az, bck_az, dist = g.inv(lon1,lat1,lon2,lat2)
lon_psi, lat_psi, bck_az = g.fwd(lon1,lat1,fwd_az,dist*2.)
lons_psi[j+1,-1] = lon_psi
lats_psi[j+1,-1] = lat_psi
for i in range(xdim):
# Top external points
#~~~~~~~~~~~~~~~~~~~~
lon1 = lons_psi[2,i+1] # top inside point
lat1 = lats_psi[2,i+1]
lon2 = lons_psi[1,i+1] # top outside point
lat2 = lats_psi[1,i+1]
# Calc dist between points, find position at dist*2 from pos1
fwd_az, bck_az, dist = g.inv(lon1,lat1,lon2,lat2)
lon_psi, lat_psi, bck_az = g.fwd(lon1,lat1,fwd_az,dist*2.)
lons_psi[0,i+1] = lon_psi
lats_psi[0,i+1] = lat_psi
# Bottom external points
#~~~~~~~~~~~~~~~~~~~~~~~
lon1 = lons_psi[-3,i+1] # bottom inside point
lat1 = lats_psi[-3,i+1]
lon2 = lons_psi[-2,i+1] # bottom outside point
lat2 = lats_psi[-2,i+1]
# Calc dist between points, find position at dist*2 from pos1
fwd_az, bck_az, dist = g.inv(lon1,lat1,lon2,lat2)
lon_psi, lat_psi, bck_az = g.fwd(lon1,lat1,fwd_az,dist*2.)
lons_psi[-1,i+1] = lon_psi
lats_psi[-1,i+1] = lat_psi
# Calculate corners:
#-------------------
# top left corner
#~~~~~~~~~~~~~~~~
lon1 = lons_psi[2,2] # bottom right point
lat1 = lats_psi[2,2]
lon2 = lons_psi[1,1] # top left point
lat2 = lats_psi[1,1]
# Calc dist between points, find position at dist*2 from pos1
fwd_az, bck_az, dist = g.inv(lon1,lat1,lon2,lat2)
lon_psi, lat_psi, bck_az = g.fwd(lon1,lat1,fwd_az,dist*2.)
lons_psi[0,0] = lon_psi
lats_psi[0,0] = lat_psi
# top right corner
#~~~~~~~~~~~~~~~~~
lon1 = lons_psi[2,-3] # bottom left point
lat1 = lats_psi[2,-3]
lon2 = lons_psi[1,-2] # top right point
lat2 = lats_psi[1,-2]
# Calc dist between points, find position at dist*2 from pos1
fwd_az, bck_az, dist = g.inv(lon1,lat1,lon2,lat2)
lon_psi, lat_psi, bck_az = g.fwd(lon1,lat1,fwd_az,dist*2.)
lons_psi[0,-1] = lon_psi
lats_psi[0,-1] = lat_psi
# bottom left corner
#~~~~~~~~~~~~~~~~~~~
lon1 = lons_psi[-3,2] # top right point
lat1 = lats_psi[-3,2]
lon2 = lons_psi[-2,1] # bottom left point
lat2 = lats_psi[-2,1]
# Calc dist between points, find position at dist*2 from pos1
fwd_az, bck_az, dist = g.inv(lon1,lat1,lon2,lat2)
lon_psi, lat_psi, bck_az = g.fwd(lon1,lat1,fwd_az,dist*2.)
lons_psi[-1,0] = lon_psi
lats_psi[-1,0] = lat_psi
# bottom right corner
#~~~~~~~~~~~~~~~~~~~~
lon1 = lons_psi[-3,-3] # top left point
lat1 = lats_psi[-3,-3]
lon2 = lons_psi[-2,-2] # bottom right point
lat2 = lats_psi[-2,-2]
# Calc dist between points, find position at dist*2 from pos1
fwd_az, bck_az, dist = g.inv(lon1,lat1,lon2,lat2)
lon_psi, lat_psi, bck_az = g.fwd(lon1,lat1,fwd_az,dist*2.)
lons_psi[-1,-1] = lon_psi
lats_psi[-1,-1] = lat_psi
return lons_psi, lats_psi
示例图片(丹麦/瑞典南部):