具有意外结果的spectrogram(Python,scipy.signal)

2024-06-01 08:27:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我想澄清一下我在理解或实施spectrogram绘图时的错误

为了确保一切都正确,我从一个玩具示例开始,所以我生成了一个非常简单的信号(三个不同频率和相移的周期信号之和,没有噪声) 作为休耕地:

import numpy as np
sampling_rate = 1.0 / 1000
duration = 2
t = np.arange(0, duration, sampling_rate)

# Signal 1 
A_1 = 0.8 # amplitude of the cosine wave
f_1 = 100 # frequency of the cosine wave
phase_1 = 30  #desired phase shift of the cosine in degrees
phi_1 = phase_1*np.pi/180
s1 = A_1*np.cos(2*np.pi*f_1*t+phi_1)

# Signal 2 
A_2 = 0.3 # amplitude of the cosine wave
f_2 = 8 # frequency of the cosine wave
phase_2 = 45  #desired phase shift of the cosine in degrees
phi_2 = phase_2*np.pi/180
s2 = A_2*np.cos(2*np.pi*f_2*t+phi_2)

# Signal 3 
A_3 = 0.1 # amplitude of the cosine wave
f_3 = 60 # frequency of the cosine wave
phase_3 = -10  #desired phase shift of the cosine in degrees
phi_3 = phase_3*np.pi/180
s3 = A_3*np.cos(2*np.pi*f_3*t+phi_3)

# Result
x = s1 + s2 + s3

我预计“x”信号的频谱图将是三条水平线,对应于生成信号的三个频率。信号不会随时间变化,因此我期望得到类似于FFT的结果,但表示形式不同

但在用下面的代码绘制之后:

from scipy import signal
import matplotlib.pyplot as plt

freqs, times, spectrogram = signal.spectrogram(x)

plt.figure(figsize=(8, 6))
plt.imshow(spectrogram, aspect='auto', cmap='hot_r', origin='lower')
plt.title('Spectrogram')
plt.ylabel('Frequency band')
plt.xlabel('Time window')
plt.tight_layout()

我得到了一件意想不到的事情:

Unexpected spectogram result

发现的频率没有意义

所以我的问题是:我在哪里犯了错误?我的期望是错误的?我的实现不知怎么被破坏了?也许有人能给我推荐一个关于这个话题的好的知识来源

提前非常感谢您的时间和帮助


Tags: oftheimportsignal信号错误nppi
1条回答
网友
1楼 · 发布于 2024-06-01 08:27:13

我在问这个问题之前找到了答案,所以我不会删除整个帖子,我会和你分享我的结果。我希望有人能从中受益

这幅图很好,但轴线的符号很差。如果你紧张你的眼睛,你会注意到实际上有三个酒吧(最弱的是大约15)。线的可见性与分量信号的振幅值成比例,这是有意义的,因为振幅的颜色代码。所以现在很容易注意到,y轴由于某种原因被4除。x轴也存在类似的问题,当您意识到我们没有在任何地方提供有关采样频率的信息时,这就更容易理解了

因此,现在我们可以纠正此问题,并将调色板更改为“休耕”:

freqs, times, spectrogram = signal.spectrogram(x,fs=1./sampling_rate)

plt.figure(figsize=(8, 6))

plt.pcolormesh(times, freqs, spectrogram, shading='gouraud')
plt.ylabel('Frequency [Hz]')
plt.ylim([0,110])
plt.xlabel('Time [sec]')

plt.tight_layout()
plt.show()

这使我们得到了预期结果(s2的振幅乘以2):

Spectogram

我希望这会有帮助

相关问题 更多 >