Search code examples
pythonpython-3.xmatlabsignal-processingwavelet

Why does the y-axis have to be flipped for a cwt analysis in Python to compare to the Matlab cwt function


For the audio file found here, I am using the ssqueezepy library in Python to generate the cwt of the signal. Here is my Python code:

import librosa
import librosa.display
import numpy as np
from ssqueezepy import cwt
from ssqueezepy.visuals import plot, imshow
import numpy as np
import matplotlib.pyplot as plt
import soundfile as sf

# Set the path to the Binary Class dataset
input_file = (r'G:/audio/AWCK AR AK 47 Close 01_trim-pt5_16bit_norm-1_Mono.wav')


[data1, sample_rate1] = sf.read(input_file)
#[sample_rate1, data1] = wav.read(input_file);
duration = len(data1)/sample_rate1

time = np.arange(0, duration, 1/sample_rate1) #time vector

 
#%%##############            Take CWT & plot                ##################################################
Wx, scales = cwt(data1, 'morlet')
imshow(Wx, yticks=scales, abs=1,
       title="abs(CWT) | Morlet wavelet",
       ylabel="scales", xlabel="samples")

plt.show()

Here is the resulting scalogram:

enter image description here

When I use Matlab:

%% preparing dataset

input_file = ['G:\audio\AWCK AR AK 47 Close 01_trim-pt5_16bit_norm-1_Mono.wav'];
 
[y,Fs] = audioread(input_file);
   
%% Display scalogram

cwt(y, "bump", Fs)

I get this plot:

enter image description here

When you look at the y-axis, Python has the y-axis inverted but then both the Python and Matlab plot looks similar.

Can you give an explanation as to why there is a difference? How to make Python match up with Matlab on the axis perspective?


Solution

  • Have a look at this GitHub package scaleogram, which builds on PyWavelet but can make a plot that looks more like the Matlab output.

    Basically, the scale at which you observe the signal becomes larger (less detail) at higher levels of decomposition. In the simplest case with discrete levels where the scale doubles at every level (you can think of the scale as the length of the filters at each level), you get this:

    level scale frequency
    0 2 256
    1 4 128
    2 8 64
    3 16 32
    4 32 16
    5 64 8
    6 128 4
    7 256 2

    As you can see the scale and frequency change exponentially with level, and this is what you see in the Pywavelet (scale) and Matlab (frequency) plots, respectively. The Matlab plot uses a logarithmic scale for the y ticks (only every power of 10) which I think is a bit easier on the eye. The scaleogram package controls the units on the y axis at this line.