效果图:
主要步骤:
1. 数据准备:我用的ERA5的2023年夏季500hPa位势高度场数据,不会下的可以看这里奥(【数据下载】ERA5 各高度层月平均数据下载-CSDN博客)
2. 数据处理:计算了夏季平均
3. 图像绘制:绘制了位势高度场等值线并加深588线
详细代码:着急的直接拖到最后有完整代码
步骤一:导入库包及图片存储路径并设置中文字体为宋体,西文为新罗马(没有的库包要先下好奥)
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_h = xr.open_dataset(datapath + 'h_2023_JJA.nc')
# print(data_h)
lons = data_h.longitude.sel(longitude=slice(60, 140))
lats = data_h.latitude.sel(latitude=slice(70, 10))
lon, lat = np.meshgrid(lons, lats)
time = data_h.time
# print(time)
h = data_h.z.sel(longitude=slice(60, 140), latitude=slice(70, 10)) / 9.8
data_h.close()
# data_v.close()
###############################################################################
# 计算JJA平均
h_clm = np.array(np.mean(h, axis=0))
步骤三:绘制图像主体即等值线,并加深588线
加深588线原理就是又绘制了一下并设置线宽为3
clabel是添加等值线标签
###############################################################################
# 绘制图像
extent = [60, 140, 10, 70]
fig=plt.figure(figsize=(15,6))
ax = fig.add_axes([0.1, 0.1, 1, 1],projection=ccrs.PlateCarree())
# 位势高度等值线
c1 = ax.contour(lon, lat, h_clm, levels=range(5600,6000, 40), colors='k')
c2 = ax.contour(lon, lat, h_clm, levels=range(5880,5881, 1), colors='k', linewidths=3)
ax.clabel(c1, inline=True, inline_spacing=15, fontsize=12)
ax.clabel(c2, inline=True, inline_spacing=15, fontsize=12)
步骤四:添加地理信息及经纬网格等
# 添加地理信息
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)
步骤五:保存图像
###############################################################################
# 保存
plt.savefig(figpath+'206 500hPa位势高度场+588线.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_h = xr.open_dataset(datapath + 'h_2023_JJA.nc')
# print(data_h)
lons = data_h.longitude.sel(longitude=slice(60, 140))
lats = data_h.latitude.sel(latitude=slice(70, 10))
lon, lat = np.meshgrid(lons, lats)
time = data_h.time
# print(time)
h = data_h.z.sel(longitude=slice(60, 140), latitude=slice(70, 10)) / 9.8
data_h.close()
# data_v.close()
###############################################################################
# 计算JJA平均
h_clm = np.array(np.mean(h, axis=0))
###############################################################################
# 绘制图像
extent = [60, 140, 10, 70]
fig=plt.figure(figsize=(15,6))
ax = fig.add_axes([0.1, 0.1, 1, 1],projection=ccrs.PlateCarree())
# 位势高度等值线
c1 = ax.contour(lon, lat, h_clm, levels=range(5600,6000, 40), colors='k')
c2 = ax.contour(lon, lat, h_clm, levels=range(5880,5881, 1), colors='k', linewidths=3)
ax.clabel(c1, inline=True, inline_spacing=15, fontsize=12)
ax.clabel(c2, inline=True, inline_spacing=15, fontsize=12)
# 添加地理信息
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)
###############################################################################
# 保存
plt.savefig(figpath+'206 500hPa位势高度场+588线.png', dpi=600, bbox_inches = 'tight')
plt.show()