气ython风雨 发表于 2024-5-14 10:49:14

Python绘制垂直剖面流线图教程


前言
近日收到读者来信

求助如何绘制垂直剖面的流线图,例如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 :
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(
    )].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(
    )].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, u.shape
      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()
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轴的刻度也有小小修改(标记的刻度是刻意修改的,以配合翻转的数组)
当然还有另一种方法就是将气压转为高度,如此就不必对数组进行翻转


文章来源于公众号:气python风雨
页: [1]
查看完整版本: Python绘制垂直剖面流线图教程