【问题标题】:How To Graph Points With Sympy?如何用 Sympy 绘制点?
【发布时间】:2019-04-16 19:03:34
【问题描述】:

我需要计算和绘制一个函数,它是前两个导数。然后,我需要在图形上绘制原始函数的最小和最大点。我已经计算了这些,但不知道如何绘制数据。 最小/最大点的 x 值为 criticalPoints[]

y 值为

criticalPointsY[]

这是出现错误的代码段。

equation=CreateFunction();
    firstDeriv=equation.diff(x);
    secondDeriv=firstDeriv.diff(x);
    print(equation);
criticalPoints=solveset(firstDeriv,x);
criticalPointsY=[];
for a in criticalPoints:
    criticalPointsY.append(equation.subs(x,a));

p=plot(equation,firstDeriv,secondDeriv,(x,-10,10));
# Need to add the critical points to the graph. We have them, and the
# y values, but need to put them on the graphs.
print(criticalPoints)
print(criticalPointsY);
for a in range(0, len(criticalPoints)):
    xval=criticalPoints[a];
    yval=criticalPointsY[a];
    plt.plot(xval, yval, 'ro')
p.show();
plt.show();

当我运行程序时,我得到了这个错误。 `

Traceback (most recent call last):
  File "--------", line 58, in <module>
    xval=criticalPoints[a];
TypeError: 'FiniteSet' object does not support indexing

我尝试在 p 上绘制点并得到不同的错误

    p.plot(criticalPoints,criticalPointsY);
AttributeError: 'Plot' object has no attribute 'plot'

有没有办法在这个图表上绘制点? (p)

【问题讨论】:

  • “'FiniteSet' 对象不支持索引”与 plottin 无关。 set 没有顺序,因此询问它的第一个或第二个元素是没有意义的。使用criticalPoints=list(solveset(firstDeriv,x))。另外,equation=CreateFunction(); 对那些不知道CreateFunction(); 是什么的人没有用处。
  • 我已经针对列表进行了调整,但是这些点绘制在不同的图表上,因为我将它们绘制在“plt”上。有没有办法在情节“p”上绘制它们?我尝试时收到第二个错误。 Create function 从用户已经收集的输入中返回一个函数 y,以 x 的形式。我没有把它包括在房间里。

标签: python matplotlib sympy graphing


【解决方案1】:

SymPy 图可以与p.extend 结合使用。但是,SymPy 图类型不包括点图,这是您想要的关键点。在这种情况下,应该直接使用 matplotlib,SymPy 无论如何都会这样做。

这是一个基于您的代码的示例,但没有分号,具有列表理解,并且所有绘图都使用了 matplotlib。请注意lambdify 提供了一种在一堆点上有效地评估一堆 SymPy 表达式的方法。

from sympy import *
import numpy as np
import matplotlib.pyplot as plt

x = symbols('x')
equation = x*exp(-x**2/10)
firstDeriv = equation.diff(x)
secondDeriv = firstDeriv.diff(x)
criticalPoints = list(solveset(firstDeriv, x))
criticalPointsY = [equation.subs(x, a) for a in criticalPoints]
xx = np.linspace(-10, 10, 1000)
yy = lambdify(x, [equation, firstDeriv, secondDeriv])(xx)
plt.plot(xx, np.transpose(yy))
plt.plot(criticalPoints, criticalPointsY, 'k*')
plt.show()

【讨论】:

  • 这些编辑有时有效,但很少使用多项式。 “plt.plot(xx, np.transpose(yy))” 行引发错误,说明 xx 和 np.transpose(yy) 具有不同的第一维,分别为 (1000,) 和 (3,)。我正在研究一个解决方案,但对为什么它们以不同的维度输出感到困惑。我正在用 "equation=x**2 +6" 测试它
  • 谢谢!帮助我想象一件事。我最初尝试在 SymPy 中使用其 plot3d & co 进行此操作,但被卡住了。使用 numpy+matplotlib 成功,完全跳过 SymPy。
【解决方案2】:

我已经解决了这个问题。由于方程的导数要么不存在,要么是一条水平线,因此出现了困境。

x = symbols('x')
UserInput()
equation = CreateFunction()
firstDeriv = equation.diff(x)
secondDeriv = firstDeriv.diff(x)
workingEquations=[]
hasEquations=False

我在这部分所做的是将方程转换为字符串进行测试,看看是否有 x 值。如果存在,我将等式附加到我们稍后将访问的数组中,否则,我绘制水平线。如果我们有一个带有变量的方程,我还会翻转一个布尔值来告诉我们。

if(not str(equation).find("x")==-1):
    workingEquations.append(equation)
    hasEquations=True
    print("True")
else:
    plt.axhline(y=equation)
if(not str(firstDeriv).find("x")==-1):
    workingEquations.append(firstDeriv)
else:
    plt.axhline(y=firstDeriv)
if(not str(secondDeriv).find("x")==-1):
    workingEquations.append(secondDeriv)
else:
    plt.axhline(y=secondDeriv)
try:
    criticalPoints = list(solveset(firstDeriv, x))
    criticalPointsY = [equation.subs(x, a) for a in criticalPoints]
    plt.plot(criticalPoints, criticalPointsY, 'k*')
except:
    print("No critical points")

如果我们有方程,我们会从添加了所有非水平方程的数组中绘制它们。

if(hasEquations):
    xx = np.linspace(-10, 10, 1000)
    yy = lambdify(x, workingEquations)(xx)
    plt.plot(xx, np.transpose(yy))
plt.show()

【讨论】:

    【解决方案3】:

    为了在这种情况下使用 Sympy 定义临界点,并在 matplotlib.pyplot 中绘制结果,sympy.utilities.lambdify 方法可用于生成要在 mathplotlib 中绘制的点列表(以下是 user6655984 的帖子)。

    数组已构建,但如果绘制了一个常数值,则其长度可能不同,这在numpy.transpose 步骤中存在问题。因此,在第一个 matplotlib.pyplot 之前传递了一个条件。

    from sympy import *
    import numpy as np
    import matplotlib.pyplot as plt
    
    x = symbols('x')
    equation = x**2 + 2 #OK = x*exp(-x**2/10) OR x**2 + 2
    firstDeriv = equation.diff(x)
    secondDeriv = firstDeriv.diff(x)
    criticalPoints = list(solveset(firstDeriv, x))
    criticalPointsY = [equation.subs(x, a) for a in criticalPoints]
    xx = np.linspace(-10, 10, 100)
    lam_f= lambdify(x, [equation, firstDeriv, secondDeriv])
    yy=[elem if  type(elem) == np.ndarray else np.full(len(xx), elem) for elem in lam_f(xx)]
    plt.plot(xx, np.transpose(yy))
    plt.plot(criticalPoints, criticalPointsY, 'k*')
    plt.show()
    

    【讨论】:

      【解决方案4】:

      其他答案的不同方法

      从 Plot 中获取图形和坐标轴。

      然后添加像点这样的附加图

      from sympy.plotting.plot import MatplotlibBackend, Plot
      
      def get_sympy_subplots(plot: Plot):
          backend = MatplotlibBackend(plot)
      
          backend.process_series()
          backend.fig.tight_layout()
          return backend.fig, backend.ax[0]
      
      p = plot(x, x**2, show=False)
      fig, axe = get_sympy_subplots(p)
      
      # add additional plots
      axe.plot([1,2,3], [1,2,3], "o")
      fig.show()
      

      【讨论】:

        猜你喜欢
        • 2016-05-28
        • 2023-01-11
        • 1970-01-01
        • 1970-01-01
        • 2015-07-19
        • 1970-01-01
        • 2018-04-08
        • 1970-01-01
        • 2020-10-04
        相关资源
        最近更新 更多