4

I'm trying to draw a (commutative) diagram using tikz-cd. The package manual, in section 3.2, describes how to use to path for fine-grained control of the shapes of arrows, but says little on how to then add labels to these arrows.

I currently have the following diagram:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{cd}
\begin{document}
    \begin{tikzcd}
        & K^n \arrow[r, "L^A_B(F)"] \arrow[dd, rounded corners, to path={ -- ([xshift=-10ex]\tikztostart.west) -- ([xshift=-10ex]\tikztotarget.west) -- (\tikztotarget.west)}] & K^m \arrow[dd, rounded corners, to path={ -- ([xshift=10ex, "L^B_D"]\tikztostart.east) -- ([xshift=10ex]\tikztotarget.east) -- (\tikztotarget.east)}] & \\
        V \arrow[rrr, "F"] \arrow[ru, "C_A"] \arrow[rd, "C_C"'] & & & W \arrow[lu, "C_B"'] \arrow[ld, "C_D"] \\
        & K^n \arrow[r, "L^C_D(F)"] & K^m &
    \end{tikzcd}
\end{document}

which produces: enter image description here I'd like to add the Labels L^A_Cand L^B_D to the outer ,,bendy`` arrows, but I'm drawing a blank as to how. The obvious, straightforward way (adding labels to the path) does not produce anything, while adding a phantom arrow to create a coordinate for where the label would then be placed, as in the tikz-cd documentation, produces an error message:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{cd}
\begin{document}
    \begin{tikzcd}
        \arrow[dd, phantom, ""{coordinate, name=Z} && K^n \arrow[r, "L^A_B(F)"] \arrow[dd, rounded corners, to path={ -- ([xshift=-10ex]\tikztostart.west) -- ([xshift=-10ex]\tikztotarget.west) -- (\tikztotarget.west)}] & K^m \arrow[dd, rounded corners, to path={ -- ([xshift=10ex, "L^B_D"]\tikztostart.east) -- ([xshift=10ex]\tikztotarget.east) -- (\tikztotarget.east)}] & \\
        &V \arrow[rrr, "F"] \arrow[ru, "C_A"] \arrow[rd, "C_C"'] & & & W \arrow[lu, "C_B"'] \arrow[ld, "C_D"] \\
        && K^n \arrow[r, "L^C_D(F)"] & K^m &
    \end{tikzcd}
\end{document}

yields

! Package pgf Error: No shape named `tikz@f@1-3-1' is known.

See the pgf package documentation for explanation.
Type  H <return>  for immediate help
...
l.6 I think the culprit is a tikzcd arrow in cell 1-1.

and several more errors in the same vein.

  • 3
    You can add node[left]{\scriptsize$L_A^C$} to the second connector --. – Sigur Jan 20 at 18:22
8

You can add a node at the second segment of the path.

enter image description here

\begin{tikzcd}
  & K^n 
  \arrow[r, "L^A_B(F)"] 
  \arrow[dd, rounded corners, 
    to path={ 
      -- ([xshift=-10ex]\tikztostart.west) 
      --node[left]{\scriptsize$L_C^A$} ([xshift=-10ex]\tikztotarget.west) 
      -- (\tikztotarget.west)}
        ]
  & K^m
  \arrow[dd, rounded corners, 
    to path={ 
      -- ([xshift=10ex, "L^B_D"]\tikztostart.east) 
      --node[right]{\scriptsize$L_D^B$} ([xshift=10ex]\tikztotarget.east)   
      -- (\tikztotarget.east)}] 
  & \\
  V 
  \arrow[rrr, "F"] 
  \arrow[ru, "C_A"] 
  \arrow[rd, "C_C"'] 
  & & & W 
  \arrow[lu, "C_B"'] 
  \arrow[ld, "C_D"] \\
  & K^n 
  \arrow[r, "L^C_D(F)"] 
  & K^m &
\end{tikzcd}
  • Simple, effective, and should have been obvious. Thank you! – chsk Jan 20 at 18:34
  • 1
    @chsk, you are welcome – Sigur Jan 20 at 18:39
4

Another option is to use \tikztonodes in to path and then use quotes to specify the labels. The labels specified using the quotes get stored into \tikztonodes. This is much more useful if you want to use the same "tikz to path" to draw multiple paths.

\documentclass{article}
\usepackage{tikz-cd}
\begin{document}
    \begin{tikzcd}
        && K^n \arrow[r, "L^A_B(F)"] 
        \arrow[dd, rounded corners, "L_A^C"', 
            to path={ 
                 -- ([xshift=-10ex]\tikztostart.west) 
                 -- ([xshift=-10ex]\tikztotarget.west)\tikztonodes % added \tikztonodes here
                 -- (\tikztotarget.west)
        }] 
        & K^m 
        \arrow[dd,"L_D^B", rounded corners, 
            to path={ 
                 -- ([xshift=10ex]\tikztostart.east) 
                 -- ([xshift=10ex]\tikztotarget.east)\tikztonodes 
                 -- (\tikztotarget.east)
        }] &
        \\
        &V \arrow[rrr, "F"] \arrow[ru, "C_A"] \arrow[rd, "C_C"'] & & & W \arrow[lu, "C_B"'] \arrow[ld, "C_D"] \\
        && K^n \arrow[r, "L^C_D(F)"] & K^m &
    \end{tikzcd}
\end{document} 
  • 1
    Shouldn't it be to path={ -- ([xshift=10ex]\tikztostart.east) -- ([xshift=10ex]\tikztostart.east|-\tikztotarget)\tikztonodes -- (\tikztotarget.east) }? In this very example it works fine, but in general the nodes won't be of equal width, and with your (as well as all others') construction the second segment may end up being not vertical. – Schrödinger's cat Jan 21 at 2:03
  • @Schrödinger'scat Sounds good. It seems to me that the question was just how to add a label to a custom to path not what the best to path to use is. With your construction you could add an extra distance option and make this into a general use key. – Hood Chatham Jan 21 at 2:07
  • 1
    @Schrödinger'scat I wrote the code for this, posted in a separate answer. It took some energy to get right, but I think the result looks pretty good. =) – Hood Chatham Jan 21 at 5:38
4

On encouragement by "Schrodinger's cat" I made a general key to do this. I called it "relay arrow" but if anyone has a better name, let me know. It works by saying e.g., \ar[ur, relay arrow=10pt].

This is strictly speaking not relevant to the question asked, but my hope is it might be useful to someone.

Here's the effect: enter image description here

Code below:

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

\tikzcdset{
    relay arrow/.default = 10pt,
    relay arrow/.style = {
        rounded corners,
        to path = {
            \pgfextra{
                \def\sourcecoordinate{\pgfpointanchor{\tikztostart}{center}}
                \def\targetcoordinate{\pgfpointanchor{\tikztotarget}{center}}
                \pgfmathanglebetweenpoints{\sourcecoordinate}{\targetcoordinate}
                \edef\tempangle{\pgfmathresult}
                \pgftransformrotate{\tempangle}
                \pgfmathifthenelse{#1>0}{\tempangle+90}{\tempangle-90}
                \pgfcoordinate{tempcoord}{\pgfpointanchor{\tikztostart}{\pgfmathresult}}
            }
            (tempcoord)
            -- ([yshift=#1]tempcoord)
            -- ([yshift=#1]tempcoord-|\tikztotarget.center)\tikztonodes
            --(\tikztotarget)
        }
    }
}
\begin{document}
    \begin{tikzcd}
     & B\\
    A \urar[relay arrow,"1"]\urar["2"]\urar[relay arrow=-25pt,"3"']&
    \end{tikzcd}

    \begin{tikzcd}
        && K^n \arrow[r, "L^A_B(F)"]
        \arrow[dd, "L_A^C"', relay arrow=-10ex]
        & K^m
        \arrow[dd,"L_D^B", relay arrow=10ex] &
        \\
        &V \arrow[rrr, "F"] \arrow[ru, "C_A"] \arrow[rd, "C_C"'] & & & W \arrow[lu, "C_B"'] \arrow[ld, "C_D"] \\
        && K^n \arrow[r, "L^C_D(F)"] & K^m &
    \end{tikzcd}
\end{document} 
3

This uses plain TikZ. pos=.25 is due to operation ++ that updated the new position for calculations.

enter image description here

\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\begin{tikzpicture}
\def\a{2.5} \def\b{1.3}
\path
(0,0) node[above]{$F$}
(\a,0) node (W) {$W$}
(-\a,0) node (V) {$V$}
(.4*\a,\b) node (Kmt) {$K^m$}
(-.4*\a,\b) node (Knt) {$K^n$}
(.4*\a,-\b) node (Kmb) {$K^m$}
(-.4*\a,-\b) node (Knb) {$K^n$};
\begin{scope}[every node/.style={midway,scale=.7}]
\draw[->] (V)--(W);
\draw[->] (Knt)--(Kmt) node[above]{$L_B^A(F)$}; 
\draw[->] (Knb)--(Kmb) node[below]{$L_D^C(F)$};
\draw[->] (V)--(Knt) node[above left]{$C_A$};
\draw[->] (W)--(Kmt) node[above right]{$C_B$};
\draw[->] (V)--(Knb) node[below left]{$C_C$};
\draw[->] (W)--(Kmb) node[below right]{$C_D$};
\draw[->,rounded corners] (Kmt)--++(0:.8*\a)|-(Kmb) node[pos=.25,right]{$L_D^B(F)$};
\draw[->,rounded corners] (Knt)--++(180:.8*\a)|-(Knb) node[pos=.25,left]{$L_A^C(F)$};
\end{scope}
\end{tikzpicture}
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.