含对数的菲涅耳衍射艾里斑函数绘图求助:报错与直线图异常
菲涅耳衍射艾里斑绘图问题排查
问题描述
我是Python绘图初学者,想绘制含对数的惠更斯积分结果的模平方,以此获取菲涅耳衍射的艾里斑,期望得到比贝塞尔函数描述的夫琅禾费衍射更宽的图案。最初运行代码时出现错误:Only size-1 arrays can be converted to Python scalars,修改代码后仅得到一条直线图,显然不符合预期,请求帮助排查问题。
原代码
import numpy as np import matplotlib.pyplot as plt from sympy import I import math f=lambda r:np.abs((-31415.9 *I) *math.log(r)/ math.log(10) - (49348 + 292886*I) - 1.97392e8 *r + (3.10063e11 *I) *r**2 + 4.3293e14*r**3 - (5.10034e17*I)*r**4 - 5.12743e20*r**5)**2 r=np.arange(1, 5, 2.7) y = np.vectorize(f) plt.plot(r, y(r))
问题排查
- 标量函数与数组不兼容:
math.log是仅支持单个数值的标量函数,无法直接处理numpy数组,这是初始报错的根源。即便用np.vectorize包装,sympy.I作为符号虚数单位,和numpy数组运算会导致计算逻辑异常。 - 采样点数量不足:
np.arange(1,5,2.7)仅生成[1, 3.7]两个点,两点连线必然是直线,完全无法体现衍射图案的曲线特征。 - 虚数单位使用错误:
sympy.I是符号计算库的虚数表示,不适合numpy的数值运算场景,应改用numpy原生的1j。
修正后的代码
import numpy as np import matplotlib.pyplot as plt def f(r): # 拆分计算项,提升可读性 term1 = (-31415.9 * 1j) * np.log10(r) term2 = -(49348 + 292886 * 1j) term3 = -1.97392e8 * r term4 = (3.10063e11 * 1j) * r**2 term5 = 4.3293e14 * r**3 term6 = -(5.10034e17 * 1j) * r**4 term7 = -5.12743e20 * r**5 # 计算复数结果的模平方 return np.abs(term1 + term2 + term3 + term4 + term5 + term6 + term7)**2 # 生成高密度采样点,步长0.01保证曲线细节 r = np.arange(1, 5, 0.01) y = f(r) # 函数直接支持数组运算,无需vectorize plt.figure(figsize=(10, 6)) plt.plot(r, y) plt.xlabel('r') plt.ylabel('模平方') plt.title('菲涅耳衍射艾里斑模平方分布') plt.grid(True) plt.show()
修正说明
- 替换虚数单位:用
1j替代sympy.I,确保复数运算在numpy数值环境下正常执行。 - 改用numpy对数函数:
np.log10直接支持数组运算,无需np.vectorize包装,避免标量/数组不兼容问题。 - 增加采样密度:将步长调整为0.01,生成足够多的采样点以呈现衍射图案的曲线细节。
- 拆分计算表达式:把复杂的单句表达式拆分为多个计算项,既提升代码可读性,也便于后续调试修改。
内容的提问来源于stack exchange,提问作者Sophie Er
相关产品推荐
相关产品推荐

