# TikZ chain adjust positions of on-the-arrow node

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{chains}
\begin{document}
\begin{tikzpicture}[start chain=circle placed {at=(\tikzchaincount*30:1.5)},regular/.style={draw,circle,inner sep=0,minimum size=4mm}]
\foreach \i in {0,...,11}
\node [on chain, regular] (\i) {\i};
\foreach \i [evaluate=\i as \ni using {int(mod(\i+1,12))}] \i in {0,3,6,9}
{\draw [->] (\i) to [bend right] node[auto] {$p_b$} (\ni); }
\foreach \i [evaluate=\i as \ni using {int(Mod(\i-1,12))}] \i in {0,3,6,9}
{\draw [->] (\i) to [bend right] node[auto] {$q_b$} (\ni); }
\foreach \i [evaluate=\i as \ni using {int(mod(\i+1,12))}] \i in {1,2,4,5,7,8,10,11}
{\draw [->] (\i) to [bend right] node[auto] {$p_g$} (\ni); }
\foreach \i [evaluate=\i as \ni using {int(Mod(\i-1,12))}] \i in {1,2,4,5,7,8,10,11}
{\draw [->] (\i) to [bend right] node[auto] {$q_g$} (\ni); }
\end{tikzpicture}
\end{document}


gave me

Although I have used node[auto] and there is certainly enough room to layout all the on-the-arrow node labels, they still crowd into a mess. I am aware that I have the option of using node[auto,above] or node[auto,below] to fine-tune the position, but that would make the code lengthy. Is there a simple way to lay out those labels beautifully?

-
The nodes are placed on inner side. You need to swap them or use auto=right. The problem with auto is that it snaps to the main anchors (multiples of 45). You will need a more sophisticated node setup for such small distances. –  Qrrbrbirlbel Oct 29 '13 at 18:59

Quite similar to the other answers, but with one or two less keystrokes.

\documentclass[border=0.125cm]{standalone}

\usepackage{tikz}
\usetikzlibrary{topaths}

\begin{document}

\begin{tikzpicture}

\foreach \n in {0,...,11}
\node [draw, circle] at (\n*30+30:2.5) (n-\n) {\n};

\foreach \n [evaluate={\m=int(mod(11+\n, 12)); \p=int(mod(\n+1,3)); \q=int(mod(\n,3)); }] in {0,...,11}{
\draw [->] (n-\m) to [bend right] node [anchor=\n*30+210] {$P_\ifodd\p b\else g\fi$} (n-\n);
\draw [<-] (n-\m) to [bend left]  node [anchor=\n*30+30]  {$P_\ifodd\q b\else g\fi$} (n-\n);
}

\end{tikzpicture}

\end{document}


-
Really nice code! –  wdg Oct 30 '13 at 3:12

Two problems:

1. The auto option places the nodes by default to the left, you will need to use auto=right (or the swap option which swaps the default side).
2. The auto option snaps to the main compass anchors east, north east, north, …, south and south east.

You want to use circle nodes so that anchors are placed in a circle around the node.
You want to use text depth=+0pt or similar solution to hide the different depths of the subscripts.
And you want to use another auto anchor/angle calculator. This is what this answer has to offer.

By the way, you might be interested in the nodes around center key for the placement of nodes in a chain. One might also add the edge nodes via the join style but that’s for another question.

## Code

\documentclass[tikz]{standalone}
\usetikzlibrary{chains}
\pgfmathparse{atan2(0,1)}% the CVS version swaps the arguments so I define new atan
% functions that have the order of arguments in their name
\ifdim\pgfmathresult pt=0pt % atan2(y, x)
\tikzset{declare function={atanXY(\x,\y)=atan2(\y,\x);atanYX(\y,\x)=atan2(\y,\x);}}
\else                       % atan2(x, y)
\tikzset{declare function={atanXY(\x,\y)=atan2(\x,\y);atanYX(\y,\x)=atan2(\x,\y);}}
\fi
\makeatletter
\let\tikz@auto@anchor@orig      \tikz@auto@anchor
\let\tikz@auto@anchor@prime@orig\tikz@auto@anchor@prime
\tikzset{
Auto/.code=\pgfkeysalso{/tikz/auto=#1}%
\let\tikz@auto@anchor      \tikz@Auto@anchor
\let\tikz@auto@anchor@prime\tikz@Auto@anchor@prime,
auto/.prefix code=\let\tikz@auto@anchor      \tikz@Auto@anchor@orig
\let\tikz@auto@anchor@prime\tikz@Auto@anchor@prime@orig}
\def\tikz@Auto@anchor{%
\pgfmathatanXY@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
\pgfutil@tempdima=\pgfmathresult pt\relax
\edef\tikz@anchor{\pgf@sys@tonumber\pgfutil@tempdima}}
\def\tikz@Auto@anchor@prime{%
\pgfmathatanXY@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
\pgfutil@tempdima=\pgfmathresult pt\relax
\edef\tikz@anchor{\pgf@sys@tonumber\pgfutil@tempdima}}
\begin{document}
\begin{tikzpicture}[Auto=right,
start chain=circle placed {at=(\tikzchaincount*30:1.5)},
regular/.style={draw,circle,inner sep=+0pt,minimum size=+4mm}]
\foreach \i in {0,...,11} \node [on chain, regular] (\i) {\i};
\tikzset{text depth=+0pt, shape=circle, inner sep=+2pt}
\foreach \i [evaluate=\i as \ni using {int(mod(\i+1,12))}] \i in {0,3,6,9}
{\draw [->] (\i) to [bend right] node {$p_b$} (\ni); }
\foreach \i [evaluate=\i as \ni using {int(Mod(\i-1,12))}] \i in {0,3,6,9}
{\draw [->] (\i) to [bend right] node {$q_b$} (\ni); }
\foreach \i [evaluate=\i as \ni using {int(mod(\i+1,12))}] \i in {1,2,4,5,7,8,10,11}
{\draw [->] (\i) to [bend right] node {$p_g$} (\ni); }
\foreach \i [evaluate=\i as \ni using {int(Mod(\i-1,12))}] \i in {1,2,4,5,7,8,10,11}
{\draw [->] (\i) to [bend right] node {$q_g$} (\ni); }
\end{tikzpicture}
\end{document}


## Output

-

With PSTricks just for fun as usual!

\documentclass[pstricks,border=12pt,12pt]{standalone}
\usepackage{pst-node,pst-plot}

\makeatletter
% Get Label
\def\GL#1#2{\pst@mod{#2}{3}\rem\ifcase\rem $#1_b$ \or $#1_g$ \or $#1_g$\fi}
\makeatother

\begin{document}
\multido{\i=0+1}{\Pnodecount}{\Cnodeput(P\i){A\i}{\i}}
\Cnodeput(P\Pnodecount){A\Pnodecount}{}
\multido{\ix=0+1,\iy=1+1}{\Pnodecount}
{
\ncarc{A\iy}{A\ix}\naput{\GL{p}{\ix}}
\ncarc{A\ix}{A\iy}\naput{\GL{q}{\iy}}
}
\end{pspicture}
\end{document}


## Just another option

\documentclass[pstricks,border=12pt,12pt]{standalone}
\usepackage{pst-node,pst-plot}

\makeatletter
% Get Label
\def\GL#1#2{\pst@mod{#2}{3}\rem\ifcase\rem $#1_b$ \or $#1_g$ \or $#1_g$\fi}
% Angle unit operator
\def\angleunit#1{\degrees[#1]\pstVerb{/angleunit {\pst@angleunit} bind def}}
\makeatother

\begin{document}
\angleunit{12}
\curvepnodes[plotpoints=13]{0}{12}{2.5 t 1 add angleunit PtoC}{P}
\multido{\i=0+1}{\Pnodecount}{\Cnodeput(P\i){A\i}{\i}}
\Cnodeput(P\Pnodecount){A\Pnodecount}{}
\multido{\ix=0+1,\iy=1+1}{\Pnodecount}
{
\ncarc{A\iy}{A\ix}\naput{\GL{p}{\ix}}
\ncarc{A\ix}{A\iy}\naput{\GL{q}{\iy}}
}
\end{pspicture}
\end{document}


The difference is

\angleunit{12}
\curvepnodes[plotpoints=13]{0}{12}{2.5 t 1 add angleunit PtoC}{P}


where

\makeatletter
\def\angleunit#1{\degrees[#1]\pstVerb{/angleunit {\pst@angleunit} bind def}}
\makeatother


is defined in the preamble.

## The simplest one

\documentclass[pstricks,border=12pt,12pt]{standalone}
\usepackage{pst-node,pst-plot}

\makeatletter
% Get Label
\def\GL#1#2{\pst@mod{#2}{3}\rem\ifodd\rem $#1_b$ \else $#1_g$ \fi}
\makeatother

\begin{document}
\multido{\i=0+1}{12}{\Cnodeput(!2.5 \i\space 1 add 30 mul PtoC){A\i}{\i}}
\Cnodeput(A0){A12}{}% auxiliary node
\multido{\ix=0+1,\iy=1+1}{12}
{
\ncarc{A\iy}{A\ix}\naput{\GL{p}{\iy}}
\ncarc{A\ix}{A\iy}\naput{\GL{q}{\numexpr\ix+2}}
}
\end{pspicture}
\end{document}


No more significant edit in the future!

-
Elegant and short! The only thing is that I think it should be plotpoints=13 to get all the circle with numbers. –  Svend Tveskæg Oct 29 '13 at 19:22
check the labels... –  percusse Oct 29 '13 at 19:23
@percusse In the question I see labels 0 to 11 so 12 would seem okay, but the output 'only' shows 0 to 10. (Am I missing something obvious?) [I assumed this was a note for me; am I right?] –  Svend Tveskæg Oct 29 '13 at 19:32
@SvendTveskæg there is no alphabetical progression but a pattern modulo three –  percusse Oct 29 '13 at 19:33

Some coordinate calculations are also useful.

\documentclass[tikz]{standalone}
\usetikzlibrary{chains,calc}
\begin{document}
\begin{tikzpicture}[start chain=circle placed {at=(\tikzchaincount*30:1.5)},
regular/.style={draw,circle,inner sep=0,minimum size=4mm}]
\foreach \i in {0,...,11}
\node [on chain, regular] (\i) {\i};
\foreach \i [evaluate=\i as \ni using {int(mod(\i+1,12))},
evaluate=\i as \pi using {int(Mod(\i-1,12))}] \i in {0,...,11}
{
\draw [->] (\i) to [bend right] (\ni);
\draw [->] (\i) to [bend right] (\pi);
\node[] at ($($(\i)!0.5!(\pi)$)!1!90:(\pi)$) {\pgfmathparse{Mod(\i,3)==0?"$q_b$":"$p_g$"}\pgfmathresult};
\node[] at ($($(\i)!0.5!(\ni)$)!1!90:(\ni)$) {\pgfmathparse{Mod(\i,3)==0?"$p_b$":"$q_g$"}\pgfmathresult};
}

\end{tikzpicture}
\end{document}


-
There is \pgfmathprint, you know? :) –  Qrrbrbirlbel Oct 29 '13 at 19:29