# How to extract the dependency (also called causal) graph of a ModelingToolkit.jl ODE model?

**URL:** <https://discourse.julialang.org/t/how-to-extract-the-dependency-also-called-causal-graph-of-a-modelingtoolkit-jl-ode-model/130576>\
**Category:** Modelling & Simulations\
**Tags:** modelingtoolkit, graphs\
**Created:** [July 9, 2025, 2:00pm UTC](https://discourse.julialang.org/t/how-to-extract-the-dependency-also-called-causal-graph-of-a-modelingtoolkit-jl-ode-model/130576 "2025-07-09T14:00:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [July 9, 2025, 2:00pm UTC](https://discourse.julialang.org/t/how-to-extract-the-dependency-also-called-causal-graph-of-a-modelingtoolkit-jl-ode-model/130576/1 "2025-07-09T14:00:29Z")

</div>

I am trying to create the dependency (sometimes called causal) graph of a complex ODE System I have created symbolically with MTK. To do this I am using the dependency graph functionality of MTK [found here], however I cannot interpret it correctly to create what I need. I will present a MWE and what I want to create and perhaps someone can help me interpret and process the `asgraph` output to get what I need?

Here is the simple model:

```julia
using ModelingToolkit
using ModelingToolkit: t_nounits as t

@variables x(t) = 1.0 y(t) = 1.0 z(t)

eqs = [
    Differential(t)(x) ~ -2x + z,
    Differential(t)(y) ~ -2y,
    z ~ x*y,
]

sys = ODESystem(eqs, t; name = :test)

ssys = structural_simplify(sys)

go = asgraph(sys; variables = [x, y, z])
gs = asgraph(ssys; variables = [x, y, z])

```

the output of `go` (which is what I believe I must use) is:

```julia
julia> go
BipartiteGraph with (3, 3) (𝑠,𝑑)-vertices
  # src dst
 1 [1, 3] [1, 3]
 2 [2] [2, 3]
 3 [1, 2] [1]

```

What I want to create is:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/0/b/0b54d590b338fcaca417d056c55eeaf98826da6d.png)

(I know how to plot graphs if I create the graph above).

Ultimately, I want to process the graph above to create the true and full causal graph of the system which is:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/3/0/3008ecdfc3098fc7a17157a2081866074d3aed40.png)

However just getting the first picture is more than enough for me!

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [July 9, 2025, 3:25pm UTC](https://discourse.julialang.org/t/how-to-extract-the-dependency-also-called-causal-graph-of-a-modelingtoolkit-jl-ode-model/130576/2 "2025-07-09T15:25:06Z")

</div>

Your first picture is just the `src` from `go` with two changes where you change indices for a variable to its derivative if it’s a differential variable. Did you try that?

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [July 9, 2025, 5:29pm UTC](https://discourse.julialang.org/t/how-to-extract-the-dependency-also-called-causal-graph-of-a-modelingtoolkit-jl-ode-model/130576/3 "2025-07-09T17:29:50Z")

</div>

Thanks that helps a bit. I realized that with this approach I need to keep track of also the order of equations that the `sys` stores for later processing, which for my actual use case is rather tedious.

Looking later down in the same documentation page, I actually found something that almost automatically creates what I need:

```julia
variables = [x, y, z]
varvardep = varvar_dependencies(asgraph(sys; variables), variable_dependencies(sys; variables))

using CairoMakie, GraphMakie
graphplot(varvardep; nlabels = string.([x, y, z]))

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/0/3/031eaaecb9d9b85353eb7a47e7e93287c02891f0.png)

I think from the above result, I only need to process all self links to be new links pointing to new variables, the derivatives.

Is it correct to assume that all self links are from variables to their derivatives? Can you imagine any other scenario where a self-link would exist? (I can’t from the top of my head). I understand that given that I know a-priory which variables of my system are differential I can manually make this distinction on the `variables` vector above, but I am hoping to get a programmatic way to distinguish this. Or is there perhaps a function offered by MTK `is_differential(sys, variable)` that spits `true` if that’s the case?

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [July 9, 2025, 5:34pm UTC](https://discourse.julialang.org/t/how-to-extract-the-dependency-also-called-causal-graph-of-a-modelingtoolkit-jl-ode-model/130576/4 "2025-07-09T17:34:09Z")

</div>

ah actually my approach above is simply incorrect.

What I have to do is first identify which of the variables are time-derivative’d. Then, for each, I have to make all incoming links point to a new variable (the derivative). So a programmatic way to check if a variable is derivative’d (i.e., a state variable) in the `sys` would be great!

---

<div class="post-metadata">

**Author:** ![SebastianM-C](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sebastianm-c/32/2480_2.png) [@SebastianM-C](https://discourse.julialang.org/u/SebastianM-C)\
**Post date:** [July 9, 2025, 7:31pm UTC](https://discourse.julialang.org/t/how-to-extract-the-dependency-also-called-causal-graph-of-a-modelingtoolkit-jl-ode-model/130576/5 "2025-07-09T19:31:17Z")

</div>

I’m using something like this:

```julia
function get_diff_variables(sys)
    only.(get_variables.(getproperty.(diff_equations(sys), :lhs)))
end

```

where `get_variables` is from Symbolics and `diff_equations` from ModelingToolkit.
