How to draw commutative diagrams in LaTeX with TikZ

Sooner or later everyone who uses LaTeX to typeset documents containing maths will encounter the problem of how to draw commutative diagrams. There are many packages, some general purpose other specialized for the task. An excellent survey of some of these alternatives by James Milne can be found here.

I use TikZ for most drawings I use in documents, so naturally I also want to use TikZ to draw commutative diagrams. The survey by Milne includes a description of how to use the matrix librariy in TikZ to typeset commutative diagrams and Felix Lenders has a short PDF document with much the same contents. I, on the other hand, do not use the matrix library and that’s the reason for writing this blog post.

Each TikZ drawing is enclosed in the tikzpicture environment. You can set options for the drawing at hand by enclosing them in square backets like, for instance:

\begin{tikzpicture}[node distance=2cm, auto]
\end{tikzpicture}

If you want to set options globally or for entire parts of a document, you can use the command \tikzset:

\tikzset{node distance=2cm, auto}

Now, let’s look at the source code for a simple diagram (for n-ary products in category theory).

\begin{tikzpicture}
  \node (C) {$C$};
  \node (P) [below of=C] {$\prod_{i \in I} A_i$};
  \node (Ai) [right of=P] {$A_i$};
  \draw[->] (C) to node {$f_i$} (Ai);
  \draw[->, dashed] (C) to node [swap] {$\langle f_i \rangle_{i \in I}$} (P);
  \draw[->] (P) to node [swap] {$\pi_i$} (Ai);
\end{tikzpicture}

You see that all commands are terminated by a semicolon. Nodes are given names like C or P in parentheses and a label that is to be displayed in the diagram enclosed in curly braces. The position of nodes relative to each other is given by human-readable attributes like above of. These positioning attributes can also be combined, for example [above of=A, below of=C]. The arrows between nodes are drawn using the \draw command which also takes attributes giving the type of arrow head or line style enclosed in square braces. They are labelled using nodes. Again, these nodes take attributes, the most used probably being swap which indicates that the label should be drawn on the other side of the arrow.
And this is how the finished diagram looks like:

n-ary product

In diagrams like the ones for equalizers you’ll need parallel arrows. This can be achieved in TikZ by explicitly stating to with position on a hypothetical circle around the node in question the line should be anchored.

\draw[->] (A.20) to node {$g$} (B.160);
\draw[->] (A.340) to node [swap] {$h$} (B.200);

The numbers after the dot denote angles. In this example the line’s anchors at the source and destination node are offset by +20° and -20° respectively from their automatically assigned positions. This leads to the following drawing.

Parallel Arrows

Another useful attribute of lines between nodes is bend. It allows you to draw lines that are curved to either the left or the right side of the straight line through its start and end point. A drawing that might use this is the commutative diagram of a pullback. Here’s the LaTeX code:

\begin{tikzpicture}
  \node (P) {$P$};
  \node (B) [right of=P] {$B$};
  \node (A) [below of=P] {$A$};
  \node (C) [below of=B] {$C$};
  \node (P1) [node distance=1.4cm, left of=P, above of=P] {$\hat{P}$};
  \draw[->] (P) to node {$\bar{f}$} (B);
  \draw[->] (P) to node [swap] {$\bar{g}$} (A);
  \draw[->] (A) to node [swap] {$f$} (C);
  \draw[->] (B) to node {$g$} (C);
  \draw[->, bend right] (P1) to node [swap] {$\hat{g}$} (A);
  \draw[->, bend left] (P1) to node {$\hat{f}$} (B);
  \draw[->, dashed] (P1) to node {$k$} (P);
\end{tikzpicture}

And this is the resulting figure:

Pullback

If you want to typeset a more complex diagram with lines crossing each other, this might help you (idea taken from the document by Felix Lenders referenced above):

\begin{tikzpicture}[%
  back line/.style={densely dotted},
  cross line/.style={preaction={draw=white, -,line width=6pt}}]
  \node (A) {$A$};
  \node [right of=A] (B) {$B$};
  \node [below of=A] (C) {$C$};
  \node [right of=C] (D) {$D$};
 
  \node (A1) [right of=A, above of=A, node distance=1cm] {$A^\prime$};
  \node [right of=A1] (B1) {$B^\prime$};
  \node [below of=A1] (C1) {$C^\prime$};
  \node [right of=C1] (D1) {$D^\prime$};
 
  \draw[back line] (D1) -- (C1) -- (A1);
  \draw[back line] (C) -- (C1);
  \draw[cross line] (D1) -- (B1) -- (A1) -- (A)  -- (B) -- (D) -- (C) -- (A);
  \draw (D) -- (D1) -- (B1) -- (B);
\end{tikzpicture}

This example draws a cube. The way the edges are drawn is special. First of all two different line styles are defined, namely back line for lines in the back (which would be invisible if the cube were solid) and cross line for a line that is to be broken by crossing lines. Note, that you first have to draw the lines in the back and then all the others in the front that may or may not cross other lines and cause these to be broken at the point of intersection. The result looks like this:Cube

Another kind of arc which might be useful (although probably not so much in commutative diagrams but rather when drawing automata for example) is a loop. The following TikZ snippet shows two ways to create arrows. Instead of above you can also use all the other symbolic anchors like right or below. The second uses angles that offset the start and end anchor point of the line that were already mentioned.

\begin{tikzpicture}
  \node {$A$} edge[loop above] (A);
  \pgftransformxshift{2cm};
  \node {$B$} edge [out=10, in=50, loop] (B);
\end{tikzpicture}

And this is the resulting picture:
Loops

Just one more thing. How to draw arrows with two labels, one above and one below? See the \draw command in the code below (you might have to tweak the above and below to suit your particular layout of course).

\begin{tikzpicture}
  \node (A) {$A$};
  \node [right of=A] (B) {$B$};
  \draw[->] (A) to node[above] {$f$} node[below] {$g$} (B);
\end{tikzpicture}

This will get you a drawing like this:
Two labels

And that’s it for now. Don’t think this is the be all and end all of drawing certain diagrams with TikZ. There are many ways and mine is probably still not the quickets and most elegant. It’s just what I do (for now).

This entry was posted in Mathematics, Tools and tagged , , , . Bookmark the permalink.

24 Responses to How to draw commutative diagrams in LaTeX with TikZ

  1. Thierry BM says:

    Hey thanks man, just what I was looking for!

    • mv vijaya kumar says:

      i am looking for diagram its diamond shape ,each edge has arrow mark and also letter after arrow mark.

      • I’m sorry, but I do not understand what exactly you want. Maybe some of the examples over at http://www.texample.net/ might help you. If you want to create more complicated shapes (i.e. those with few if any right angles) then your best bet, as far as I can tell, is to use absolute positioning instead of the relative positioning I used in this blog post.

  2. AMHA says:

    Thanks a million… this is really what I need.
    Now, I’ve a new challenge, since I need to find the TikZ package???? Where’s it?

    • Should be part of your LaTeX installation already. If not, either grab it from CTAN and install it manually or install the latest TeXLive distribution (recommended).

  3. Manuel Bärenz says:

    Wonderful, thank you!

    Do you have an idea how to insert a symbol like circlearrowleft painlessly, to denote a diagram to be commuting?
    I tried to do it with an arc with arrowtips, but it is hard to center it correctly because I can’t set the midpoint of the arc, only starting point and endpoint.

    • I have never thought about that. The method I describe is probably not suited to what you want to accomplish. Perhaps using a matrix or even placing the nodes on a grid by spelling out the coordinates manually might do the trick. Should you find an painless way to do what you want I would be interested in hearing about it. Good luck!

  4. madhavi says:

    How to draw two diagrams in one line OR one diagram with matrix in one line
    thanks

    • I’m not sure what you are after. A very simple way of having two diagrams side by side is to use a parbox and two tikzpicture environments, one for each. You could also use pgftransform{xshift=2cm} (IIRC) to shift parts of a TikZ drawing around. I have never used the matrix stuff in TikZ, so I cannot help with that.

  5. madhavi says:

    thanks for your quick reply.I am using Latex to write down graph theory report.I am new to tikz and using node command with draw for drawing simple graphs.I have used two tikzpicture environments one after one.but it didnt work .can u help me more .

  6. Sam Akkawi says:

    Hallo, with the new update of the package, all arrows seem to disappear, and other than that the letter seem to either shift to some place or all go to the same spot on the pdf output… what should I do?

    • I cannot help you with that. Seems like a problem with your specific TeX distribution. The only general advice I can give you is to not update TeX stuff unless you absolutely have to. There are so many things that can break and are near impossible to fix or even pin down.

  7. sunita says:

    hello ! Thomas ,
    can you explain , how to get diagrams. sty. file ? .

    I have issue in drawing diagram . the source code gives an error ‘ diagrams.sty. ‘ in not found .
    the solution is to rename …. but what to rename ?? extention or what ??

    please help !!

    • I cannot help you with diagrams.sty as I use TikZ exclusively for creating figures in LaTeX. Try looking on CTAN for diagrams.sty and put it directly into the directory with the offending .tex files. That usually helps. If not, consider learning about the paths and packages management facilities of your LaTeX distribution.

  8. Che-Ping says:

    Thanks very much!

  9. Kenny says:

    Hi,
    I tried to use loop as your example above for nodes A and B, but doesn’t work. Wonder if any library of tikz you used?

  10. lmh says:

    Hi,

    I’m sorry if this is not the right place to ask, but I’ve been struggling with this hexagon for a while, it reported an error that I could not figure it out. Please help! Thank you.
    \[
    \begin{tikzcd}
    & G_0 \arrow{dl}{\ell_1} \arrow{dd}{i_0} \arrow{dr}{\ell_2} & \\
    G_1\prime & & G_2\prime\\
    & G \arrow{ul}{j_1} \arrow{dd}{j_0} \arrow{ur}[swap]{j_2} \\
    G_1\arrow{u}{k_1} \arrow{ur}{i_1} \arrow{dr}{h_1}& & G_2\arrow{u}{k_2}
    \arrow{ul}{i_2} \arrow{dl}{h_2} \\
    & G_o\prime &
    \end{tikzcd}
    \[

    • Thomas Strathmann says:

      I have never used the tikz-cd package. In fact, I’ve only just discovered it through your code. The only thing I can tell without digging into tikz-cd (which I think from seeing the example is not a very high-level package and probably not worth the effort) is that the closing displayed math delimiter is missing: in its place is an opening one. Good luck with your diagram!

      • lmh says:

        Thank you for your time. I already fixed the delimiter mistake, but there’s still a “missing $ inserted” error.

  11. Joerg Baeuerle says:

    Hey Thomas,

    is there a way to have different vertical and horizontal node distances? Tikz seems to ignore the second number of the option [node distance=2cm and 4cm].

    Thanks a lot in advance,
    Joerg

    • Thomas Strathmann says:

      You could try

      \node (c) [below right=1cm and 2cm of a] {z};

      That works for me. There’s also the possibility of using xshift and yshift
      or computing relative coordinates. You’ll probably want to look at the positioning TikZ library.

  12. Abi says:

    Thanks a trillion! This was so helpful. So well done. Many thanks again.

  13. 2Chart says:

    Thanks for this perfect solution! All other packages are more complicated to use and not so beautiful!

Leave a Reply

Your email address will not be published. Required fields are marked *