I am studying the Wavelet transform and I am considering this example that I took from PyWavelets documentation. The signal in time domain has the following shape:
Till the value of zero on the horizontal axis we have a signal with a constant frequency. So I would expect the scalogram to have something like a constant (both in color and in dimension) horizontal stripe at a specific value of the scale (or period or frequency or whatever you want to put on the y axis of the scalogram) till the zero value, while instead it has like vertical stripes that alternate their colors from the extreme violet color to the extreme green. Why ?! This is the image:
From a scalogram like this, I would expect a signal that changes frequencies because the changing of colors means that changing of values of wavelets coefficients and so the changing of similarity between the wavelet and the input signal (since the operation that is done is the convolution between the wavelet and the data). High similarity should mean high coefficients (so green color) while low similarity means low values of coefficients (so violet colors); if the colors changes means that the similarity changes and so also the shape of the signal changes and thus also the frequency. Is this right ? What am I missing ?
Any suggestion would be really appreciated. Thanks in advance.
EDITI:I appreciate the suggestions in the comments below my post but since there has not been an answer to my post and my question has not been closed, I want to share with you that I found a clear explanation in this nice video Wavelets: a mathematical microscope. As Ash pointed out, one should plot the magnitude of a complex wavelet and so one has to consider the convolution with both the real and imaginary part of the wavelet. Hence by following this procedure, I obtain the plot as I expected it to be but with still one problem: the red bar that should be in correspondence of scale value equal to 30 and the distortions (that correspond to signal changing in frequency) should go from 30 to lower scales, in my case is inverted. Why ?
Here is the Python code that I used:
time = np.linspace(-1, 1, 200, endpoint=False)
signal = np.cos(2 * np.pi * 7 * time) + np.real(np.exp(-7*(time-0.4)**2)*np.exp(1j*2*np.pi*2*(time-0.4)))
fig, ax = plt.subplots(figsize=(9, 5))
ax.plot(time,signal)
sns.despine(fig, bottom=False, left=False)
plt.show()
scales = np.arange(1,31)
ylabel = 'Period'
xlabel = 'Time'
waveletname='cgau2'
coef, freqs=pywt.cwt(signal, scales, waveletname)
fig, ax = plt.subplots(figsize=(12, 2))
contourf_ = ax.contourf(time, scales, np.abs(coef), cmap=plt.cm.Reds)#extend='both',
ax.set_title('Wavelet Transform of Signal (${}$)'.format(waveletname), fontsize=20)
ax.set_ylabel('Scales', fontsize=14)
ax.set_xlabel('Time (s)', fontsize=14)
fig.colorbar(contourf_)
plt.show()
EDITII:
#Time domain signal
time = np.linspace(-1, 1, 200, endpoint=False)
signal = np.cos(2 * np.pi * 7 * time) + np.real(np.exp(-7*(time-0.4)**2)*np.exp(1j*2*np.pi*2*(time-0.4)))
fig, ax = plt.subplots(figsize=(9, 5))
ax.plot(time,signal)
sns.despine(fig, bottom=False, left=False)
plt.show()
#Setting parameters for Continous Wavelet Transform
scales = np.arange(1,31)
waveletname='cgau2'
coef, freqs=pywt.cwt(signal, scales, waveletname)
#contourf
fig, ax = plt.subplots(figsize=(12, 2))
contourf_ = ax.contourf(time, scales, np.abs(coef), cmap=plt.cm.Reds)#extend='both',
ax.set_title('Wavelet Transform of Signal (${}$)'.format(waveletname), fontsize=20)
ax.set_ylabel('Scales', fontsize=14)
ax.set_xlabel('Time (s)', fontsize=14)
fig.colorbar(contourf_)
plt.show()
#matshow
fig, ax = plt.subplots(figsize=(12, 5))
matshow_ = ax.matshow(np.abs(coef), extent=[-1, 1, 1, 31], aspect = 'auto', cmap='Reds',
vmax=abs(coef).max(), vmin=0)
fig.colorbar(matshow_)
plt.gca().xaxis.tick_bottom() # it puts x axis from top to bottom of figure.
loc = plticker.MultipleLocator(base=0.25) # this locator puts ticks at regular intervals
ax.xaxis.set_major_locator(loc)
ax.set_title('Wavelet Transform of Signal (${}$)'.format(waveletname), fontsize=20)
ax.set_ylabel('Scales', fontsize=15)
ax.set_xlabel('Time', fontsize=15)
plt.show()
#imshow
fig, ax = plt.subplots(figsize=(12, 5))
imshow_ = plt.imshow(np.abs(coef), extent=[-1, 1, 1, 31], cmap='Reds', aspect='auto',
vmax=abs(coef).max(), vmin=0)
fig.colorbar(imshow_)
ax.set_title('Wavelet Transform of Signal (${}$)'.format(waveletname), fontsize=20)
ax.set_ylabel('Scales', fontsize=15)
ax.set_xlabel('Time', fontsize=15)
plt.show()
This is the plot using matshow
or imshow
.