Python | ENSO | Nino区绘制

文摘   2024-10-13 16:05   北京  

ENSO

厄尔尼诺-南方涛动(ENSO) 是地球上最重要的气候现象之一,因为它能够改变全球大气环流,进而影响全球温度和降水。我们关注 ENSO 的另一个重要原因在于,它的出现通常可以提前多个季节预测,从而让人类能够在其对天气和气候产生最强影响之前做出准备。

虽然 ENSO 是一个单一的气候现象,但它可以处于三种状态或阶段。两个相对的阶段是El NiñoLa Niña,由于 ENSO 是一个耦合的气候现象,这两种状态都需要海洋和大气的某些变化。中性则处于这两个事件的中间位置。

  1. El Niño:热带太平洋中部和东部的海洋表面变暖,或高于平均海面温度(SST)。印度尼西亚的降雨量往往会减少,而热带太平洋的降雨量则会增加。通常沿着赤道从东向西吹的信风反而减弱,或者在某些情况下开始向另一个方向吹(从西向东或西风)。

  2. La Niña:热带太平洋中部和东部的海洋表面变冷,或低于平均海面温度 (SST)。印度尼西亚的降雨量趋于增加,而热带太平洋中部的降雨量趋于减少。沿赤道的正常东风变得更强。

  3. 中性:既不是El Niño,也不是La Niña。热带太平洋海表温度通常接近平均水平。然而,在某些情况下,海洋看起来可能处于El NiñoLa Niña状态,但大气层并没有发挥作用(反之亦然)。

Nino指数

有多种指数用于监测热带太平洋,所有这些指数均基于特定区域的平均海面温度(SST)异常。通常,异常值是相对于 30 年的基期计算的。Niño 3.4 指数和海洋 Niño 指数 (ONI) 是定义El NiñoLa Niña事件最常用的指数。其他指数用于帮助描述每个事件的独特性质。

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ñoLa Niña事件的首选。

  • Niño 3.4区(5N-5S,170W-120W):该区的海温异常可以代表从日界线到南美洲海岸的赤道太平洋的平均海温。这个区域的指数通常使用5个月的滑动平均值,当El Niño 3.4区域的海温超过(低于)+(-)0.4°C并持续六个月或更长时间时,就定义为El NiñoLa Niña事件。

  • ONI(5N-5S,170W-120W):该区使用与El Niño 3.4区域相同的区域。ONI使用3个月的滑动平均值,要被归类为一次成熟的El NiñoLa 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=(128), 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 = [55.550]
minlons = [160190210.5269.5]
maxlons = [209.5240270.5280]
xlocs = [163204257262]
ylocs = [6-106-14]
lats = [-2323]
lons = [140280]

cf = ax.contourf(data.lon, data.lat, ssta[:],
                  cmap = cmap_temp,
                    levels = np.linspace(-22101),
                    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] + 120), crs=ccrs.PlateCarree()) #Hide end points of longitude tickmarks
ax.set_yticks(np.arange(-2020 + 110), crs=ccrs.PlateCarree()) #Hide end points of latitude tickmarks
cbar_ax = fig.add_axes([0.950.250.020.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=(128), 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 = [55.550]
minlons = [160190210.5269.5]
maxlons = [209.5240270.5280]
xlocs = [163204257262]
ylocs = [6-106-14]
lats = [-2323]
lons = [140280]

cf = ax.contourf(data.lon, data.lat, ssta[:],
                  cmap = cmap_temp,
                    levels = np.linspace(-22101),
                    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] + 120), crs=ccrs.PlateCarree()) #Hide end points of longitude tickmarks
ax.set_yticks(np.arange(-2020 + 110), crs=ccrs.PlateCarree()) #Hide end points of latitude tickmarks
cbar_ax = fig.add_axes([0.950.250.020.5])  #[left, bottom, width, height]
plt.colorbar(cf, cax=cbar_ax, orientation='vertical', label='SST(°C)')
plt.show()

Output

Nino区

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风雨
主要发一些涉及大气科学的Python文章与个人学习备忘录
 最新文章