5 Best Ways to Plot a Phase Spectrum in Matplotlib in Python

πŸ’‘ Problem Formulation: When working with signal processing in Python, you may need to visualize the phase spectrum of a signal to analyze its frequency characteristics. This article explains how to plot a phase spectrum using Matplotlib, starting with the signal’s Fast Fourier Transform (FFT). The input is a time-domain signal, and the desired output is a plot showing the phase angle versus frequency.

Method 1: Basic Phase Spectrum Plot

This method involves computing the phase spectrum of a signal using the numpy.fft module and then plotting it with Matplotlib. The numpy.angle function is used to extract phase information from the FFT of the signal.

Here’s an example:

import numpy as np
import matplotlib.pyplot as plt

# Time-domain signal example
t = np.linspace(0, 1, 500, endpoint=False)
signal = np.sin(2 * np.pi * 5 * t)

# FFT of the signal
fft_signal = np.fft.fft(signal)
freqs = np.fft.fftfreq(len(signal))

# Compute phase spectrum
phase_spectrum = np.angle(fft_signal)

# Plot phase spectrum
plt.figure()
plt.plot(freqs, phase_spectrum, label="Phase Spectrum")
plt.xlabel('Frequency [Hz]')
plt.ylabel('Phase [Radians]')
plt.title('Phase Spectrum')
plt.legend()
plt.show()

Phase Spectrum Plot

The above code snippet generates an FFT of a sine wave signal, calculates the corresponding phase angles, and plots them as a function of frequency. The phase spectrum helps to identify the phase of each frequency component present in the signal.

Method 2: Unwrapping Phase Angles

To avoid discontinuities in the phase spectrum plot, phase angles can be unwrapped using the np.unwrap function. This method changes abrupt jumps by 2Ο€ to their 2Ο€ complement.

Here’s an example:

# Same initial steps from Method 1 are assumed here

# Unwrap the phase angles to avoid discontinuities
unwrapped_phase_spectrum = np.unwrap(phase_spectrum)

# Plot unwrapped phase spectrum
plt.figure()
plt.plot(freqs, unwrapped_phase_spectrum, label="Unwrapped Phase Spectrum")
plt.xlabel('Frequency [Hz]')
plt.ylabel('Phase [Radians]')
plt.title('Unwrapped Phase Spectrum')
plt.legend()
plt.show()

Unwrapped Phase Spectrum Plot

In this code snippet, the np.unwrap function is used after computing the phase spectrum to create a continuous plot, which is easier to interpret, especially for signals with complex phase behavior.

Method 3: Handling Negative Frequencies

Since FFTs produce symmetric results for negative and positive frequencies, it’s often useful to plot only the positive half of the frequency spectrum. This method uses conditional array slicing to select only the positive frequencies.

Here’s an example:

# Same initial steps from Method 1 are assumed here

# Select half the spectrum, positive frequencies only
half_n = len(signal) // 2
positive_freqs = freqs[:half_n]
positive_phase_spectrum = phase_spectrum[:half_n]

# Plot phase spectrum for positive frequencies
plt.figure()
plt.plot(positive_freqs, positive_phase_spectrum, label="Positive Frequencies Phase Spectrum")
plt.xlabel('Frequency [Hz]')
plt.ylabel('Phase [Radians]')
plt.title('Phase Spectrum for Positive Frequencies')
plt.legend()
plt.show()

Positive Frequencies Phase Spectrum Plot

This snippet fine-tunes the frequency spectrum visualization by plotting only the phase associated with positive frequencies. It simplifies the plot and makes it more relevant for most practical applications, where negative frequencies are often redundant.

Method 4: Phase Spectrum with Magnitude Threshold

When plotting the phase spectrum, it might be useful to consider only those frequencies that have a magnitude above a certain threshold, which allows for a more focused analysis of significant frequency components.

Here’s an example:

# Same initial steps from Method 1 are assumed here

# Magnitude threshold
magnitude_threshold = 0.1
magnitudes = np.abs(fft_signal)

# Mask elements below threshold
significant_phases = phase_spectrum[magnitudes > magnitude_threshold]

# Plot phase spectrum with magnitude threshold
plt.figure()
plt.plot(freqs[magnitudes > magnitude_threshold], significant_phases, label="Significant Phases")
plt.xlabel('Frequency [Hz]')
plt.ylabel('Phase [Radians]')
plt.title('Phase Spectrum with Magnitude Threshold')
plt.legend()
plt.show()

Phase Spectrum with Magnitude Threshold Plot

The code here filters out the phase information for frequency components with magnitudes below the defined threshold. This results in a phase spectrum that highlights only the significant frequency components, hence potentially revealing the true characteristics of the signal.

Bonus One-Liner Method 5: Phase Spectrum with Log Scale

For signals with a wide range of frequencies, it might be beneficial to plot the phase spectrum on a logarithmic scale which can potentially reveal details in lower frequency components that might be missed in a linear scale.

Here’s an example:

# Same initial steps from Method 1 are assumed here

# Plotting with log scale for frequency
plt.figure()
plt.semilogx(freqs, phase_spectrum, basex=10, label="Phase Spectrum")
plt.xlabel('Frequency [Hz]')
plt.ylabel('Phase [Radians]')
plt.title('Log Scale Phase Spectrum')
plt.legend()
plt.show()

Phase Spectrum on Log Scale Plot

In this one-liner method, the Matplotlib’s semilogx function is used to generate a phase spectrum plot where the x-axis (frequency) is scaled logarithmically, providing a detailed view across a broad range of frequencies.

Summary/Discussion

  • Method 1: Basic Phase Spectrum Plot. This method is straightforward and suitable for simple signals. However, it might not handle phase discontinuities well.
  • Method 2: Unwrapping Phase Angles. Unwrapping provides a continuous phase plot, which eases interpretation. It may introduce artificial trends if not used judiciously.
  • Method 3: Handling Negative Frequencies. Removing negative frequencies simplifies the plot. Care should be taken with complex signals where negative frequencies are informative.
  • Method 4: Phase Spectrum with Magnitude Threshold. This approach focuses on significant components, but small but potentially important details might be missed.
  • Method 5: Phase Spectrum with Log Scale. Useful for a broad spectrum, though it can be less intuitive for those unfamiliar with log scale interpretation.