用Python复现气象顶刊图表:手把手教你做小波分析(附Torrence-Compo代码)

张开发
2026/4/17 11:52:16 15 分钟阅读

分享文章

用Python复现气象顶刊图表:手把手教你做小波分析(附Torrence-Compo代码)
Python气象科研实战从Torrence-Compo代码到顶刊级小波分析图表第一次看到《地理科学》那篇长江中下游降水研究的功率谱图时我被那些优美的等高线圈和醒目的显著性区域震撼到了——这不正是我论文需要的关键证据吗但当我打开MATLAB准备复现时面对一堆看不懂的cwt函数参数和神秘的影响锥概念整整两周毫无进展。直到我发现科罗拉多大学Torrence和Compo教授那篇被引7000次的经典论文以及Predybaylo博士移植的Python版本才真正打开了小波分析的大门。1. 环境配置与数据准备工欲善其事必先利其器。我们先搭建一个专为气象数据分析优化的Python环境conda create -n wavelet python3.8 conda install -c conda-forge numpy scipy matplotlib jupyterTorrence-Compo官方代码库提供了两个关键文件waveletFunctions.py核心算法模块waveletAnalysis.py示例分析脚本建议直接克隆原始仓库import urllib.request urllib.request.urlretrieve( https://raw.githubusercontent.com/chris-torrence/wavelets/master/python/waveletFunctions.py, waveletFunctions.py )准备你的时间序列数据时要注意数据应该是一维数组如某站点的年降水量序列缺失值需提前处理线性插值或剔除时间间隔dt要准确设置月数据为1/12年数据为1import numpy as np # 示例南京站1901-2020年夏季降水量(mm) nanjing_rain np.array([...]) dt 1 # 年数据2. 小波变换核心参数解析运行小波变换前这些参数决定了分析的质量# 关键参数设置 pad 1 # 推荐填充零值到2的幂次长度 dj 0.25 # 尺度间隔每octave分4个子尺度 s0 2*dt # 最小尺度2倍时间间隔 J1 7/dj # 尺度数量 mother MORLET # 小波母函数Morlet小波的波形控制参数k0尤为重要k06默认平衡时频分辨率k06时间分辨率↑频率分辨率↓k06频率分辨率↑时间分辨率↓气象数据通常使用k06生物医学信号可能用k02通过调整这些参数我曾发现某期刊论文中声称的20年周期其实是参数设置不当导致的伪信号——把dj从0.5改为0.25后那个显著峰就消失了。3. 结果可视化与学术规范得到小波功率谱后如何制作符合顶刊要求的图表看这段改进版的绘图代码def plot_wavelet(time, data, wave, period, coi, sig95, global_ws, global_sig): plt.figure(figsize(10, 8)) # 时间序列子图 plt.subplot(3, 1, 1) plt.plot(time, data, k, linewidth1.5) plt.ylabel(Precipitation (mm)) plt.title(a) Nanjing Summer Rainfall Anomalies) # 功率谱子图 plt.subplot(3, 1, 2) levels np.linspace(0, np.max(power), 20) plt.contourf(time, period, power, levels, cmapjet) plt.colorbar(labelPower (°C²)) plt.contour(time, period, sig95, [1], colorsk, linewidths2) plt.plot(time, coi, k--) plt.yscale(log) plt.ylabel(Period (years)) plt.title(b) Wavelet Power Spectrum) # 全局谱子图 plt.subplot(3, 1, 3) plt.plot(global_ws, period, k, labelPower) plt.plot(global_sig, period, r--, label95% significance) plt.yscale(log) plt.xlabel(Power (°C²)) plt.title(c) Global Wavelet Spectrum)几个让审稿人眼前一亮的细节使用jet色带增强冷暖对比显著性检验线加粗到2pt子图标题用a)、b)编号坐标标签带单位影响锥(COI)用虚线表示4. 高级分析与论文写作技巧小波分析结果如何转化为论文中的科学发现这里有个真实案例发现1交叉小波揭示遥相关# 计算两个序列的交叉小波谱 cross_power np.abs(wave1 * wave2.conj())发现2尺度平均方差突显年代际变化# 计算2-8年尺度平均 scale_avg (scale 2) (scale 8) avg_power np.mean(power[scale_avg, :], axis0)在论文方法部分要注明 小波分析采用Torrence和Compo(1998)的方法显著性检验基于红噪声背景谱(滞后1自相关0.72)讨论部分可以这样写 3.6年的显著周期(图3b)与ENSO的典型周期一致这与Wang等(2017)的发现相吻合。但值得注意的是在1980年后该周期信号明显减弱可能反映了太平洋年代际振荡(PDO)相位转变的影响。5. 常见陷阱与解决方案问题1边界效应失真对策始终关注COI曲线外的结果不可靠代码检查coi_mask np.tile(period, (len(time),1)).T np.tile(coi, (len(period),1)) power[coi_mask] np.nan问题2虚假显著周期对策尝试不同的lag1自相关值诊断代码for lag1 in [0.6, 0.7, 0.8]: sig95 wave_signif(variance, dt, scale, lag1lag1) # 比较不同lag1下的显著区域变化问题3尺度分辨率不足现象周期轴出现阶梯状伪影改进减小dj到0.125增加J1到56那次我帮学弟检查论文发现他漏掉了COI区域的数据筛选差点把边界效应导致的伪信号当作重大发现。现在他的致谢里还留着我的名字——科学研究的严谨性就体现在这些细节里。

更多文章