This tutorial shows you how to create node-link diagrams in Julia using Graphs.jl and GraphPlot.jl. These diagrams are perfect for system maps — think stocks connected by flows, or components linked by relationships. You’ll learn how to build a graph, label nodes and edges, apply colours, and export your diagram. We will also use Compose.jl to draw the graphs, and Cairo.jl and Fontconfig.jl to render the graphs as SVGs for display.
Your first graph: nodes and edges
A graph is a collection of nodes (vertices) connected by edges. Let’s create a simple graph with four nodes connected in a chain:
importPkgusingGraphsusingGraphPlotusingMeasuresusingComposeimportCairoimportFontconfig# Create a graph with 4 nodes and 3 edgesg = Graphs.path_graph(4)# Draw itgplot(g) |>SVG()
1
You can replace SVG() with PDF() or PNG() and pass a filename as the argument, e.g.PDF("figure.pdf").
You should see a diagram with four circles connected by lines. path_graph(4) creates nodes 1–2–3–4 linked in sequence.
TipHow to view the plot
In VS Code: Install Cairo.jl (Pkg.add("Cairo")). The plot will appear in the Plot pane.
In the REPL (terminal): Use gplothtml(g) to open it in your browser.
Adding node labels
Without labels, you can’t tell the nodes apart. Add labels as a vector of strings (one per node):
In a stock-and-flow diagram, flows have direction. A directed graph uses arrows to show which way material (money, energy, information) moves. GraphPlot.jl draws arrowheads automatically on directed edges.
Different layouts reveal different structure. Try these on your graph:
# Force-directed (default, good for most cases)gplot(g, layout=spring_layout, nodelabel=stock_labels) |>SVG(15cm, 10cm)
# Circular --- good for closed loops like nutrient cyclesgplot(g, layout=circular_layout, nodelabel=stock_labels) |>SVG(15cm, 10cm)
Saving your diagram
Use Compose.jl with Cairo.jl and Fontconfig.jl to export your diagram as PNG, PDF, or SVG:
usingComposeimportCairoimportFontconfig# Create the plotp =gplot(g, nodelabel=stock_labels, nodefillc=nodefillc)# Save as PNGp |>PNG("stock-flow.png", 16cm, 16cm)# Save as PDF (vector format, scales to any size)p |>PDF("stock-flow.pdf", 16cm, 16cm)# Save as SVGp |>SVG("stock-flow.svg", 16cm, 16cm)
Complete example: carbon cycle diagram
Here is a full script you can copy and run, using SimpleDiGraph instead of path_digraph as above. It builds a simple carbon-cycle model with four stocks (atmosphere, plants, soil, ocean) and five flows.
GraphPlot.jl only draws circular nodes. If you need rectangles, diamonds, or custom shapes for stock-and-flow diagrams (e.g., rectangles for stocks, valves for flows), you will need a different package:
GraphRecipes.jl (with Plots.jl) — supports markershape for different node shapes.
GraphMakie.jl — the most flexible; supports custom node markers, interactive plots, and 3D.
You can install these packages the same way as the others (Pkg.add("GraphRecipes") or Pkg.add("GraphMakie")).
Troubleshooting
Symptom
Fix
Package GraphPlot not found
Run Pkg.add("GraphPlot") in the REPL.
Plot doesn’t appear in VS Code
Run Pkg.add("Cairo"), then restart Julia.
Labels overlap nodes
Increase nodelabeldist (e.g., 2.0).
“No display backend” error
Install Cairo (Pkg.add("Cairo")) and try using Cairo first.
All nodes same colour
nodefillc must be a vector with length equal to the number of nodes.
Next steps
Experiment with shell_layout to group nodes in concentric rings.
Use nodesize to make important stocks larger relative to others.