ENSO
厄尔尼诺-南方涛动(ENSO) 是地球上最重要的气候现象之一,因为它能够改变全球大气环流,进而影响全球温度和降水。我们关注 ENSO 的另一个重要原因在于,它的出现通常可以提前多个季节预测,从而让人类能够在其对天气和气候产生最强影响之前做出准备。
虽然 ENSO 是一个单一的气候现象,但它可以处于三种状态或阶段。两个相对的阶段是El Niño和La Niña,由于 ENSO 是一个耦合的气候现象,这两种状态都需要海洋和大气的某些变化。中性
则处于这两个事件的中间位置。
El Niño:热带太平洋中部和东部的海洋表面变暖,或高于平均海面温度(SST)。印度尼西亚的降雨量往往会减少,而热带太平洋的降雨量则会增加。通常沿着赤道从东向西吹的信风反而减弱,或者在某些情况下开始向另一个方向吹(从西向东或西风)。
La Niña:热带太平洋中部和东部的海洋表面变冷,或低于平均海面温度 (SST)。印度尼西亚的降雨量趋于增加,而热带太平洋中部的降雨量趋于减少。沿赤道的正常东风变得更强。
中性:既不是El Niño,也不是La Niña。热带太平洋海表温度通常接近平均水平。然而,在某些情况下,海洋看起来可能处于El Niño或La Niña状态,但大气层并没有发挥作用(反之亦然)。
Nino指数
有多种指数用于监测热带太平洋,所有这些指数均基于特定区域的平均海面温度(SST)异常。通常,异常值是相对于 30 年的基期计算的。Niño 3.4 指数和海洋 Niño 指数 (ONI) 是定义El Niño和La Niña事件最常用的指数。其他指数用于帮助描述每个事件的独特性质。
不同Nino区的定义及其意义:
Niño 1+2区(0-10S,90W-80W):是El Niño海温区域中最小且最东部的区域,与南美洲沿海地区最先发现El Niño现象的区域相对应。这个区域的海温异常指数往往具有最大的方差,意味着它的变化幅度在所有El Niño指数中最为显著。
Niño 3区(5N-5S,150W-90W):曾经是监测和预测El Niño现象的主要焦点。然而,研究人员后来发现ENSO海气耦合相互作用的关键区域实际上位于更西边,因此,El Niño 3.4区域和ONI(Oceanic Niño Index)成为了定义El Niño和La Niña事件的首选。
Niño 3.4区(5N-5S,170W-120W):该区的海温异常可以代表从日界线到南美洲海岸的赤道太平洋的平均海温。这个区域的指数通常使用5个月的滑动平均值,当El Niño 3.4区域的海温超过(低于)+(-)0.4°C并持续六个月或更长时间时,就定义为El Niño或La Niña事件。
ONI(5N-5S,170W-120W):该区使用与El Niño 3.4区域相同的区域。ONI使用3个月的滑动平均值,要被归类为一次成熟的El Niño或La Niña事件,海温异常必须超过+0.5°C或-0.5°C至少连续五个月。
Niño 4区域(5N-5S,160E-150W):该区用于捕捉中太平洋赤道区域的海温异常。与其他El Niño区域相比,这个区域的方差往往较小,意味着它的变化幅度不如其他区域那么显著。
Python代码
以下代码用于绘制Nino分区。使用的数据是NOAA Extended Reconstructed SST V5,下载地址为:https://psl.noaa.gov/data/gridded/data.noaa.ersst.v5.html
.
导入库
import numpy as np
import xarray as xr
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import cartopy.mpl.ticker as cticker
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pylab as pylab
读取数据
data = xr.open_dataset(r"sst.mnmean.nc")
ssta = (data.sst.sel(time = slice("2015", "2015")) - data.sst.sel(time = slice("1990", "2020")).mean("time")).mean("time")
绘图
params = {'legend.fontsize':15,
'axes.labelsize':16.5,
'axes.titlesize':14.5,
'xtick.labelsize':14.5,
'ytick.labelsize':14.5}
cmap_temp = plt.get_cmap('RdBu_r')
pylab.rcParams.update(params)
fig = plt.figure(figsize=(12, 8), dpi=300)
ax = plt.subplot(111, projection=ccrs.PlateCarree(
central_longitude = 180))
land = cfeature.NaturalEarthFeature('physical', 'land', '50m')
ax.add_feature(land, color='lightgray', zorder=-1)
regions = ['Niño4', 'Niño3.4', 'Niño3', 'Niño1+2']
cols = ['r', 'k', 'b', 'k']
minlats = [-5, -5.5, -5, -10]
maxlats = [5, 5.5, 5, 0]
minlons = [160, 190, 210.5, 269.5]
maxlons = [209.5, 240, 270.5, 280]
xlocs = [163, 204, 257, 262]
ylocs = [6, -10, 6, -14]
lats = [-23, 23]
lons = [140, 280]
cf = ax.contourf(data.lon, data.lat, ssta[:],
cmap = cmap_temp,
levels = np.linspace(-2, 2, 101),
extend = 'both',
transform = ccrs.PlateCarree())
ax.coastlines()
ax.set_title('Nino SSTA', loc='center', fontweight = 'bold')
ax.set_extent([lons[0], lons[1], lats[0], lats[1]], ccrs.PlateCarree())
ax.set_xlabel('Longitude ($^{\circ}$E)')
ax.set_ylabel('Latitude ($^{\circ}$N)')
ax.set_title('')
for i in range(len(regions)):
ax.add_patch(Rectangle((minlons[i], minlats[i]), (maxlons[i]- minlons[i]), abs(maxlats[i] - minlats[i]),
fill=False, linestyle='--', linewidth = 1.5, color=cols[i], transform=ccrs.PlateCarree()));
ax.text(xlocs[i], ylocs[i], regions[i], fontsize=12, fontweight='bold', color = cols[i], transform = ccrs.PlateCarree())
lat_formatter = cticker.LatitudeFormatter()
long_formatter = cticker.LongitudeFormatter()
ax.yaxis.set_major_formatter(lat_formatter)
ax.xaxis.set_major_formatter(long_formatter)
ax.set_xticks(np.arange(lons[0], lons[1] + 1, 20), crs=ccrs.PlateCarree()) #Hide end points of longitude tickmarks
ax.set_yticks(np.arange(-20, 20 + 1, 10), crs=ccrs.PlateCarree()) #Hide end points of latitude tickmarks
cbar_ax = fig.add_axes([0.95, 0.25, 0.02, 0.5]) #[left, bottom, width, height]
plt.colorbar(cf, cax=cbar_ax, orientation='vertical', label='SST(°C)')
plt.show()
完整代码
import numpy as np
import xarray as xr
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import cartopy.mpl.ticker as cticker
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pylab as pylab
data = xr.open_dataset(r"sst.mnmean.nc")
ssta = (data.sst.sel(time = slice("2015", "2015")) - data.sst.sel(time = slice("1990", "2020")).mean("time")).mean("time")
params = {'legend.fontsize':15,
'axes.labelsize':16.5,
'axes.titlesize':14.5,
'xtick.labelsize':14.5,
'ytick.labelsize':14.5}
cmap_temp = plt.get_cmap('RdBu_r')
pylab.rcParams.update(params)
fig = plt.figure(figsize=(12, 8), dpi=300)
ax = plt.subplot(111, projection=ccrs.PlateCarree(
central_longitude = 180))
land = cfeature.NaturalEarthFeature('physical', 'land', '50m')
ax.add_feature(land, color='lightgray', zorder=-1)
regions = ['Niño4', 'Niño3.4', 'Niño3', 'Niño1+2']
cols = ['r', 'k', 'b', 'k']
minlats = [-5, -5.5, -5, -10]
maxlats = [5, 5.5, 5, 0]
minlons = [160, 190, 210.5, 269.5]
maxlons = [209.5, 240, 270.5, 280]
xlocs = [163, 204, 257, 262]
ylocs = [6, -10, 6, -14]
lats = [-23, 23]
lons = [140, 280]
cf = ax.contourf(data.lon, data.lat, ssta[:],
cmap = cmap_temp,
levels = np.linspace(-2, 2, 101),
extend = 'both',
transform = ccrs.PlateCarree())
ax.coastlines()
ax.set_title('Nino SSTA', loc='center', fontweight = 'bold')
ax.set_extent([lons[0], lons[1], lats[0], lats[1]], ccrs.PlateCarree())
ax.set_xlabel('Longitude ($^{\circ}$E)')
ax.set_ylabel('Latitude ($^{\circ}$N)')
ax.set_title('')
for i in range(len(regions)):
ax.add_patch(Rectangle((minlons[i], minlats[i]), (maxlons[i]- minlons[i]), abs(maxlats[i] - minlats[i]),
fill=False, linestyle='--', linewidth = 1.5, color=cols[i], transform=ccrs.PlateCarree()));
ax.text(xlocs[i], ylocs[i], regions[i], fontsize=12, fontweight='bold', color = cols[i], transform = ccrs.PlateCarree())
lat_formatter = cticker.LatitudeFormatter()
long_formatter = cticker.LongitudeFormatter()
ax.yaxis.set_major_formatter(lat_formatter)
ax.xaxis.set_major_formatter(long_formatter)
ax.set_xticks(np.arange(lons[0], lons[1] + 1, 20), crs=ccrs.PlateCarree()) #Hide end points of longitude tickmarks
ax.set_yticks(np.arange(-20, 20 + 1, 10), crs=ccrs.PlateCarree()) #Hide end points of latitude tickmarks
cbar_ax = fig.add_axes([0.95, 0.25, 0.02, 0.5]) #[left, bottom, width, height]
plt.colorbar(cf, cax=cbar_ax, orientation='vertical', label='SST(°C)')
plt.show()
Output
Reference
Trenberth, Kevin & National Center for Atmospheric Research Staff (Eds). Last modified 2024-03-20 "The Climate Data Guide: Nino SST Indices (Nino 1+2, 3, 3.4, 4; ONI and TNI).
往期回顾
Python | MJO | 位相图 Python | 半球间经度转换 Python | 大气科学 | 偏相关 Python | 气象绘图 | 台风降水 Python | 解决 cmaps 库报错的问题 Python | 批量下载 NCEP2 再分析数据 Python | 北大西洋涛动 | NAO 指数 | EOF