You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sympy绘制分段函数图像添加垂直竖线触发报错问题

问题说明

在Jupyter Notebook中定义如下分段弯矩函数:

from sympy import *
Mt, F1, Fax, Fay, Faz, Fbz, Fby, l, x, alpha, a, b, c, d, e = symbols('Mt, F1, Fax, Fay, Faz, Fbz, Fby, l, x, alpha, a, b, c, d, e')

My1 = 0
My2 = sin(alpha)*F1*(x-a)
My3 = sin(alpha)*F1*(x-a) - Fay*(x-(a+b))
My4 = sin(alpha)*F1*(x-a) - Fay*(x-(a+b))- Fby*(x-(a+b+c))
My5 = 0

My = Piecewise((My1, x<a), (My2, And(a<x, x<b)), (My3, And(b<x, x<c)), (My4, And(c<x, x<d)), (My5, And(d<x, x<e)))

My

使用如下代码绘制函数图像,基础效果符合预期:

params = {alpha: 30, a:0.024, b:0.074, c:0.132, d:0.189, e:0.219, F1:11700, Fay:-8762.57, Fby:26973.41}
plot(My.subs(params), (x, 0, e.subs(params)), title= "Biegemoment $M_y(x)$")

初始绘图结果
现在需要在x=0.074位置添加一条垂直竖线,尝试调整adaptive、nb_of_points参数时触发如下浮点运算报错:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/usr/lib/python3/dist-packages/sympy/plotting/experimental_lambdify.py in __call__(self, *args)
    118             temp_args = (np.array(a, dtype=np.complex) for a in args)
--> 119             results = self.vector_func(*temp_args)
    120             results = np.ma.masked_where(

...

/usr/lib/python3/dist-packages/numpy/lib/function_base.py in _vectorize_call(self, func, args)
   2165                       for a in args]
   2166 
-> 2167             outputs = ufunc(*inputs)
   2168 
   2169             if ufunc.nout == 1:

FloatingPointError: invalid value encountered in ? (vectorized)
报错原因
  1. 核心诱因是分段函数定义存在逻辑漏洞:函数表达式中用到的分段节点为a、a+b、a+b+c、a+b+c+d,但Piecewise里写的区间判断条件是x<b、x<c、x<d、x<e,两者分界位置不匹配,导致x轴上存在部分区间没有被任何分段条件覆盖,属于无定义区域。默认自适应采样可能刚好避开了这些异常点,一旦调整nb_of_points增加采样密度,采样点落到无定义区域就会触发计算错误。
  2. 额外注意:SymPy的三角函数默认输入为弧度,直接传alpha:30会按30弧度计算,和工程上常用的30度物理意义不符,如果要使用角度单位需要手动转弧度。
实现方案

添加垂直竖线完全不需要修改原函数的采样参数,SymPy的plot底层封装了Matplotlib,直接调用底层接口添加竖线是最稳定的方案,不会涉及原函数的额外采样计算,自然可以规避报错。
如果已经验证过分段函数的物理意义不需要修改,直接用如下代码即可:

params = {alpha: 30, a:0.024, b:0.074, c:0.132, d:0.189, e:0.219, F1:11700, Fay:-8762.57, Fby:26973.41}
x_end = e.subs(params)
# 绘制原函数,暂不显示
p = plot(My.subs(params), (x, 0, x_end), title= "Biegemoment $M_y(x)$", show=False)
# 获取底层Matplotlib轴对象
ax = p._backend.ax[0]
# 添加x=0.074位置的垂直竖线,可自定义颜色、线型、线宽
ax.axvline(x=0.074, color='crimson', linestyle='--', linewidth=1.5, label='x = 0.074')
ax.legend()
# 展示最终图像
p.show()

如果要彻底解决采样报错的隐患,建议修正分段函数的区间判断条件,让区间分界和表达式中的节点完全对应,同时修正角度单位问题:

# 若alpha输入为角度,可将My2-My4中的sin(alpha)替换为sin(alpha*pi/180)
My = Piecewise(
    (My1, x<a), 
    (My2, And(a<=x, x<a+b)), 
    (My3, And(a+b<=x, x<a+b+c)), 
    (My4, And(a+b+c<=x, x<a+b+c+d)), 
    (My5, x>=a+b+c+d)
)

修正后再调整采样参数也不会触发浮点错误。

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 06:34:03