我有一些复杂的数据(设定频率附近的小带宽),我很想绘制,但我对如何解释在特定范围内采样的复杂信号的处理方式略有不足。
所以,例如,这里是我编写的代码(以及我对这个问题的相当差的尝试),所以我有一个干净的例子来试验人工信号,它产生78 KHz波的复杂表示。我要做的是获得一个以120 KHz为中心的图,范围从70到170 KHz,模拟真实接收器的窄采样范围。
import numpy as np
import matplotlib.pyplot as plt
#sampling rate, samples/second; 100 KHz
rate = 100*10**3
#sample spacing in time, seconds/sample
interval = np.true_divide(1, rate)
#length of the fourier transform
n = 256
#time vector
t = np.linspace(0.0, n*interval, n)
#frequency of artificial signal; 78 KHz
f = 78*10**3
#complex signal
s = np.exp(1j*2*np.pi*f*t)
#dft of the data
dft = np.fft.fft(s)
#frequency bins
x = np.fft.fftfreq(n, d=interval)
#center zero-frequency component in data; take absolute values
dft = np.abs(np.fft.fftshift(dft))
#center zero frequency component in bins; naively add the center frequency, 120 KHz
x = np.fft.fftshift(x) + 120*10**3
plt.plot(x, dft)
plt.show()
输出是错误的,正如预期的那样,原油试图模仿特定的频率范围。
Plot made by the code snippet above
P.S。 Different plot,f = 88*10*83
- 为什么这里的数量突然变了?
编辑:我的帖子已被标记为重复,主题与绘图相关,而我实际上正在处理和/或反转带通滤波数据。
答案 0 :(得分:4)
您的信号应为+78 kHz的(复数)指数振荡,采样频率为100 kHz。 This doesn't work。您所看到的是-22 kHz(78 kHz - 100 kHz)的别名频率。您必须确保信号的频率不高于采样频率的一半。例如,对于78 kHz的信号,采样频率为200 kHz。
import numpy as np
from matplotlib import pyplot as plt
sample_frequency = 200e3 # 200 kHz
sample_interval = 1 / sample_frequency
samples = 256 # you don't necessarily have to use a power of 2
time = np.linspace(0, samples*sample_interval, samples)
signal_frequency = 78e3 # 78 kHz
signal = np.exp(2j*np.pi*signal_frequency*time)
fftfreq
np.fft.fftfreq
已经返回正确的频率,添加“中心频率”毫无意义。不要这样做。
signal_spectrum = np.fft.fftshift(np.fft.fft(signal))
freqs = np.fft.fftshift(np.fft.fftfreq(samples, d=sample_interval))
您问题的绘图部分仅与设置轴有关。使用plt.xlim
。
plt.figure(figsize=(10,5))
plt.plot(freqs / 1e3, np.abs(signal_spectrum)) # in kHz
plt.xlim(70, 170)
绘制的线在100 kHz之前结束,因为如上所述,您的信号的频率部分不能高于半采样频率。
由于您的信号是时间离散的(几个单个样本,而不是连续函数),因此您的频谱是连续的。但是,Discrete Fourier Transform仅返回连续光谱的离散样本。如果您通过采样点拟合曲线,则其峰值对于不同的频率将具有相同的幅度。
或者,您可以通过零填充信号来增加FFT采样点的数量(请查看numpy.fft.fft
documentation):
signal_spectrum = np.fft.fftshift(np.fft.fft(signal, 10*samples))
freqs = np.fft.fftshift(np.fft.fftfreq(10*samples, d=sample_interval))
plt.figure(figsize=(10,5))
plt.plot(freqs / 1e3, np.abs(signal_spectrum)) # in kHz
plt.xlim(65, 95).
plt.grid()
如果你问自己为什么光谱看起来如此波动,请看看spectral leakage。