crash course to tikz [2 · positioning]

In the first tutorial, we learned about drawing diagrams as graphs and stylizing components of those graphs.

We constructed those graphs by placing nodes at fixed coordinates. However, visualizing the document grid may be tedious, especially when elements may have a perfectly simple orientation, relative to each other. For example, in this cycle consistency figure, you know that $F$ and $G$ should be midway between $X$ and $Y$, but it’s annoying to compute their exact locations.

1
2
3
4
5
6
7
\begin{tikzpicture}
    \node[draw] (x) {$X$};
    \node[draw,right=1cm of x] (y) {$Y$};
    \path[->]
        (x) edge[bend left=30] node[pos=0.5,above] {$G$} (y)
        (y) edge[bend left=30] node[pos=0.5,below] {$F$} (x);
\end{tikzpicture}

Luckily, there are multiple ways to position nodes beyond specifying coordinates. Let’s explore some of them.

Note: The TeX source for this post may be found here.

Example: Nodes on paths

Before we dive deep, let’s visit a motivating example of relative positioning. For diagrams, I find that it is extremely useful to place nodes on paths as labels.

1
2
3
4
5
6
7
\begin{tikzpicture}[every node/.append style={fill=white}]
    \path[->] (0,0) edge
        node[pos=0.25] {0.25}
        node[pos=0.5] {0.5}
        node[pos=0.75] {0.75}
    (6,0);
\end{tikzpicture}

You may specify any pos between 0 and 1, which correspond to the start and end of a path respectively.

1
2
3
4
5
\begin{tikzpicture}
    \path (0,0)
        edge[bend left=15] node[pos=0.5,above] {above} (3,0)
        edge[bend right=15] node[pos=0.5,below] {below} (3,0);
\end{tikzpicture}

Often, we don’t want the nodes directly on top of the path. In these cases, you can easily specify that a node should be placed “above” or “below” the path. We will formalize this idea later.

With this example in mind, let’s start from the fundamentals.

Anchors

In the figure above, you may notice that the center node is vertically centered, while the above and below nodes are positioned conveniently not to obscure the label. This behavior is due to anchors, which specify which part of a node its position is rooted to.

At first, it may be slightly counterintuitive that an east anchor places the node to the west, and vice versa.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
\begin{tikzpicture}[every node/.append style={draw, minimum size=0.8cm}]
    \node[draw=none] at (0,0) {\textbullet};
    \node[anchor=center, label=below:{center}] at (0,0) {};
    \node at (0,0) {};

    \node[draw=none] at (2,0) {\textbullet};
    \node[anchor=west] at (2,0) {west};
    \node[anchor=east] at (2,0) {east};

    \node[draw=none] at (4,0) {\textbullet};
    \node[anchor=north] at (4,0) {north};
    \node[anchor=south] at (4,0) {south};

    \node[draw=none] at (6,0) {\textbullet};
    \node[anchor=north west] at (6,0) {nw};
    \node[anchor=north east] at (6,0) {ne};
    \node[anchor=south east] at (6,0) {se};
    \node[anchor=south west] at (6,0) {sw};
\end{tikzpicture}

By default, each node is anchored at center. There are also 8 other built-in anchors, depicted above. It is helpful to change anchors when nodes are explicitly placed relative to other elements. However, you usually don’t have to adjust the anchor yourself; TikZ has very nice defaults for this behavior, as we will see next.

Relative positioning}

The positioning library allows you to place nodes at a specified direction and distance from other nodes. To load the library, include in your preamble:

\usetikzlibrary{positioning}

You place nodes in any of 8 directions.

1
2
3
4
5
6
7
8
9
10
11
12
\begin{tikzpicture}
    \draw[help lines] (-2,-2) grid (2,2);
    \node (0) {origin};
    \node[right=of 0] {right};
    \node[below right=of 0] {below right};
    \node[below=of 0] {below};
    \node[below left=of 0] {below left};
    \node[left=of 0] {left};
    \node[above left=of 0] {above left};
    \node[above=of 0] {above};
    \node[above right=of 0] {above right};
\end{tikzpicture}

These relative positions also change the default anchor of the node.

Node labels

You may have noticed that labels for each node are generally placed in the absolute center. While this behavior is reasonable for most cases, sometimes you will need to shift the position of a label. For example, in the anchors figure above, it was more clear to place the label below the node, rather than in the middle. Luckily, it’s simple to do so.

1
2
3
4
5
6
\begin{tikzpicture}
    \node[label=left:left] at (0,0) {\textbullet};
    \node[label=above:above] at (2,0) {\textbullet};
    \node[label=below:below] at (4,0) {\textbullet};
    \node[label=right:right] at (6,0) {\textbullet};
\end{tikzpicture}

The general syntax is:

label={[options]angle:text}

where angle may specify a numeric angle or a relative position, and text is displayed as your label text. Behind the scenes, each label is a new node, created and placed at the location you specify.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\begin{tikzpicture}[pin distance=10mm]
    \node[pin={[pin distance=5mm]0:0},
          pin={[pin edge={->}]30:30},
          pin={[pin edge={<-}]60:60},
          pin={[magenta]90:90},
          pin={[pin edge={magenta}]120:120},
          pin={[pin edge={thick}]150:150},
          pin={[pin edge={dotted}]180:180},
          pin={[pin edge={dashed}]210:210},
          pin={[scale=1.2]240:240},
          pin={[scale=0.8]270:270},
          pin={300:$3\times10$},
          pin={330:meow}]
    at (11,-2) {\textbullet};
\end{tikzpicture}

If for any reason, you want an extra line connecting your label and the original node, you may replace label with pin with no other changes.