16

How do you draw natural transformation arrows as mentioned in this question but using TikZ rather than xy? More generally, is it possible to draw edges between edge labels, from an edge label to a node, and from a node to an edge label or is it necessary to explicitly construct a node in order to draw an edge? Does providing an edge label in the path environment implicitly construct a node that can be used as the source and target of another edge? I would like to do this using the matrix and path environments in TikZ if possible.

Example:

\documentclass{article} 
\usepackage{tikz}
\usetikzlibrary{matrix,arrows}

\begin{tikzpicture}[description/.style={fill=white,inner sep=2pt}]
    \matrix (m) [matrix of math nodes, row sep=3em,
    column sep=2.0em, text height=1.5ex, text depth=0.25ex]
    { \mathcal{D} & & \mathcal{J} \\
      \mathcal{C} & & \\ };
    \path[->,font=\scriptsize]
    (m-1-1) edge[loop left] node[auto] {$ F \circ G $} (m-1-1)
    (m-1-1.20) edge node[auto] {$ G $} (m-1-3.160)
    (m-1-3.200) edge node[auto] {$ F $} (m-1-1.340)
    (m-1-1) edge node[left] {$ H $} (m-2-1);    
\end{tikzpicture}

\end{document}

example diagram

How can I connect F◦G and H with a curved natural transformation arrow ⟹? Feel free to rearrange the diagram if you'd like.

3
  • 8
    I think you would be quite happy when reading the manual of tikz-cd. Feels like it is what you need.
    – percusse
    May 10, 2012 at 21:43
  • Thank you percusse for the information on tikz-cd, I did not know it existed. May 11, 2012 at 13:20
  • Anyway, in the meantime, I've provided a solution to your new request. Please see my updated answer. May 11, 2012 at 16:35

3 Answers 3

23

As percusse mentions in his comment, the tikz-cd package offers you a convenient set of macros to draw commutative diagrams; here's a little example:

\documentclass{article} 
\usepackage{tikz-cd}

\begin{document}

\begin{tikzcd}[column sep=huge]
\textbf{CRing}
  \arrow[bend left=50]{r}[name=U,label=above:$\scriptstyle\mathrm{GL}_n$]{}
  \arrow[bend right=50]{r}[name=D,label=below:$\scriptstyle U$]{} &
\textbf{Grp}
  \arrow[shorten <=10pt,shorten >=10pt,Rightarrow,to path={(U) -- node[label=right:$\det$] {} (D)}]{}
\end{tikzcd}

\end{document}

enter image description here

Since originally the question asked for a TikZ solution using a matrix of nodes, here's a "pure" TikZ possible solution:

\documentclass{article} 
\usepackage{tikz}
\usetikzlibrary{matrix,arrows}

\begin{document}

\begin{tikzpicture}
\matrix[matrix of nodes,column sep=2cm] (cd)
{
   \textbf{CRing} & \textbf{Grp} \\
};
\draw[->] (cd-1-1) to[bend left=50] node[label=above:$\scriptstyle\mathrm{GL}_n$] (U) {} (cd-1-2);
\draw[->] (cd-1-1) to[bend right=50,name=D] node[label=below:$\scriptstyle U$] (V) {} (cd-1-2);
\draw[double,double equal sign distance,-implies,shorten >=10pt,shorten <=10pt] 
  (U) -- node[label=right:$\det$] {} (V);
\end{tikzpicture}

\end{document}

enter image description here

An answer to the edit to the original question, showing two possibilities (a curved double arrow, and a straight one):

\documentclass{article} 
\usepackage{tikz}
\usetikzlibrary{matrix,arrows}

\begin{document}

\begin{tikzpicture}[description/.style={fill=white,inner sep=2pt}]
    \matrix (m) [matrix of math nodes, row sep=3em,
    column sep=2.0em, text height=1.5ex, text depth=0.25ex]
    { \mathcal{D} & & \mathcal{J} \\
      \mathcal{C} & & \\ };
    \path[->,font=\scriptsize]
    (m-1-1) edge[loop left] node[auto] (fg) {$ F \circ G $} (m-1-1)
    (m-1-1.20) edge node[auto] {$ G $} (m-1-3.160)
    (m-1-3.200) edge node[auto] {$ F $} (m-1-1.340)
    (m-1-1) edge node[left] (h) {$ H $} (m-2-1);
    \draw[double,double equal sign distance,-implies] (fg.290) -- (h.150);    
\end{tikzpicture}

\begin{tikzpicture}[description/.style={fill=white,inner sep=2pt}]
    \matrix (m) [matrix of math nodes, row sep=3em,
    column sep=2.0em, text height=1.5ex, text depth=0.25ex]
    { \mathcal{D} & & \mathcal{J} \\
      \mathcal{C} & & \\ };
    \path[->,font=\scriptsize]
    (m-1-1) edge[loop left] node[auto] (fg) {$ F \circ G $} (m-1-1)
    (m-1-1.20) edge node[auto] {$ G $} (m-1-3.160)
    (m-1-3.200) edge node[auto] {$ F $} (m-1-1.340)
    (m-1-1) edge node[left] (h) {$ H $} (m-2-1);
    \draw[double,double equal sign distance,-implies] (fg.290) to[out=-90,in=180] (h.180);    
\end{tikzpicture}

\end{document}

enter image description here

And here's the corresponding code using tikz-cd:

\documentclass{article} 
\usepackage{tikz-cd}

\begin{document}

\begin{tikzcd}[column sep=huge,row sep=huge]
\mathcal{D}
  \arrow[loop left]{}[name=fg]{F \circ G}
  \rar[start anchor=30, end anchor=151]{G}
  \arrow{d}[name=h,swap]{H} & 
\mathcal{J}\lar[start anchor=196, end anchor=-14]{F} \\
\mathcal{C}
\arrow[shorten >=4pt,Rightarrow,to path={(fg.290) -- (h.175)}]{}
\end{tikzcd}

\begin{tikzcd}[column sep=huge,row sep=huge]
\mathcal{D}
  \arrow[loop left]{}[name=fg]{F \circ G}
  \rar[start anchor=30, end anchor=151]{G}
  \arrow{d}[swap,name=h]{H} & 
\mathcal{J}\lar[start anchor=196, end anchor=-14]{F} \\
\mathcal{C}
\arrow[shorten >=3pt,Rightarrow,to path={(fg.290) to[out=-90,in=180] (h)}]{}
\end{tikzcd}

\end{document}

enter image description here

To add a label to the double arrow (as requested in a comment), you can use an additional node; here's an example using both approaches (the first one using tikz-cd and the second one using "pure" TikZ):

\documentclass{article} 
\usepackage{tikz-cd}
\usepackage{tikz}
\usetikzlibrary{matrix,arrows}

\begin{document}

\begin{tikzcd}[column sep=huge,row sep=huge]
\mathcal{D}
  \arrow[loop left]{}[name=fg]{F \circ G}
  \rar[start anchor=30, end anchor=151]{G}
  \arrow{d}[swap,name=h]{H} & 
\mathcal{J}\lar[start anchor=196, end anchor=-14]{F} \\
\mathcal{C}
\arrow[shorten >=1pt,Rightarrow,to path={(fg.290) to[out=-90,in=180] node[xshift=-3.5mm] {$\tau$} (h)}]{}
\end{tikzcd}

\begin{tikzpicture}[description/.style={fill=white,inner sep=2pt}]
    \matrix (m) [matrix of math nodes, row sep=3em,
    column sep=2.0em, text height=1.5ex, text depth=0.25ex]
    { \mathcal{D} & & \mathcal{J} \\
      \mathcal{C} & & \\ };
    \path[->,font=\scriptsize]
    (m-1-1) edge[loop left] node[auto] (fg) {$ F \circ G $} (m-1-1)
    (m-1-1.20) edge node[auto] {$ G $} (m-1-3.160)
    (m-1-3.200) edge node[auto] {$ F $} (m-1-1.340)
    (m-1-1) edge node[left] (h) {$ H $} (m-2-1);
    \draw[double,double equal sign distance,-implies] (fg.290) to[out=-90,in=180] node[xshift=-3.5mm] {$\tau$} (h.180);    
\end{tikzpicture}

\end{document}

enter image description here

6
  • Thank you Gonzalo for the examples and pointing me to tikz-cd. I probably wouldn't have requested to use matrix and path if I knew tikz-cd existed. May 11, 2012 at 13:22
  • tikz-cd uses a matrix but the matrix is hidden. May 11, 2012 at 14:01
  • Thank you very much for the additional examples Gonzalo. How can I add an edge label to the natural transformation arrow? May 14, 2012 at 2:51
  • @camrn86: You're welcome. Please see my updated answer for an example on how to add the label. May 14, 2012 at 3:02
  • That is nice and elaborate! +1.
    – user11232
    May 14, 2012 at 4:19
8

I don't respect some initial conditions because I don't understand what it's interesting to use a matrix for two vertices. I think matrix is very useful but only for complex structures.

Here we need two lines to place the main nodes. I used outer sep=4pt to put the arrows at right places. Then I place two nodes in the middle of each arrows. I named these nodes to be able to draw the last double arrow. The option fo this arrow are complex, so I think it's preferable to use a style.

\documentclass{article} 
\usepackage{tikz}
\usetikzlibrary{arrows}

\begin{document}

\tikzset{dbl/.style={double,
                     double equal sign distance,
                     -implies,
                     shorten >=10pt,
                     shorten <=10pt}}

\begin{tikzpicture} [every node/.style={outer sep=4pt}]
 \node  (A) at (0,0)  {\textbf{CRing}}; 
 \node  (B) at (4,0)  {\textbf{Grp}};

 \draw[->]  (A.north)  to [bend left = 30]  node[above] (C) {$\scriptstyle\mathrm{GL}_n$} (B.north);
 \draw[->]  (A.south)  to [bend right= 30]  node[below] (D) {$\scriptstyle U$}            (B.south);   
 \draw[dbl]   (C)      to                   node[right]     {$\det$}                      (D);
\end{tikzpicture}     

\end{document}

enter image description here

The aim of this method is to be able to scale the figure like I want, now two examples :

\documentclass{article} 
\usepackage{tikz}
\usetikzlibrary{arrows}

\begin{document}

\tikzset{dbl/.style={double,
                     double equal sign distance,
                     -implies,
                     shorten >=10pt,
                     shorten <=10pt}}

\begin{tikzpicture} [every node/.style={outer sep=4pt},yscale=1.5]
 \node  (A) at (0,0)  {\textbf{CRing}}; 
 \node  (B) at (4,0)  {\textbf{Grp}};

 \draw[->]  (A.north) to [bend left = 30]  node[above] (C) {$\scriptstyle\mathrm{GL}_n$}  (B.north);
 \draw[->]  (A.south) to [bend right= 30]  node[below] (D) {$\scriptstyle U$}             (B.south);   
 \draw[dbl]   (C)     to                   node[right]     {$\det$}                       (D);
\end{tikzpicture}
\begin{tikzpicture} [every node/.style={outer sep=4pt},xscale=1.5,yscale=1.25]
 \node  (A) at (0,0)  {\textbf{CRing}}; 
 \node  (B) at (4,0)  {\textbf{Grp}};

 \draw[->]  (A.north)  to [bend left = 30]  node[above] (C) {$\scriptstyle\mathrm{GL}_n$} (B.north);
 \draw[->]  (A.south)  to [bend right= 30]  node[below] (D) {$\scriptstyle U$}            (B.south);   
 \draw[dbl]   (C)      to                   node[right]     {$\det$}                      (D);
\end{tikzpicture}   
\end{document}

enter image description here

2
  • Thank you for the examples Altermundus. The reason I asked to use matrix is that I have more complicated diagrams in mind. I just linked to that previous post because it had an example of a natural transformation arrow between two edge labels. That is nice to be able to scale the drawing. I think I will stick with tikz-cd for what seems to be the relative simplicity of the syntax, but that might change with more complicated diagrams. Is it possible to scale a diagram like this with tikz-cd? May 11, 2012 at 13:25
  • I don't know, I never use tikz-cd. I try with only with your example and it seems not easy to do. Perhaps scale a matrix is a problem. May 11, 2012 at 13:59
1

I just wanted to add that it can be very useful to write a macro for that. For example as follows:

\documentclass{article}
\usepackage{tikz-cd}

\newcommand{\nat}[6][large]{%
  \begin{tikzcd}[ampersand replacement = \&, column sep=#1]
    #2\ar[bend left=40,""{name=U}]{r}{#4}\ar[bend right=40,',""{name=D}]{r}{#5}\& #3
          \ar[shorten <=10pt,shorten >=10pt,Rightarrow,from=U,to=D]{d}{~#6}
    \end{tikzcd}
}
\newcommand{\te}[1]{\text{#1}}
\newcommand{\tf}[1]{\textbf{#1}}

The command \nat takes 6 arguments but includes one default argument for the column separation, so you just need to specify 5. Then your document looks as follows:

\begin{document}

    \nat{\tf{CRing}}{\tf{Mon}}{M_n}{U}{\te{det}}
    \nat[huge]{\tf{CRing}}{\tf{Mon}}{M_n}{U}{\te{det}}

\end{document}`

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .