效果图:
主要步骤:
1. 数据准备:我用的1950-2023年夏季的温度数据(更多数据下载方法可看:【数据下载】ERA5地表月平均数据下载_era5月平均数据哪里下-CSDN博客
【数据下载】ERA5 各高度层月平均数据下载-CSDN博客)
2. 数据处理:计算了每年的夏季平均温度,及温度距平,并进行了数据淹没
3. 图像绘制:绘制了eof的前四个模态
详细代码:着急的直接拖到最后有完整代码
步骤一:导入库包及图片存储路径并设置中文字体为宋体,西文为新罗马(没有的库包要先下好奥)
###############################################################################
# 导入库及文件
from netCDF4 import Dataset
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import netCDF4 as nc
from cnmaps import get_adm_maps, draw_maps
from matplotlib import rcParams
import cartopy.feature as cfeature
from eofs.standard import Eof
from cartopy.mpl import ticker
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/'
shppath = r'H:/00.csdn/04shp/cn_shp/Province_9/Province_9.shp'
data_tem = Dataset(datapath + 't2m_cn_jja_1950-2023.nc', mode='r')
# print(data_tem)
lons = data_tem.variables['longitude'][:]
lats = data_tem.variables['latitude'][:]
lon, lat = np.meshgrid(lons, lats)
time = data_tem.variables['time']
time_new = nc.num2date(time[:], time.units)
# print(time_new)
tem = data_tem.variables['t2m'][:]
data_tem.close()
步骤三:计算夏季温度平均及温度距平,并对数据进行掩膜
##############################################################################
# 计算每年的夏季平均
t_mean = np.empty((74, 601, 901))
for i in range(0, 74, 1):
t_mean[i, :, :] = np.mean(tem[i*3 : (i+1)*3, : :], 0)
# 计算温度距平
dt = t_mean - np.mean(t_mean, 0)
# 掩膜数据
SC = get_adm_maps(province='四川省', only_polygon=True, record='first')
maskout_t = SC.maskout(lon, lat, dt)
步骤四:创建eof分解器(只需在Eof(maskout_t)中将maskout_t换成自己的数据就好啦)
###############################################################################
# 创建EOF分解器
solver = Eof(maskout_t)
eof = solver.eofsAsCorrelation(neofs=4)
pc = solver.pcs(npcs=4, pcscaling=1)
var = solver.varianceFraction(neigs=4)
步骤五:绘制eof的前四个空间模态
###############################################################################
# 绘制图像
fig=plt.figure(figsize=(15, 15))
proj=ccrs.PlateCarree(central_longitude=180)
lonW,lonE,latS,latN=(97, 109, 25, 35)
# 绘制空间模态
def sp_plot(value, location, title, var):
fig_ax = fig.add_axes(location, projection=proj)
fig_ax.set_extent([lonW, lonE, latS, latN], crs=ccrs.PlateCarree())
fig_ax.set_xticks(list(range(lonW, lonE+1, 3)), crs=ccrs.PlateCarree())
fig_ax.set_yticks(list(range(latS, latN+1, 3)), crs=ccrs.PlateCarree())
fig_ax.add_feature(cfeature.OCEAN, edgecolor='black')
fig_ax.add_feature(cfeature.LAKES, alpha=0.5)
fig_ax.add_feature(cfeature.COASTLINE, lw=1)
fig_ax.xaxis.set_major_formatter(ticker.LongitudeFormatter())
fig_ax.yaxis.set_major_formatter(ticker.LatitudeFormatter())
draw_maps(get_adm_maps(province='四川省', level='省'), color='k', linewidth=1)
fig_ax.set_title(title, loc='left', fontsize =15)
fig_ax.set_title('%.2f%%' % (var*100), loc='right', fontsize =15)
c = fig_ax.contourf(lons, lats, value, levels=np.arange(-1, 1, 0.05),
zorder=0, extend='both', transform=ccrs.PlateCarree(), cmap=plt.cm.RdBu_r)
return c
f1 = sp_plot( eof[0,:,:], [0.1,0.99,0.47,0.2], '(a) EOF1', var[0])
f2 = sp_plot( eof[1,:,:], [0.1,0.74,0.47,0.2], '(c) EOF2', var[1])
f3 = sp_plot( eof[2,:,:], [0.1,0.49,0.47,0.2], '(e) EOF3', var[2])
f4 = sp_plot( eof[3,:,:], [0.1,0.24,0.47,0.2], '(g) EOF4', var[3])
cbposition=fig.add_axes([0.19, 0.2, 0.3, 0.015])
fig.colorbar(f4, cax=cbposition, orientation='horizontal', format='%.1f')
步骤六:绘制eof的前四个pc
# 绘制pc
def time_plot(value, location, title):
fig0 = fig.add_axes(location)
fig0.set_title(title, loc='left', fontsize = 15)
fig0.set_ylim(-4, 4)
fig0.axhline(0, linestyle="--")
fig0.plot(np.arange(1950, 2024, 1), value, color='blue')
# return fig0
f5 = time_plot(pc[:,0],[0.55, 0.99, 0.47, 0.2], '(b) PC1')
f6 = time_plot(pc[:,1],[0.55, 0.74, 0.47, 0.2], '(d) PC2')
f7 = time_plot(pc[:,2],[0.55, 0.49, 0.47, 0.2], '(f) PC3')
f8 = time_plot(pc[:,3],[0.55, 0.24, 0.47, 0.2], '(h) PC4')
步骤七:保存图像
###########################################################################
# 存图
plt.savefig(figpath+'207 温度 eof分解', dpi=600, bbox_inches = 'tight')
plt.show()
完整代码在这里:
###############################################################################
# 导入库及文件
from netCDF4 import Dataset
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import netCDF4 as nc
from cnmaps import get_adm_maps, draw_maps
from matplotlib import rcParams
import cartopy.feature as cfeature
from eofs.standard import Eof
from cartopy.mpl import ticker
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/'
shppath = r'H:/00.csdn/04shp/cn_shp/Province_9/Province_9.shp'
data_tem = Dataset(datapath + 't2m_cn_jja_1950-2023.nc', mode='r')
# print(data_tem)
lons = data_tem.variables['longitude'][:]
lats = data_tem.variables['latitude'][:]
lon, lat = np.meshgrid(lons, lats)
time = data_tem.variables['time']
time_new = nc.num2date(time[:], time.units)
# print(time_new)
tem = data_tem.variables['t2m'][:]
data_tem.close()
##############################################################################
# 计算每年的夏季平均
t_mean = np.empty((74, 601, 901))
for i in range(0, 74, 1):
t_mean[i, :, :] = np.mean(tem[i*3 : (i+1)*3, : :], 0)
# 计算温度距平
dt = t_mean - np.mean(t_mean, 0)
# 掩膜数据
SC = get_adm_maps(province='四川省', only_polygon=True, record='first')
maskout_t = SC.maskout(lon, lat, dt)
###############################################################################
# 创建EOF分解器
solver = Eof(maskout_t)
eof = solver.eofsAsCorrelation(neofs=4)
pc = solver.pcs(npcs=4, pcscaling=1)
var = solver.varianceFraction(neigs=4)
###############################################################################
# 绘制图像
fig=plt.figure(figsize=(15, 15))
proj=ccrs.PlateCarree(central_longitude=180)
lonW,lonE,latS,latN=(97, 109, 25, 35)
# 绘制空间模态
def sp_plot(value, location, title, var):
fig_ax = fig.add_axes(location, projection=proj)
fig_ax.set_extent([lonW, lonE, latS, latN], crs=ccrs.PlateCarree())
fig_ax.set_xticks(list(range(lonW, lonE+1, 3)), crs=ccrs.PlateCarree())
fig_ax.set_yticks(list(range(latS, latN+1, 3)), crs=ccrs.PlateCarree())
fig_ax.add_feature(cfeature.OCEAN, edgecolor='black')
fig_ax.add_feature(cfeature.LAKES, alpha=0.5)
fig_ax.add_feature(cfeature.COASTLINE, lw=1)
fig_ax.xaxis.set_major_formatter(ticker.LongitudeFormatter())
fig_ax.yaxis.set_major_formatter(ticker.LatitudeFormatter())
draw_maps(get_adm_maps(province='四川省', level='省'), color='k', linewidth=1)
fig_ax.set_title(title, loc='left', fontsize =15)
fig_ax.set_title('%.2f%%' % (var*100), loc='right', fontsize =15)
c = fig_ax.contourf(lons, lats, value, levels=np.arange(-1, 1, 0.05),
zorder=0, extend='both', transform=ccrs.PlateCarree(), cmap=plt.cm.RdBu_r)
return c
f1 = sp_plot( eof[0,:,:], [0.1,0.99,0.47,0.2], '(a) EOF1', var[0])
f2 = sp_plot( eof[1,:,:], [0.1,0.74,0.47,0.2], '(c) EOF2', var[1])
f3 = sp_plot( eof[2,:,:], [0.1,0.49,0.47,0.2], '(e) EOF3', var[2])
f4 = sp_plot( eof[3,:,:], [0.1,0.24,0.47,0.2], '(g) EOF4', var[3])
cbposition=fig.add_axes([0.19, 0.2, 0.3, 0.015])
fig.colorbar(f4, cax=cbposition, orientation='horizontal', format='%.1f')
# 绘制pc
def time_plot(value, location, title):
fig0 = fig.add_axes(location)
fig0.set_title(title, loc='left', fontsize = 15)
fig0.set_ylim(-4, 4)
fig0.axhline(0, linestyle="--")
fig0.plot(np.arange(1950, 2024, 1), value, color='blue')
# return fig0
f5 = time_plot(pc[:,0],[0.55, 0.99, 0.47, 0.2], '(b) PC1')
f6 = time_plot(pc[:,1],[0.55, 0.74, 0.47, 0.2], '(d) PC2')
f7 = time_plot(pc[:,2],[0.55, 0.49, 0.47, 0.2], '(f) PC3')
f8 = time_plot(pc[:,3],[0.55, 0.24, 0.47, 0.2], '(h) PC4')
###########################################################################
# 存图
plt.savefig(figpath+'207 温度 eof分解', dpi=600, bbox_inches = 'tight')
plt.show()