Jupyter Notebook中Python绘图代码运行结果与预期不符
问题描述
同一段Python数值计算代码在常规脚本环境下运行,可以输出符合预期的引力透镜光变曲线绘图,但在Jupyter Notebook中运行时输出结果与参考结果偏差极大。
- 预期正确绘图:

- Jupyter环境异常输出:

说明:该代码单次完整运行耗时约17分钟,目前暂未定位到不同环境结果不一致的根因,完整复现代码如下:
import matplotlib.pyplot as plt import numpy as np from scipy import integrate G = 6.6743*10**(-11) # 万有引力常数 M = 10*(1.988*10**30) # 黑洞质量(kg) m = 1*(1.988*10**30) # 伴星质量(kg) Mt = M + m # 总质量(kg) q = m/M # 质量比 c = 2.99792458*10**8 # 光速(m/s) Period = 10 # 轨道周期(天) P = Period*86400 # 轨道周期(秒) phi = 0.001*(np.pi/(180)) # 视线方向倾角 t0 = Period/2 # 脉冲中点时间 a = ((P**2*G*(Mt))/(4*np.pi**2))**(1/3) # 半长轴 omega = ((G*(m + M))/a**3)**0.5 # 角速度 vtran = a*omega # 横向速度 Rs = (2*G*M)/c**2 # 史瓦西半径 Rein = (2*Rs*a)**0.5 # 爱因斯坦半径 te = (Rein/vtran)/86400 # 爱因斯坦时间 u0 = (a/Rein)*phi # 最近角距 pstar = ((1*(6.957*10**8))/Rein) t = np.linspace(0,P,15000) # 时间向量 u = ((u0**2)+((((t/86400)-t0)/te))**2)**0.5 # 角距离 U=lambda r:(1-(3/2)*((pstar**2-r**2)/pstar**2)**0.5) gamma = 0.3 # 积分分母部分 pre_bottom=lambda r:r*(1-gamma*U(r)) # 计算分母积分结果 bottom_res,bottom_err=integrate.quadrature(pre_bottom,0,pstar,maxiter=100) bottom=2*np.pi*bottom_res # 结果存储数组 A=np.empty(len(u)) # 积分分子部分定义 pre_top=lambda r,th:(1-gamma*U(r))*(r*(u[i]**2 + r**2 - 2*u[i]*r*np.cos(th)+2))/((((u[i]**2 + r**2 - 2*u[i]*r*np.cos(th)))**0.5)*(((u[i]**2 + r**2 - 2*u[i]*r*np.cos(th)+4))**0.5)) # 积分子区间上限设置 options={'limit':100} # 遍历所有时间点计算分子积分 for i in range(len(u)): top_res,top_err=integrate.nquad(pre_top,[[0,pstar],[0,(2*np.pi)]],opts=[options,options]) # 计算最终光变值 A[i]=top_res/bottom plt.plot(t,A) plt.xlim([426000, 438000]) plt.show()
排查建议
- 优先排查Jupyter全局变量残留问题:Jupyter默认保留所有单元格运行过的变量,代码中
pre_top、U两个lambda函数直接引用全局变量,循环变量i也是全局变量,如果之前运行过其他代码残留了同名变量,会直接导致积分计算使用错误参数。测试前先重启Jupyter内核,选择「Restart & Run All」从头运行所有单元格,不要分段手动执行;也可以在代码最开头加%reset -f强制清空全局命名空间后再运行。 - 核对两边环境的依赖版本:重点对比
numpy、scipy、matplotlib的版本,不同版本的scipy.integrate数值积分默认收敛阈值、迭代逻辑存在差异,很容易导致长耗时积分结果偏差。在两边环境分别执行print(np.__version__, scipy.__version__, plt.matplotlib.__version__)确认版本,版本不一致时先统一依赖版本再测试。 - 验证积分收敛性:传入
nquad的limit=100是子区间数量上限,不是强制迭代次数,如果Jupyter环境下积分提前触发收敛条件返回未收敛结果,会直接导致光变曲线计算错误。可以在积分循环中打印每次返回的top_err误差值,和正常脚本环境的误差值对比,如果误差明显偏大,调大limit参数,同时显式设置epsabs=1e-8、epsrel=1e-8收紧积分容差再测试。 - 核对中间变量计算结果:在常量计算完成、时间向量
t和角距离向量u生成后,打印两边环境下a、Rein、te、u0、pstar、u.min()、u.max()等核心中间值,确认常量计算阶段没有出现数值偏差,排除单位换算、常量赋值错误的问题。
内容的提问来源于stack exchange,提问作者sorabella91
相关产品推荐
相关产品推荐

