You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Python中仅对傅里叶变换取绝对值才能正常绘图?

为什么直接绘制np.fft.fft结果会异常,取绝对值后恢复正常?

核心原因

np.fft.fft()返回的是复数数组,而matplotlib的plot()函数直接绘制复数时只会取实部,导致图形混乱;取绝对值(复数的模)后,我们得到的是各频率分量的振幅强度,这才是频域分析中需要观察的有效信息。

详细拆解

  1. 傅里叶变换的复数本质
    傅里叶变换的作用是把时域信号分解成不同频率的正弦/余弦分量,每个分量用复数来描述:
  • 复数的**模(绝对值)**对应该频率分量的振幅大小
  • 复数的辐角对应该频率分量的相位
    对于你使用的正弦信号sin(2π*50t),它的傅里叶变换会在+50Hz和-50Hz处各出现一个共轭复数峰(实部相同,虚部相反)。
  1. 直接绘制复数的问题
    当你执行plt.plot(xf02, yf02)时,matplotlib默认只提取复数的实部进行绘制。由于±50Hz处的复数实部相同、虚部相反,直接画实部会导致正负频率的信号相互干扰,再加上计算过程中的微小数值误差,最终呈现出杂乱无章的异常图形。

  2. 取绝对值的意义
    abs(yf02)计算的是复数的模,也就是对应频率分量的振幅强度。对于你的正弦信号,±50Hz处的模是相等的,所以绘制后会看到两个对称的尖锐峰,这正是正弦信号频域的典型特征(正常结果)。

额外补充

  • 如果需要观察相位信息,可以用np.angle(yf02)绘制相位谱
  • 针对实值信号,也可以用np.fft.rfft()直接计算正频率部分的傅里叶变换,结果更简洁,无需处理负频率的共轭对称部分

你的测试代码

异常版本(直接绘制复数)

import numpy as np
import matplotlib.pyplot as plt

# x轴
x02 = np.arange(0, 1, 0.001) # start, stop, step
y02 = np.sin(50.0 * 2.0 * np.pi * x02)

# 绘制时域正弦信号
plt.figure()
plt.plot(x02, y02, color ='b')
plt.grid()
plt.title('Sinus in time domain')
plt.show()

# 傅里叶变换
yf02 = np.fft.fft(y02)
xf02 = np.fft.fftfreq(len(y02), 0.001)

# 绘制频域结果(直接用复数)
plt.figure()
plt.plot(xf02, yf02, color ='b')
plt.grid()
plt.title('Sinus in frequency domain')
plt.show()

正常版本(取绝对值)

import numpy as np
import matplotlib.pyplot as plt

# x轴
x02 = np.arange(0, 1, 0.001) # start, stop, step
y02 = np.sin(50.0 * 2.0 * np.pi * x02)

# 绘制时域正弦信号
plt.figure()
plt.plot(x02, y02, color ='b')
plt.grid()
plt.title('Sinus in time domain')
plt.show()

# 傅里叶变换
yf02 = np.fft.fft(y02)
xf02 = np.fft.fftfreq(len(y02), 0.001)

# 绘制频域结果(取绝对值)
plt.figure()
plt.plot(xf02, abs(yf02), color ='b')
plt.grid()
plt.title('Sinus in frequency domain')
plt.show()

内容的提问来源于stack exchange,提问作者Apinorr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:43:15