Plotting a differential equation using Sympy.jl and Plots.jl

I was just checking out some parts of the Julia ecosystem and wanted to plot the solutions to some simple linear first order ordinary differential equations that were solved by Sympy.

So if I have a growth equation like

using SymPy
@vars t k
F = SymFunction("F")
diffeq = F'(t) - k*F(t)
res = dsolve(diffeq, F(t), ics=(F, 0, 2))

So I get an expected result like

F(t) = 2e^{kt}

However, when I go to plot this, the code will break

using Plots
plot(res, -1, 5) 

The message looks as below. I can include the full stacktrace if anyone is interested.

ERROR: MethodError: no method matching ##465(::Float64)
Closest candidates are:
  ##465(::Any, ::Any) at none:0

So I am just trying to figure out what I am missing to make the plot work? Any suggestions?

1 Like

You probably want to get a vector of times and the solution to your ODE at those times using your parameter, and then pass those vectors to plot. The plot function doesn’t know how to plot an arbitrary SymPy object.

That’s incorrect. It does know how to plot an arbitrary SymPy object. This just looks like a bug. I’d open an issue.

3 Likes

Oops! Sorry, should have checked first!

You need to plot an expression that can be “lambdified,” in this case, just the right hand side. You also need to have k set to a value, not a symbol. Something like this:

plot(rhs(res)(k=>2), 0, 2 )

The lambdify function could (should) be extended to handle Eq objects like res, so that might be worth an issue.

3 Likes

Thanks Chris. Wow, I did not imagine I would find a bug. I figured that so many people would have used SymPy to plot simple ODEs that it must be a well-traveled area of code. I will open a bug request and see what the response is. Thanks.

@j_verzani thanks for the explanation and the example. I saw that SymPy could plot other simple symbolic equations in a tutorial, but could not get it to work with the solutions to ODEs. I saw that a regular symbolic equation only had the right hand side and that ODE solutions had both a right and left hand side–but referenced the same “Symbol” type. So now I understand that I can extract the equation from the ODE solution using rhs(). I can use the code you provided :). I will also open up an issue with the SymPy.jl folks and see what they say.

1 Like

@jkbest2 thanks for the suggestion. You are right that I could have tried manually computing the output of the equation. I remember that in python Sympy a user can directly plot an ODE solution, so I figured it might be the same in Julia. Turns out Julia users can directly plot the solution too. I guess you never know till you try.

1 Like

Ahh, I didn’t know the Eq was different. Thanks!

New issue opened with SymPy.jl.

https://github.com/JuliaPy/SymPy.jl/issues/298

So we can track the progress there.