我不知道该如何做到这一点我给了一个例子,spectrogram e.g.但这是2D。
我这里有代码生成混合频率,我可以在fft中选择这些,我怎么可能 在频谱图中看到这些?我很欣赏我的例子中的频率不随时间变化;这是否意味着我会在谱图中看到一条直线?
我的代码和输出图像:
# create a wave with 1Mhz and 0.5Mhz frequencies
dt = 2e-9
t = np.arange(0, 10e-6, dt)
y = np.cos(2 * pi * 1e6 * t) + (np.cos(2 * pi * 2e6 *t) * np.cos(2 * pi * 2e6 * t))
y *= np.hanning(len(y))
yy = np.concatenate((y, ([0] * 10 * len(y))))
# FFT of this
Fs = 1 / dt # sampling rate, Fs = 500MHz = 1/2ns
n = len(yy) # length of the signal
k = np.arange(n)
T = n / Fs
frq = k / T # two sides frequency range
frq = frq[range(n / 2)] # one side frequency range
Y = fft(yy) / n # fft computing and normalization
Y = Y[range(n / 2)] / max(Y[range(n / 2)])
# plotting the data
subplot(3, 1, 1)
plot(t * 1e3, y, 'r')
xlabel('Time (micro seconds)')
ylabel('Amplitude')
grid()
# plotting the spectrum
subplot(3, 1, 2)
plot(frq[0:600], abs(Y[0:600]), 'k')
xlabel('Freq (Hz)')
ylabel('|Y(freq)|')
grid()
# plotting the specgram
subplot(3, 1, 3)
Pxx, freqs, bins, im = specgram(y, NFFT=512, Fs=Fs, noverlap=10)
show()
答案 0 :(得分:8)
您所拥有的技术上是正确的,但您只需要查看带有趣谱图的信号。为此,您需要频率随时间变化。 (为了实现这一点,你需要很多振荡,因为它需要一些振荡来建立一个频率,然后你需要其中许多振荡频率随着时间的变化而变得有趣。)
下面我修改了你的代码,尽可能少地获得一个有趣的频率(fscale
只是随着时间推移频率)。我发布了所有代码以使其工作,但我只更改前四行中的三个。
# create a wave with 1Mhz and 0.5Mhz frequencies
dt = 40e-9
t = np.arange(0, 1000e-6, dt)
fscale = t/max(t)
y = np.cos(2 * pi * 1e6 * t*fscale) + (np.cos(2 * pi * 2e6 *t*fscale) * np.cos(2 * pi * 2e6 * t*fscale))
y *= np.hanning(len(y))
yy = np.concatenate((y, ([0] * 10 * len(y))))
# FFT of this
Fs = 1 / dt # sampling rate, Fs = 500MHz = 1/2ns
n = len(yy) # length of the signal
k = np.arange(n)
T = n / Fs
frq = k / T # two sides frequency range
frq = frq[range(n / 2)] # one side frequency range
Y = fft(yy) / n # fft computing and normalization
Y = Y[range(n / 2)] / max(Y[range(n / 2)])
# plotting the data
subplot(3, 1, 1)
plot(t * 1e3, y, 'r')
xlabel('Time (micro seconds)')
ylabel('Amplitude')
grid()
# plotting the spectrum
subplot(3, 1, 2)
plot(frq[0:600], abs(Y[0:600]), 'k')
xlabel('Freq (Hz)')
ylabel('|Y(freq)|')
grid()
# plotting the specgram
subplot(3, 1, 3)
Pxx, freqs, bins, im = specgram(y, NFFT=512, Fs=Fs, noverlap=10)
show()
此外,请注意,只有频谱图才有用。如果你能看到一个好的波形或光谱,光谱图可能不会很有趣:1)如果波形是清晰的,你可能没有足够的数据和时间来定义频率,并且变化足以引起兴趣; 2)如果完整的光谱是清晰的,那么光谱图的频率可能没有足够的变化,因为光谱基本上只是光谱图中随时间变化的平均值。
如果您真的想要查看原始信号的频谱图,您只需要在y轴上放大以查看您期望的峰值(请注意,频谱图y轴为2.5e8,必须大于您的光谱):
答案 1 :(得分:2)
获得你想要的东西:
1)以高频率采样1d波形(至少是其最高频率分量频率的5倍)
2)使用样本块(2的幂,如1024,16384等)来计算FFT
3)对于每个光谱图,一个垂直的像素线,其颜色代表每个频率的幅度。
4)对每个样本块重复步骤2和3。
在你的情况下,情节有一个完整的彩虹色彩,不应该只有几个非常不同的频率。您的光谱图在峰周围有相当宽的波段,但这可能是由于采样率低和绘图平滑。
答案 2 :(得分:0)
我刚开始使用Python 3.6 感谢您使用Spectrogram示例代码!
然而,在Python 3.6中,我努力使这个样本频谱图代码工作(函数调用和浮点除法) 我编辑了代码,所以它现在适用于python 3.6 for python newbies pals out。
享受
'''
Original Script for Python 2.7
https://stackoverflow.com/questions/19052324/how-do-i-generate-a-spectrogram-of-a-1d-signal-in-python
Modified in August 2017 for Python 3.6
Python 2.7 two integers / Division generate Integer
Python 3.6 two integers / Division generate Float
Python 3.6 two integers // Division generate integer
'''
import numpy as np
from scipy import fftpack
import matplotlib.pyplot as plt
dt = 40e-9
t = np.arange(0, 1000e-6, dt)
fscale = t/max(t)
y = np.cos(2 * np.pi * 1e6 * t*fscale) + (np.cos(2 * np.pi * 2e6 *t*fscale) * np.cos(2 * np.pi * 2e6 * t*fscale))
y *= np.hanning(len(y))
yy = np.concatenate((y, ([0] * 10 * len(y))))
# FFT of this
Fs = 1 / dt # sampling rate, Fs = 500MHz = 1/2ns
n = len(yy) # length of the signal
k = np.arange(n)
T = n / Fs
frq = k / T # two sides frequency range
frq = frq[range(n // 2)] # one side frequency range
Y = fftpack.fft(yy) / n # fft computing and normalization
Y = Y[range(n // 2)] / max(Y[range(n // 2)])
# plotting the data
plt.subplot(3, 1, 1)
plt.plot(t * 1e3, y, 'r')
plt.xlabel('Time (micro seconds)')
plt.ylabel('Amplitude')
plt.grid()
# plotting the spectrum
plt.subplot(3, 1, 2)
plt.plot(frq[0:600], abs(Y[0:600]), 'k')
plt.xlabel('Freq (Hz)')
plt.ylabel('|Y(freq)|')
plt.grid()
# plotting the specgram
plt.subplot(3, 1, 3)
Pxx, freqs, bins, im = plt.specgram(y, NFFT=512, Fs=Fs, noverlap=10)
plt.show()