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

为何运行相同Python SymPy绘图代码每次得到不同图像?

SymPy大区间绘图结果不一致的原因分析

问题复现

在Linux Mint 21.2、Python 3.10环境下运行SymPy 1.9的绘图代码:

import sympy
print(sympy.__version__) # '1.9'
from sympy import symbols, sin
from sympy.plotting import plot
t = symbols('t')
plotP = plot(50*sin(t/30)+30*sin(1.3*t/30)+20*sin(2.7*t/30)+25*sin(3.7*t/30), (t, 24800, 35800))

出现的异常现象:

  • 每次运行生成的图像形态都有差异
  • 升级SymPy、matplotlib版本或改用shell执行脚本,问题仍存在
  • 切换为0-400这类小区间绘图时,结果完全一致,图像平滑无异常

核心原因

  1. 自适应采样的随机性
    SymPy的plot函数默认采用自适应采样逻辑:先在区间内取少量初始点,再根据曲线波动程度动态补充采样点。但在跨度11000的大区间下,函数包含多个不同频率的正弦项,高频项的峰值间距(比如3.7*t/30的周期约为50.6)远小于初始采样点的间隔,导致每次采样捕捉到的峰值位置存在随机性,最终绘制的曲线形态出现差异。

  2. 大数值下的浮点精度误差
    当t取值达到2万以上时,t/30这类大数值无法被浮点数精确表示,计算正弦函数时会产生微小的精度偏差。多个正弦项的偏差叠加后,会放大为曲线整体形态的差异,这也是每次绘图结果不同的诱因之一。

  3. 小区间的稳定逻辑
    在0-400的小区间里,采样点密度足够覆盖所有正弦项的周期,且t数值小,浮点精度误差可以忽略,自适应采样能稳定捕捉曲线特征,因此每次绘图结果完全一致。

稳定绘图的解决思路

如果需要大区间下的稳定绘图结果,可以尝试两种方式:

  • 关闭自适应采样,手动指定足够多的采样点:
    plotP = plot(50*sin(t/30)+30*sin(1.3*t/30)+20*sin(2.7*t/30)+25*sin(3.7*t/30), (t, 24800, 35800), adaptive=False, nb_of_points=10000)
    
  • 将符号函数转换为数值函数,直接用matplotlib控制采样精度:
    import numpy as np
    import matplotlib.pyplot as plt
    t_vals = np.linspace(24800, 35800, 20000)
    f = lambda t: 50*np.sin(t/30)+30*np.sin(1.3*t/30)+20*np.sin(2.7*t/30)+25*np.sin(3.7*t/30)
    plt.plot(t_vals, f(t_vals))
    plt.show()
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 10:35:24