# TikZ: Bend text so that it follows a line

I have two arrows going from a node on the left to a node on the right. Both arrows are slightly bent. I want to label the arrows with text that is bent just like the arrows. This is as far as I've got:

\begin{tikzpicture}
\node (One) at (-3,0) [shape=circle,draw] {One};
\node (Two) at (3,0) [shape=circle,draw] {Two};
\draw [->, thick] (One) to [bend right=45]  (Two);
\draw [->, thick] (One) to  [bend left=45] (Two);
\node (mental) at (0,1.75) {Some bent text};
\node (non-mental) at (0,-1.75) {Some more bent text};
\end{tikzpicture}
-
You want the node text to be bent? I'm not sure that's easy... – Seamus Jul 4 '11 at 17:00
Sorry, I was a bit unclear there. I don't really care what it is that gets bent. I just want bent text as the end result. My first try was to do this with nodes. – Speldosa Jul 4 '11 at 17:19
Note that for straight node labels you normally attach the node to the path and not place it manually: \draw [->, thick] (One) to [bend right=45] (Two) node [midway] {some text}; – Martin Scharrer Jul 4 '11 at 17:43
how to specify same decoration to all paths, like in tikz environment – user12491 Mar 10 '12 at 14:13
@gangadhar You'll have better luck asking a new question than using an answer to ask a question. – Alan Munn Mar 10 '12 at 16:05

This can be done by the decorations.text library gives you a text along path decoration. See the PGF/TikZ manual (v2.10) on page 337, section 30.6 Text decorations for more details. You can't draw and decorate the path at the same time directly, but can use postaction={..} to decorate the path after you have drawn it (Thanks goes to Alan Munn for this tip).

To format the text place the style macros between | in the text argument. Non-English characters need to be included in braces, e.g. text={|\itshape|Some Text {ö} more text}. One issue is to raise the font (it is just placed really on the path!). I looked into the source code and found out that the font macros are placed before each single processed character but with an \relax between it, i.e. <your style>\relax<character>. You could define a macro which takes two arguments, the first is the \relax and the second the character, then use \raisebox{<length>}{<content>} to raise or lower the character.

\documentclass{article}

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

\begin{document}

\begin{tikzpicture}
\node (One) at (-3,0) [shape=circle,draw] {$One$};
\node (Two) at (3,0) [shape=circle,draw] {$Two$};
\def\myshift#1{\raisebox{-2.5ex}}
\draw [->,thick,postaction={decorate,decoration={text along path,text align=center,text={|\sffamily\myshift|Some more bent text}}}] (One) to [bend right=45]  (Two);
\def\myshift#1{\raisebox{1ex}}
\draw [->,thick,postaction={decorate,decoration={text along path,text align=center,text={|\sffamily\myshift|Some bent text}}}]      (One) to [bend left=45] (Two);
\end{tikzpicture}

\end{document}

-
You could shift the coordinates for the text path with ($(One)+(0,1)$) for example (needs calc library). I don’t know why yshift=1cm doesn’t work. Maybe because you don’t use absolute coordinates. – Tobi Jul 4 '11 at 18:55
@Speldosa: font is only used for nodes AFAIK. Styles can be given between delimiters which are set using text format delimiters={<start>}{<begin>}, by default both are |, so use text={|\somefontcommands|your text}. – Martin Scharrer Jul 4 '11 at 19:39
@Speldosa: I think you’ll have to aply the font directly to the path’s text, like text={|\sffamily| Some Text}; please see page 337 an 338 of the pgfmanual. EDIT: Martin was faster … – Tobi Jul 4 '11 at 19:40
OT: It's times like these I'm wondering why I even bother using TikZ. Then again, when I see the final result, I remember why :) – Speldosa Jul 4 '11 at 19:46
@MartinScharrer It's possible to replace \def\myshift#1{\raisebox{1ex}} by raise=1ex \draw [->,thick,postaction={decorate,decoration={raise=-2.5ex,text along path,text align=center,text={|\sffamily|Some more bent text}}}] (One) to [bend right=45] (Two); I think that is valable since pgf 2.1 – Alain Matthes Dec 18 '11 at 17:15

You can use raise to place the text

\documentclass{article}

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

\begin{document}
\begin{tikzpicture}
\node (One) at (-3,0) [shape=circle,draw] {$One$};
\node (Two) at (3,0) [shape=circle,draw] {$Two$};
\draw [->,thick,postaction={decorate,decoration={raise=-2.5ex,text along path,text align=center,text={|\sffamily|Some more bent text}}}] (One) to [bend right=45]  (Two);
\draw [->,thick,postaction={decorate,decoration={raise=1ex,text along path,text align=center,text={|\sffamily|Some bent text}}}]      (One) to [bend left=45] (Two);
\end{tikzpicture}

\end{document}

-

The tikz library decorations.text allows you to place text along a path. The default placement of the text is not very nice if you are trying to have the text on a line (this seems to be because the default assumption is that the text is the line). You can use the \pgftransform... commands to shift the text around. These are described in Section 79 of the pgf manual. It's a bit cumbersome, since you can't use the node labels any more (they retain their coordinates). Here's your example with the text shifted as I suggested in my comment to Martin:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.text}
\begin{document}

\begin{tikzpicture}
\node (One) at (-3,0) [shape=circle,draw] {$One$};
\node (Two) at (3,0) [shape=circle,draw] {$Two$};
\draw [->, thick] (One) to [bend right=45]  (Two);
\pgftransformyshift{-.65cm}
\draw [decoration={text along path,
text={Some more bent text},text align={center}},decorate]  (-3,0) to [bend right=45]  (3,0);
\draw [->, thick] (One) to  [bend left=45] (Two);
\pgftransformreset
\pgftransformyshift{.5cm}
\draw[decoration={text along path,
text={Some bent text},text align={center}},decorate] (-3,0) to [bend left=45]  (3,0);
\node (mental) at (0,1.75) {};
\node (non-mental) at (0,-1.75) {};
\end{tikzpicture}

\end{document}

-