- 积分
- 3433
- 贡献
-
- 精华
- 在线时间
- 小时
- 注册时间
- 2016-12-19
- 最后登录
- 1970-1-1
|
登录后查看更多精彩内容~
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 数学学得特别好 于 2023-10-6 19:38 编辑
单层和整层的水汽通量及水汽通量散度在ncl下的计算在论坛里已经有很多讨论和经验了,这里总结分享一下python下的计算方法。计算使用的数据是era5,如果使用其他数据计算也都大同小异。主要用到的python库有metpy,geocat。
在ncl中垂直积分有dpres_plevel,vibeta两种计算方法,geocat作为ncar开发的库提供了dpres_plevel的python实现,因此这里使用的是dpres_plevel方法。计算过程和单位的处理参考这个链接:https://cloud.tencent.com/developer/article/1764064 。大家觉得不对的地方欢迎提出交流哈。
2023.09.21更新:geocat-comp库更新后,dpres_plev更新为delta_pressure,不再需要层顶;除此之外修改了图片的量级。
- import xarray as xr
- import numpy as np
- import cfgrib
- import matplotlib.pyplot as plt
- import matplotlib.ticker as mticker
- import cartopy.crs as ccrs
- import cartopy.feature as cfeature
- from cartopy.io.shapereader import Reader # 读取 .shp
- import metpy.calc as mpcalc
- import geocat.comp as gc
- import cmaps
- from metpy.units import units
- # 读取省界
- shpName = 'Province_9.shp'
- reader = Reader(shpName)
- provinces = cfeature.ShapelyFeature(reader.geometries(), ccrs.PlateCarree(), edgecolor='k', facecolor='none')
- # 需要的层次
- levels = [1000., 975., 950., 925., 900., 850., 800., 750., 700., 650.,
- 600., 550., 500., 450., 400., 350., 300., 250., 200.]
- # 常数
- g = 9.8
- # 读取文件
- files = 'ERA5/' # 这里改成自己的数据路径
- file = 'pl_2014070506.grib'
- file_sl = "sl_2014070506.grib"
- ds = cfgrib.open_datasets(files+file)
- ds_sl = cfgrib.open_datasets(files+file_sl)
- # 读取变量
- u_levels = ds[0].u.sel(isobaricInhPa=levels)
- v_levels = ds[0].v.sel(isobaricInhPa=levels)
- q_levels = ds[0].q.sel(isobaricInhPa=levels) # kg/kg
- psfc = ds_sl[4].sp # 为了在垂直积分时考虑地形,计算时要用到地表气压,单位Pa
- # 接下来是数据的处理:
- plev = u_levels.coords["isobaricInhPa"] * 100 # 单位变为Pa
- plev.attrs['units'] = 'Pa'
- q_levels = q_levels * 1000 # kg/kg -> g/kg
- q_levels.attrs['units'] = 'g/kg'
- # 计算各层次厚度,效果类似ncl中的dpres_plevel
- dp = gc.meteorology.delta_pressure(pressure_lev=plev.data, surface_pressure=psfc.data)
- # Layer Mass Weighting
- dpg = dp / g
- dpg = np.transpose(dpg, (2,0,1)) # 调整dpg维度的顺序,和下面的uq vq保持一致
- # 水汽通量
- uq = u_levels * q_levels
- vq = v_levels * q_levels
- uq.attrs["units"] = "("+u_levels.units+")("+q_levels.units+")"
- vq.attrs["units"] = "("+v_levels.units+")("+q_levels.units+")"
- uq_dpg = uq * dpg.data
- vq_dpg = vq * dpg.data
- # 整层水汽通量
- iuq = uq_dpg.sum(axis=0)
- ivq = vq_dpg.sum(axis=0)
- iuq.attrs["units"] = "[m/s][g/kg]"
- ivq.attrs["units"] = "[m/s][g/kg]"
- # 水汽通量散度
- duvq = mpcalc.divergence(uq, vq)
- duvq.attrs["units"] = "g/(kg-s)"
- duvq_dpg = duvq * dpg.data
- # 整层水汽通量散度
- iduvq = duvq_dpg.sum(axis=0)
- iduvq = iduvq * units('kg/m^2')
- iduvq.attrs["units"] = "g/(m2-s)"
- # 画图
- leftlon, rightlon, lowerlat, upperlat = 80, 100, 20, 40
- img_extent = [leftlon, rightlon, lowerlat, upperlat]
- levs = np.arange(-3, 3+0.5, 0.5)
- fig = plt.figure(figsize=(12,9))
- ax = plt.subplot(111, projection=ccrs.PlateCarree())
- ax.set_extent(img_extent)
- ax.coastlines('50m', linewidth=0.8)
- # 整层水汽通量散度填色
- mfc_contourf = ax.contourf(lons, lats,
- iduvq,
- cmap=cmaps.MPL_seismic,
- levels=levs,
- extend='both', transform=ccrs.PlateCarree()) # testcmap precip3_16lev levels=levs,
- # 整层水汽通量流线
- mf_stream = ax.streamplot(lons, lats,
- iuq, ivq,
- color='black', transform=ccrs.PlateCarree())
- gl = ax.gridlines(draw_labels=True, dms=False,
- linestyle='--', color='gray',
- x_inline=False, y_inline=False)
- gl.top_labels = False
- gl.right_labels = False
- ax.add_feature(provinces, linewidth=1)
- # 让色标和图等宽
- position = fig.add_axes([ax.get_position().x0,
- ax.get_position().y0-0.08,
- ax.get_position().width,
- 0.02])
- cb = fig.colorbar(mfc_contourf, orientation='horizontal', cax=position)
- cb.set_label('%s'%iduvq.units, fontsize=12)
复制代码
最后出的图:
vimfc
notebook文件:
|
评分
-
查看全部评分
|