【气象常用】等值线填充+风矢量

效果图:

主要步骤:

1. 数据准备:下载ERA5 500hPa月平均风场数据就好啦(不会的可以看这篇帖子)

2. 数据处理:计算气候态u、v风速以及合成风速

3. 图像绘制:绘制矢量风场及等值线填充,并设置图像地理信息、经纬网格及坐标刻度

详细代码:着急的直接拖到最后有完整代码

步骤一:导入库包及图片存储路径并设置中文字体为宋体,西文为新罗马(没有的库包要先下好奥)

import numpy as np
import matplotlib.pyplot as plt
import cartopy.feature as cfeature
import cartopy.crs as ccrs
import matplotlib.ticker as mticker
#from datetime import datetime
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
from cartopy.io.shapereader import Reader
import xarray as xr
# 设置西文字体为新罗马字体,中文为宋体,字号为12
from matplotlib import rcParams
config = {
            "font.family": 'serif',
            "font.size": 12,
            "mathtext.fontset": 'stix',
            "font.serif": ['SimSun'],
          }
rcParams.update(config)
rcParams['axes.unicode_minus']=False
###############################################################################

步骤二:读取nc文件并读入数据

# 读取nc文件
datapath = r'H:/00.csdn/01data/'
figpath = r'H:/00.csdn/02fig/'
shppath = r'H:/00.csdn/04shp/cn_shp/Province_9/Province_9.shp'
data_u = xr.open_dataset(datapath + 'uwnd.nc')
data_v = xr.open_dataset(datapath + 'vwnd.nc')
# print(data_u)
lons = data_u.longitude
lats = data_u.latitude
lon, lat = np.meshgrid(lons, lats)

time = data_u.time
# print(time)
u = data_u.u
v = data_v.v
# print(u)

data_u.close()
data_v.close()

步骤三:计算u、v风速气候态及全风速

# 计算气候态
u_clm = np.array(np.mean(u, axis=0))
v_clm = np.array(np.mean(v, axis=0))

# 计算气候态风速
speed = (u_clm **2 + v_clm**2) **0.5

步骤四:绘制图像主体(即是矢量风场和风速填充)

这里提供了两种矢量画法,一个是箭头表示风速风向,另一个是风羽表示,大家按需选择

###############################################################################
# 绘制图像
level = np.arange(0, 10, 1)
extent = [60, 140, 10, 70]
fig=plt.figure(figsize=(15,6))
ax = fig.add_axes([0.1, 0.1, 1, 1],projection=ccrs.PlateCarree(central_longitude=120))

# 风速
counter = ax.contourf(lon, lat, speed, levels=level, 
                       extend='both', cmap='RdBu_r', transform=ccrs.PlateCarree())
# # 风羽
# plt.barbs(lon[::10, ::10], lat[::10, ::10],
#           u_clm[::10, ::10], v_clm[::10, ::10],
#           color='k',length=5 ,
#           transform=ccrs.PlateCarree()) 

# 箭头
quiver = ax.quiver(lon[::10, ::10], lat[::10, ::10],
                    u_clm[::10, ::10], v_clm[::10, ::10],
                    pivot='mid',width=0.002, 
                    headwidth=4, alpha=1,
                    transform=ccrs.PlateCarree())

步骤五:设置图像地理信息、经纬网格及坐标刻度

# 添加地理信息
ax.add_feature(cfeature.OCEAN.with_scale('50m'))  # 海洋填充为蓝色
ax.add_feature(cfeature.LAND.with_scale('50m'), facecolor='w')  # 陆地填充为白色
# help(ax.add_feature)
# ax.add_feature(cfeature.RIVERS.with_scale('50m'))  # 添加河流
# ax.add_feature(cfeature.LAKES.with_scale('50m'))  # 添加湖泊
# ax.add_feature(cfeature.BORDERS.with_scale('50m'),lw=0.5)  # 添加国界线
ax.add_feature(cfeature.COASTLINE.with_scale('50m'),lw=0.5)  # 添加海岸线
ax.add_geometries(Reader(shppath).geometries(), ccrs.PlateCarree(),
                  facecolor='none', edgecolor='k', linewidth=0.7)  #添加中国国界

# 设置显示范围
ax.set_extent(extent, crs=ccrs.PlateCarree())

# 设置是否显示经纬网格线及坐标刻度
# 画经纬度网格
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1.2, 
                  color='k', alpha=0.5, linestyle='--')
    
gl.top_labels = False  # 关闭顶端的经纬度标签
gl.right_labels = False  # 关闭右侧的经纬度标签
gl.xformatter = LONGITUDE_FORMATTER  # x轴设为经度的格式
gl.yformatter = LATITUDE_FORMATTER  # y轴设为纬度的格式

# 设置经纬度网格的间隔及坐标标签
gl.xlocator = mticker.FixedLocator(np.arange(extent[0], extent[1]+10, 10))
gl.ylocator = mticker.FixedLocator(np.arange(extent[2], extent[3]+10, 10))
ax.set_xticks(list(range(extent[0], extent[1]+10, 10)), crs=ccrs.PlateCarree())
ax.set_yticks(list(range(extent[2], extent[3]+10, 10)), crs=ccrs.PlateCarree())
    
lon_formatter = LongitudeFormatter(zero_direction_label=True)  # zero_direction_label用来设置经度的0度加不加E和W
lat_formatter = LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)

步骤六:设置色标

###############################################################################
# 色标设置
rect = [0.3, 0.015, 0.6, 0.04]
cbar_ax = fig.add_axes(rect)

cb = fig.colorbar(counter, drawedges=True, ticks=level, 
                  cax=cbar_ax, orientation='horizontal')
cb.set_label('m/s', fontsize=12)
cb.ax.tick_params(length=0)

步骤七:保存图像

###############################################################################
# 保存
plt.savefig(figpath+'003 风场+填色(箭头).png', dpi=600, bbox_inches = 'tight')
plt.show()

完整代码在这里:

import numpy as np
import matplotlib.pyplot as plt
import cartopy.feature as cfeature
import cartopy.crs as ccrs
import matplotlib.ticker as mticker
#from datetime import datetime
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
from cartopy.io.shapereader import Reader
import xarray as xr
# 设置西文字体为新罗马字体,中文为宋体,字号为12
from matplotlib import rcParams
config = {
            "font.family": 'serif',
            "font.size": 12,
            "mathtext.fontset": 'stix',
            "font.serif": ['SimSun'],
          }
rcParams.update(config)
rcParams['axes.unicode_minus']=False
###############################################################################
# 读取nc文件
datapath = r'H:/00.csdn/01data/'
figpath = r'H:/00.csdn/02fig/'
shppath = r'H:/00.csdn/04shp/cn_shp/Province_9/Province_9.shp'
data_u = xr.open_dataset(datapath + 'uwnd.nc')
data_v = xr.open_dataset(datapath + 'vwnd.nc')
# print(data_u)
lons = data_u.longitude
lats = data_u.latitude
lon, lat = np.meshgrid(lons, lats)

time = data_u.time
# print(time)
u = data_u.u
v = data_v.v
# print(u)

data_u.close()
data_v.close()

###############################################################################
# 计算气候态
u_clm = np.array(np.mean(u, axis=0))
v_clm = np.array(np.mean(v, axis=0))

# 计算气候态风速
speed = (u_clm **2 + v_clm**2) **0.5
###############################################################################
# 绘制图像
level = np.arange(0, 10, 1)
extent = [60, 140, 10, 70]
fig=plt.figure(figsize=(15,6))
ax = fig.add_axes([0.1, 0.1, 1, 1],projection=ccrs.PlateCarree(central_longitude=120))

# 风速
counter = ax.contourf(lon, lat, speed, levels=level, 
                       extend='both', cmap='RdBu_r', transform=ccrs.PlateCarree())
# # 风羽
# plt.barbs(lon[::10, ::10], lat[::10, ::10],
#           u_clm[::10, ::10], v_clm[::10, ::10],
#           color='k',length=5 ,
#           transform=ccrs.PlateCarree()) 

# 箭头
quiver = ax.quiver(lon[::10, ::10], lat[::10, ::10],
                    u_clm[::10, ::10], v_clm[::10, ::10],
                    pivot='mid',width=0.002, 
                    headwidth=4, alpha=1,
                    transform=ccrs.PlateCarree())


# 添加地理信息
ax.add_feature(cfeature.OCEAN.with_scale('50m'))  # 海洋填充为蓝色
ax.add_feature(cfeature.LAND.with_scale('50m'), facecolor='w')  # 陆地填充为白色
# help(ax.add_feature)
# ax.add_feature(cfeature.RIVERS.with_scale('50m'))  # 添加河流
# ax.add_feature(cfeature.LAKES.with_scale('50m'))  # 添加湖泊
# ax.add_feature(cfeature.BORDERS.with_scale('50m'),lw=0.5)  # 添加国界线
ax.add_feature(cfeature.COASTLINE.with_scale('50m'),lw=0.5)  # 添加海岸线
ax.add_geometries(Reader(shppath).geometries(), ccrs.PlateCarree(),
                  facecolor='none', edgecolor='k', linewidth=0.7)  #添加中国国界

# 设置显示范围
ax.set_extent(extent, crs=ccrs.PlateCarree())

# 设置是否显示经纬网格线及坐标刻度
# 画经纬度网格
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1.2, 
                  color='k', alpha=0.5, linestyle='--')
    
gl.top_labels = False  # 关闭顶端的经纬度标签
gl.right_labels = False  # 关闭右侧的经纬度标签
gl.xformatter = LONGITUDE_FORMATTER  # x轴设为经度的格式
gl.yformatter = LATITUDE_FORMATTER  # y轴设为纬度的格式

# 设置经纬度网格的间隔及坐标标签
gl.xlocator = mticker.FixedLocator(np.arange(extent[0], extent[1]+10, 10))
gl.ylocator = mticker.FixedLocator(np.arange(extent[2], extent[3]+10, 10))
ax.set_xticks(list(range(extent[0], extent[1]+10, 10)), crs=ccrs.PlateCarree())
ax.set_yticks(list(range(extent[2], extent[3]+10, 10)), crs=ccrs.PlateCarree())
    
lon_formatter = LongitudeFormatter(zero_direction_label=True)  # zero_direction_label用来设置经度的0度加不加E和W
lat_formatter = LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)
###############################################################################
# 色标设置
rect = [0.3, 0.015, 0.6, 0.04]
cbar_ax = fig.add_axes(rect)

cb = fig.colorbar(counter, drawedges=True, ticks=level, 
                  cax=cbar_ax, orientation='horizontal')
cb.set_label('m/s', fontsize=12)
cb.ax.tick_params(length=0)
###############################################################################
# 保存
plt.savefig(figpath+'003 风场+填色(箭头).png', dpi=600, bbox_inches = 'tight')
plt.show()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值