Wavelet & Fourier Analysis on the ENSO and monsoon data ... https://towardsdatascience.com/wavelet-fourier-analysis-on-t...
1 of 10 10/14/2021, 10:20 AM
Wavelet & Fourier Analysis on the ENSO and monsoon data ... https://towardsdatascience.com/wavelet-fourier-analysis-on-t...
2 of 10 10/14/2021, 10:20 AM
Wavelet & Fourier Analysis on the ENSO and monsoon data ... https://towardsdatascience.com/wavelet-fourier-analysis-on-t...
3 of 10 10/14/2021, 10:20 AM
Wavelet & Fourier Analysis on the ENSO and monsoon data ... https://towardsdatascience.com/wavelet-fourier-analysis-on-t...
import pywt
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
plt.style.use('seaborn')
dataset = "monsoon.txt"
df_nino = pd.read_table(dataset, skiprows=19,
header=None)
N = df_nino.shape[0]
t0 = 1871
dt = 0.25
time = np.arange(0, N) * dt + t0
signal = df_nino.values.squeeze() #to get the scalar
values
signal = signal - np.mean(signal)
scales = np.arange(1, 128) #set the wavelet scales
def plot_signal(time, signal, average_over=5,
figname=None):
fig, ax = plt.subplots(figsize=(15, 3))
ax.plot(time, signal, label='signal')
4 of 10 10/14/2021, 10:20 AM
Wavelet & Fourier Analysis on the ENSO and monsoon data ... https://towardsdatascience.com/wavelet-fourier-analysis-on-t...
ax.set_xlim([time[0], time[-1]])
ax.set_ylabel('Signal Amplitude', fontsize=18)
# ax.set_title('Signal + Time Average',
fontsize=18)
ax.set_xlabel('Time', fontsize=18)
ax.legend()
if not figname:
plt.savefig('signal_plot.png', dpi=300,
bbox_inches='tight')
else:
plt.savefig(figname, dpi=300,
bbox_inches='tight')
plt.close('all')
plot_signal(time, signal) #plot and label the axis
read_table
monsoon.txt
wavelet_visualize
def get_fft_values(y_values, T, N, f_s):
f_values = np.linspace(0.0, 1.0/(2.0*T), N//2)
fft_values_ = np.fft.fft(y_values)
fft_values = 2.0/N * np.abs(fft_values_[0:N//2])
return f_values, fft_values
def plot_fft_plus_power(time, signal, figname=None):
dt = time[1] - time[0]
N = len(signal)
5 of 10 10/14/2021, 10:20 AM
Wavelet & Fourier Analysis on the ENSO and monsoon data ... https://towardsdatascience.com/wavelet-fourier-analysis-on-t...
fs = 1/dt
fig, ax = plt.subplots(2, 1, figsize=(15, 3),
sharex=True)
variance = np.std(signal)**2
f_values, fft_values = get_fft_values(signal, dt,
N, fs)
fft_power = variance * abs(fft_values) ** 2 # FFT
power spectrum
ax[0].plot(f_values, fft_values, 'r-',
label='Fourier Transform')
ax[1].plot(f_values, fft_power, 'k--',
linewidth=1, label='FFT Power Spectrum')
ax[1].set_xlabel('Frequency [Hz / year]',
fontsize=18)
ax[1].set_ylabel('Amplitude', fontsize=12)
ax[0].set_ylabel('Amplitude', fontsize=12)
ax[0].legend()
ax[1].legend()
# plt.subplots_adjust(hspace=0.5)
if not figname:
plt.savefig('fft_plus_power.png', dpi=300,
bbox_inches='tight')
else:
plt.savefig(figname, dpi=300,
bbox_inches='tight')
plt.close('all')
plot_fft_plus_power(time, signal)
def plot_wavelet(time, signal, scales,
waveletname='cmor1.5-1.0', cmap=plt.cm.seismic,
title='Wavelet Transform (Power Spectrum) of signal',
ylabel='Period (years)', xlabel='Time', figname=None):
dt = time[1] - time[0]
6 of 10 10/14/2021, 10:20 AM
Wavelet & Fourier Analysis on the ENSO and monsoon data ... https://towardsdatascience.com/wavelet-fourier-analysis-on-t...
[coefficients, frequencies] = pywt.cwt(signal,
scales, waveletname, dt)
power = (abs(coefficients)) ** 2
period = 1. / frequencies
scale0 = 8
numlevels = 10
levels = [scale0]
for ll in range(1, numlevels):
scale0 *= 2
levels.append(scale0)
contourlevels = np.log2(levels)
fig, ax = plt.subplots(figsize=(15, 10))
im = ax.contourf(time, np.log2(period),
np.log2(power),
contourlevels, extend='both',
cmap=cmap)
ax.set_title(title, fontsize=20)
ax.set_ylabel(ylabel, fontsize=18)
ax.set_xlabel(xlabel, fontsize=18)
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.invert_yaxis()
ylim = ax.get_ylim()
ax.set_ylim(ylim[0], -1)
cbar_ax = fig.add_axes([0.95, 0.15, 0.03, 0.7])
fig.colorbar(im, cax=cbar_ax,
orientation="vertical")
if not figname:
plt.savefig('wavelet_{}.png'.format(waveletname),
dpi=300, bbox_inches='tight')
else:
plt.savefig(figname, dpi=300,
bbox_inches='tight')
plt.close('all')
plot_wavelet(time, signal, scales)
7 of 10 10/14/2021, 10:20 AM
Wavelet & Fourier Analysis on the ENSO and monsoon data ... https://towardsdatascience.com/wavelet-fourier-analysis-on-t...
8 of 10 10/14/2021, 10:20 AM
Wavelet & Fourier Analysis on the ENSO and monsoon data ... https://towardsdatascience.com/wavelet-fourier-analysis-on-t...
9 of 10 10/14/2021, 10:20 AM
Wavelet & Fourier Analysis on the ENSO and monsoon data ... https://towardsdatascience.com/wavelet-fourier-analysis-on-t...
10 of 10 10/14/2021, 10:20 AM