Getting Started

Prerequisites

DAGMakie requires a Makie backend. CairoMakie is typical for static figures:

using Pkg
Pkg.add("CairoMakie")
Pkg.add("Graphs")

A chain DAG

using Graphs, DAGMakie, CairoMakie

# Create a simple chain: A → B → C
g = SimpleDiGraph(3)
add_edge!(g, 1, 2)
add_edge!(g, 2, 3)

# Plot with labels
fig, ax, p = dagplot(g, nlabels=["A", "B", "C"])
fig
Example block output

dagplot returns:

  • fig: the Figure
  • ax: the Axis
  • p: the GraphPlot (node positions and plot attributes)

Edge labels (structural parameters)

GraphMakie elabels pass through dagplot. Prefer structural_edge_labels so labels follow Graphs.edges(g) order and optional LaTeX maths (path coefficients or short mechanism fragments):

g_w, labels_w = confounding_graph(["Z", "X", "Y"])
# B[i,j] = structural weight on j → i
B = [
    0.0  0.0  0.0;
    0.8  0.0  0.0;
    0.5  1.2  0.0;
]
fig, ax, p = dagplot(g_w;
    nlabels = labels_w,
    elabels = structural_edge_labels(g_w, B; digits = 1),
    elabels_fontsize = 14,
    elabels_distance = 12,
    elabels_rotation = 0,
    padding = 0.45,
)
fig
Example block output

Symbolic TeX on the same topology:

fig, ax, p = dagplot(g_w;
    nlabels = labels_w,
    elabels = structural_edge_labels(
        g_w,
        ["\\beta_{ZX}", "\\beta_{ZY}", "\\beta_{XY}"];
        latex = true,
    ),
    elabels_fontsize = 14,
    elabels_distance = 12,
    elabels_rotation = 0,
    padding = 0.45,
)
fig
Example block output

See Basic plotting for more elabels_* options.

Saving figures

save("my_dag.png", fig)           # PNG
save("my_dag.pdf", fig)           # PDF (vector)
save("my_dag.svg", fig)           # SVG (vector)

Common patterns

Convenience constructors for frequent causal structures:

fig = Figure(size = (1000, 220))
ax1 = Axis(fig[1, 1], title = "Chain")
ax2 = Axis(fig[1, 2], title = "Fork")
ax3 = Axis(fig[1, 3], title = "Collider")
ax4 = Axis(fig[1, 4], title = "Confounding")

g_chain, _ = chain_graph(["X", "Y", "Z"])
g_fork, _ = fork_graph(["X", "Y", "Z"])
g_collider, _ = collider_graph(["X", "Y", "Z"])
g_conf, _ = confounding_graph(["Z", "X", "Y"])

dagplot!(ax1, g_chain, nlabels = ["X", "Y", "Z"])
dagplot!(ax2, g_fork, nlabels = ["X", "Y", "Z"])
dagplot!(ax3, g_collider, nlabels = ["X", "Y", "Z"])
# Triangle layout is applied automatically for the Z→X→Y, Z→Y pattern
dagplot!(ax4, g_conf, nlabels = ["Z", "X", "Y"])
fig
Example block output

Each pattern also has a one-liner (dagplot_chain, dagplot_fork, …). Composed into one figure:

fig = Figure(size = (1100, 200))
ax1 = Axis(fig[1, 1], title = "chain")
ax2 = Axis(fig[1, 2], title = "fork")
ax3 = Axis(fig[1, 3], title = "collider")
ax4 = Axis(fig[1, 4], title = "confounding")
ax5 = Axis(fig[1, 5], title = "mediation")

g_chain, _ = chain_graph(["X", "Y", "Z"])
g_fork, _ = fork_graph(["X", "Y", "Z"])
g_collider, _ = collider_graph(["X", "Y", "Z"])
g_conf, _ = confounding_graph(["Z", "X", "Y"])
g_med, _ = mediation_graph(["X", "M", "Y"])
dagplot!(ax1, g_chain; nlabels = ["X", "Y", "Z"])
dagplot!(ax2, g_fork; nlabels = ["X", "Y", "Z"])
dagplot!(ax3, g_collider; nlabels = ["X", "Y", "Z"])
dagplot!(ax4, g_conf; nlabels = ["Z", "X", "Y"])
dagplot!(ax5, g_med; nlabels = ["X", "M", "Y"])
fig
Example block output

Stand-alone one-liners return (fig, ax, p):

fig, ax, p = dagplot_chain(["X", "Y", "Z"])
fig, ax, p = dagplot_fork(["X", "Y", "Z"])
fig, ax, p = dagplot_collider(["X", "Y", "Z"])
fig, ax, p = dagplot_confounding(["Z", "X", "Y"])
fig, ax, p = dagplot_mediation(["X", "M", "Y"])

Confounding, mediation, and mixed-graph helpers (dagplot_frontdoor, dagplot_iv_confounded, etc.) use fixed triangle layouts by default so shortcut and bidirected edges remain visible. Pass layout=... to override.

Multiple DAGs in one figure

fig = Figure(size = (900, 280))

ax1 = Axis(fig[1, 1], title = "Chain")
ax2 = Axis(fig[1, 2], title = "Fork")
ax3 = Axis(fig[1, 3], title = "Collider")

g_chain, _ = chain_graph(["A", "B", "C"])
g_fork, _ = fork_graph(["A", "B", "C"])
g_collider, _ = collider_graph(["A", "B", "C"])

dagplot!(ax1, g_chain, nlabels = ["A", "B", "C"])
dagplot!(ax2, g_fork, nlabels = ["A", "B", "C"])
dagplot!(ax3, g_collider, nlabels = ["A", "B", "C"])
fig
Example block output

See also