Time-varying frequency analysis
Inspecting changing frequency content in audio, vibration, or sensor recordings.
SciPy · Function
Computes a spectrogram by applying consecutive Fourier transforms to windowed segments of a time series. It returns frequency bins, segment times, and the resulting spectral representation.
The function divides a time series into overlapping windowed segments, computes a Fourier transform for each segment, and returns frequency bins, segment times, and a spectrogram array. Its default PSD mode represents frequency content as spectral density, while other modes can return the complex spectrum, magnitude, or phase.
scipy.signal.spectrogram(x, fs=1.0, window=('tukey', 0.25), nperseg=None, noverlap=None, nfft=None, detrend='constant', return_onesided=True, scaling='density', axis=-1, mode='psd')| Name | Type | Description |
|---|---|---|
x | array_like | Time series of measurement values. |
fs | float, optional | Sampling frequency of x; defaults to 1.0. |
window | str or tuple or array_like, optional | Desired window specification; defaults to ('tukey', 0.25). |
nperseg | int, optional | Length of each segment. |
noverlap | int, optional | Number of points to overlap between segments. |
nfft | int, optional | Length of the FFT used; defaults to nperseg when None. |
detrend | str or function or False, optional | Detrending method applied to each segment; defaults to 'constant'. |
return_onesided | bool, optional | Whether to return a one-sided spectrum for real data; defaults to True. |
scaling | {'density', 'spectrum'}, optional | Scaling of the result: 'density' or 'spectrum'; defaults to 'density'. |
axis | int, optional | Axis along which x is processed; defaults to -1. |
mode | {'psd', 'complex', 'magnitude', 'angle'}, optional | Output mode: 'psd', 'complex', 'magnitude', or 'angle'; defaults to 'psd'. |
Returns f, t, and Sxx: sample frequencies, segment times, and the spectrogram of x.
import numpy as np
from scipy import signal
fs = 1000.0
t = np.arange(0, 2, 1 / fs)
x = np.sin(2 * np.pi * 50 * t)
f, times, sxx = signal.spectrogram(x, fs=fs, nperseg=256)
peak_frequency = f[np.argmax(sxx[:, 1])]
print(peak_frequency)Computes a power spectral density spectrogram for a sampled 50 Hz sine wave and finds the strongest frequency in one time segment.
Inspecting changing frequency content in audio, vibration, or sensor recordings.
Locating transient tones or changes in oscillation frequency.
Generating a time-frequency representation for visualization or downstream feature extraction.
It computes consecutive Fourier transforms over windowed segments of a time series. The outputs are frequency samples, segment times, and the spectrogram array.
Follow-up: How would you interpret the array dimensions? The frequency dimension corresponds to the returned frequency vector, and the time dimension corresponds to the returned segment-time vector.
With scaling='density', the default, the result is a power spectral density representation. The scaling option can also be set to 'spectrum' for a power spectrum.
Follow-up: What changes when mode='complex'? The function returns the complex analytic short-time Fourier transform rather than PSD values.
return_onesided=True requests a one-sided spectrum for real-valued data, which omits negative frequencies. Setting it to False requests a two-sided spectrum, while complex input always produces two-sided output.
Follow-up: Why can a real signal use a one-sided spectrum? Its negative-frequency content is redundant with the positive-frequency content under the usual conjugate-symmetry relationship.
scipy.signal.stftscipy.signal.ShortTimeFFTscipy.signal.welch