# Relative positioning of edge labels in Tikz

I have a graph with multiple edges that originate at the same y-level (possibly at different angles) and end at different y-levels. I would like to position the edge labels at the same y height.

Example:

\documentclass[a4paper]{article}

\usepackage{tikz}
\usetikzlibrary{arrows,automata}

\begin{document}

\tikz{
\node[draw,circle,minimum size=5mm] (a1) at (0,0) {};
\node[draw,circle,minimum size=5mm] (a2) at (1,0) {};
\node[draw,circle,minimum size=5mm] (b1) at (1,-3) {};
\node[draw,circle,minimum size=5mm] (b2) at (3,-5) {};
\draw (a1) to node [auto,near start] {1} (b1);
\draw (a2) to node [auto,very near start] {2} (b2);
}

\end{document}


output:

As you can see the labels "1" and "2" are not at the same height. Is there a way to position label "2" exactly at the same y-coordinate as "1"? (The x coordinate should then be determined by the edge itself)

I would like to keep the connection between edge and label so that even when the endpoints of the edges (here b1 and b2) move the labels move with them.

-
Here, your first line ends at (1,-3). If your second line ends at (3,10) or at (-10,-5) (instead of (3,-5)), there is no solution (with non-overlaped and horizontally aligned labels). – Paul Gaborit Feb 28 '14 at 7:30

## 2 Answers

Here, I created a macro \addfig that draws the two interconnected circles, and places a label at elevation y=-\labelht, which is specified in advance. \addfig takes four arguments:

1) a unique identifier used in creating a node name,

2) the x-coordinate of the top circle (y=0 assumed),

3) the x-coordinate of the bottom circle,

4) the y-coordinate of the bottom circle.

The macro \addfig is called repeatedly, for as many segments are required. Changing the value of \labelht will automatically adjust the placement of the labels at that height, accounting for the slope of the lines (Try It!).

The advantage of this solution is that the location of the each label is automatically calculated.

\documentclass[a4paper]{article}
\usepackage{tikz}
\usetikzlibrary{arrows,automata}
\usepackage{stackengine}
\newcommand\addfig[4]{% {index}{x0}{x1}{y1}
\node[draw,circle,minimum size=5mm] (a#1) at (#2,0) {};
\node[draw,circle,minimum size=5mm] (b#1) at (#3,-#4) {};
\node (c#1) at (#2+#3/#4*\labelht-#2/#4*\labelht+.25,-\labelht) {#1};
\draw (a#1) to node [auto,near start] {} (b#1);
}
\begin{document}
\def\labelht{0.7}
\tikz{
\addfig{1}{0}{1}{3}
\addfig{2}{1}{3}{5}
\addfig{3}{2}{4}{4.5}
\addfig{4}{4}{6}{5.5}
}%
\end{document}


My original solution, as stack insets to the finished picture. The drawback is that the label placement must be individually calculated or empirically determined.

If a solution does not present itself within tikz, one can always inset the labels atop an existing image. The \stackinsets may be nested, as shown. The l and t arguments mean that the inset distances are taken with respect to the left-top of the image.

\documentclass[a4paper]{article}
\usepackage{tikz}
\usetikzlibrary{arrows,automata}
\usepackage{stackengine}
\begin{document}
\stackinset{l}{0.70cm}{t}{0.75cm}{1}{%
\stackinset{l}{1.70cm}{t}{0.75cm}{2}{%
\stackinset{l}{2.70cm}{t}{0.75cm}{3}{%
\tikz{
\node[draw,circle,minimum size=5mm] (a1) at (0,0) {};
\node[draw,circle,minimum size=5mm] (a2) at (1,0) {};
\node[draw,circle,minimum size=5mm] (b1) at (1,-3) {};
\node[draw,circle,minimum size=5mm] (b2) at (3,-5) {};
\draw (a1) to node [auto,near start] {} (b1);
\draw (a2) to node [auto,very near start] {} (b2);
}%
}}}
\end{document}


-
Sure I can position the labels by hand, but I would like to keep the connection between edge and label so that when the edge angle changes I do not need to reposition the label manually. – Geminus Feb 27 '14 at 14:20
@Geminus I have revised my answer to address your concern. – Steven B. Segletes Feb 28 '14 at 4:20
Thanks, I will use that! – Geminus Feb 28 '14 at 9:30

Use positioning library:

\documentclass[a4paper]{article}

\usepackage{tikz}
\usetikzlibrary{arrows,automata,positioning}

\begin{document}

\begin{tikzpicture}
\node[draw,circle,minimum size=5mm] (a1) at (0,0) {};
\node[draw,circle,minimum size=5mm] (a2) at (1,0) {};
\node[draw,circle,minimum size=5mm] (b1) at (1,-3) {};
\node[draw,circle,minimum size=5mm] (b2) at (3,-5) {};
\draw (a1) to node [auto,near start] (1) {1} (b1);
\draw (a2) to  (b2);
\node [right=0.6cm of 1] {2};    %%% draw here
\end{tikzpicture}

\end{document}


-
This separates the node from the edge, thus when the edge angle changes the node does not move with it. Is there any way to keep node and edge connected? – Geminus Feb 27 '14 at 14:19