如何在 matplotlib 中将正弦波的 FFT 居中?
How to center the FFT of sine wave in matplotlib?
我想使用 matplotlib 绘制正弦波的 FFT,我想在正弦波所属的频率上绘制一条直线。
这是我的代码
import numpy as np
import matplotlib.pyplot as plt
f = 3
t = np.arange(-np.pi, np.pi, 0.01)
y = np.sin(2*np.pi*f*t)
plt.subplot(2, 1, 1)
plt.plot(t, y)
ft = np.fft.fft(y)
plt.subplot(2, 1, 2)
plt.plot(ft.real)
plt.show()
并且,这是上面代码的输出。
我想将 FFT 绘制成一条直线,这条直线将在给定的正弦波频率处直线上升。假设,如果我将两个 20Hz 和 40Hz 的正弦波加在一起,如 sine(2*pi*20*t) + sine(2*pi*40*t)
那么它们的 FFT 应该在 20Hz 和 30Hz 处有两条直线。
如何修改我的代码以获得我想要的?我在 Whosebug 上看到很多问题,但我不明白。任何帮助将不胜感激。
这里有一些东西要打开。
对真实信号使用np.fft.rfft
由于您的信号是 real-valued(即没有复数),所以您的 fft 的后半部分没有包含任何信息。您应该使用 rfft
代替真实信号。
请参阅 numpy 文档的 this 部分。
使用abs
得到振幅
您似乎对每个频率分量的幅度感兴趣。幅值取fft的绝对值得到:
ft = np.fft.rfft(y)
amplitude = abs(ft)
有关详细信息,请参阅 numpy 文档的 this 部分。
正确缩放频率
您可以使用 np.fft.rfftfreq
获取每个分量的频率,但是这些频率将按 1 / number of points
缩放。
要缩放频率以使其与您的 f
参数相匹配,您需要知道系列中各点之间的时间差:
delta_t = 0.01
t = np.arange(-np.pi, np.pi, delta_t)
freq = np.fft.rfftfreq(len(t)) / delta_t
综合起来
import numpy as np
import matplotlib.pyplot as plt
# Extract delta_t to rescale the frequencies later
delta_t = 0.01
t = np.arange(-np.pi, np.pi, delta_t)
# Signal is a mixture of 2 frequencies
f0 = 3
f1 = 8
y = np.sin(2*np.pi*f0*t) + 0.5 * np.sin(2*np.pi*f1*t)
plt.subplot(2, 1, 1)
plt.plot(t, y)
ft = np.fft.rfft(y)
# Frequency of each component, scaled like f0 and f1
freq = np.fft.rfftfreq(len(t)) / delta_t
# Amplitude of each frequency is given by the absolute value
amplitude = abs(ft)
plt.subplot(2, 1, 2)
plt.plot(freq, amplitude)
plt.xlabel('frequency')
plt.ylabel('amplitude')
plt.show()
我想使用 matplotlib 绘制正弦波的 FFT,我想在正弦波所属的频率上绘制一条直线。
这是我的代码
import numpy as np
import matplotlib.pyplot as plt
f = 3
t = np.arange(-np.pi, np.pi, 0.01)
y = np.sin(2*np.pi*f*t)
plt.subplot(2, 1, 1)
plt.plot(t, y)
ft = np.fft.fft(y)
plt.subplot(2, 1, 2)
plt.plot(ft.real)
plt.show()
并且,这是上面代码的输出。
我想将 FFT 绘制成一条直线,这条直线将在给定的正弦波频率处直线上升。假设,如果我将两个 20Hz 和 40Hz 的正弦波加在一起,如 sine(2*pi*20*t) + sine(2*pi*40*t)
那么它们的 FFT 应该在 20Hz 和 30Hz 处有两条直线。
如何修改我的代码以获得我想要的?我在 Whosebug 上看到很多问题,但我不明白。任何帮助将不胜感激。
这里有一些东西要打开。
对真实信号使用np.fft.rfft
由于您的信号是 real-valued(即没有复数),所以您的 fft 的后半部分没有包含任何信息。您应该使用 rfft
代替真实信号。
请参阅 numpy 文档的 this 部分。
使用abs
得到振幅
您似乎对每个频率分量的幅度感兴趣。幅值取fft的绝对值得到:
ft = np.fft.rfft(y)
amplitude = abs(ft)
有关详细信息,请参阅 numpy 文档的 this 部分。
正确缩放频率
您可以使用 np.fft.rfftfreq
获取每个分量的频率,但是这些频率将按 1 / number of points
缩放。
要缩放频率以使其与您的 f
参数相匹配,您需要知道系列中各点之间的时间差:
delta_t = 0.01
t = np.arange(-np.pi, np.pi, delta_t)
freq = np.fft.rfftfreq(len(t)) / delta_t
综合起来
import numpy as np
import matplotlib.pyplot as plt
# Extract delta_t to rescale the frequencies later
delta_t = 0.01
t = np.arange(-np.pi, np.pi, delta_t)
# Signal is a mixture of 2 frequencies
f0 = 3
f1 = 8
y = np.sin(2*np.pi*f0*t) + 0.5 * np.sin(2*np.pi*f1*t)
plt.subplot(2, 1, 1)
plt.plot(t, y)
ft = np.fft.rfft(y)
# Frequency of each component, scaled like f0 and f1
freq = np.fft.rfftfreq(len(t)) / delta_t
# Amplitude of each frequency is given by the absolute value
amplitude = abs(ft)
plt.subplot(2, 1, 2)
plt.plot(freq, amplitude)
plt.xlabel('frequency')
plt.ylabel('amplitude')
plt.show()