嘿嘿嘿嘿,我又回来啦!
效果图:
主要步骤:
1. 数据准备:用的era5月尺度2m温度数据,下载方法看这里【数据下载】ERA5地表月平均数据下载_era5-land逐年下载-CSDN博客
2. 数据处理:计算了温度距平
3. 图像绘制:在一张图上绘制12个月全球温度距平的等值线
详细代码:着急的直接拖到最后有完整代码
步骤一:导入库包及图片存储路径并设置中文字体为宋体,西文为新罗马(没有的库包要先下好奥)
import numpy as np
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
from cartopy.io.shapereader import Reader
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import xarray as xr
# from cnmaps import get_adm_maps, draw_maps
# # import pygrib as pg
# 设置西文字体为新罗马字体,中文为宋体,字号为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
步骤二:读入数据
##########################################################
datapath = r'H:/00.csdn/01data/'
figpath = r'H:/00.csdn/02fig/'
# 读入数据
f = xr.open_dataset(datapath + 'adaptor.mars.internal-1722923621.7120583-8340-14-564f2282-d1be-45f2-b27b-1237762039a5.nc')
# print(f)
t = f['t2m']
time = f['time']
lons = t['longitude']
lats = t['latitude']
lon, lat = np.meshgrid(lons, lats)
# 计算时间维平均,及距平
t_mean = np.mean(t, axis=0)
dt = t[:, :, :] - t_mean
print(f'最大值:{np.max(dt).values:5.2f},最小值:{np.min(dt).values:5.2f}')
extent = [-180, 180, -90, 90]
步骤三:绘制图像
# data:所绘制的数据
# sub_fig_location:子图位置
# sub_title:子图名称
# sub_title_position:标题位置
# level:等值线间隔
# show:是否显示网格线
##########################################################
# 画图
t_level = np.arange(-30, 30, 5)
fig = plt.figure(figsize=(15, 6))
# 定义画图函数
def plot_cont(data, sub_fig_location, sub_title, sub_title_position, level, show):
# data:所绘制的数据
# sub_fig_location:子图位置
# sub_title:子图名称
# sub_title_position:标题位置
# level:等值线间隔
# show:是否显示网格线
ax = fig.add_axes(sub_fig_location, projection=ccrs.PlateCarree(central_longitude=120))
c1 = ax.contourf(lon, lat, data, levels=level,
extend='both', cmap='RdBu_r', 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) # 添加海岸线
title = ax.set_title(sub_title, fontsize=12)
title.set_position(sub_title_position) # 调整位置
# 设置显示范围
ax.set_extent(extent, crs=ccrs.PlateCarree())
# 设置是否显示经纬网格线及坐标刻度
if show == True:
# 画经纬度网格
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, 60))
gl.ylocator = mticker.FixedLocator(np.arange(extent[2], extent[3]+10, 30))
ax.set_xticks(list(range(extent[0], extent[1]+10, 60)), crs=ccrs.PlateCarree())
ax.set_yticks(list(range(extent[2], extent[3]+10, 30)), 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)
return c1
location = [[0.1, 0.9, 0.4, 0.3], [0.4, 0.9, 0.4, 0.3], [0.7, 0.9, 0.4, 0.3], [1, 0.9, 0.4, 0.3],
[0.1, 0.5, 0.4, 0.3], [0.4, 0.5, 0.4, 0.3], [0.7, 0.5, 0.4, 0.3], [1, 0.5, 0.4, 0.3],
[0.1, 0.1, 0.4, 0.3], [0.4, 0.1, 0.4, 0.3], [0.7, 0.1, 0.4, 0.3], [1, 0.1, 0.4, 0.3],]
title = ['(a)JAN', '(b)FEB', '(c)MAR', '(d)APR',
'(e)MAY', '(f)JUN', '(g)JUL', '(h)AUG',
'(i)SEP', '(j)OCT', '(k)NOV', '(l)DEC']
for i in range(12):
CN = plot_cont(dt[i], sub_fig_location=location[i], sub_title=title[i], sub_title_position=[0.08, 1.05], level=t_level, show=True)
步骤四:设置色标
###############################################################################
# 色标设置
rect = [0.3, 0.015, 0.8, 0.03]
cbar_ax = fig.add_axes(rect)
cb = fig.colorbar(CN, drawedges=True, ticks=t_level,
cax=cbar_ax, orientation='horizontal')
cb.set_label('℃', fontsize=12)
# cb.ax.tick_params(length=0)
步骤五:保存图像
###############################################################################
# 存图
plt.savefig(figpath+'216 全球填色加组图', dpi=600, bbox_inches = 'tight')
plt.show()
完整代码在这里:
import numpy as np
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
from cartopy.io.shapereader import Reader
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import xarray as xr
# from cnmaps import get_adm_maps, draw_maps
# # import pygrib as pg
# 设置西文字体为新罗马字体,中文为宋体,字号为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
##########################################################
datapath = r'H:/00.csdn/01data/'
figpath = r'H:/00.csdn/02fig/'
# 读入数据
f = xr.open_dataset(datapath + 'adaptor.mars.internal-1722923621.7120583-8340-14-564f2282-d1be-45f2-b27b-1237762039a5.nc')
# print(f)
t = f['t2m']
time = f['time']
lons = t['longitude']
lats = t['latitude']
lon, lat = np.meshgrid(lons, lats)
# 计算时间维平均,及距平
t_mean = np.mean(t, axis=0)
dt = t[:, :, :] - t_mean
print(f'最大值:{np.max(dt).values:5.2f},最小值:{np.min(dt).values:5.2f}')
extent = [-180, 180, -90, 90]
##########################################################
# 画图
t_level = np.arange(-30, 30, 5)
fig = plt.figure(figsize=(15, 6))
# 定义画图函数
def plot_cont(data, sub_fig_location, sub_title, sub_title_position, level, show):
# data:所绘制的数据
# sub_fig_location:子图位置
# sub_title:子图名称
# sub_title_position:标题位置
# level:等值线间隔
# show:是否显示网格线
ax = fig.add_axes(sub_fig_location, projection=ccrs.PlateCarree(central_longitude=120))
c1 = ax.contourf(lon, lat, data, levels=level,
extend='both', cmap='RdBu_r', 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) # 添加海岸线
title = ax.set_title(sub_title, fontsize=12)
title.set_position(sub_title_position) # 调整位置
# 设置显示范围
ax.set_extent(extent, crs=ccrs.PlateCarree())
# 设置是否显示经纬网格线及坐标刻度
if show == True:
# 画经纬度网格
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, 60))
gl.ylocator = mticker.FixedLocator(np.arange(extent[2], extent[3]+10, 30))
ax.set_xticks(list(range(extent[0], extent[1]+10, 60)), crs=ccrs.PlateCarree())
ax.set_yticks(list(range(extent[2], extent[3]+10, 30)), 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)
return c1
location = [[0.1, 0.9, 0.4, 0.3], [0.4, 0.9, 0.4, 0.3], [0.7, 0.9, 0.4, 0.3], [1, 0.9, 0.4, 0.3],
[0.1, 0.5, 0.4, 0.3], [0.4, 0.5, 0.4, 0.3], [0.7, 0.5, 0.4, 0.3], [1, 0.5, 0.4, 0.3],
[0.1, 0.1, 0.4, 0.3], [0.4, 0.1, 0.4, 0.3], [0.7, 0.1, 0.4, 0.3], [1, 0.1, 0.4, 0.3],]
title = ['(a)JAN', '(b)FEB', '(c)MAR', '(d)APR',
'(e)MAY', '(f)JUN', '(g)JUL', '(h)AUG',
'(i)SEP', '(j)OCT', '(k)NOV', '(l)DEC']
for i in range(12):
CN = plot_cont(dt[i], sub_fig_location=location[i], sub_title=title[i], sub_title_position=[0.08, 1.05], level=t_level, show=True)
###############################################################################
# 色标设置
rect = [0.3, 0.015, 0.8, 0.03]
cbar_ax = fig.add_axes(rect)
cb = fig.colorbar(CN, drawedges=True, ticks=t_level,
cax=cbar_ax, orientation='horizontal')
cb.set_label('℃', fontsize=12)
# cb.ax.tick_params(length=0)
###############################################################################
# 存图
plt.savefig(figpath+'216 全球填色加组图', dpi=600, bbox_inches = 'tight')
plt.show()