Sitemap
The Pythoneers

Your home for innovative tech stories about Python and its limitless possibilities. Discover, learn, and get inspired.

Wavelet Transform: A Practical Approach to Time-Frequency Analysis

Unlocking the Power of Wavelet Transforms: A Guide to Time-Frequency Signal Analysis with Real-World Applications

8 min readOct 5, 2024

--

Introduction

The wavelet transform is one of the most powerful tools for analyzing time-varying signals, offering both time and frequency resolution. Unlike the Fourier transform, which only reveals the frequency content of a signal, the wavelet transform provides a much richer representation that captures both when and which frequencies are present in a signal.

In this post, we’ll dive into the wavelet transform by:

  • Breaking down the mathematical concepts.
  • Exploring the differences between wavelet and Fourier transforms.
  • Implementing wavelet analysis with Python.
  • Analyzing real-world data using wavelets.

By the end of this post, I hope you’ll be able to apply wavelet transforms to your own data and extract meaningful insights from time-frequency analysis.

What is a Wavelet Transform?

A wavelet transform is a mathematical technique used to decompose a signal into scaled and translated versions of a simple, oscillating wave-like function called a wavelet. The key advantage of wavelets is that they allow us to analyze a signal locally at different scales (frequencies).

The continuous wavelet transform (CWT) of a signal x(t) is defined as:

continuous wavelet transform (CWT)

Where:

  • ψ(t) is the mother wavelet, a function chosen based on the characteristics of the signal.
  • a is the scaling factor (dilation), which controls the frequency.
  • b is the translation factor, which controls the time shift.
  • ψ is the complex conjugate of the wavelet function.

But Wait, We Can Further Simplify

  • a: The scaling factor a stretches or compresses the wavelet. Large values of a correspond to low-frequency components (coarse details), while small values correspond to high-frequency components (fine details).
  • b: The translation factor b shifts the wavelet in time, allowing us to localize where specific frequency components occur in the signal.
  • Wavelet function: The wavelet is analogous to the sinusoid in Fourier analysis, but unlike sinusoids, wavelets are localized in time.

The result of the wavelet transform is a time-frequency representation of the signal, showing how different frequency components evolve over time.

Wavelet vs. Fourier Transform

To understand why wavelets are so useful, let’s compare them to the Fourier transform. While Fourier transform decomposes a signal into its constituent frequencies, it does not provide any information about when those frequencies occur. This is fine for stationary signals, where the frequency content doesn’t change over time, but most real-world signals are non-stationary.

The wavelet transform, however, allows us to analyze signals in both time and frequency simultaneously.

Get Thomas Konstantinovsky’s stories in your inbox

Join Medium for free to get updates from this writer.

For example:

  • In EEG or ECG signals, we might want to detect when certain frequency bands (e.g., alpha waves or heart arrhythmias) are prominent.
  • In seismic data, we might want to track the frequency changes associated with different types of ground motion over time.

Example: A Quick Comparison

Let’s quickly compare the results of a Fourier transform and a wavelet transform using Python.

import numpy as np
import matplotlib.pyplot as plt
from scipy.fft import fft
from scipy.signal import morlet, cwt

# here we simulate a simple signal: sum of two sine waves
t = np.linspace(0, 1, 1000, endpoint=False)
signal = np.sin(2 * np.pi * 5 * t) + np.sin(2 * np.pi * 50 * t)

# calcualte the fourier transform
fft_values = fft(signal)

# plot the original signal
plt.figure(figsize=(20,11))
plt.subplot(2, 1, 1)
plt.plot(t, signal)
plt.title('Original Signal (Time Domain)')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')

# plot the fourier transform of the simulated sequence
frequencies = np.fft.fftfreq(len(t), d=t[1] - t[0])
plt.subplot(2, 1, 2)
plt.plot(frequencies, np.abs(fft_values))
plt.title('Fourier Transform (Frequency Domain)')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Amplitude')
plt.tight_layout()
plt.show()
Press enter or click to view image in full size
  • In the time domain, we see the original signal — a combination of two sine waves at 5 Hz and 50 Hz.
  • In the frequency domain, the Fourier transform correctly identifies these two frequencies. However, it doesn’t tell us when these frequencies occur within the signal. This is where the wavelet transform comes in.

Wavelet Transform

Choosing a Wavelet

The choice of wavelet depends on the characteristics of the signal you’re analyzing. Common wavelets include:

For our example, we will use the Morlet wavelet, which is particularly good at capturing oscillations.

Example: Wavelet Transform of a Synthetic Signal

Let’s apply the continuous wavelet transform (CWT) to a signal that contains both high- and low-frequency components.

from scipy.signal import cwt, morlet

# simulate another signal: sum of sine waves with varying frequencies
signal = np.sin(2 * np.pi * 5 * t) + np.sin(2 * np.pi * 50 * t) + np.sin(2 * np.pi * 20 * t)

# set the wavelet scales
scales = np.arange(1, 100)

# performe continuous wavelet transform using the Morlet wavelet
coefficients = cwt(signal, morlet, scales)

# display the original signal and the wavelet transform result
plt.figure(figsize=(20, 11))
plt.subplot(2, 1, 1)
plt.plot(t, signal)
plt.title('Original Signal (Time Domain)')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')

plt.subplot(2, 1, 2)
plt.imshow(np.abs(coefficients), extent=[0, 1, 1, 100], cmap='PRGn', aspect='auto',
vmax=abs(coefficients).max(), vmin=-abs(coefficients).max())
plt.title('Wavelet Transform (Time-Frequency Domain)')
plt.xlabel('Time [s]')
plt.ylabel('Scale')
plt.tight_layout()
plt.show()
Press enter or click to view image in full size
  • The first plot shows the original signal, which contains oscillations at 5 Hz, 20 Hz, and 50 Hz.
  • The second plot shows the wavelet transform, which reveals how the frequency content of the signal changes over time. The vertical axis represents the scale (related to frequency), and the color intensity indicates the strength of the signal at each scale and time point.

From this, we can clearly see when each frequency component is present in the signal, something the Fourier transform could not show.

Real-World Example: Seismic Data Analysis

Now let’s use wavelet transforms to analyze real-world data. Seismic data, which records ground motion over time, is an excellent example of non-stationary signals where wavelets are extremely useful.

We’ll use an example seismic dataset to identify transient seismic events and analyze their frequency content.

Step 1: Loading the Data

We will use the obspy library, which provides access to real-world seismic data.

pip install obspy
from obspy.clients.fdsn import Client
from obspy import UTCDateTime
import matplotlib.pyplot as plt

# create a client for IRIS data
client = Client("IRIS")

# specify the event time and parameters
starttime = UTCDateTime("2020-01-01T00:00:00")
endtime = starttime + 60 * 60 # 1 hour of data

# retrieve the waveform data for a specific station
# Example: Station ANMO, Network IU, Channel BHZ (Broadband High Gain Vertical)
waveform = client.get_waveforms(network="IU", station="ANMO", location="00", channel="BHZ",
starttime=starttime, endtime=endtime)

# extract the trace
tr = waveform[0]

# plot the waveform (time domain)
tr.plot(type="relative")
Press enter or click to view image in full size

Explanation of Parameters:

  • network="IU": Specifies the network code (International Seismological Centre network code).
  • station="ANMO": Specifies the station code for Albuquerque, New Mexico (ANMO).
  • channel="BHZ": Selects the vertical broadband channel.
  • starttime=t: The time to start the waveform retrieval.
  • endtime=t + 60 * 60: Ends the waveform retrieval after one hour.

Step 2: Applying the Wavelet Transform

Now that we have retrieved real-world seismic data using the IRIS client, we can apply the wavelet transform as described earlier.

from scipy.signal import cwt, morlet
import numpy as np
import matplotlib.pyplot as plt

# extract the seismic data from the trace
seismic_data = tr.data
times = np.linspace(0, tr.stats.npts / tr.stats.sampling_rate, tr.stats.npts)

# increase the range and resolution of scales
scales = np.arange(1, 256)

# perform wavelet transform using the Morlet wavelet
coefficients = cwt(seismic_data, morlet, scales)

# plot the original signal and the wavelet transform result
plt.figure(figsize=(12, 6))

# plot the seismic signal (time domain)
plt.subplot(2, 1, 1)
plt.plot(times, seismic_data)
plt.title('Seismic Signal (Time Domain)')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')

# plot the wavelet transform (time-frequency domain) with adjusted color scaling
plt.subplot(2, 1, 2)
plt.imshow(np.abs(coefficients), extent=[times[0], times[-1], scales[-1], scales[0]],
cmap='inferno', aspect='auto', vmax=np.percentile(np.abs(coefficients), 99),
vmin=np.percentile(np.abs(coefficients), 1))
plt.title('Wavelet Transform (Time-Frequency Domain)')
plt.xlabel('Time [s]')
plt.ylabel('Scale')
plt.colorbar(label='Magnitude')
plt.tight_layout()
plt.show()
Press enter or click to view image in full size
  • The top plot represents the seismic signal in the time domain, showing how the ground motion changes over time.
  • The bottom plot shows the time-frequency representation generated by the wavelet transform. The color intensity shows the strength of the frequency components at various times.

Conclusion: When to Use Wavelet Transforms and What to Look For

Wavelet transforms are a powerful tool for analyzing signals that have non-stationary or time-varying frequency content. If you’re working with data where the frequency components change over time, such as seismic signals, EEG data, or even financial data, wavelet transforms can help you uncover time-frequency patterns that other methods, like the Fourier transform, may miss.

Here are a few rules of thumb to guide you:

  1. Use Wavelet Transforms for Non-Stationary Signals: If the signal’s frequency components evolve over time (e.g., an earthquake’s different wave types or a sudden spike in heart rate), wavelet transforms are well-suited for capturing both when and which frequencies are present.
  2. Choose the Right Wavelet: The choice of wavelet (e.g., Morlet, Mexican Hat, or Haar) should depend on the signal’s characteristics. Morlet is a good general-purpose wavelet for oscillatory data, while Haar is better for edge detection in step-like signals.
  3. Look for Patterns in Time and Frequency: When analyzing the wavelet transform output, pay attention to where certain frequencies emerge or disappear. For instance, high-frequency components may appear briefly during transient events, while low-frequency components might persist longer, indicating different types of phenomena.
  4. Adjust Scales for Better Resolution: Different scales in wavelet transforms correspond to different frequency ranges. If you’re analyzing high-frequency signals, choose smaller scales. For low-frequency signals, larger scales will capture the relevant information.
  5. Use Color Intensity as a Guide: The color intensity in the wavelet transform plot indicates the strength of different frequency components at various times. Look for regions with higher intensity, which represent the most prominent features in your signal.

Wavelet transforms give you the flexibility to analyze signals in both time and frequency domains, making them invaluable for a wide range of applications. Whether you’re detecting anomalies, analyzing physiological signals, or investigating geophysical events, wavelet analysis provides insights that go beyond traditional methods.

Thomas Konstantinovsky
Thomas Konstantinovsky

Written by Thomas Konstantinovsky

PhD Student & Data Scientist driven by curiosity—on a relentless quest to uncover the hidden patterns that shape our world.

The Pythoneers
The Pythoneers

Published in The Pythoneers

Your home for innovative tech stories about Python and its limitless possibilities. Discover, learn, and get inspired.