近日收到读者来信
求助如何绘制垂直剖面的流线图,例如V-W的剖面,想尝试用流线图画个类似的经圈环流图
matplotlib可以用streamplot(X,Y,u,v)画流线,但是X,Y的要求比较严格(等距,单调递增)
但是画出来的图方向和大小是不对的
在今天的文章中,我们运用Python的numpy、matplotlib.pyplot及scipy.interpolate库来生动展示全球大气风场。核心是定义一个名为myStreamPlot
的函数,它将经纬度和风速数据转换为流线图,利用三重网格插值确保准确性。
首先设置好坐标轴范围与刻度,以等高线形式呈现风切变率。然后调用myStreamPlot
函数,对经度、纬度、东西风向分量u、南北风向分量v以及垂直风速w_clm进行预处理,并调整单位便于理解。通过streamplot绘制出清晰易懂的全球风场流线图。
简而言之,这段代码通过计算与可视化手段实现垂直剖面流线图。希望这的编程实践能激发你对气象学的探索兴趣,欢迎在评论区分享你的想法与讨论。
数据获取or代码在线运行,可点击Python绘制垂直剖面流线图教程 🔜🔜若没有成功加载可视化图,点击运行可以查看 ps:隐藏代码在【代码已被隐藏】所在行,点击所在行,可以看到该行的最右角,会出现个三角形,点击查看即可
In [10]:
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
import datetime as dt
import cartopy.mpl.ticker as cticker
f_v = xr.open_dataset('/home/mw/input/moyu1828/vwnd.mon.mean.nc')
v_clm = f_v.vwnd.loc[f_v.time.dt.month.isin(
[6, 7, 8])].loc['1980-01-01':'2010-12-31', 1000:100, 90:-90, :].mean('time').mean('lon') # 代入a6、a7
f_w = xr.open_dataset('/home/mw/input/moyu1828/omega.mon.mean.nc')
w_clm = f_w.omega.loc[f_w.time.dt.month.isin(
[6, 7, 8])].loc['1980-01-01':'2010-12-31', 1000:100, 90:-90, :].mean('time').mean('lon') # 代入a6、a7
lat = w_clm.lat
lev = w_clm.level
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata
# 定义创建流线图的函数
def myStreamPlot(lon, lat, u, v, color='k', density=2.5):
from scipy.interpolate import griddata
n, m = u.shape[1], u.shape[0]
x = np.linspace(np.nanmin(lon), np.nanmax(lon), n) # 为网格创建x值数组
y = np.linspace(np.nanmin(lat), np.nanmax(lat), m) # 为网格创建y值数组
xi, yi = np.meshgrid(x, y) # 创建x和y值的网格
lon, lat = np.meshgrid(lon, lat) # 创建输入经度和纬度的网格
lon = lon.flatten() # 展平经度网格
lat = lat.flatten() # 展平纬度网格
# 确保风分量的方向正确
u = np.flipud(u) # 翻转风速u分量
v = np.flipud(v) # 翻转风速v分量
u = u.flatten() # 展平u分量
v = v.flatten() # 展平v分量
# 对u和v分量进行插值处理到网格上
gu = griddata((lon, lat), u, (xi, yi), method='cubic')
gv = griddata((lon, lat), v, (xi, yi), method='cubic')
gspd = np.sqrt(gu**2 + gv**2) # 计算风速大小
SL = plt.streamplot(x, y, gu, gv, linewidth=1., color=color, density=density) # 创建流线图
# 创建一个图和子图
fig = plt.figure(dpi=200)
ax1 = fig.add_subplot(1, 1, 1)
# 设置x和y轴的范围
ax1.set_xlim(-90, 90)
ax1.set_ylim(100, 1000)
# 设置轴标签和格式
ax1.set_ylabel('气压层 (hPa)', fontsize=14)
ax1.xaxis.set_major_formatter(cticker.LatitudeFormatter())
ax1.set_yticks([1000, 500, 300, 200, 100])
ax1.set_yticklabels(['100', '200', '300', '500', '1000'])
# 创建等值线图
c1 = ax1.contourf(lat, lev, np.flipud(w_clm), levels=np.arange(-0.05, 0.055, 0.005), extend='both', cmap=plt.cm.bwr)
# 调用自定义的流线图函数
myStreamPlot(lat[::2], lev, v_clm[:, ::2], -w_clm[:, ::2]*100, color='k', density=2.5)
# 显示图形
plt.show()
在以上代码中我对风数据作了翻转后再插值处理,
还有y轴的刻度也有小小修改(标记的刻度是刻意修改的,以配合翻转的数组) 当然还有另一种方法就是将气压转为高度,如此就不必对数组进行翻转
有更好的方法欢迎私信交流