重新捕获常规netcdf数据

问题描述 投票:2回答:4

我有一个包含全球海面温度的netcdf文件。使用matplotlib和Basemap,我设法使用以下代码对这些数据进行映射:

from netCDF4 import Dataset
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

filename = '/Users/Nick/Desktop/SST/SST.nc'
fh = Dataset(filename, mode='r')

lons = fh.variables['LON'][:]
lats = fh.variables['LAT'][:]
sst = fh.variables['SST'][:].squeeze()

fig = plt.figure()

m = Basemap(projection='merc', llcrnrlon=80.,llcrnrlat=-25.,urcrnrlon=150.,urcrnrlat=25.,lon_0=115., lat_0=0., resolution='l')

lon, lat = np.meshgrid(lons, lats)
xi, yi = m(lon, lat)

cs = m.pcolormesh(xi,yi,sst, vmin=18, vmax=32)

m.drawmapboundary(fill_color='0.3')
m.fillcontinents(color='0.3', lake_color='0.3')
cbar = m.colorbar(cs, location='bottom', pad="10%", ticks=[18., 20., 22., 24., 26., 28., 30., 32.])
cbar.set_label('January SST (' + u'\u00b0' + 'C)')
plt.savefig('SST.png', dpi=300)

问题是数据的分辨率很高(9公里网格),这使得生成的图像非常嘈杂。我想将数据放到较低分辨率的网格(例如1度)上,但是我在努力解决该问题。我遵循了一个可行的解决方案,通过在下面的示例中插入以下代码来尝试使用matplotlib griddata函数,但这导致“ ValueError:条件必须为一维数组”。

xi, yi = np.meshgrid(lons, lats)

X = np.arange(min(x), max(x), 1)
Y = np.arange(min(y), max(y), 1)

Xi, Yi = np.meshgrid(X, Y)

Z = griddata(xi, yi, z, Xi, Yi)

我是Python和matplotlib的相对入门者,所以我不确定自己做错了什么(或者可能有什么更好的方法)。任何建议表示赞赏!

python numpy matplotlib matplotlib-basemap
4个回答
10
投票

如果您regrid使用例如双线性插值,这将导致smoother字段。

NCAR ClimateData指南的introduction to regridding非常不错(一般,不是特定于Python的。)>

据我所知,最适用于Python的重排例程的实现是Earth System Modeling Framework (ESMF) Python interface (ESMPy)。如果您的应用程序涉及的内容过多,则应查看

  1. [EarthPy关于重新网格化的教程(例如,使用PyresamplecKDTreeBasemap)。
  2. 将数据转换为Iris多维数据集并使用Iris' regridding functions
  3. 由于您已经在使用EarthPy regridding tutorial using Basemap,所以也许开始吧。

在您的示例中执行此操作的方法是

from mpl_toolkits import basemap
from netCDF4 import Dataset

filename = '/Users/Nick/Desktop/SST/SST.nc'
with Dataset(filename, mode='r') as fh:
   lons = fh.variables['LON'][:]
   lats = fh.variables['LAT'][:]
   sst = fh.variables['SST'][:].squeeze()

lons_sub, lats_sub = np.meshgrid(lons[::4], lats[::4])

sst_coarse = basemap.interp(sst, lons, lats, lons_sub, lats_sub, order=1)

这会在您的SST数据上执行双线性插值(order=1)到二次采样的网格上(每四个点)。之后,您的图将看起来更粗糙。如果您不喜欢,请使用[

插回原始网格
sst_smooth = basemap.interp(sst_coarse, lons_sub[0,:], lats_sub[:,0], *np.meshgrid(lons, lats), order=1)

0
投票

我通常通过拉普拉斯过滤器运行数据以进行平滑处理。也许您可以尝试下面的功能,看看它是否对您的数据有帮助。可以使用或不使用掩码(例如,海洋数据点的陆地/海洋掩码)来调用该函数。希望这可以帮助。 T


0
投票

也要回答关于scipy.interpolate.griddata的原始问题:


0
投票

使用xarray查看此示例...使用ds.interp方法并指定新的纬度和经度值。

© www.soinside.com 2019 - 2024. All rights reserved.