Casting complex values报错:FFT参数均衡器滑块交互图代码问题排查
问题排查与修复方案
核心问题点
- 复数输出处理错误:
scipy.fftpack.fft()返回复数数组,你初始绘图直接传入复数触发警告,且更新时仅取虚部的逻辑完全不符合频响曲线的绘制要求,频响曲线需要取FFT结果的幅值,即np.abs(yf) - 横坐标轴不匹配:你当前用的
x是时域采样点,不能直接当作频域的频率轴使用,需要根据采样参数计算FFT对应的真实频率坐标 - 逻辑矛盾:初始绘制时直接传入完整FFT复数结果,更新时却仅取FFT虚部,前后逻辑不一致导致绘图异常
- 初始参数错误:初始
f1_0 = 0会生成全0的正弦信号,FFT结果无有效峰值
修正后的完整代码
import matplotlib.pyplot as plt from numpy import pi, sin import numpy as np from matplotlib.widgets import Slider import scipy.fftpack # 生成信号并计算FFT幅值 def fermi(A1, F1, A2, F2, x, fs): peak1 = A1 * sin(2.0 * pi * F1 * x) pFl = A2 * sin(2.0 * pi * F2 * x) y = peak1 + pFl yf = scipy.fftpack.fft(y) # 取正频率部分的幅值并归一化 N = len(y) yf_amp = 2.0/N * np.abs(yf[:N//2]) # 计算对应频率轴 freqs = scipy.fftpack.fftfreq(N, 1/fs)[:N//2] return freqs, yf_amp fig = plt.figure(figsize=(5, 5)) # 采样参数设置 fs = 800 # 采样率 N = 1000 # 采样点数 x = np.linspace(0, 30, N) # 时域采样点 # 创建主轴 ax = fig.add_subplot(111) ax.set_xlim([0,30]) ax.set_ylim([-2, 10]) fig.subplots_adjust(bottom=0.5, top=0.95) ax.set_xlabel('频率 (Hz)') ax.set_ylabel('幅值') # 创建滑块轴 ax_a1 = fig.add_axes([0.3, 0.10, 0.4, 0.05]) ax_f1 = fig.add_axes([0.3, 0.01, 0.4, 0.05]) ax_a2 = fig.add_axes([0.3, 0.20, 0.4, 0.05]) ax_f2 = fig.add_axes([0.3, 0.30, 0.4, 0.05]) # 创建滑块 s_a1 = Slider(ax=ax_a1, label='amp1 ', valmin=-2, valmax=6, valinit=5, valfmt=' %1.1f eV', facecolor='#cc7000') s_f1 = Slider(ax=ax_f1, label='f1 ', valmin=0, valmax=30, valinit=1.5, valfmt=' %i K', facecolor='#cc7000') s_a2 = Slider(ax=ax_a2, label='amp2 ', valmin=-2, valmax=6, valinit=2, valfmt=' %1.1f eV', facecolor='#cc7000') s_f2 = Slider(ax=ax_f2, label='f2 ', valmin=0, valmax=30, valinit=3.946, valfmt=' %i K', facecolor='#cc7000') # 初始绘图 freqs, y_amp = fermi(s_a1.val, s_f1.val, s_a2.val, s_f2.val, x, fs) f_d, = ax.plot(freqs, y_amp, linewidth=0.5, color='#000000') # 更新函数 def update(val): aa1 = s_a1.val ff1 = s_f1.val aa2 = s_a2.val ff2 = s_f2.val freqs_new, y_amp_new = fermi(aa1, ff1, aa2, ff2, x, fs) f_d.set_data(freqs_new, y_amp_new) fig.canvas.draw_idle() s_a1.on_changed(update) s_f1.on_changed(update) s_a2.on_changed(update) s_f2.on_changed(update) plt.show()
修复说明
- 新增了频率轴计算逻辑,用
scipy.fftpack.fftfreq()生成和FFT结果匹配的频率坐标,符合频响曲线的横轴要求 - 统一返回FFT的归一化幅值,既消除了复数警告,也符合参数均衡器的幅值显示需求
- 调整了初始滑块值,初始运行即可看到两个频率对应的峰值,和预期参考效果一致
- 优化了函数参数传递,避免了全局变量
x的隐式依赖,逻辑更清晰
内容的提问来源于stack exchange,提问作者Roberto Valenzuela
相关产品推荐
相关产品推荐

