近来小编花销见涨,但收益不见涨,遂将积压的老代码做一下付费。这个主题针对一个2020年的enso文献《Mid-latitude leading double-dip La Niña》做一下复现,大概出个六七期。如有疏漏还望指出。如需数据可以通过公众号后台联系。
Hovmöller 图(时间-经度/纬度图)是气象和海洋学中分析波动传播(如 Kelvin 波、Rossby 波)和气候事件(如 ENSO)演化的核心工具。
在 《Mid-latitude leading double-dip La Niña》 的 Figure 1 中,作者通过 Hovmöller 图对比了单年型 (Single-year) 与 多年型 (Multi-year) La Niña 事件在赤道太平洋海温 (SSTA) 和风应力异常上的演变特征。
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd
import os
# --- 配置 ---
DATA_DIR = r"./data"
SST_FILE = f"{DATA_DIR}/sst.mnmean.nc"
TAUX_FILE = f"{DATA_DIR}/uflx.mon.mean.nc"
TAUY_FILE = f"{DATA_DIR}/vflx.mon.mean.nc"
# 论文 Table 1 中的事件年份
SINGLE_YEAR_EVENTS = [1964, 1988, 1995, 2005]
MULTI_YEAR_EVENTS = [1949, 1954, 1970, 1973, 1998, 2007, 2010]
# 气候态周期
CLIM_START = '1981-01-01'
CLIM_END = '2010-12-31'
# 分析范围
LON_RANGE = slice(120, 280) # 120E to 80W
LAT_EQ_RANGE = slice(-5, 5) # 赤道平均范围 (5S-5N)
LAT_OFF_EQ_RANGE = slice(0, 15) # 副热带范围 (0-15N)
Hovmöller 图的 Y 轴是时间,X 轴是经度。我们将在此叠加海温 (Shade)、风应力旋度 (Contour) 和纬向风应力 (Vector)。
def plot_reproduction():
# 加载 SST 并计算异常
ds_sst = xr.open_dataset(SST_FILE).sortby('lat')
sst_anom = calculate_anomaly(ds_sst, 'sst')
sst_hov_raw = sst_anom.sel(lat=LAT_EQ_RANGE, lon=LON_RANGE).mean(dim='lat')
# 合成数据
comp_sst_single = get_composite(sst_hov_raw, SINGLE_YEAR_EVENTS)
comp_sst_multi = get_composite(sst_hov_raw, MULTI_YEAR_EVENTS)
lons = sst_hov_raw.lon.values
months = np.arange(36)
fig, axes = plt.subplots(1, 2, figsize=(12, 8), sharey=True)
levels = np.arange(-2.0, 2.1, 0.2)
for i, (data, title) in enumerate(zip([comp_sst_single, comp_sst_multi],
["(a) Single-year La Niña", "(b) Multi-year La Niña"])):
ax = axes[i]
cf = ax.contourf(lons, months, data, levels=levels, cmap='RdBu_r', extend='both')
ax.set_title(title, fontsize=14)
ax.set_ylim(35, 0) # 时间由上往下
ax.set_xticks(np.arange(120, 281, 40))
ax.set_xticklabels(["120E", "160E", "160W", "120W", "80W"])
ax.set_yticks([0, 12, 24, 35])
ax.set_yticklabels(["Jan(-1)", "Jan(0)", "Jan(+1)", "Dec(+1)"])
fig.colorbar(cf, ax=axes, orientation='horizontal', label='SSTA (°C)', pad=0.1)
plt.show()
plot_reproduction()
复现图

figure1_reproduction
原图

import xarray as xr