python画WRF垂直剖面

本文介绍了如何使用Python和WRF(WeatherResearchandForecasting)数据库,结合NCL和GrADS的经验,创建了一张T2变量的垂直剖面图,展示了从Python编程角度实现数据处理和可视化的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一直很想画垂直剖面图,借鉴了很多大佬的笔记,包括NCL和GrADS代码,最后发现还是python好用,然后自己根据需要改了改,此贴更多为自己记录学习下~废话不多说,附上代码。(图为T2例图,可以根据需要换参数)

import netCDF4 as nc
from wrf import to_np,getvar,CoordPair,vertcross,interplevel
import cartopy.crs as ccrs
from cartopy.io import shapereader
filename =shapereader.natural_earth()
import cartopy.feature as cfeat
import matplotlib.pyplot as plt
import cmaps
import matplotlib as mpl
import matplotlib.ticker as mticker
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
from matplotlib.font_manager import FontProperties
import numpy as np

Simsun = FontProperties(fname="E:\\anaconda\\Lib\\site-packages\\matplotlib\\times.ttf")
Times = FontProperties(fname="E:\\anaconda\\Lib\\site-packages\\matplotlib\\times.ttf")
mpl.rcParams['axes.unicode_minus']=False
config = {
    "font.family":'serif',
    "mathtext.fontset": 'stix',
    "font.serif": ['SimSun'],
}
mpl.rcParams.update(config)

big_p,small_p,interval_p=1000,500,50
start_lon,end_lon,interval_lon=114.1,114.6,0.2
start_lat,end_lat=38.98,39.01
startpoint = CoordPair(lat=start_lat, lon=start_lon)
endpoint = CoordPair(lat=end_lat, lon=end_lon)
ncfile=nc.Dataset('E:\wrf 20211209 hysplit\wrfoutd03.00')
t=getvar(ncfile,'tc',timeidx=48)
lat=getvar(ncfile,'lat')
lon=getvar(ncfile,'lon')
height=getvar(ncfile,'height')
hgt=getvar(ncfile,'HGT')
height2earth=height-hgt
ua=getvar(ncfile,'ua',timeidx=48)
va=getvar(ncfile,'va',timeidx=48)
wa=getvar(ncfile,'wa',timeidx=48)
wa = wa * 10
p = getvar(ncfile, 'pressure', timeidx=48)
t_vert = vertcross(t, p, wrfin=ncfile, start_point=startpoint, end_point=endpoint, latlon=True)
ua_vert = vertcross(ua, p, wrfin=ncfile, start_point=startpoint, end_point=endpoint, latlon=True)
va_vert = vertcross(va, p, wrfin=ncfile, start_point=startpoint, end_point=endpoint, latlon=True)
wa_vert = vertcross(wa, p, wrfin=ncfile, start_point=startpoint, end_point=endpoint, latlon=True)
ws_vert = np.sqrt(ua_vert ** 2 + va_vert ** 2)
wdir_vert = np.arctan2(va_vert, ua_vert) * 180 / np.pi
line_angel = np.arctan2(end_lat - start_lat, end_lon - start_lon) * 180 / np.pi
vl_angel = wdir_vert - line_angel
vl_angel = np.cos(np.deg2rad(vl_angel))
ws_vert = ws_vert * vl_angel

lonlist, latlist, hlist = [], [], []
plist = to_np(va_vert.coords['vertical'])
for i in range(len(ua_vert.coords['xy_loc'])):
    s = str(ua_vert.coords['xy_loc'][i].values)
    lonlist.append(float(s[s.find('lon=') + 4:s.find('lon=') + 12]))
    latlist.append(float(s[s.find('lat=') + 4:s.find('lat=') + 12]))
for i in range(big_p, small_p - interval_p, -interval_p):
    hlist.append(float(np.max(interplevel(height2earth, p, i)).values))
hlist = np.array([int(i) for i in hlist])
str_lonlist, float_lonlist = [], []
a = np.mgrid[0:len(lonlist) - 1:complex(str(int(round((end_lon + interval_lon - start_lon) / interval_lon))) + 'j')]
a = np.around(a, decimals=0)
for i in range(int((end_lon + interval_lon - start_lon) / interval_lon)):
    float_lonlist.append(lonlist[int(a[i])])
    lo, la = round(lonlist[int(a[i])], 2), round(latlist[int(a[i])], 2)
    str_lonlist.append(str(lo) + '°E' + "\n" + str(la) + '°N')

fig=plt.figure(figsize=(10,10),dpi=150)
axe=plt.subplot(1,1,1)
axe.set_title('Vertical_wind',fontsize=12,y=1.05)
axe.set_xlim(start_lon, end_lon)
axe.set_ylim(small_p, big_p)
axe.invert_yaxis()  # 翻转纵坐标
axe.grid(color='gray', linestyle=':', linewidth=0.7, axis='y')
plt.xticks(float_lonlist, str_lonlist, fontsize=8, color='k')
axe.set_xlabel('Lat/Lon', fontproperties=Simsun, fontsize=12)
axe.get_xaxis().set_visible('True')
plt.yticks(fontsize=8, color='k')
axe.get_yaxis().set_visible('True')
axe.set_yticks(np.arange(small_p, big_p, interval_p))
axe.set_ylabel('P$\mathrm{(hPa))}$', fontproperties=Simsun, fontsize=12)
axe.tick_params(length=2)
labels = axe.get_xticklabels() + axe.get_yticklabels()
[label.set_fontproperties(FontProperties(fname="E:\\anaconda\\Lib\\site-packages\\matplotlib\\times.ttf", size=8)) for label in labels]

axe.grid(color='gray', linestyle=":", linewidth=0.7, axis='y')

t_level=np.arange(-10,10,2)
contourf = axe.contourf(lonlist, plist, t_vert, levels=t_level, cmap=cmaps.NCV_jaisnd,extend='neither')
axe.quiver(lonlist, plist, ws_vert, wa_vert, pivot='mid',
           width=0.001, scale=700, color='k', headwidth=4,
           alpha=1)

fig.subplots_adjust(right=0.78)
rect = [0.87, 0.07, 0.01, 0.57]
cbar_ax = fig.add_axes(rect)
cb = fig.colorbar(contourf, drawedges=True, ticks=t_level, cax=cbar_ax, orientation='vertical',spacing='uniform')
cb.set_label('t', fontsize=12)
cb.ax.tick_params(length=0)
# labels = cb.ax.get_xticklabels()+cb.ax.get_yticklabels()
# [label.set_fontproperties(FontProperties(fname="E:\\anaconda\\Lib\\site-packages\\matplotlib\\times.ttf",size=10)) for label in labels]

axe1 = fig.add_axes([0.8,0.69,0.2,0.2], projection=ccrs.PlateCarree())
LAKES_border=cfeat.NaturalEarthFeature('physical','lakes','10m',edgecolor='black',facecolor='never')
axe1.add_feature(cfeat.COASTLINE.with_scale("10m"), linewidth=0.7, color='k')
axe1.add_feature(cfeat.RIVERS.with_scale("10m"))
axe1.add_feature(cfeat.OCEAN.with_scale("10m"))
axe1.add_feature(cfeat.LAKES.with_scale("10m"))
axe1.set_extent([111.5, 114.5, 37.5, 39.5], crs=ccrs.PlateCarree())
gl = axe1.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=0.5, color='gray',linestyle=':')
gl.xlocator = mticker.FixedLocator(np.arange(111.5, 114.5, 0.5))
gl.ylocator = mticker.FixedLocator(np.arange(37.5, 39.5, 0.5))
gl.xformatter = LongitudeFormatter
gl.yformatter = LatitudeFormatter
axe1.set_xticks(np.arange(111.5, 114.5, 1), crs=ccrs.PlateCarree())
axe1.set_yticks(np.arange(37.5, 39.5, 0.5), crs=ccrs.PlateCarree())
plt.tick_params(top=True,bottom=True,left=True,right=True)
plt.tick_params(labeltop=True,labelleft=True,labelright=True,labelbottom=True)
axe1.xaxis.set_major_formatter(LongitudeFormatter())
axe1.yaxis.set_major_formatter(LatitudeFormatter())
axe1.set_xticks(np.arange(111.5, 114.5, 1), crs=ccrs.PlateCarree(), minor=True)
axe1.set_yticks(np.arange(37.5, 39.5, 0.5), crs=ccrs.PlateCarree(), minor=True)
axe1.tick_params(labelcolor='k',length=2)
labels = axe1.get_xticklabels() + axe1.get_yticklabels()
[label.set_fontproperties(FontProperties(fname="E:\\anaconda\\Lib\\site-packages\\matplotlib\\times.ttf",size=6)) for label in labels]


axe1.plot([lonlist[0], lonlist[-1]], [latlist[0], latlist[-1]], color='red', linewidth=1.5,linestyle='-')
axe1.plot(lonlist[0], latlist[0], marker='o', color='red', markersize=2.5)
axe1.plot(lonlist[-1], latlist[-1], marker='o', color='red', markersize=2.5)
axe1.text(lonlist[0], latlist[0], 'A', fontproperties=FontProperties(fname="E:\\anaconda\\Lib\\site-packages\\matplotlib\\times.ttf", size=8))
axe1.text(lonlist[-1], latlist[-1], 'A'+"'", fontproperties=FontProperties(fname="E:\\anaconda\\Lib\\site-packages\\matplotlib\\times.ttf", size=8))

axe_sub = axe.twinx()
axe_sub.set_ylim(hlist[0],hlist[-1])
axe_sub.set_yticks(np.mgrid[hlist[0]:hlist[-1]:complex(str(int(hlist.shape[0])) + 'j')])
round_hlist=np.around(hlist,-1)
axe_sub.set_yticklabels(round_hlist)
axe_sub.set_ylabel('Height$\mathrm{(m))}$', fontsize=12)
axe_sub.tick_params(labelcolor='black', length=3)
labels = axe_sub.get_xticklabels() + axe_sub.get_yticklabels()
[label.set_fontproperties(FontProperties(fname="E:\\anaconda\\Lib\\site-packages\\matplotlib\\times.ttf", size=8)) for label in labels]

plt.show()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值