我有时域振动数据,想使用 fft
将其转换为频域。然而,FFT 绘图仅显示零处的大尖峰,没有其他任何内容。
这是我的振动数据:https://pastebin.com/7RK57kJW
我的代码:
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(3000)
a1_fft= np.fft.fft(a1, axis=0)
freq = np.fft.fftfreq(t.shape[-1])
plt.plot(freq, a1_fft)
我的 FFT 图:
我在这里做错了什么?我很确定我的数据是统一的,这在其他情况下会引发与 fft 类似的问题。
最佳答案
FFT 的 bin 对应于 0、df、2df、3df、...、F-2df、F-df
处的频率,其中 df
是由 bin 数量决定,F
是每个 bin 1 个周期。
注意开始时的零频率。这称为直流偏移。这是你的数据的平均值。在您显示的数据中,平均值约为 1.32,而正弦波的幅度约为 0.04。您看不到比 DC 项小 33 倍的峰值,这并不奇怪。
有一些常见的数据可视化方法可以帮助您解决这个问题。一种常见的方法是保留 DC 偏移但使用对数刻度,至少对于 y 轴:
plt.semilogy(freq, a1_fft)
或者
plt.loglog(freq, a1_fft)
您可以做的另一件事是放大图的底部 1/33 左右。您可以手动执行此操作,或通过调整显示的 Y 轴的跨度来执行此操作:
p = np.abs(a1_fft[1:]).max() * [-1.1, 1.1]
plt.ylim(p)
如果您已经绘制绝对值,请使用
p = np.abs(a1_fft[1:]).max() * [-0.1, 1.1]
另一种方法是消除直流偏移。比 @J. Schmidt 更优雅的方法建议只是不显示 DC 项:
plt.plot(freq[1:], a1_fft[1:])
或者仅对于正频率:
n = freq.size
plt.plot(freq[1:n//2], a1_fft[1:n//2])
n//2
处的截止值只是近似值。正确的截止取决于 FFT 的元素数是偶数还是奇数。对于偶数,中间的 bin 实际上具有来自频谱两侧的能量,并且通常会得到特殊处理。
关于python - Python 中的快速傅立叶图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65551946/