# How to force nodes on different lines to have equal y-positioning

I have, hopefully, a very simple question. I use tikz to make a figure for confirmatory factor analysis (CFA). In the minimal example there a 6 arrows going from the circle to a fixed place. However, as a previous question pointed out (TikZ: How to set a node on an exact position on a line?) the positioning depends on the length of the line so therefore the nodes do not align vertically (although it is only marginal...). I wonder, therefore, if its possible (probably yes), to have all nodes still snapped to the lines but on exactly the same y coordinate (height).

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\node[circle,draw] (A) at (0,0) {A};

\draw[->] (A) -- (-2.5,-2) node[near end,fill=white] {u};
\draw[->] (A) -- (-1.5,-2) node[near end,fill=white] {v};
\draw[->] (A) -- ( -.5,-2) node[near end,fill=white] {w};
\draw[->] (A) -- (  .5,-2) node[near end,fill=white] {x};
\draw[->] (A) -- ( 1.5,-2) node[near end,fill=white] {y};
\draw[->] (A) -- ( 2.5,-2) node[near end,fill=white] {z};
\end{tikzpicture}

\end{document}

-

This is very similary to one of the tutorials in the pgf manual. You should specify the text height and depth, preferrably via ex units:

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[text height=1.5ex,text depth=0.25ex]
\node[circle,draw] (A) at (0,0) {A};

\draw[->] (A) -- (-2.5,-2) edge[draw=none] node[near start,fill=white] (U) {u}  (A.center);
\draw[->] (A) -- (-1.5,-2) edge[draw=none] node[near start,fill=white] {v} (A.center);
\draw[->] (A) -- ( -.5,-2) edge[draw=none] node[near start,fill=white] {w} (A.center);
\draw[->] (A) -- (  .5,-2) edge[draw=none] node[near start,fill=white] {x} (A.center);
\draw[->] (A) -- ( 1.5,-2) edge[draw=none] node[near start,fill=white] {y} (A.center);
\draw[->] (A) -- ( 2.5,-2) edge[draw=none] node[near
start,fill=white] (Z) {z} (A.center);
\draw (U.base) -- (Z.base);
\end{tikzpicture}

\end{document}

-
Nodes are still are not aligned precisely vertically for this example. –  Tahtisilma Apr 8 at 14:24
Updated - the drawn paths are of different lengths, but one needs to place the nodes on ones of fixed length - now provided by an edge operation. –  Andrew Swann Apr 8 at 15:48
Thanks, everyone, for the answers provided. I choose this answer as this is, for me, the most intuitive! –  Huub Hoofs Apr 9 at 13:53
• Option anchor=base moves the reference point of the node from the middle to the base line with the effect, the nodes are aligned along their base lines.
• Secondly, the lines does not start at the same heights because of the circular shape of node A. Thus the relative positioning near end should refer to A.center instead to get the same vertical component for each arrow.
\documentclass{article}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\node[circle,draw] (A) at (0,0) {A};

\foreach \x/\t in {-2.5/u, -1.5/v, -.5/w, .5/x, 1.5/y, 2.5/z} {
\draw[->] (A) -- (\x,-2);
\path (A.center) -- (\x,-2) node[
near end,
anchor=base,
fill=white,
]{\t};
}
\end{tikzpicture}
\end{document}


## Without the white background hack

• The following example gets rid of the white background, by drawing the node first and making a separated arrow through the node.

• Also the \foreach automatically calculates the horizontal positions.

\documentclass{article}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\node[circle,draw] (A) at (0,0) {A};

\foreach \t [
count=\i,
evaluate=\i as \x using {-2.5+\i-1}
] in {u, ..., z} {
\coordinate (\t0) at (\x,-2);
\path (A.center) -- (\x,-2) node [
near end,
anchor=base,
] (uz\i) {\t};
\draw[->] (A) -- (uz\i) -- (\x,-2);
}
\end{tikzpicture}
\end{document}


-
Nodes are still are not aligned precisely vertically for this example. –  Tahtisilma Apr 8 at 14:24
@Tahtisilma: The vertical component of the arrow lines is different because of the circular shape of node A. Answer updated. –  Heiko Oberdiek Apr 8 at 14:48

For me the simplest solution would be to use intersections library from TikZ:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{intersections}

\begin{document}

\begin{tikzpicture}
\node[circle,draw] (A) at (0,0) {A};

\draw[name path=u,->] (A) -- (-2.5,-2);
\draw[name path=v,->] (A) -- (-1.5,-2);
\draw[name path=w,->] (A) -- ( -.5,-2);
\draw[name path=x,->] (A) -- (  .5,-2);
\draw[name path=y,->] (A) -- ( 1.5,-2);
\draw[name path=z,->] (A) -- ( 2.5,-2);
\path[name path=level] (-2.5,-1.5)--(2.5,-1.5);
\foreach \x in {u,...,z}{
\path[name intersections={of=level and \x}](intersection-1) node[fill=white]{\x};
}
\end{tikzpicture}

\end{document}


-
The vertical alignment of y is not correct, a little moved to the top. It can be fixed with anchor=base. –  Heiko Oberdiek Apr 8 at 15:05
@Heiko Oberdiek - if you want the nodes to be centered by middle of the node then it is correctly aligned, if you want it to be centered by base line of the text you need to add option base=anchor as you did in your answer. –  Tahtisilma Apr 8 at 15:11

Here is a simple solution via TikZ (as all other solutions...).

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node[circle,draw] (A) at (0,0) {A};
\foreach \name[count=\c,evaluate=\c as \xpos using {-3.5+\c}] in {u,...,z}{
\draw[->] (A) -- (\xpos,-2);
\path (A.center) -- (\xpos,-2) node[anchor=base,near end,fill=white] {\name};
}
\end{tikzpicture}
\end{document}


-

The only way (i know about) to get all nodes to one height is to set the label-nodes to this specific y-value. This way the y-position of the label-node is fixed and the lines are drawn using partway coordinate specifications. The following code is an short example how to do this:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}
\node [circle, draw] (A) at (0,0) {A};
% set y-value
\newcommand{\y}{-2}
% loop over node-names and x-values
\foreach \n\x in {u/-2.5,v/-1.5,w/-.5,x/.5,y/1.5,z/2.5} {
% draw the arrowed line with offset over end point
\draw [->] (A) -- ($(A)!1.25!(\x, \y)$);
% draw the node and fill background white
\node (\n) [fill=white] at (\x, \y) {\n};
}
\end{tikzpicture}
\end{document}


What we have done here is to draw the arrowed lines for each point (x,y) with the coordinate specification of x1.25 line length. After drawing the arrowed line the labelled node is drawn with white filled background to overdraw the line.

Hope this helps.

-