Python学习笔记——eofs.standard的使用

eof是经常用来处理时空数据集的方法;在python中有直接可以使用的库来进行分解。以下是使用eofs的学习心得:

1>数据集要求:  `numpy.ndarray`, `numpy.ma.MaskedArray` or `dask.array.Array`
两维及以上、且第一维为时间 。缺测数据需要满足时间上连续性(缺测点一直缺测)

2>需要加载的库:(包括读取和绘图)

import xarray as xr
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from eofs.standard import Eof
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import cartopy.mpl.ticker as cticker
nf = xr.open_mfdataset('D:\\fang\\data\\t2m\\*.nc')  # 批量读取多个nc文件,读取后nf为xarray。Dataset对象
t2_3 = nf.variables['t2m'][2: :12, :, :]    #t2_3为DataArray对象
t2m = np.array(t2_3)                #  转换为eof库需要的numpy array

3>数据处理:

因为eof库需要数组中存在缺测的点一直缺测。即缺测的时间连续性。故需要对数据进行处理,将存在缺测的格点赋为nan。 

ind_always = np.ones((t2m.shape[1], t2m.shape[2]))  #创建一个与t2m空间场shape相同的逻辑数组
ind_always = (ind_always == 1)  # 全是True 
for i in range(t2m.shape[0]):       # 以年为循环次数
    temp = t2m[i, :, :]  # 第i年的空间场  
    ind_always = ind_always & (~np.isnan(temp))   #找出一直有数据的空间场格点
# ind_always表示一直有数据的格点的索引逻辑数组 
t2m[:, ~ind_always] = np.nan     #将存在缺测的格点剔除   
print(t2m.shape)

4>  进行eof分解:

eof = Eof(t2m)   #进行eof分解
U = eof.eofs(eofscaling=2, neofs=3)  # 得到空间模态U eofscaling 对得到的场进行放缩 (1为除以特征值平方根,2为乘以特征值平方根,默认为0不处理) neofs决定输出的空间模态场个数
PC = eof.pcs(pcscaling=1, npcs=3)  # 同上 npcs决定输出的时间序列个数
s = eof.varianceFraction(neigs=3)   # 得到前neig个模态的方差贡献
print(U.shape, PC.shape, s.shape)   

5>绘图:

接下来就是绘图啦!先是时间序列图:

fg=plt.figure(facecolor='w')  #设置背景颜色为白色
ax1=fg.add_subplot(111)
for i in range(0,62):         # 画bar图大于0值为红色,小于0值为蓝色
  if PC[i,0]>0:
    ax1.bar(i,PC[i,0],color='r')
  elif PC[i,0]<0:
    ax1.bar(i,PC[i,0],color='b')
ax1.set_xticks([0,10,20,30,40,50,60],[1960,1970,1980,1990,2000,2010,2020])  #设置x坐标

出图效果(时间序列):

Python学习笔记——eofs.standard的使用_第1张图片

然后是空间场图:

cm = plt.cm.get_cmap('RdYlBu_r')    #设置绘图颜色
fg = plt.figure(facecolor='w')
gax1 = fg.add_subplot(111,projection=ccrs.PlateCarree())
lon,lat= np.meshgrid(np.linspace(0,360,3600), np.linspace(90,-90.1,1801))
qs=gax1.contourf(lon,lat,U[0,:,:],cmap=cm,transform=ccrs.PlateCarree())  #设置投影
gax1.add_feature(cfeature.COASTLINE.with_scale('50m'))  #绘制海岸线
gax1.set_xticks([-120,-60,0,60,120])   #设置坐标刻度 下同
gax1.set_yticks([-60,-30,0,30,60])
gax1.xaxis.set_major_formatter(cticker.LongitudeFormatter()) # 设置坐标刻度格式
gax1.yaxis.set_major_formatter(cticker.LatitudeFormatter())
fg.colorbar(qs,ax=gax1,shrink =0.5)  #绘制色标

 效果图:

 Python学习笔记——eofs.standard的使用_第2张图片

 

你可能感兴趣的:(学习)