Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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:

The generated 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.

share|improve this question
    
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 at 7:30

2 Answers 2

up vote 2 down vote accepted

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}

enter image description here


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}

enter image description here

share|improve this answer
    
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 at 14:20
    
@Geminus I have revised my answer to address your concern. –  Steven B. Segletes Feb 28 at 4:20
    
Thanks, I will use that! –  Geminus Feb 28 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}

enter image description here

share|improve this answer
    
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 at 14:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.