Search code examples
pythonmatplotlibsympygraphing

How To Graph Points With Sympy?


I need to calculate and graph a function and it's first two derivatives. Then, I need to graph the minimum and maximum points of the original function on the graph. I have calculated these, but am lost as to how to graph the data. The x values for the minimum/maximum points are criticalPoints[]

with the y values being

criticalPointsY[]

Here is the segment of code where the error appears.

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();

When I run the program, I get this error. `

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

I have tried plotting the points on p and get a different error

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

Is there a way to plot points on this graph? (p)


Solution

  • I have fixed the issue. The dilemma was occurring due to equations who's derivatives would either be nonexistent, or a horizontal line.

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

    What I do at this segment is test by converting the equation to a string and see if there is an x value. If one is present, I append the equation to an array we will access later, otherwise, I graph the horizontal line. I also flip a bool to tell us later if we have an equation with a variable.

    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 we have equations, we graph them from that array we appended all non-horizontal equations to.

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