2

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

enter image description here

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

enter image description here

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?

2

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}

enter image description here

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}

enter image description here

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}

enter image description here

  • +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? – jakun 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

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.