scipy.signal.

spectrogram#

scipy.signal.spectrogram(x, fs=1.0, window=('tukey_periodic', 0.25), nperseg=None, noverlap=None, nfft=None, detrend='constant', return_onesided=True, scaling='density', axis=-1, mode='psd')[源码]#

使用连续傅里叶变换计算谱图(旧版函数)。

谱图可用于可视化非平稳信号的频率含量随时间的变化。

旧版

此函数被视为旧版(legacy),将不再接收更新。虽然我们目前没有删除它的计划,但建议新代码改用更现代的替代方案。ShortTimeFFT 是一个更新的 STFT / ISTFT 实现,具有更多功能,同时也包含一个 spectrogram 方法。不同实现之间的比较可以在 SciPy 用户指南短时傅里叶变换章节中找到。

参数:
xarray_like

测量值的时序数据

fsfloat,可选

x 时序的采样频率。默认为 1.0。

windowstr 或 tuple 或 array_like, 可选

希望使用的窗函数。如果 window 是字符串或元组,它将被传递给 get_window 来生成窗函数值(默认情况下是 DFT 对称的)。有关窗函数列表和所需参数,请参阅 get_window。如果 window 是类数组,它将直接用作窗函数,其长度必须为 nperseg。默认为形状参数为 0.25 的周期性 Tukey 窗。

npersegint, 可选

每个段的长度。默认为 None,但如果 window 是字符串或元组,则设置为 256,如果 window 是类数组对象,则设置为窗口的长度。

noverlapint, 可选

分段之间重叠的点数。如果为 None,则 noverlap = nperseg // 8。默认为 None

nfftint, 可选

如果需要零填充 FFT,则用于 FFT 的长度。如果 None,则 FFT 长度为 nperseg。默认为 None

detrendstr 或 function 或 False,可选

指定如何去趋势化每个段。如果 detrend 是字符串,则将其作为 type 参数传递给 detrend 函数。如果它是函数,它将接收一个段并返回一个去趋势化后的段。如果 detrendFalse,则不进行去趋势化。默认为 ‘constant’。

return_onesidedbool,可选

如果 True,则为实数数据返回单边频谱。如果 False,则返回双边频谱。默认为 True,但对于复数数据,始终返回双边频谱。

scaling{ ‘density’, ‘spectrum’ },可选

选择计算功率谱密度(‘density’,此时 Sxx 的单位为 V**2/Hz)还是计算功率谱(‘spectrum’,此时 Sxx 的单位为 V**2),假设 x 的测量单位为 V,fs 的测量单位为 Hz。默认为 ‘density’。

axisint, 可选

计算谱图的轴;默认为最后一个轴(即 axis=-1)。

mode字符串, 可选

定义预期的返回值类型。选项有 [‘psd’, ‘complex’, ‘magnitude’, ‘angle’, ‘phase’]。‘complex’ 等同于没有填充或边界扩展的 stft 的输出。‘magnitude’ 返回 STFT 的绝对幅度。‘angle’ 和 ‘phase’ 分别返回 STFT 的复数相位(解缠绕和未解缠绕)。

返回:
fndarray

采样频率数组。

tndarray

分段时间数组。

Sxxndarray

x 的谱图。默认情况下,Sxx 的最后一个轴对应于分段时间。

另请参阅

periodogram

简单、可选的修改周期图

lombscargle

Lomb-Scargle 周期图,用于不均匀采样的数据

welch

Welch 方法的功率谱密度。

csd

Welch 方法的互功率谱密度。

ShortTimeFFT

更新的 STFT/ISTFT 实现,提供更多功能,其中也包含一个 spectrogram 方法。

附注

适当的重叠量取决于窗口的选择和您的需求。与 Welch 方法(对整个数据流进行平均)不同,在计算谱图时,可能希望使用较小的重叠(或者完全不重叠),以保持各个分段之间的一定统计独立性。正因如此,默认窗口是两端各有窗口长度 1/8 重叠的 Tukey 窗。

添加于 0.16.0 版本。

数组 API 标准支持

spectrogram 不在 NumPy 以外的 Python Array API 标准兼容后端的支持范围内。

有关更多信息,请参阅 对数组 API 标准的支持

参考文献

[1]

Oppenheim, Alan V., Ronald W. Schafer, John R. Buck “Discrete-Time Signal Processing”, Prentice Hall, 1999.

示例

>>> import numpy as np
>>> from scipy import signal
>>> from scipy.fft import fftshift
>>> import matplotlib.pyplot as plt
>>> rng = np.random.default_rng()

生成一个测试信号:一个 2 Vrms 的正弦波,其频率在 3kHz 左右缓慢调制,并伴有采样率为 10 kHz、幅度呈指数衰减的白噪声。

>>> fs = 10e3
>>> N = 1e5
>>> amp = 2 * np.sqrt(2)
>>> noise_power = 0.01 * fs / 2
>>> time = np.arange(N) / float(fs)
>>> mod = 500*np.cos(2*np.pi*0.25*time)
>>> carrier = amp * np.sin(2*np.pi*3e3*time + mod)
>>> noise = rng.normal(scale=np.sqrt(noise_power), size=time.shape)
>>> noise *= np.exp(-time/5)
>>> x = carrier + noise

计算并绘制谱图。

>>> f, t, Sxx = signal.spectrogram(x, fs)
>>> plt.pcolormesh(t, f, Sxx, shading='gouraud')
>>> plt.ylabel('Frequency [Hz]')
>>> plt.xlabel('Time [sec]')
>>> plt.show()
../../_images/scipy-signal-spectrogram-1_00_00.png

注意,如果使用非单边(not one sided)的输出,请使用以下方法

>>> f, t, Sxx = signal.spectrogram(x, fs, return_onesided=False)
>>> plt.pcolormesh(t, fftshift(f), fftshift(Sxx, axes=0), shading='gouraud')
>>> plt.ylabel('Frequency [Hz]')
>>> plt.xlabel('Time [sec]')
>>> plt.show()
../../_images/scipy-signal-spectrogram-1_01_00.png