Causal Modeling Diagrams in TikZ

Here, I’ll walk through how to code causal modeling diagrams in TikZ, like the following:

intervention-2.jpg

TikZ is a package for LaTeX that is included in the base distribution. If you’re not sure what LaTeX is, or would like some help installing and getting started with it, I recommend AJ Hildrebrand’s site. Once you’re set up and have some familiarity with typesetting basic mathematical and logical formulas, then it’s time for TikZ!

Basic Stuff

The first thing to do is load TikZ in your preamble. We’ll also need to direct your compiler to load the following TikZ libraries: patternsshapes, and decorations:

\usepackage
\usetikzlibrary

Next, let’s draw some basic shapes, for instance, a circle:

\begin{tikzpicture}
\draw[-] (0,0) circle (1cm);
\end{tikzpicture}
circle11.jpg

The \draw command tells us to draw something. We specify that what we want is a solid line (that’s the [-] part). Next, we have the coordinates specifying the center of the circle, that’s (0,0). We specify the radius of the circle as 1cm. Finally, notice that we end the command with a semicolon, ;. Note that TikZ is built on a grid system. We can overlay the grid to see what’s going on in the background:

\begin{tikzpicture}
\draw[help lines] (-2,-2) grid (2,2);
\draw[-] (0,0) circle (1cm);
\end{tikzpicture}
grid.jpg

We also use the \draw command to draw lines and arrows:

\begin{tikzpicture}
\draw[help lines] (-2,-2) grid (2,2);
\draw[-] (0,0) circle (1cm);
\draw[-] (-2,-2) -- (0,0);
\draw[->] (-1,1.5) -- (1.5,1.5) -- (1.5,-1.5);
\end{tikzpicture}
grid2-1.jpg

The other crucial component of TikZ is the \node command, which allows you to specify a point with various properties, like a circle that contains some text:

\begin{tikzpicture}
\node[circle,draw] at (0,0) (A) ;
\end{tikzpicture}
node.jpg

Here, draw specifies that we want to draw the circle around the node, at (0,0) tells us where the node is located on the grid, (A) labels the node (this will be useful for referring back to it later), and {A} specifies what is to be written inside of the node. We can position nodes relative to one another using the commands

  • right of

  • left of

  • above of

  • below of

in various combinations:

\begin{tikzpicture}
\node[circle,draw] at (0,0) (A) ;
\node[circle,draw,right of=A] (B) ;
\node[circle,draw,below right of=B] (C) ;
\end{tikzpicture}
node2.jpg

Finally, we can offset nodes from their relative positions using the xshift and yshift commands:

\begin{tikzpicture}
\node[circle,draw] at (0,0) (A) ;
\node[circle,draw,right of=A] (B) ;
\node[circle,draw,below right of=B,xshift=1cm] (C) ;
\node[circle,draw,below right of=B,yshift=-1cm] (D) ;
\end{tikzpicture}
node3.jpg

Putting Things Together

We can now start to combine nodes and arrows to generate basic causal model diagrams. To start, I’ll start our tikzpicture with the command \begin{tikzpicture}[node distance=2cm], which will specify that we want 2cm between nodes rather than the usual 1cm. Let’s start simple:

\begin{tikzpicture}[node distance=2cm]
\node[circle,draw] at (0,0) (A) {\bf A};
\node[circle,draw,right of=A,yshift=1cm] (B) {\bf B};
\node[circle,draw,right of=A,yshift=-1cm] (C) {\bf C};
\draw[->] (A) -- (B);
\draw[->] (A) -- (C);
\end{tikzpicture}
i1.jpg

To draw the lines connecting B and C to D, notice that I specify the path more explicitly, marking the waypoints I want the line to trace through:

\begin{tikzpicture}[node distance=2cm]
\node[circle,draw] at (0,0) (A) {\bf A};
\node[circle,draw,right of=A,yshift=1cm] (B) {\bf B};
\node[circle,draw,right of=A,yshift=-1cm] (C) {\bf C};
\node[circle,draw,right of=B,yshift=-1cm] (D) {\bf D};
\draw[->] (A) -- (B);
\draw[->] (A) -- (C);
\draw[->] (B) -- (3,1) -- (3,0) -- (D);
\draw[-] (C) -- (3,-1) -- (3,0);
\end{tikzpicture}
i2-1.jpg

We can add squiggly lines, label nodes, and make them either bold or dashed or dotted using the commands:

  • \draw[snake]

  • \node[thick]

  • \node[dashed]

  • \node[dotted]

  • \node[label=above: … ]

\begin{tikzpicture}[node distance=2cm]
\node[circle,draw,dashed] at (0,0) (A) {\bf A};
\node[circle,draw,right of=A,yshift=1cm,dotted] (B) {\bf B};
\node[circle,draw,right of=A,yshift=-1cm,thick,label=above:\tiny{\sf F}] (C) {\bf C};
\draw[->] (A) -- (B);
\draw[->] (A) -- (C);
\draw[snake] (-1,2) -- node[at start, above]  (-1,-2);
\end{tikzpicture}
 
i3-1.jpg
 

Some Finishing Touches

You’re now on your way to making some fun causal modeling diagrams. I want to conclude with a few advanced features to get things looking even better.

The first is a tikzset, which you can use to define global properties that you can call on inside of your tikzpictures. You’ll want to add tikzsets to your preamble (before \begin{document}). Here is one:

\tikzset{
intervention/.style ={node distance=2cm},
p/.style={circle,draw,minimum size=0.5cm},
arrow/.style={->,>=stealth,shorten >=1pt},
snake/.style={-,decorate, decoration=snake}
}

What this does is specify my node distance and then defines three parameters: parrow, and snake. For instance, p/.style={circle,draw,minimum size=0.5cm} just allows me to write:

\node[p]

instead of

\node[circle,draw,minimum size=0.5cm]

Now, our code above can be simplified to:

\begin{tikzpicture}[intervention]
\node[p] at (0,0) (A) {\bf A};
\node[p,right of=A,yshift=1cm] (B) {\bf B};
\node[p,right of=A,yshift=-1cm] (C) {\bf C};
\node[p,right of=B,yshift=-1cm] (D) {\bf D};
\draw[arrow] (A) -- (B);
\draw[arrow] (A) -- (C);
\draw[arrow] (B) -- (3,1) -- (3,0) -- (D);
\draw[-] (C) -- (3,-1) -- (3,0);
\end{tikzpicture}
i4.jpg

(Notice also the nicer arrowheads and the spacing on the arrows is a bit cleaner too!)

Finally, we can add split nodes using the circle split command in \node to create:

\begin{tikzpicture}
\node[circle split, draw] (A) {{\bf A} \nodepart {\bf B}};
\end{tikzpicture}
i5.jpg

There you have it! Hopefully this gives you a sense of how to make your own causal modeling diagrams in TikZ. Check back in for more tutorials like this soon.