import numpy as np
import xarray as xr
import matplotlib.pyplot as plt

%matplotlib inline

厄尔尼诺/拉尼娜 (El Nino/La Nina) 现象

https://www.ncdc.noaa.gov/teleconnections/enso/indicators/sst.php

El Niño (La Niña) 现象指的是热带太平洋海面温度(Sea Surface Temperature, SST)随时间的震荡变化。El Niño 时,该平均海温比长期平均值高,而 La Niña 时,该平均海温较长期平均值低。通常以 0.5 °C 为阈值(即高出0.5 °C或低于-0.5 °C才认为发生 El Niño/La Niña 现象)。计算时通常取3个月的滚动平均值,并需要连续5个月满足条件,才会认定该年份为 El Niño 或 La Niña 年,否则为中性年。该温度差值被称为 Oceanic Niño Index (ONI)。

El Niño (La Niña) is a phenomenon in the equatorial Pacific Ocean characterized by a five consecutive 3-month running mean of sea surface temperature (SST) anomalies in the Niño 3.4 region that is above (below) the threshold of +0.5°C (-0.5°C). This standard of measure is known as the Oceanic Niño Index (ONI).

如上图所示,ONI 可以在多个区域进行计算。常用的为 Nino3.4(对应图中标示为3.4的区域),即 5°N - 5°S,120 - 170°W。Nino3.4 结果如下图:

数据

我们使用 NOAA 的 Extended Reconstructed Sea Surface Temperature (ERSST) V5 (https://www.esrl.noaa.gov/psd/data/gridded/data.noaa.ersst.v5.html) 月平均温度数据来计算 Nino3.4 指数,并绘出上面的图。

sst = xr.open_dataarray('sst.mnmean.1950-2019.nc')
sst
<xarray.DataArray 'sst' (time: 840, lat: 89, lon: 180)>
[13456800 values with dtype=float32]
Coordinates:
  * lat      (lat) float32 88.0 86.0 84.0 82.0 80.0 ... -82.0 -84.0 -86.0 -88.0
  * lon      (lon) float32 0.0 2.0 4.0 6.0 8.0 ... 350.0 352.0 354.0 356.0 358.0
  * time     (time) datetime64[ns] 1950-01-01 1950-02-01 ... 2019-12-01
Attributes:
    long_name:     Monthly Means of Sea Surface Temperature
    units:         degC
    var_desc:      Sea Surface Temperature
    level_desc:    Surface
    statistic:     Mean
    dataset:       NOAA Extended Reconstructed SST V5
    parent_stat:   Individual Values
    actual_range:  [-1.8     42.32636]
    valid_range:   [-1.8 45. ]

注意经度是 0 - 360 度,纬度是 88 - -88 度 (逆序)

sst.mean(dim='time').plot(vmin=-2, vmax=30)
/Users/lixx/miniconda3/lib/python3.7/site-packages/xarray/core/nanops.py:142: RuntimeWarning: Mean of empty slice
  return np.nanmean(a, axis=axis, dtype=dtype)
<matplotlib.collections.QuadMesh at 0x11f0a76d0>
../_images/Exercise_El_Nino_8_2.png

作业1

请将上图进行美化:

  • 将经度改为 -180 - 180 度

  • 增加投影信息(PlateCarree)

  • 加上海岸线

  • 在坐标轴标签改成格式化的经纬度 (如 90°E,20°N等)

  • 将坐标轴的标题(‘Longitude’,’Latitude‘)去掉

# 你的代码
sst_zonal_time_mean = sst.mean(dim=('time', 'lon'))
sst_zonal_time_mean.plot()
[<matplotlib.lines.Line2D at 0x11f761ed0>]
../_images/Exercise_El_Nino_12_1.png

我们可以来看看海温异常(anomaly)随时间和纬度的变化

(sst.mean(dim='lon') - sst_zonal_time_mean).T.plot()
/Users/lixx/miniconda3/lib/python3.7/site-packages/xarray/core/nanops.py:142: RuntimeWarning: Mean of empty slice
  return np.nanmean(a, axis=axis, dtype=dtype)
<matplotlib.collections.QuadMesh at 0x117605390>
../_images/Exercise_El_Nino_14_2.png

不同纬度处的海温变化幅度是不同的

sst.sel(lon=120, lat=17, method='nearest').plot(color='r')
sst.sel(lon=120, lat=0, method='nearest').plot(color='b')
[<matplotlib.lines.Line2D at 0x11f3f8ad0>]
../_images/Exercise_El_Nino_16_1.png

SST 异常(anomaly)

# 气候(即长期平均值)
sst_clim = sst.groupby('time.month').mean(dim='time')
sst_clim.sel(lon=120, lat=17, method='nearest').plot()
/Users/lixx/miniconda3/lib/python3.7/site-packages/xarray/core/nanops.py:142: RuntimeWarning: Mean of empty slice
  return np.nanmean(a, axis=axis, dtype=dtype)
[<matplotlib.lines.Line2D at 0x11f8a0d10>]
../_images/Exercise_El_Nino_18_2.png
# Hovmoller 图
sst_clim.mean(dim='lon').T.plot.contourf(levels=np.arange(-2,32))
/Users/lixx/miniconda3/lib/python3.7/site-packages/xarray/core/nanops.py:142: RuntimeWarning: Mean of empty slice
  return np.nanmean(a, axis=axis, dtype=dtype)
<matplotlib.contour.QuadContourSet at 0x11c49ccd0>
../_images/Exercise_El_Nino_19_2.png

我们可以计算海温的异常值(即瞬时值 - 气候)

sst_anom = sst.groupby('time.month') - sst_clim
sst_anom.sel(lon=120, lat=17, method='nearest').plot()
[<matplotlib.lines.Line2D at 0x11bb3a610>]
../_images/Exercise_El_Nino_21_1.png
sst_anom.std(dim='time').plot()
/Users/lixx/miniconda3/lib/python3.7/site-packages/numpy/lib/nanfunctions.py:1667: RuntimeWarning: Degrees of freedom <= 0 for slice.
  keepdims=keepdims)
<matplotlib.collections.QuadMesh at 0x11bcf1410>
../_images/Exercise_El_Nino_22_2.png

作业2

绘制 NOAA 的 Nino3.4 曲线图 (本文件从上往下数第2张图)

  • 计算Nino3.4区域内的海温异常的空间平均值(即对经度和纬度求平均)

  • 对该平均值再求3个月滚动平均,命名为 oni

  • 绘制3个月滚动平均随时间的变化

  • 对正、负值进行填色

  • 画出 0.5,0, -0.5 °C 三条横线,其中 0 为实线,其它两条为虚线 ax.axhline()

  • 修改坐标轴的标题

# 你的代码

对厄尔尼诺/拉尼娜进行聚合分析 Composite analysis

聚合分析是指对性质相似的事件进行归类、取平均,以便归纳同类型事件的特性。此处我们来看厄尔尼诺和拉尼娜现象对应的海温异常分布。

# 创建一个新的 dataarray,其形状和 sst 一样,但是数据类型是分类(category)
# oni 是你在作业2中创建的Nino3.4指数

nino34 = xr.full_like(oni, 'none', dtype='U4')
nino34[oni >= 0.5] = 'nino'
nino34[oni <= -0.5] = 'nina'
nino34

作业3

  • 根据上面的 nino3.4,对 sst_anom 进行分类,并求平均

  • 分别画出厄尔尼诺和拉尼娜时的 sst_anom 空间分布图。注意:要按照作业1的美观要求进行绘制。

# 你的代码