# TikZ path decoration: text below path

I would like to place a text below a given path in TikZ, see "label b" in the screenshots below.

Unfortunately I have failed to find a below key for path decorations in the documentation.

So instead I have tried to measure the height of the text, negate it and raise the decoration by that amount.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.text}

\begin{document}
\begin{tikzpicture}
\newcommand{\radius}{2}
\coordinate (cs-center);

\draw (cs-center) circle (\radius);
\draw (cs-center) -- ++(  0 + 180 : \radius);
\draw (cs-center) -- ++(120 + 180 : \radius);
\draw (cs-center) -- ++(240 + 180 : \radius);

\newcommand{\labelraise}{1pt}
\path[decorate, decoration={text along path, text=label a, text align=center, raise=\labelraise}] (cs-center) ++(180 : \radius) arc (180 : 300 : \radius);

\newlength{\labelheight}
\settoheight{\labelheight}{l}
\path[decorate,decoration={text along path, text=label b, text align=center, raise=-\labelheight-\labelraise}] (cs-center) ++(180 : \radius) arc (180 : 60 : \radius);
\end{tikzpicture}
\end{document}


But \settoheight does not seems to work inside of the tikzpicture. \labelheight is set to zero. (So "label b" is lowered by the 1pt of \labelraise only.)

If I try to raise it by a (not satisfying) hardcoded -1em the characters of the label move together (the b and the e are even touching each other):

So I have tried to change the path itself, decreasing the radius by 1em, but that results in a ! Dimension too large.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.text}

\begin{document}
\begin{tikzpicture}
\newcommand{\radius}{2}
\coordinate (cs-center);

\draw (cs-center) circle (\radius);
\draw (cs-center) -- ++(  0 + 180 : \radius);
\draw (cs-center) -- ++(120 + 180 : \radius);
\draw (cs-center) -- ++(240 + 180 : \radius);

\newcommand{\labelraise}{1pt}
\path[decorate, decoration={text along path, text=label a, text align=center, raise=\labelraise}] (cs-center) ++(180 : \radius) arc (180 : 300 : \radius);

\newlength{\labelheight}
%\settoheight{\labelheight}{l} % this does not work
\setlength{\labelheight}{1em}
\newcommand{\textradius}{\radius-\labelheight}
\path[decorate,decoration={text along path, text=label b, text align=center, raise=-\labelraise}] (cs-center) ++(180 : \textradius) arc (180 : 60 : \textradius);
\end{tikzpicture}
\end{document}


I have seen the question Text decoration below path but the only answer there just suggests a hardcoded raise which has the above shown problems.

How can I place a text below a path so that I do not need to change hardcoded numbers if I want to change the font size and where the characters have a natural distance?

## 1 Answer

With TikZ it is very simple to compute the height of a character, e.g. height("l").

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.text}

\begin{document}
\begin{tikzpicture}
\newcommand{\radius}{2}
\coordinate (cs-center);

\draw (cs-center) circle (\radius);
\draw (cs-center) -- ++(  0 + 180 : \radius);
\draw (cs-center) -- ++(120 + 180 : \radius);
\draw (cs-center) -- ++(240 + 180 : \radius);

\newcommand{\labelraise}{1pt}
\path[decorate, decoration={text along path, text=label a, text align=center, raise=\labelraise}] (cs-center) ++(180 : \radius) arc (180 : 300 : \radius);

\pgfmathsetmacro{\labelheight}{height("l")}
\path[decorate,decoration={text along path, text=label b, text align=center,
raise=-\labelraise-\labelheight}] (cs-center) ++(180 : \radius) arc (180 : 60 : \radius);
\end{tikzpicture}
\end{document}


One way to adjust the space between the characters is

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.text}

\begin{document}
\begin{tikzpicture}
\newcommand{\radius}{2}
\coordinate (cs-center);

\draw (cs-center) circle (\radius);
\draw (cs-center) -- ++(  0 + 180 : \radius);
\draw (cs-center) -- ++(120 + 180 : \radius);
\draw (cs-center) -- ++(240 + 180 : \radius);

\newcommand{\labelraise}{1pt}
\path[decorate,decoration={text effects along path, text={label a},
raise=\labelraise, text align=center,
text effects/every character/.style={text along path,inner xsep=0.1pt}}] (cs-center) ++(180 : \radius) arc (180 : 300 : \radius);

\pgfmathsetmacro{\labelheight}{height("l")}
\path[decorate,decoration={text effects along path, text={label b},
raise=-\labelraise-\labelheight, text align=center,
text effects/every character/.style={text along path,inner xsep=0.3pt}}] (cs-center) ++(180 : \radius) arc (180 : 60 : \radius);
\end{tikzpicture}
\end{document}


An arguably cleaner solution is to just shift the second path:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.text}

\begin{document}
\begin{tikzpicture}
\newcommand{\radius}{2}
\coordinate (cs-center);

\draw (cs-center) circle (\radius);
\draw (cs-center) -- ++(  0 + 180 : \radius);
\draw (cs-center) -- ++(120 + 180 : \radius);
\draw (cs-center) -- ++(240 + 180 : \radius);

\newcommand{\labelraise}{1pt}
\path[decorate, decoration={text along path, text=label a, text align=center, raise=\labelraise}] (cs-center) ++(180 : \radius) arc (180 : 300 : \radius);

\pgfmathsetmacro{\newradius}{\radius*1cm-\labelraise-height("l")}
\path[decorate,decoration={text along path, text=label b, text align=center}]
(cs-center) ++(180 : {\newradius*1pt}) arc (180 : 60 : {\newradius*1pt});
\end{tikzpicture}
\end{document}


• +1 for \pgfmathsetmacro{\labelheight}{height("l")}. that's a good step forward. do you also have an idea how to increase the distance between the characters so that b and e don't touch each other? Jun 25 '18 at 10:10
• @jakun I added one possibility. Another possibility would be to draw a path parallel to the one you chose and to put the text there.
– user121799
Jun 25 '18 at 14:41