So I've been learning about wavelets for a few weeks because I'd like to use them in a research project I'm working on and I've been trying to grasp the general ideas behind them.I've been struggling with plotting the scalograms of a CWT of a signal.
I would really appreciate it if someone could go through my scalogram plotting function to see if I'm plotting this scalogram correctly. I'm mainly struggling on how to visualize the power levels of the signal in the scalogram, or if im even doing it correctly now
The Raw Signal and Scalogram Plots:
The sampling frequency of this signal is 2048hz and the length of the signal is 2048 samples so this is a 1 second sample of my signal. You can ignore the black lined signal in the first plot. I applied the cwt function on the raw blue signal using the pywavlets cwt function.
questions about my plot_wavelet function:
1. In the function below there are hardcoded levels values. The log2 values are in the color bar on the right of the plot. These are used in the ax.contourf function for creating the contour lines. How should I go about determining how many levels to use or the values of the levels? This is the main thing I've been struggling with here. How to relate the power to color in the plot basically.
2. At this point in my scalogram plots I'm assuming that the areas closer to the value 0 have the most power. It kind of makes sense when i compare the location with what i see in the raw signal plot. Would this be a correct assumption? I'm wondering though how can I make the resolution of my graph better or is this even possible? If i use a longer range of scales i guess I can possibily increase the frequency band resolution? Is this the correct line of thinking.
3. How should I display my y-axis in the scalogram? The pywt.cwt function returns frequencies but I guess they are more like ranges of frequencies? I'm kind of stuggling as in understanding how exactly to interpret the y-axis... I've read so many different papers/ tutorials that I think I've confused myself a bit in regards to how to relate scale and frequency or how to plot it in this manner.
plot_wavelet function code :
def plot_wavelet(ax, time2, signal, scales, waveletname = 'cmor', cmap =plt.cm.seismic, title = '', ylabel = '', xlabel = ''): dt=time2 coefficients, frequencies = pywt.cwt(signal, scales, waveletname, dt) power = (abs(coefficients)) ** 2 period = frequencies levels = [0.015625,0.03125,0.0625, 0.125, 0.25, 0.5, 1] contourlevels = np.log2(levels) #original time=range(2048) 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)) #original ax.set_yticklabels(yticks) #original ax.invert_yaxis() ylim = ax.get_ylim() cbar_ax = fig.add_axes([0.95, 0.5, 0.03, 0.25]) fig.colorbar(im, cax=cbar_ax, orientation="vertical") return yticks, ylim
the code to create the two above plots, remember you can ignore the black signal in the first plot. I performed the CWT on the original blue signal.
xrange=list(range(2048)) fig, ax = plt.subplots(figsize=(12,8)) ax.plot(xrange,signal, color="b", alpha=0.5, label='original signal') #rec = lowpassfilter(signal, 0.4) ax.plot(xrange,rec, 'k', label='DWT smoothing}', linewidth=2) ax.legend() ax.set_title('Removing High Frequency Noise with DWT', fontsize=18) ax.set_ylabel('Signal Amplitude', fontsize=16) ax.set_xlabel('Sample No', fontsize=16) plt.margins(0) plt.show() scale_range = np.arange(2, 50) # number of scales fig, ax = plt.subplots(figsize=(12, 8)) plot_wavelet(ax=ax, time2=sp, signal=signal, scales=scale_range,waveletname='cmor1.5-1.0', title = "CWT of Signal", ylabel = ylabel, xlabel = xlabel) plt.show()