Sympy完成积分计算后如何对结果函数绘图与求值
问题复现
运行如下Sympy积分+绘图代码时,抛出TypeError: can't convert expression to float错误,同时输出空白图像,需要实现I1的定点求值与图像绘制:
from sympy.abc import x,y,z import sympy as S def f(x,y,z): return (1)/(S.sqrt(x**2+z**2-2*z*x*S.cos(y))) I1 = S.integrate(f(x,y,z),(y,0,2*S.pi),(x,0,z)) S.plot(I1)
错误原因
- 该二重积分的计算结果是分段符号表达式,不同z取值范围对应不同表达式分支,直接传入
plot时,函数无法自动处理分支判断逻辑,无法将符号表达式转换为浮点数值参与绘图计算。 - 调用
S.plot()时未指定自变量取值范围,Sympy默认取自由变量z的范围为[-10,10],但该积分的积分限为x∈[0,z],z≤0时属于无效计算区间(z=0为被积函数奇点、z<0时积分上下限逻辑反转),无效区间的计算也会触发报错。
解决方案
1. 提取有效分支后直接用Sympy绘图/求值
打印I1可查看分段结果:z>0时积分结果为常数4,z<0时结果为-4,z=0无定义。提取z>0的有效分支,指定正区间绘图即可:
# 接前面的积分计算代码 # 提取z>0对应的有效表达式,指定绘图范围避开z=0奇点 S.plot(4, (z, 0.1, 10), xlabel='z', ylabel='I1(z)', axis_center=(0,0))
定点求值时用evalf()方法代入数值计算即可:
# 计算z=5处的函数值 z_val = 5 res = float(I1.subs(z, z_val).evalf()) print(res) # 输出4.0
2. 转换为数值函数后用Matplotlib灵活绘图
如果需要自定义绘图样式、做后续数值计算,可以用lambdify把符号表达式转成NumPy兼容的数值函数:
import numpy as np import matplotlib.pyplot as plt from sympy.utilities.lambdify import lambdify # 接前面的积分计算代码 # 转成numpy可调用的数值函数,自动适配z的正负取值 I1_calc = lambdify(z, I1, 'numpy') # 生成z轴采样点,避开z=0 z_pos = np.linspace(0.01, 10, 500) z_neg = np.linspace(-10, -0.01, 500) z_arr = np.concatenate([z_neg, z_pos]) I1_arr = I1_calc(z_arr) # 绘图 plt.plot(z_arr, I1_arr) plt.xlabel('z') plt.ylabel('I1(z)') plt.axvline(0, color='gray', linestyle='--') plt.axhline(0, color='gray', linestyle='--') plt.grid(alpha=0.3) plt.show()
定点求值直接调用转换后的数值函数即可,比如I1_calc(2)直接返回4.0,I1_calc(-3)返回-4.0。
内容的提问来源于stack exchange,提问作者Rishab Navaneet
相关产品推荐
相关产品推荐

