Python | NCL风格 | EOF | 相关 | 回归

这里在linux系统上使用geocat实现NCL风格的图片绘制

geocat

Linux上安装 geocat

conda update conda
conda create -n geocat -c conda-forge geocat-viz
conda activate geocat
conda update geocat-viz
  • Dataset
- NOAA Optimum Interpolation (OI) SST V2 # 海温月平均数据
- lsmask # 掩膜数据
- 1°x1° (180latx360lon)   # 空间分辨率
- 1981-12-01 ~ 2021-07-01  # 时间覆盖范围
- https://psl.noaa.gov/data/gridded/

导入基础库

import numpy as np
import pandas as pd
import xarray as xr
import os
from datetime import datetime
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
import matplotlib.patheffects as PathEffects
from scipy import stats
import geocat.viz.util as gvutil
import cmaps
from geocat.comp import eofunc_eofs, eofunc_pcs
import sys
import inspect

设置数据时间、范围、EOF模态数量

# ----- Parameter setting ------
ystr = 1982
yend = 2020latS = -30.
latN = 30.
lonW = 120.
lonE = 290neof = 3

读取SST数据和MASK掩膜数据

# 打印当前目录
print("当前目录:", os.getcwd())
# == netcdf file name and location"
fnc = 'oisst_monthly.nc'
dmask = xr.open_dataset('lsmask.nc')
print(dmask)ds = xr.open_dataset(fnc)
print(ds)

对于SST进行陆地掩膜 | 计算异常

# === Climatology and Anomalies
sst = ds.sst.where(dmask.mask.isel(time=0) == 1)
clm = sst.sel(time=slice(f'{ystr}-01-01',f'{yend}-12-01')).groupby('time.month').mean(dim='time')
anm = (sst.groupby('time.month') - clm)plt.figure(dpi=200,figsize=(12,4))
plt.subplot(121)
sst[0].plot()
plt.title('With mask')
plt.subplot(122)
ds.sst[0].plot()
plt.title('Not mask')

Figure 2024-04-04 144410

计算季节平均 | 去趋势

# == seasonal mean
anmS = anm.rolling(time=3, center=True).mean('time')
anmDJF=anmS.sel(time=slice(f'{ystr}-01-01',f'{yend}-12-01',12))
print(anmDJF)def wgt_areaave(indat, latS, latN, lonW, lonE):lat=indat.latlon=indat.lonif ( ((lonW < 0) or (lonE < 0 )) and (lon.values.min() > -1) ):anm=indat.assign_coords(lon=( (lon + 180) % 360 - 180) )lon=( (lon + 180) % 360 - 180)else:anm=indatiplat = lat.where( (lat >= latS ) & (lat <= latN), drop=True)iplon = lon.where( (lon >= lonW ) & (lon <= lonE), drop=True)#  print(iplat)
#  print(iplon)wgt = np.cos(np.deg2rad(lat))odat=anm.sel(lat=iplat,lon=iplon).weighted(wgt).mean(("lon", "lat"), skipna=True)return(odat)# -- Detorending
def detrend_dim(da, dim, deg=1):# detrend along a single dimensionp = da.polyfit(dim=dim, deg=deg)fit = xr.polyval(da[dim], p.polyfit_coefficients)return da - fitanmDJF=detrend_dim(anmDJF,'time',1)  

这里的rolling(time=3, center=True).mean('time')可以理解为计算季节平均的过程,返回的是以1981-12-01为中心的(*、1981-12-01、1982-01-01)的平均值,1982-01-01为中心的(1981-12-01、1982-01-01、1982-02-01)的平均值,1982-02-01为中心的(1982-01-01、1982-02-01、1982-03-01)的平均值,…依次类推。

通过时间截取每12个月为一个周期的季节平均,即挑选出:1982-01-01 1983-01-01 ... 2020-01-01为中心的季节平均,作为每年的冬季平均值。

定义一个去趋势函数,函数名为detrend_dim,它的作用是沿着指定的维度对数据进行去趋势化处理。

函数的参数包括:

  • da:输入的数据数组,可以是 xarray.DataArray 类型。
  • dim:指定的维度,沿着这个维度进行去趋势化处理。
  • deg:多项式拟合的阶数,默认为1,即线性拟合。

函数的主要步骤包括:

  • 使用 da.polyfit() 方法进行多项式拟合,拟合得到沿着指定维度的多项式系数。
  • 使用 xr.polyval() 方法根据拟合的多项式系数计算拟合曲线。
  • 将原始数据减去拟合曲线得到去趋势化后的数据。
  • 最终函数返回去趋势化后的数据数组。

rolling()函数通过计算窗口中的数据点的平均值来代表窗口中心点的值。这与中心差分类似,因为我们在某一点附近使用了周围数据点的平均值来估计该点的值。因此,在某种程度上,你可以将滚动窗口均值视为一种离散形式的中心差分。

这里使用官网的一个例子来解释:
https://docs.xarray.dev/en/stable/generated/xarray.DataArray.rolling.html

da = xr.DataArray(np.linspace(0, 11, num=12),coords=[pd.date_range("1999-12-15",periods=12,freq=pd.DateOffset(months=1),)],dims="time",
)da
<xarray.DataArray (time: 12)> Size: 96B
array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11.])
Coordinates:* time     (time) datetime64[ns] 96B 1999-12-15 2000-01-15 ... 2000-11-15da.rolling(time=3, center=True).mean()
<xarray.DataArray (time: 12)> Size: 96B
array([nan,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., nan])
Coordinates:* time     (time) datetime64[ns] 96B 1999-12-15 2000-01-15 ... 2000-11-15

在第一个数据点处,窗口中包含了该数据点、下一个数据点和前一个数据点。而在最后一个数据点处,窗口中包含了该数据点、前一个数据点和后一个数据点。由于这些位置处的窗口无法完全包含3个数据点,因此在这些位置处的滚动窗口均值计算结果为NaN。

所以第一个点rolling后的数值为nan,第二个点的数值为(0+1+2)/3=1,依次类推。


计算nino指数 | 与冬季海温异常的相关/回归系数

eof_sstDJF-nino_corr

nino=wgt_areaave(anmDJF,-5,5,-170,-120)
ninoSD=nino/nino.std(dim='time')# simultaneous
cor0 = xr.corr(ninoSD, anmDJF, dim="time")
reg0 = xr.cov(ninoSD,  anmDJF, dim="time")/ninoSD.var(dim='time',skipna=True).values

绘图 | Nino 指数 | 显著打点


def makefig0(cor, title, grid_space):cor = gvutil.xr_add_cyclic_longitudes(cor, 'lon')ax = fig.add_subplot(grid_space,projection=ccrs.Robinson(central_longitude=180))ax.coastlines(linewidth=0.5, alpha=0.6)gl = ax.gridlines(crs=ccrs.PlateCarree(),draw_labels=True,dms=False,x_inline=False,y_inline=False,linewidth=1,linestyle='dotted',color="black",alpha=0.3)gl.top_labels = Falsegl.right_labels = Falsegl.rotate_labels = Falsegvutil.add_major_minor_ticks(ax, labelsize=10)gvutil.add_lat_lon_ticklabels(ax)newcmp = cmaps.BlueYellowRedindex = [5, 20,  35, 50, 65, 85, 95, 110, 125,  0, 0, 135, 150,  165, 180, 200, 210, 220, 235, 250 ]color_list = [newcmp[i].colors for i in index]color_list[9]=[ 1., 1., 1.]color_list[10]=[ 1., 1., 1.]kwargs = dict(vmin = -1.0,vmax = 1.0,levels = 21,colors=color_list,add_colorbar=False,  # allow for colorbar specification latertransform=ccrs.PlateCarree(),  # ds projection)fillplot = cor.plot.contourf(ax=ax,  **kwargs)ax.add_feature(cfeature.LAND, facecolor='lightgray', zorder=1)ax.add_feature(cfeature.COASTLINE, edgecolor='gray', linewidth=0.5, zorder=1)df = 35 sig=xr.DataArray(data=cor.values*np.sqrt((df-2)/(1-np.square(cor.values))),dims=["lat","lon'"],coords=[cor.lat, cor.lon])t90=stats.t.ppf(1-0.05, df-2)t95=stats.t.ppf(1-0.025, df-2)sig.plot.contourf(ax=ax,levels = [-1*t95, -1*t90, t90, t95], colors='none', hatches=['..', None, None, None, '..'], extend='both', add_colorbar=False, transform=ccrs.PlateCarree())gvutil.set_titles_and_labels(ax,lefttitle=title,lefttitlefontsize=16,righttitle='',righttitlefontsize=16,xlabel="",ylabel="")return ax, fillplotdef make_bar_plot0(dataset, grid_space):years = list(dataset.time.dt.year)values = list(dataset.values)colors = ['blue' if val < 0 else 'red' for val in values]ax = fig.add_subplot(grid_space)ax.bar(years,values,color=colors,width=1.0,edgecolor='black',linewidth=0.5)gvutil.add_major_minor_ticks(ax,x_minor_per_major=5,y_minor_per_major=5,labelsize=10)gvutil.set_axes_limits_and_ticks(ax,xticks=np.linspace(1980, 2020, 5),xlim=[1979.5, 2020.5])gvutil.set_titles_and_labels(ax,lefttitle='Nino3.4 index',lefttitlefontsize=16,righttitle='',righttitlefontsize=16,xlabel="Year",ylabel="Standardized")return ax# Show the plotfig = plt.figure(figsize=(10, 12),dpi=200)
grid = fig.add_gridspec(ncols=1, nrows=3)
ax1, fill1 = makefig0(cor0,'SST correlation (>95%)', grid[0:2,0])fig.colorbar(fill1,ax=[ax1],
#                 ticks=np.linspace(-5, 5, 11),drawedges=True,orientation='horizontal',shrink=0.5,pad=0.05,extendfrac='auto',extendrect=True)ax2 = make_bar_plot0(ninoSD, grid[2,0])fig.suptitle('ENSO (DJF)', fontsize=18, y=0.9)plt.draw()plt.savefig(fnFIG+"nino_corr.png")

纬度加权处理

anmDJF = anmDJF.sortby("lat", ascending=True)
clat = anmDJF['lat'].astype(np.float64)
clat = np.sqrt(np.cos(np.deg2rad(clat)))
wanm = anmDJF 
wanm = anmDJF * clat
wanm.attrs = anmDJF.attrs
print(wanm)

截取太平洋中部区域

xw_anm = wanm.sel(lat=slice(latS, latN), lon=slice(lonW, lonE)).transpose('time', 'lat', 'lon')
print(xw_anm)

EOF 分析

eofs = eofunc_eofs(xw_anm.data, neofs=neof, meta=True)
pcs = eofunc_pcs(xw_anm.data, npcs=neof, meta=True)
# 对主成分进行标准化,即除以时间维度上的标准差,以确保主成分的方差为1。
pcs = pcs / pcs.std(dim='time')
pcs['time']=anmDJF['time']
pcs.attrs['varianceFraction'] = eofs.attrs['varianceFraction']
print(pcs)evec = xr.DataArray(data=eofs, dims=('eof','lat','lon'),coords = {'eof': np.arange(0,neof), 'lat': xw_anm['lat'], 'lon': xw_anm['lon']} )
print(evec)

计算主成分与原始数据之间的相关系数(correlation)和回归系数(regression coefficient)

  • 计算主成分与原始数据 anmDJF 之间的相关系数,使用的函数是 xr.corr(),其中参数 dim="time" 指定了计算相关系数时沿着时间维度进行计算。

  • 使用 xr.cov() 函数计算协方差,然后除以第一个主成分的方差来得到回归系数。

如果解释变量(自变量)是一个主成分,而响应变量(因变量)是原始数据,且假设线性关系是准确的,那么回归系数可以通过计算主成分与原始数据的协方差除以主成分的方差来得到。最小二乘法的目标是最小化观测值与回归模型的残差平方和。对于简单线性回归模型,可以证明,使得残差平方和最小化的回归系数可以通过以下公式计算:

假设简单线性回归模型为:

Y = β 0 + β 1 x + ε Y=\beta_0+\beta_1x+\varepsilon Y=β0+β1x+ε
其中, Y Y Y 是响应变量, x x x 是解释变量, β 0 \beta_0 β0 β 1 \beta_1 β1 是回归系数, ε \varepsilon ε 是随机误差。
我们知道,协方差的定义是:

C o v ( x , Y ) = 1 n ∑ i = 1 n ( x i − x ˉ ) ( Y i − Y ˉ ) \mathrm{Cov}(x,Y)=\frac{1}{n}\sum_{i=1}^n(x_i-\bar{x})(Y_i-\bar{Y}) Cov(x,Y)=n1i=1n(xixˉ)(YiYˉ)
其中, x ˉ \bar{x} xˉ Y ˉ \bar{Y} Yˉ 分别是 x x x Y Y Y 的样本均值。现在,我们对 Y Y Y 给定 x x x 求期望:

E ( Y ∣ x ) = E ( β 0 + β 1 x + ε ∣ x ) = β 0 + β 1 x + E ( ε ∣ x ) E(Y|x)=E(\beta_0+\beta_1x+\varepsilon|x)=\beta_0+\beta_1x+E(\varepsilon|x) E(Yx)=E(β0+β1x+εx)=β0+β1x+E(εx)
因为 ε \varepsilon ε 是一个随机误差,所以在给定 x x x 的情况下, ε \varepsilon ε的期望为零。因此,上式可以简化为

$$

E(Y|x)=\beta_{0}+\beta_{1}x

$$
现在,我们来计算

C o v ( x , E ( Y ∣ x ) ) = 1 n ∑ i = 1 n ( x i − x ˉ ) ( E ( Y i ∣ x ) − E ( Y ˉ ∣ x ) ) Cov(x,E(Y|x))=\frac1n\sum_{i=1}^n(x_i-\bar{x})(E(Y_i|x)-E(\bar{Y}|x)) Cov(x,E(Yx))=n1i=1n(xixˉ)(E(Yix)E(Yˉx))

因为

E ( Y i ∣ x ) = β 0 + β 1 x i , E(Y_i|x)=\beta_0+\beta_1x_i, E(Yix)=β0+β1xi,

而且
E ( Y ˉ ∣ x ) = β 0 + β 1 x ˉ , E(\bar{Y}|x)=\beta_0+\beta_1\bar{x}, E(Yˉx)=β0+β1xˉ,
所以上式可以进一步简化为:
C o v ( x , E ( Y ∣ x ) ) = 1 n ∑ i = 1 n ( x i − x ˉ ) ( β 0 + β 1 x i − ( β 0 + β 1 x ˉ ) ) = 1 n ∑ i = 1 n ( x i − x ˉ ) ( β 1 x i − β 1 x ˉ ) = β 1 1 n ∑ i = 1 n ( x i − x ˉ ) 2 = β 1 V a r ( x ) \begin{aligned} &Cov(x,E(Y|x))=\frac1n\sum_{i=1}^n(x_i-\bar{x})(\beta_0+\beta_1x_i-(\beta_0+\beta_1\bar{x})) \\ &=\frac1n\sum_{i=1}^n(x_i-\bar{x})(\beta_1x_i-\beta_1\bar{x}) \\ &=\beta_1\frac1n\sum_{i=1}^n(x_i-\bar{x})^2 \\ &=\beta_1\mathrm{Var}(x) \end{aligned} Cov(x,E(Yx))=n1i=1n(xixˉ)(β0+β1xi(β0+β1xˉ))=n1i=1n(xixˉ)(β1xiβ1xˉ)=β1n1i=1n(xixˉ)2=β1Var(x)

因此,我们得到了公式 C o v ( x , E ( Y ∣ x ) ) = β 1 Cov( x, E( Y|x) ) = \beta_1 Cov(x,E(Yx))=β1Var$( x) $

cor1 = xr.corr(pcs[0,:], anmDJF, dim="time")
cor2 = xr.corr(pcs[1,:], anmDJF, dim="time")
cor3 = xr.corr(pcs[2,:], anmDJF, dim="time")
reg1 = xr.cov(pcs[0,:], anmDJF, dim="time")/pcs[0,:].var(dim='time',skipna=True).values
reg2 = xr.cov(pcs[1,:], anmDJF, dim="time")/pcs[1,:].var(dim='time',skipna=True).values
reg3 = xr.cov(pcs[2,:], anmDJF, dim="time")/pcs[2,:].var(dim='time',skipna=True).values

定义绘图函数 - 空间pattern

def makefig(dat, ieof, grid_space):# 通过添加子图 ax,使用 ccrs.PlateCarree 投影来绘制地图,并设置中心经度为 180 度。# 这样做是为了修正在 0 和 360 度经度附近未显示数据的问题。ax = fig.add_subplot(grid_space,projection=ccrs.PlateCarree(central_longitude=180))# 绘制海岸线ax.coastlines(linewidth=0.5, alpha=0.6)# 创建网格线,并进行相应的设置,包括绘制标签、设置线宽和样式、设置颜色和透明度等gl = ax.gridlines(crs=ccrs.PlateCarree(),draw_labels=True,dms=False,x_inline=False,y_inline=False,linewidth=1,linestyle='dotted',color="black",alpha=0.3)gl.top_labels = Falsegl.right_labels = Falsegl.rotate_labels = Falsegl.xlocator=ctk.LongitudeLocator(20)gl.ylocator=ctk.LatitudeLocator(5)# 添加主要和次要刻度线。gvutil.add_major_minor_ticks(ax, labelsize=10)# 添加纬度和经度的刻度标签。gvutil.add_lat_lon_ticklabels(ax)# 设置了填充图的颜色newcmp = cmaps.BlueYellowRedindex = [5, 20,  35, 50, 65, 85, 95, 110, 125,  0, 0, 135, 150,  165, 180, 200, 210, 220, 235, 250 ]color_list = [newcmp[i].colors for i in index]#-- Change to whitecolor_list[9]=[ 1., 1., 1.]color_list[10]=[ 1., 1., 1.]# 绘制填充图所需的参数,如最小值、最大值、颜色等kwargs = dict(vmin = -0.06,vmax = 0.06,levels = 21,colors=color_list,add_colorbar=False,  # allow for colorbar specification latertransform=ccrs.PlateCarree(),  # ds projection)# 填充图,并将其保存到变量 fillplot 中fillplot = dat[ieof,:,:].plot.contourf(ax=ax,  **kwargs)# 添加陆地和海岸线等地图特征。ax.add_feature(cfeature.LAND, facecolor='lightgray', zorder=1)ax.add_feature(cfeature.COASTLINE, edgecolor='gray', linewidth=0.5, zorder=1)# 图形的标题和标签。gvutil.set_titles_and_labels(ax,lefttitle=f'EOF{ieof+1} pattern',lefttitlefontsize=12,righttitle='',righttitlefontsize=12,maintitle='',xlabel="",ylabel="")return ax, fillplot

定义柱状图的绘图函数

该函数接受三个参数:

  • dataset:包含数据的 xarray 数据集。
  • ieof:表示要绘制的主成分(PC)的索引。
  • grid_space:指定子图在网格中的位置。
def make_bar_plot(dataset, ieof, grid_space):# 获取数据集中时间坐标的年份、指定主成分的数据,并将其转换为列表 years = list(dataset.time.dt.year)values = list(dataset[ieof,:].values)# 根据主成分的值,生成与其相对应的颜色列表 colors,如果值小于 0,则对应颜色为蓝色,否则为红色。colors = ['blue' if val < 0 else 'red' for val in values]ax = fig.add_subplot(grid_space)ax.bar(years,values,color=colors,width=1.0,edgecolor='black',linewidth=0.5)# 添加主要和次要刻度线,并设置刻度线的密度和标签大小gvutil.add_major_minor_ticks(ax,x_minor_per_major=5,y_minor_per_major=5,labelsize=10)# 设置坐标轴的范围和刻度值。gvutil.set_axes_limits_and_ticks(ax,xticks=np.linspace(1980, 2020, 5),xlim=[1979.5, 2020.5],ylim=[-3.0, 3.5])pct = dataset.attrs['varianceFraction'].values[ieof] * 100print(pct)# 获取主成分的方差百分比,并将其转换为字符串格式# 设置图形的标题和标签,包括左侧标题、右侧标题、横坐标标签和纵坐标标签。gvutil.set_titles_and_labels(ax,lefttitle=f'PC{ieof+1} (normalized)',lefttitlefontsize=12,righttitle=f'{pct:.1f}%',righttitlefontsize=12,xlabel="Year",ylabel="",labelfontsize=10 )return ax

绘图 | 保存图片


fig = plt.figure(figsize=(14, 6),dpi=200)
grid = fig.add_gridspec(ncols=3, nrows=3, hspace=0.4)ax1, fill1 = makefig(evec,0, grid[0:2,0])
ax2, fill2 = makefig(evec,1, grid[0:2,1])
ax3, fill3 = makefig(evec,2, grid[0:2,2])fig.colorbar(fill2,ax=[ax1,ax2,ax3],ticks=np.linspace(-0.06, 0.06, 5),drawedges=True,label='Eigenvector',orientation='horizontal',shrink=0.3,pad=0.08,extendfrac='auto',extendrect=True)ax1 = make_bar_plot(pcs,0,grid[2,0])
ax2 = make_bar_plot(pcs,1,grid[2,1])
ax3 = make_bar_plot(pcs,2,grid[2,2])fig.suptitle('EOF for SST (DJF)', fontsize=16, y=0.9)plt.draw()
plt.savefig(fnFIG+".png")

展示绘图结果

eof_sstDJF


未去线性趋势结果

  • 可以对比发现,未去掉线性趋势,对于模态的影响在第三模态,其空间patter以及PC的结果存在较大差异;而前两个模态影响较小。但是这个仅仅是对于该区域来说,对于其他区域的影响仍需要进一步探究。

eof_sstDJF-without-detrend

未加权处理结果

  • 对于此区域来看,加权的结果对于分析影响较小。
    eof_sstDJF-without-weight

绘制全球范围的EOF分析

eof_sstDJF-v3-glbaol

未使用异常数据 | 全球

eof_sstDJF-without_ana

未使用异常数据 | 中太平洋

eof_sstDJF-without_ana_loc

  • 对于是否使用异常SST来看,对于主导模态结果影响较小;但是个人感觉来说更取决于你所关注的研究方向。

绘制相关系数空间分布

eof_sstDJF-corr


def makefig2(dat, ieof, grid_space):ax = fig.add_subplot(grid_space,projection=ccrs.PlateCarree(central_longitude=180))ax.coastlines(linewidth=0.5, alpha=0.6)gl = ax.gridlines(crs=ccrs.PlateCarree(),draw_labels=True,dms=False,x_inline=False,y_inline=False,linewidth=1,linestyle='dotted',color="black",alpha=0.3)gl.top_labels = Falsegl.right_labels = Falsegl.rotate_labels = Falsegvutil.add_major_minor_ticks(ax, labelsize=10)gvutil.add_lat_lon_ticklabels(ax)newcmp = cmaps.BlueYellowRedindex = [5, 20,  35, 50, 65, 85, 95, 110, 125,  0, 0, 135, 150,  165, 180, 200, 210, 220, 235, 250 ]color_list = [newcmp[i].colors for i in index]#-- Change to whitecolor_list[9]=[ 1., 1., 1.]color_list[10]=[ 1., 1., 1.]kwargs = dict(vmin = -1.0,vmax = 1.0,levels = 21,colors=color_list,add_colorbar=False,  # allow for colorbar specification latertransform=ccrs.PlateCarree(),  # ds projection)fillplot = dat[:,:].plot.contourf(ax=ax,  **kwargs)ax.add_feature(cfeature.LAND, facecolor='lightgray', zorder=1)ax.add_feature(cfeature.COASTLINE, edgecolor='gray', linewidth=0.5, zorder=1)gvutil.set_titles_and_labels(ax,lefttitle=f'EOF{ieof+1} pattern',lefttitlefontsize=12,righttitle='',righttitlefontsize=12,maintitle='',xlabel="",ylabel="")return ax, fillplot# Show the plot
fig = plt.figure(figsize=(14, 8),dpi=200)
grid = fig.add_gridspec(ncols=3, nrows=3, hspace=0.4)
ax1, fill1 = makefig2(cor1,0, grid[0:2,0])
ax2, fill2 = makefig2(cor2,1, grid[0:2,1])
ax3, fill3 = makefig2(cor3,2, grid[0:2,2])
fig.colorbar(fill2,ax=[ax1,ax2,ax3],ticks=np.linspace(-1.0, 1.0, 5),drawedges=True,label='Correlation',orientation='horizontal',shrink=0.3,pad=0.08,extendfrac='auto',extendrect=True)
fig.suptitle('EOF for SST (DJF)', fontsize=16, y=0.85)
plt.draw()
plt.savefig(fnFIG+"corr.png",bbox_inches='tight')

https://geocat-viz.readthedocs.io/en/latest/installation.html

https://geocat-viz.readthedocs.io/en/latest/examples.html

http://unidata.github.io/netcdf4-python/

https://geocat-examples.readthedocs.io/en/latest/gallery/index.html

https://climate.usu.edu/people/yoshi/pyclm101/index.html

https://docs.xarray.dev/en/stable/gallery.html

本文由mdnice多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/300844.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

内容创作策略:打造影响力强大的技术博客

CSDN的朋友你们好&#xff0c;我是未来&#xff0c;今天给大家带来专栏【程序员博主教程&#xff08;完全指南&#xff09;】的第6篇文章——“博客内容创作策略”。本文为技术博主提供了一个精简的内容创作策略指南&#xff0c;涵盖了设定目标、分析竞争、关键词研究、内容规划…

24 个Intellij IDEA好用插件

24 个Intellij IDEA好用插件 一. 安装插件 Codota 代码智能提示插件 只要打出首字母就能联想出一整条语句&#xff0c;这也太智能了&#xff0c;还显示了每条语句使用频率。 原因是它学习了我的项目代码&#xff0c;总结出了我的代码偏好。 Key Promoter X 快捷键提示插件 …

vscode 安装vim插件配置ctrl + c/v功能

搜索Vim插件 插件介绍部分有提示操作 首先安装该插件&#xff0c;然后按照下述步骤设置ctrl相关的快捷键&#xff0c;以便于脱离im快捷键而愉快的敲代码。 1.在“设置”搜索框内搜索vim.handleKeys&#xff0c;选择 Edit in settings.json 2. 设置ctrl-c,ctrl-v等快捷键置为fa…

室友打团太吵?一条命令让它卡死

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;更多干货&#xff0c;请关注专栏《网络安全自学教程》 SYN Flood 1、hping3实现SYN Flood1.1、主机探测1.2、扫描端…

Unity类银河恶魔城学习记录12-7-1 p129 Craft UI - part 1源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili UI_CraftList.cs using System.Collections; using System.Collections.Gen…

zdpdjango_argonadmin使用Django开发一个美观的后台管理系统

初始代码 安装依赖 pip install -r requirements.txt生成管理员账户 迁移模型&#xff1a; python manage.py makemigrations python manage.py migrate创建超级用户&#xff1a; python manage.py createsuperuser启动服务 python manage.py runserver浏览器访问&#xf…

2024新版PHP在线客服系统多商户AI智能在线客服系统源码机器人自动回复即时通讯聊天系统源码PC+H5

搭建环境&#xff1a; 服务器 CPU 2核心 ↑ 运存 2G ↑ 宽带 5M ↑ 服务器操作系统 Linux Centos7.6-7.9 ↑ 运行环境&#xff1a; 宝塔面板 Nginx1.18- 1.22 PHP 7.1-7.3 MYSQL 5.6 -5.7 朵米客服系统是一款全功能的客户服务解决方案&#xff0c;提供多渠道支持…

计算机组成原理(超详解!!) 第四节 存储系统和结构

1.存储器概述 1.存储器分类 存储器&#xff1a;用来存储程序和数据的记忆设备。 存储介质&#xff1a;具有两种明显区别且稳定的物理状态&#xff0c;在外界的作用下&#xff0c;能够相互转化&#xff1b;一种稳定状态表示“0”&#xff0c;则另一种状态表示“1”。目前主要…

es6新增set、map两种数据结构(超级详细-附加代码)

文章目录 一、Set增删改查add()delete()has()clear()遍历 二、Map增删改查sizeset()get()has()delete()clear()遍历 三、WeakSet 和 WeakMapWeakSetWeakMap 参考文献 如果要用一句来描述&#xff0c;我们可以说 Set是一种叫做集合的数据结构&#xff0c;Map是一种叫做字典的数…

数据结构——链表

目录 一、链表 1、单向链表 单向链表的遍历方式&#xff1a; 2、循环链表 3、双向链表 二、自行车停放&#xff08;双向链表&#xff09; 一、链表 链表是由许多相同数据类型的数据项按特定顺序排列而成的线性表特性&#xff1a;存放的位置是不连续且随机的&#xff0c;动…

全坚固笔记本丨工业笔记本丨三防笔记本相较于普通笔记本有哪些优势?

三防笔记本和普通笔记本在设计和性能方面存在显著差异&#xff0c;三防笔记本相较于普通笔记本具备以下优势&#xff1a; 三防笔记本通常采用耐磨、耐摔的材料&#xff0c;并具有坚固的外壳设计&#xff0c;能够承受恶劣环境和意外碰撞&#xff0c;有效保护内部组件不受损坏。相…

armlinux裸机-uart

uart是一对一的串行异步全双工通信通信协议&#xff0c;串行速度较慢&#xff08;usart支持同步通信&#xff09; 传输原理 多个参数可以设置 为满足使用需求&#xff0c;我们一般都用带fifo缓冲中断。 我们使用S3C2440芯片&#xff0c;具体寄存器操作可以查看用户手册

NOI - OpenJudge - 2.5基本算法之搜索 - 1490:A Knight‘s Journey - 超详解析(含AC代码)

点赞关注吧~ 1490:A Knights Journey 查看提交统计提问 总时间限制: 1000ms 内存限制: 65536kB 描述 Background The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey around the world. When…

【WEEK6】 【DAY7】MD5 Encryption Transactions【English Version】

2024.4.7 Sunday Following the previous article 【WEEK6】 【DAY3】MySQL Functions【English Version】 Contents 5.3. MD5 Encryption5.3.1. Introduction5.3.2. Testing MD5 Encryption5.3.2.1. Plain Text Passwords5.3.2.2. Implementing Data Encryption5.3.2.3. Encry…

实景三维在文化旅游领域的应用

实景三维技术&#xff0c;作为一种前沿的科技手段&#xff0c;近年来在文化旅游领域的应用逐渐崭露头角。它能够将真实世界的场景以三维的形式精确呈现&#xff0c;为游客带来身临其境的体验&#xff0c;为文化旅游注入新的活力。本文将探讨实景三维在文化旅游领域的应用及其所…

npm版本切换工具nvm

有了nvm&#xff0c;可以在一台机器上同时安装多个版本的nodejs&#xff0c;然后指定使用某个版本。 前端开发的时候&#xff0c;安装依赖一直是个令我头痛的问题。总是报错&#xff0c;或者不是少了这样就是少了那样&#xff0c;鸡飞狗走。以往&#xff0c;一般要装个enpm&am…

【java的本地锁到分布式锁介绍】

文章目录 1.java本地自带锁介绍及应用synchronized&#xff08;1&#xff09;synchronized原理和优化&#xff08;2&#xff09;synchronized作用&#xff08;3&#xff09;synchronized的使用 CAS(1) CAS原理&#xff08;2&#xff09;CAS和synchronized优缺点 lock 2.分布式锁…

基于Spring Boot的网上书城系统(带文档)

主要功能 本次设计任务是要设计一个网上书城管理系统&#xff0c;通过这个系统能够满足网上书城的管理及用户的图书信息管理及购物功能。系统的主要功能包括&#xff1a;首页、个人中心、用户管理、图书类型管理、图书分类管理、图书信息管理、我的收藏管理、系统管理、订单管…

c++的学习之路:14、list(1)

本章讲一下如何使用list&#xff0c;代码在文章末 目录 一、list介绍 二、增 三、删 四、查和改 五、交换 六、代码 一、list介绍 首先还是看一看官方文档的介绍如下图&#xff0c;如下方五点&#xff1a; 1. list是可以在常数范围内在任意位置进行插入和删除的序列式…

面向电力行业定制安全云工作站解决方案,麒麟信安出席2024年电力企业信创替代技术研讨会

日前&#xff0c;由中国电子企业协会主办的“2024年电力企业信创替代技术研讨会”在江苏南京正式召开。会议以国家推进实现自主可控、加快建设“数字中国”为大背景&#xff0c;聚焦电力企业紧抓“信创替代”机遇&#xff0c;通过安全可靠的软硬件迭代升级&#xff0c;实现企业…