使用Matplotlib绘制两个趋近于0的函数时图像异常求助
解决双反比例函数同图绘制时一条显示为直线的问题
问题分析
核心问题是两个函数的数值量级差距过大:
计算两个势能函数的系数:
- 第一个函数系数:
G*m1*m2 = 1.6e-11 * 2e24 * 3e30 = 9.6e43 - 第二个函数系数:
G*m3*m4 = 1.6e-11 * 2e16 * 3e25 = 9.6e30
两者相差13个数量级。在普通线性坐标系中,数值大的曲线会占据整个y轴的显示范围,数值小的曲线因变化幅度相对极小,被压缩成了直线。另外原代码中r包含0值,会触发除以0的错误(生成inf值),也会影响绘图效果。
解决方案
下面提供两种可行的修改方式:
方式1:使用对称对数坐标轴(symlog)
这种方式能同时显示量级差距极大的数值,完整保留两条曲线的形态:
import numpy as np import matplotlib.pyplot as plt # 变量定义 m1= 2e+24 m2= 3e+30 m3= 2e+16 m4= 3e+25 G = 1.6e-11 # 规避r=0,从1e20开始生成取值 r = np.linspace(1e20,1e+50,50) # 第一个函数U(r) def U(r): return -(G*m1*m2)/r Ur_name = r'$U(r)=\frac{-(Gm_1m_2)}{r}$' y=U(r) # 第二个函数U2(r) def U2(r): return -(G*m3*m4)/r U2r_name= r'$U_2(r)=\frac{-(Gm_3m_4)}{r}$' y2=U2(r) # 绘图配置 plt.plot(r, y, label=Ur_name) plt.plot(r,y2, label=U2r_name) # 设置y轴为对称对数刻度,适配正负数值的大范围显示 plt.yscale('symlog', linthresh=1e30) plt.legend(loc='upper left') plt.xlabel('r') plt.ylabel('Potential Energy') plt.show()
方式2:对小量级函数做缩放
如果需要保持线性坐标轴,可以将数值小的函数放大到接近另一个的量级,同时在图例中标注缩放说明:
import numpy as np import matplotlib.pyplot as plt m1= 2e+24 m2= 3e+30 m3= 2e+16 m4= 3e+25 G = 1.6e-11 r = np.linspace(1e20,1e+50,50) def U(r): return -(G*m1*m2)/r Ur_name = r'$U(r)=\frac{-(Gm_1m_2)}{r}$' y=U(r) def U2(r): return -(G*m3*m4)/r # 缩放第二个函数,同步修改图例说明 U2r_name= r'$U_2(r)\times 10^{13}=\frac{-(Gm_3m_4)}{r}\times 10^{13}$' y2=U2(r) * 1e13 plt.plot(r, y, label=Ur_name) plt.plot(r,y2, label=U2r_name) plt.legend(loc='upper left') plt.xlabel('r') plt.ylabel('Potential Energy') plt.show()
内容的提问来源于stack exchange,提问作者Addu
相关产品推荐
相关产品推荐

