如何用Python绘制傅里叶级数图像?求修复维度不匹配错误
解决傅里叶级数绘图的维度不匹配问题及代码修正
首先来看你遇到的ValueError: x and y must have same first dimension错误,这是因为你生成的x_是包含10000个点的数组,但st只是5个单一数值的列表——你在循环里每次调用s(1,6),只计算了t=1这一个点的函数值,自然无法和长度为10000的x_匹配绘制曲线。
除此之外,你的代码还有一处关键笔误会导致傅里叶级数计算错误:在s(t,n)函数的正弦项里,你用了n代替循环变量i,这会让所有谐波项都使用同一个n值,而非当前循环的第i次谐波。
下面是修正后的完整代码,我会逐点解释修改的地方:
import numpy as np import matplotlib.pyplot as plt # 生成x轴数据,10000个点覆盖0到30 x_ = np.linspace(0, 30, 10000) a0 = 3/5 f0 = 5 # 修正a(n)和b(n)的写法,确保系数计算符合公式 def a(n): return (1/(n * np.pi)) * (np.sin(0.4 * n * np.pi) + np.sin(0.8 * n * np.pi)) def b(n): return (1/(n * np.pi)) * (2 - np.cos(0.4 * n * np.pi) - np.cos(0.8 * n * np.pi)) # 修正s(t,n)函数:正弦项的谐波次数用i而非n,同时支持数组输入 def s(t, n_terms): temp = np.zeros_like(t) # 创建和t同形状的零数组用于累加 for i in range(1, n_terms + 1): # 修正正弦项的i,对应第i次谐波 temp += a(i) * np.cos(2 * np.pi * i * f0 * t) + b(i) * np.sin(2 * np.pi * i * f0 * t) temp += a0 # 加上直流分量a0 return temp # 生成不同项数的傅里叶级数结果:每个n对应x_上所有点的函数值 st_list = [] for n in range(1, 6): st_list.append(s(x_, n)) # 绘制所有曲线并优化可视化 plt.title("Fourier Series Approximation (n=1 to 5)") labels = [f"n={n}" for n in range(1,6)] for st, label in zip(st_list, labels): plt.plot(x_, st, label=label) plt.legend() plt.xlabel("t") plt.ylabel("s(t)") plt.show()
关键修改点说明:
维度匹配修正:
- 让
s(t, n_terms)函数接受数组类型的t输入(比如x_),返回同样长度的数组,这样每个n对应的结果都和x_维度一致,可以正常绘制。 - 生成
st_list时,对每个n调用s(x_, n),计算整个x_区间的函数值,而非单一的t=1点。
- 让
傅里叶级数计算修正:
- 把正弦项里的
2 * np.pi * n * f0 * t改成2 * np.pi * i * f0 * t,确保第i次谐波使用正确的次数i。 - 调整了
a(n)和b(n)的括号位置,确保1/(n*np.pi)是整体系数(原代码的1/n * np.pi等价于np.pi/n,和你注释里的公式不符)。
- 把正弦项里的
可视化优化:
- 添加了图例、坐标轴标签,方便观察不同项数的傅里叶级数逼近效果。
如果你想进一步提升代码效率,可以用numpy的向量化操作代替循环,尤其当n_terms很大时:
def s_vectorized(t, n_terms): n = np.arange(1, n_terms+1) an = (1/(n * np.pi)) * (np.sin(0.4 * n * np.pi) + np.sin(0.8 * n * np.pi)) bn = (1/(n * np.pi)) * (2 - np.cos(0.4 * n * np.pi) - np.cos(0.8 * n * np.pi)) # 利用广播机制一次性计算所有谐波项的和 cos_terms = an * np.cos(2 * np.pi * n[:, None] * f0 * t) sin_terms = bn * np.sin(2 * np.pi * n[:, None] * f0 * t) return a0 + np.sum(cos_terms + sin_terms, axis=0)
这个版本利用numpy的广播特性,避免了Python层面的循环,计算速度会快很多。
内容的提问来源于stack exchange,提问作者Chatchai W.
相关产品推荐
相关产品推荐

