首页
学习
活动
专区
圈层
工具
发布
44 篇文章
1
机器学习需要掌握的九种工具!
2
PyAOS:大气和海洋科学Python社区
3
地球人工智能研究综述
4
优化物理和机器学习之间的协同作用
5
构建便于气象海洋应用的Anaconda环境(window版本)
6
Python结合Matlab气候数据工具箱CDT
7
用Python复现一篇Nature的研究: 1.数据下载及预处理
8
Python气象数据处理与绘图:相关性分析之散点图
9
Nature | 数据驱动的地球系统深度学习与过程理解
10
Python气象数据处理与绘图:常见的10种图像滤波方法
11
JAMES: 地球系统模式机器学习应用专刊
12
Python可视化 | xarray绘图样式配置
13
xarray系列|WRF模式前处理和后处理
14
Python可视化 | xarray一维数据绘图
15
构建适合大气与海洋应用的Anaconda环境
16
统计学中数据分析方法汇总!
17
Python可视化 | xarray 绘图时序图
18
深度学习 | 时序问题LSTM入门讲解
19
Python可视化 | xarray 二维绘图配色方案设置
20
MeteoInfoLab中如何将格点插值到站点?(附完整代码)
21
利用 pandas 和 xarray 整理气象站点数据
22
tensor与numpy数据类型转换
23
【机器学习基础】|交叉验证及Stacking
24
让数据动起来!用Python制作动画可视化效果,让数据不再枯燥!
25
数据处理 | EOF用法及可视化实例
26
数据处理 | 使用cfgrib加载GRIB文件
27
GISer如何学Python
28
数据下载 | NCEP再分析数据自动批量下载
29
关于滤波和NCL的filwgts_lanczos函数
30
数据处理 | xarray的计算距平、重采样、时间窗
31
数据处理 | xarray的NC数据基础计算(1)
32
基于Python的神经网络模型可视化绘图方法
33
python可视化 | 小波分析——​海温数据的时频域分解
34
Python精美地理可视化绘制
35
Python的常用库的数组定义及常用操作
36
Python可视化 | 温度、水深&CTRL向量空间分布图
37
python可视化 | contour、contourf、cartopy补充
38
NCL专辑 | 常用插值函数集锦
39
数值模式常用参数化方案简析及引用文献
40
数据处理与可视化 | 站点插值格点+空间区域掩膜
41
自动化工程 | 利用Python自动生成降雨量统计分析报告
42
图解NumPy:常用函数的内在机制
43
用手机运行你的Python代码
44
数据可视化 | 双Y轴可视化绘制方法(Python、R两种方法)

python可视化 | 小波分析——​海温数据的时频域分解

模块安装

使用到的库是pycwt,安装非常简单,直接使用pip即可

代码语言:javascript
复制
pip install pycwt

导入模块

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt
import pycwt as wavelet
from pycwt.helpers import find
from matplotlib.pyplot import MultipleLocator

下载数据

代码语言:javascript
复制
# 从网页获取数据
url = 'http://paos.colorado.edu/research/wavelets/wave_idl/nino3sst.txt'
dat = np.genfromtxt(url, skip_header=19)
print(dat.shape)
代码语言:javascript
复制
(504,)

设置参数

代码语言:javascript
复制
title = 'NINO3 Sea Surface Temperature'   # 标题
label = 'NINO3 SST'                       # 标签 
units = 'degC'                            # 单位
t0 = 1871.0                               # 开始的时间,以年为单位
dt = 0.25                                 # 采样间隔,以年为单位
N = dat.size                              # 时间序列的长度
t = np.arange(0, N) * dt + t0             # 构造时间序列数组

去趋势&标准化

代码语言:javascript
复制
p = np.polyfit(t - t0, dat, 1)               # 线性拟合
dat_notrend = dat - np.polyval(p, t - t0)    # 去趋势
std = dat_notrend.std()                      # 标准差
var = std ** 2                               # 方差
dat_norm = dat_notrend / std                 # 标准化

选择小波基函数

代码语言:javascript
复制
mother = wavelet.Morlet(6)      # Monther Wavelet: Morlet 
s0 = 2 * dt                     # Starting scale, in this case 2 * 0.25 years = 6 months
dj = 0.25                       # Twelve sub-octaves per octaves
J = 7 / dj                      # Seven powers of two with dj sub-octaves
alpha, _, _ = wavelet.ar1(dat)  # Lag-1 autocorrelation for red noise

计算小波变换(wave)和逆小波变换(iwave)

代码语言:javascript
复制
wave, scales, freqs, coi, fft, fftfreqs = wavelet.cwt(dat_norm, dt, dj, s0, J, mother)
iwave = wavelet.icwt(wave, scales, dt, dj, mother) * std

计算小波能量谱

能量谱也叫能量谱密度,能量谱密度描述了信号或时间序列的能量如何随频率分布。能量谱是原信号傅立叶变换的平方。

代码语言:javascript
复制
power = np.power(np.abs(wave),2)
fft_power = np.power(np.abs(fft),2)
period = 1 / freqs
#power /= scales[:,None]

计算小波功率谱

功率谱是功率谱密度函数,它定义为单位频带内的信号功率,是针对功率信号来说的。求功率谱就有了两种方法,分别叫做直接法和相关函数法:1、(傅立叶变换的平方)/(区间长度);2、自相关函数的傅里叶变换。

代码语言:javascript
复制
signif, fft_theor = wavelet.significance(1.0, dt, scales, 0, alpha,
                                         significance_level=0.95,
                                         wavelet=mother)
sig95 = np.ones([1, N]) * signif[:, None]
sig95 = power / sig95
代码语言:javascript
复制
glbl_power = power.mean(axis=1)
dof = N - scales                   # Correction for padding at edges
glbl_signif, tmp = wavelet.significance(var, dt, scales, 1, alpha,
                                        significance_level=0.95, dof=dof,
                                        wavelet=mother)

计算小波方差

代码语言:javascript
复制
sel = find((period >= 2) & (period < 8))
Cdelta = mother.cdelta
scale_avg = (scales * np.ones((N, 1))).transpose()
scale_avg = power / scale_avg  # As in Torrence and Compo (1998) equation 24
scale_avg = var * dj * dt / Cdelta * scale_avg[sel, :].sum(axis=0)
scale_avg_signif, tmp = wavelet.significance(
    var, dt, scales, 2, alpha,
    significance_level=0.95,
    dof=[scales[sel[0]],
    scales[sel[-1]]],
    wavelet=mother
)

绘制小波分析结果

代码语言:javascript
复制
# Prepare the figure
fig = plt.figure(figsize=(11, 8))

# First sub-plot, the original time series anomaly and inverse wavelet transform.
ax = plt.axes([0.1, 0.75, 0.65, 0.2])
ax.plot(t, iwave, '-', linewidth=1, color=[0.5, 0.5, 0.5])
ax.plot(t, dat, 'k', linewidth=1.5)
ax.set_title('a) {}'.format(title))
ax.set_ylabel(r'{} [{}]'.format(label, units))

# Second sub-plot, the normalized wavelet power spectrum and significance
# level contour lines and cone of influece hatched area. Note that period
# scale is logarithmic.
bx = plt.axes([0.1, 0.37, 0.65, 0.28], sharex=ax)
levels = [0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16]
bx.contourf(t, np.log2(period), np.log2(power), np.log2(levels), extend='both', cmap=plt.cm.viridis)
extent = [t.min(), t.max(), 0, max(period)]

bx.contour(t, np.log2(period), sig95, [-99, 1], colors='k', linewidths=1, extent=extent)
bx.fill(np.concatenate([t, t[-1:] + dt, t[-1:] + dt,t[:1] - dt, t[:1] - dt]),
        np.concatenate([np.log2(coi), [1e-9], np.log2(period[-1:]),np.log2(period[-1:]), [1e-9]]),
        'k', alpha=0.3, hatch='x')
bx.set_title('b) {} Wavelet Power Spectrum ({})'.format(label, mother.name))
bx.set_ylabel('Period (years)')
Yticks = 2 ** np.arange(np.ceil(np.log2(period.min())),np.ceil(np.log2(period.max())))
bx.set_yticks(np.log2(Yticks))
bx.set_yticklabels(Yticks)

# Third sub-plot, the global wavelet and Fourier power spectra and theoretical
# noise spectra. Note that period scale is logarithmic.
cx = plt.axes([0.77, 0.37, 0.2, 0.28], sharey=bx)
cx.plot(glbl_signif, np.log2(period), 'k--')
cx.plot(var * fft_theor, np.log2(period), '--', color='#cccccc')
cx.plot(var * fft_power, np.log2(1/fftfreqs), '-', color='#cccccc',linewidth=1)
cx.plot(var * glbl_power, np.log2(period), 'k-', linewidth=1.5)
cx.set_title('c) Global Wavelet Spectrum')
cx.set_xlabel(r'Power [({})^2]'.format(units))
cx.set_xlim([0, 6])
cx.set_ylim(np.log2([period.min(), period.max()]))
cx.set_yticks(np.log2(Yticks))
cx.set_yticklabels(Yticks)
plt.setp(cx.get_yticklabels(), visible=False)

# Fourth sub-plot, the scale averaged wavelet spectrum.
dx = plt.axes([0.1, 0.07, 0.65, 0.2], sharex=ax)
dx.axhline(scale_avg_signif, color='k', linestyle='--', linewidth=1.)
dx.plot(t, scale_avg, 'k-', linewidth=1.5)
dx.set_title('d) {}--{} year scale-averaged power'.format(2, 8))
dx.set_xlabel('Time (year)')
dx.set_ylabel(r'Average variance [{}]'.format(units))
ax.set_xlim([t.min(), t.max()])
plt.savefig('wavelet_analysis.jpg',dpi=600)
plt.show()

绘制小波方差

代码语言:javascript
复制
Cdelta = mother.cdelta
scale_avg = (scales * np.ones((N, 1))).transpose()
scale_avg = power / scale_avg  # As in Torrence and Compo (1998) equation 24
scale_avg = var * dj * dt / Cdelta * scale_avg[sel, :].sum(axis=0)
scale_avg_signif, tmp = wavelet.significance(var, dt, scales, 2, alpha,
                                             significance_level=0.95,
                                             dof=[scales[0],scales[-1]],
                                             wavelet=mother)
fig = plt.figure(figsize=(14, 6))
ax = fig.add_subplot(111)
ax.plot(t-t0, scale_avg, 'k-')
ax.axhline(scale_avg_signif, color='k', linestyle='--', linewidth=1.)
ax.set_xlim(0,126)
ax.grid()
x_major_locator=MultipleLocator(5)
ax.xaxis.set_major_locator(x_major_locator)

绘制小波系数

代码语言:javascript
复制
fig = plt.figure(figsize=(14, 6))
ax = fig.add_subplot(111)
cf = plt.contourf(t, np.log2(period), np.log2(wave.real), 
                  np.arange(-4,4,0.5), extend='both', cmap=plt.cm.jet)
#plt.clabel(cf,colors='k')
Yticks = 2 ** np.arange(np.ceil(np.log2(period.min())),np.ceil(np.log2(period.max())))
ax.set_yticks(np.log2(Yticks))
ax.set_yticklabels(Yticks)
ax.set_ylabel('Period (years)')
plt.colorbar()

脚本获取

在好奇心Log公众号后台回复小波分析,获取全部代码及图片

R语言专辑 | CMIP5/6各模式之间的相关系数可视化

2021-03-16

学习资源 | 物理海洋学(南信大官方)

2021-03-15

教程 | 如何在Windows 10上安装WSL 2

2021-03-12

美国气象行业如何应用云计算?

2021-03-10

工具推荐 | CDO的介绍与安装

2021-03-09

全国12.5m DEM免费下载!

2021-03-05

下一篇
举报
领券