0
0
RosHow-ToBeginner · 3 min read

How to Estimate Power Spectral Density in Signal Processing

To estimate power spectral density (PSD) in signal processing, you can use methods like the periodogram or Welch's method. These methods analyze the signal's frequency content by computing the squared magnitude of its Fourier transform, often averaging over segments to reduce noise.
📐

Syntax

The common syntax for estimating PSD using Welch's method in Python with SciPy is:

scipy.signal.welch(x, fs=1.0, window='hann', nperseg=256, noverlap=None)

Where:

  • x: input signal array
  • fs: sampling frequency
  • window: window function applied to each segment
  • nperseg: length of each segment
  • noverlap: number of points to overlap between segments

This function returns frequencies and PSD estimates.

python
from scipy.signal import welch

frequencies, psd = welch(x, fs=fs, window='hann', nperseg=256, noverlap=128)
💻

Example

This example shows how to estimate the PSD of a noisy sine wave using Welch's method and plot the result.

python
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import welch

# Create a sample signal: 5 Hz sine wave + noise
fs = 100  # Sampling frequency 100 Hz
T = 2     # Duration in seconds
n = int(fs * T)
t = np.linspace(0, T, n, endpoint=False)
signal = np.sin(2 * np.pi * 5 * t) + 0.5 * np.random.randn(n)

# Estimate PSD using Welch's method
frequencies, psd = welch(signal, fs=fs, window='hann', nperseg=256, noverlap=128)

# Plot PSD
plt.figure(figsize=(8,4))
plt.semilogy(frequencies, psd)
plt.title('Power Spectral Density Estimate using Welch')
plt.xlabel('Frequency [Hz]')
plt.ylabel('PSD [V**2/Hz]')
plt.grid(True)
plt.show()
Output
A plot window showing the PSD curve with a peak near 5 Hz on a logarithmic scale.
⚠️

Common Pitfalls

  • Using too short segments: Leads to poor frequency resolution.
  • No windowing: Causes spectral leakage and inaccurate PSD.
  • Incorrect overlap: Too little overlap reduces averaging benefits; too much increases computation.
  • Ignoring sampling frequency: Results in wrong frequency axis scaling.

Always choose segment length and window carefully based on signal length and frequency resolution needs.

python
import numpy as np
from scipy.signal import welch

# Wrong: no window and very short segment
frequencies_bad, psd_bad = welch(signal, fs=fs, window='boxcar', nperseg=20)

# Right: use Hann window and longer segment
frequencies_good, psd_good = welch(signal, fs=fs, window='hann', nperseg=256)
📊

Quick Reference

Tips for estimating PSD:

  • Use Welch's method for a good balance of noise reduction and resolution.
  • Apply a window like Hann to reduce spectral leakage.
  • Choose nperseg to balance frequency resolution and variance.
  • Set noverlap to about 50% of nperseg for smooth averaging.
  • Always specify the correct sampling frequency fs for accurate frequency axis.

Key Takeaways

Use Welch's method with windowing to estimate PSD reliably.
Choose segment length and overlap to balance resolution and noise reduction.
Always specify the sampling frequency to get correct frequency values.
Avoid no window or very short segments to prevent spectral leakage and poor resolution.
Visualize PSD on a logarithmic scale to see frequency components clearly.