[英]How do I plot an fft in python using scipy and modify the frequency range so that it shows the two peaks frequencies in the center?
The following Python code uses numpy to produce a frequency plot of a sinusoid graph:以下 Python 代码使用 numpy 生成正弦曲线图的频率 plot:
import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack
# Number of samplepoints
N = 600
# sample spacing
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N)
y = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)
yf = scipy.fftpack.fft(y)
xf = np.linspace(0.0, 1.0/(2.0*T), N//2)
fig, ax = plt.subplots()
ax.plot(xf, 2.0/N * np.abs(yf[:N//2]))
plt.show()
Based on the code above, we are plotting a sine wave with two frequencies, one at 50Hz and another at 80 Hz.基于上面的代码,我们绘制了一个具有两个频率的正弦波,一个频率为 50Hz,另一个频率为 80Hz。 You can clearly see the Fourier transform plot shows peaks at those two frequencies.您可以清楚地看到傅立叶变换 plot 显示了这两个频率的峰值。
My question: How do I modify the above code so that the x-axis ranges from 0-100Hz?我的问题:如何修改上面的代码,使 x 轴的范围为 0-100Hz?
If I change如果我改变
xf = np.linspace(0.0, 1.0/(2.0*T), N//2)
to到
xf = np.linspace(0.0, 100, N//2)
Then my graph looks like:然后我的图表看起来像:
But the graph now shows my peaks at around 11 and 20Hz, which is not correct.但是图表现在显示我的峰值在 11 和 20Hz 左右,这是不正确的。 When I change my axis, the peak values should not change.当我改变轴时,峰值不应改变。
What am I doing wrong?我究竟做错了什么?
import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack
# Number of samplepoints
N = 600
# sample spacing
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N)
y = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)
yf = scipy.fftpack.fft(y)
xf = np.linspace(0.0, 1.0/(2.0*T), N//2)
fig, ax = plt.subplots()
ax.plot(xf, 2.0/N * np.abs(yf[:N//2]))
ax.set(
xlim=(0, 100)
)
plt.show()
simply add the xlim
只需添加xlim
An alternate solution is to plot the appropriate range of values.另一种解决方案是 plot 的适当范围值。
When performing a FFT, the frequency step of the results, and therefore the number of bins up to some frequency, depends on the number of samples submitted to the FFT algorithm and the sampling rate.执行 FFT 时,结果的频率步长以及达到某个频率的 bin 数量取决于提交给 FFT 算法的样本数量和采样率。 So there is a simple calculation to perform when selecting the range to plot, eg the index of bin with center f is:因此,选择到plot的范围时,可以执行一个简单的计算,例如,带有中心F的bin索引为:
idx = ceil(f * t.size / sr)
This code works:此代码有效:
from numpy import arange, sin, pi, abs
from math import ceil
import matplotlib.pyplot as plt
from scipy.fft import rfft, rfftfreq
sr = 800 # Sampling rate = 800Hz
N = 600 # Number of samplepoints (duration = 0.75s)
t = arange(0, N/sr, 1/sr) # Sampling times
# Sampled values
s = sin(50 * 2*pi*t) + 0.5*sin(80 * 2*pi*t)
# FFT and bin centers
y = rfft(s)
f = rfftfreq(t.size, 1/sr)
# Index of 100Hz bin
f_hi = 100
idx_hi = ceil(f_hi * t.size / sr)
# Plot spectrum
fig, ax = plt.subplots()
ax.plot(f[:idx_hi], abs(y[:idx_hi]))
plt.show()
and produces:并产生:
As you only work with the real signal, you can cut computing time using rfft
instead of fft
which works with complex values.由于您只处理真实信号,因此可以使用rfft
而不是处理复数的fft
来缩短计算时间。 To get the frequency bin centers, you can use rfftfreq
要获得频点中心,您可以使用rfftfreq
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.