# Labelling arrows drawn to paths in tikz-cd

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: 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.

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

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

\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, 2020 at 18:34
• @chsk, you are welcome Jan 20, 2020 at 18:39
• Excuse for my previous bad answer. Mar 13, 2020 at 12:40

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:

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}


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}

• 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.
– user194703
Jan 21, 2020 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. Jan 21, 2020 at 2:07
• @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. =) Jan 21, 2020 at 5:38

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

\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}
`