# Adding nullclines to a streamplot

**URL:** <https://discourse.julialang.org/t/adding-nullclines-to-a-streamplot/111750>\
**Category:** General Usage\
**Tags:** plotting, diffeq\
**Created:** [March 18, 2024, 5:51am UTC](https://discourse.julialang.org/t/adding-nullclines-to-a-streamplot/111750 "2024-03-18T05:51:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Thomas\_Petit](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thomas_petit/32/207813_2.png) [@Thomas\_Petit](https://discourse.julialang.org/u/Thomas_Petit)\
**Post date:** [March 18, 2024, 5:51am UTC](https://discourse.julialang.org/t/adding-nullclines-to-a-streamplot/111750/1 "2024-03-18T05:51:35Z")

</div>

Hello there,

I’m still extremely new to Julia and I’m currently trying to plot both the flow of an autonomous system of linear ODEs + their corresponding nullclines. The flow itself I’m using -

```julia
using Makie
using CairoMakie; cm = CairoMakie

odeSol(x,y) = Point(y - x^2 + 2, x*y - y^2) #x(t)' = ..., y(t)' = ...
scene = cm.Scene(size =(500,500))
cm.streamplot!(scene, odeSol, -5..5, -5..5,
            backgroundcolor = :black, colormap = cm.Reverse(:plasma),
    gridsize= (30,30), arrow_size = 0.1)

save("odeField.png", scene)

```

Is there some sophisticated way to add the nullclines here that I should be using?

Thank you in advance a lot.

---

<div class="post-metadata">

**Author:** ![JonasWickman](https://avatars.discourse-cdn.com/v4/letter/j/9de0a6/32.png) [@JonasWickman](https://discourse.julialang.org/u/JonasWickman)\
**Post date:** [March 18, 2024, 6:11pm UTC](https://discourse.julialang.org/t/adding-nullclines-to-a-streamplot/111750/2 "2024-03-18T18:11:01Z")

</div>

Something like this should do the trick:

```julia
using CairoMakie
fig = Figure()
fx(x,y) = y - x^2 + 2
fy(x,y) = x*y - y^2
odeSol(x,y) = Point2(fx(x,y), fy(x,y)) #x(t)' = ..., y(t)' = ...
ax = Makie.Axis(fig[1,1])
streamplot!(ax, odeSol, -5..5, -5..5,
    backgroundcolor = :black, colormap = cm.Reverse(:plasma),
    gridsize= (30,30), arrow_size = 0.1)

xs = range(-5, 5; length = 201)
ys = range(-5, 5; length = 201)

FX = [fx(x,y) for x ∈ xs, y ∈ ys]
FY = [fy(x,y) for x ∈ xs, y ∈ ys]

contour!(ax, xs, ys, FX; levels = [0.0], color = :black)
contour!(ax, xs, ys, FY; levels = [0.0], color = :gray, linestyle = :dash)
fig 

save("odeField.png", fig)

```

![odeField](https://global.discourse-cdn.com/julialang/original/3X/2/1/21783bd0175d36590a45ffa0afa954ac6110c170.png)

---

<div class="post-metadata">

**Author:** ![Thomas\_Petit](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thomas_petit/32/207813_2.png) [@Thomas\_Petit](https://discourse.julialang.org/u/Thomas_Petit)\
**Post date:** [March 18, 2024, 6:42pm UTC](https://discourse.julialang.org/t/adding-nullclines-to-a-streamplot/111750/3 "2024-03-18T18:42:42Z")

</div>

Thank you a lot! I’ve added some minor aesthetic changes as well

```julia
using CairoMakie; cm = CairoMakie
using LaTeXStrings

fig = cm.Figure()
fx(x,y) = y - x^2 + 2
fy(x,y) = x*y - y^2
odeSol(x,y) = Point2(fx(x,y), fy(x,y)) #x(t)' = ..., y(t)' = ...
ax = Makie.Axis(fig[1,1],
                xlabel = "X",
                ylabel = "Y",
                title = "Nullclines and ODE flow field.")
cm.streamplot!(ax, odeSol, -5..5, -5..5,
    colormap = :grays, alpha = 0.2,
    gridsize= (30,30), arrow_size = 0.1)

xs = range(-5, 5; length = 201)
ys = range(-5, 5; length = 201)

FX = [fx(x,y) for x ∈ xs, y ∈ ys]
FY = [fy(x,y) for x ∈ xs, y ∈ ys]

cm.contour!(ax, xs, ys, FX; levels = [0.0], color = :blue, linestyle = :dash,
            linewidth = 2, label = L"\frac{dx}{dt} = 0")
cm.contour!(ax, xs, ys, FY; levels = [0.0], color = :orange, linestyle = :dash,
            linewidth = 2, label = L"\frac{dy}{dt} = 0")
cm.axislegend(ax)
fig

save("odeField.png", fig)

```

Would you know how to fix the legend so that it displays the colours assigned to the contour lines?

---

<div class="post-metadata">

**Author:** ![JonasWickman](https://avatars.discourse-cdn.com/v4/letter/j/9de0a6/32.png) [@JonasWickman](https://discourse.julialang.org/u/JonasWickman)\
**Post date:** [March 18, 2024, 7:03pm UTC](https://discourse.julialang.org/t/adding-nullclines-to-a-streamplot/111750/4 "2024-03-18T19:03:19Z")

</div>

I think for contourlines you have to manually specify the legend entries (not, sure, but the below code does work)

```julia
using CairoMakie; cm = CairoMakie
using LaTeXStrings

fig = cm.Figure()
fx(x,y) = y - x^2 + 2
fy(x,y) = x*y - y^2
odeSol(x,y) = Point2(fx(x,y), fy(x,y)) #x(t)' = ..., y(t)' = ...
ax = Makie.Axis(fig[1,1],
                xlabel = "X",
                ylabel = "Y",
                title = "Nullclines and ODE flow field.")
cm.streamplot!(ax, odeSol, -5..5, -5..5,
    colormap = :grays, alpha = 0.2,
    gridsize= (30,30), arrow_size = 0.1)

xs = range(-5, 5; length = 201)
ys = range(-5, 5; length = 201)

FX = [fx(x,y) for x ∈ xs, y ∈ ys]
FY = [fy(x,y) for x ∈ xs, y ∈ ys]

cm.contour!(ax, xs, ys, FX; levels = [0.0], color = :blue, linestyle = :dash,
            linewidth = 2, label = L"\frac{dx}{dt} = 0")
cm.contour!(ax, xs, ys, FY; levels = [0.0], color = :orange, linestyle = :dash,
            linewidth = 2, label = L"\frac{dy}{dt} = 0")

leg_elems = [
    LineElement(color = :blue, linestyle = :dash),
    LineElement(color = :orange, linestyle = :dash)
]
leg_strs = [
    L"\frac{dx}{dt} = 0",
    L"\frac{dy}{dt} = 0"
]

Legend(fig[1,1], leg_elems, leg_strs;
    halign = :right,
    valign = :top,
    tellwidth = false,
    tellheight = false
)
fig

```

---

<div class="post-metadata">

**Author:** ![Thomas\_Petit](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thomas_petit/32/207813_2.png) [@Thomas\_Petit](https://discourse.julialang.org/u/Thomas_Petit)\
**Post date:** [March 18, 2024, 7:18pm UTC](https://discourse.julialang.org/t/adding-nullclines-to-a-streamplot/111750/5 "2024-03-18T19:18:02Z")

</div>

Thanks a lot, this is perfect.
