# Tikz tree drawing with comments to each level

I have problem with drawing trees with tikz.

The tree is correct, but 'rightarrows' wrongly indicate to text, which is related to each tree-level (it doesn't look good). Of course, the text should by shown also without circles.

Could anyone can help with that?

I wrote the tree, based on this example: http://www.texample.net/tikz/examples/merge-sort-recursion-tree

My code:

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

\begin{document}
\begin{tikzpicture}[level distance=1.5cm,
level 1/.style={sibling distance=3.5cm},
level 2/.style={sibling distance=1cm}]
\tikzstyle{every node}=[circle,draw]
\node [red] {1}
child [red] {
node {3}
child { node {4} }
child [black] { node {5} }
child [black] { node {5} }
}
child {
node {3}
child { node {4} }
child { node {5} }
child { node {5} }
}
child {
node {3}
child { node {4} }
child { node {5} }
child { node {5}
child [grow=right] { node (q) {$\Rightarrow$} edge from parent [draw=none]
child [grow=right] {node (q) {$\textrm{2nd level arrow indicates here}$} edge from parent[draw=none]
child [grow=up] {node (q) {$\Rightarrow$} edge from parent[draw=none]
child [grow=right] {node (r) {$\textrm{1st level arrow indicates here}$} edge from parent[draw=none]
child [grow=up] {node (s) {$\Rightarrow$} edge from parent[draw=none]
child [grow=right] {node (r) {$\textrm{1st level arrow indicates here}$} edge from parent[draw=none]
}
}
}
}
}
}
}
};

\end{tikzpicture}
\end{document}

-

You can make use of an interesting feature of TikZ tree nodes. If you give a name to the root node, eg. Root, then all the nodes in the tree are automatically named too. Each of the children of node Root are named Root-1, Root-2, Root-3 and so on. Each of these children can have childrens in turn, which are named with the same schema. For example, in your tree, the leftmost child node would be called Root-1-1, while the rightmost node of the tree is Root-3-3.

Once you know the names of these nodes, you can draw anything at coordinates relative to them. For example:

\path (Root)  ++(3cm,0) node{Foo};


Would place the text Foo at 3cm from the Root node.

If you want the comments to be vertically aligned, they should share the horizontal coordinate. A good reference point from which position each comment would be the coordinate whose y part is the same of the commented level, while the x part is the same than the rightmost node. These coordinates can be specified using -| syntax. For example, coordinate (Root -| Root-3-3) is the point at the intersection between a horizontal line through Root and a vertical line through Root-3-3. This is the point marked in red in the following picture:

In the same way (Root-1 -| Root-3-3) would give a point at the same horizontal coordinate, but at second level, and (Root-1-1 -| Root-3-3) for the third level.

These coordinates can be used to position the comments and the arrows, as the following MWE shows:

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

\begin{document}
\begin{tikzpicture}[level distance=1.5cm,
level 1/.style={sibling distance=3.5cm},
level 2/.style={sibling distance=1cm}]
\tikzstyle{every node}=[circle,draw]
\node (Root) [red] {1}
child [red] {
node {3}
child { node {4} }
child [black] { node {5} }
child [black] { node {5} }
}
child {
node {3}
child { node {4} }
child { node {5} }
child { node {5} }
}
child {
node {3}
child { node {4} }
child { node {5} }
child { node {5} }
};
\begin{scope}[every node/.style={right}]
\path (Root    -| Root-3-3) ++(5mm,0) node {$\Rightarrow$} ++(5mm,0) node {1st level arrow indicates here};
\path (Root-1  -| Root-3-3) ++(5mm,0) node {$\Rightarrow$} ++(5mm,0) node {2nd level arrow indicates here};
\path (Root-1-1-| Root-3-3) ++(5mm,0) node {$\Rightarrow$} ++(5mm,0) node {3rd level arrow indicates here};
\end{scope}

\end{tikzpicture}
\end{document}


Wich results in:

Of course this kind of repetitive tasks are better handled with a loop. In this case I will use a variable called \text to loop over the comments for each level, and let the body of the loop to calculate the appropiate coordinates. I use a nasty trick, in which the string "-1" is added to the end of the macro \level at each iteration of the loop, so that the first iteration it expands to Root, the second one to Root-1, the third to Root-1-1 and so on:

 \begin{scope}[every node/.style={right}]
\xdef\level{Root}  % Initial top level
\def\rightmostnode{Root-3-3}   % Name of the node with greater x coordinate
\foreach \text in {1st level arrow indicates here,
2nd level arrow indicates here,
3rd level arrow indicates here}
{
\path (\level -|\rightmostnode) ++(5mm,0) node{$\Rightarrow$} ++(5mm,0) node {\text};
\xdef\level{\level-1}
}
\end{scope}


Note that this "general" solution produces the same result, but is more complex and uses more lines and memory than the initial, more straight, solution. But I could not help showing it. It is a programmer's disease.

-
Very good advice! –  Paul Gaborit Jul 17 '12 at 22:26

You can use the technique described in this question How to draw custom nodes attached to tikz-qtree? to draw the annotations as a separate tree beside the first tree using TikZ's scope mechanism. This way you will line up the levels correctly. For most trees, the tikz-qtree package provides a much simpler syntax for entering the tree itself.

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-qtree}
\begin{document}

\begin{tikzpicture}[every tree node/.style={draw,circle},edge from parent path={(\tikzparentnode) -- (\tikzchildnode)},sibling distance=.5cm]
\Tree [.\node[red] (1) {1};
\edge[red]; [.\node[red] (3) {3}; \edge[red];[.\node[red] (4) {4}; ] [.5 ] [.5 ] ]
[.3 [.4 ] [.5 ] [.5 ] ]
[.3 [.4 ] [.5 ] [.5 ] ]
]
\begin{scope}[xshift=3in,every tree node/.style={},edge from parent path={}]
\Tree [.{First level} [.{Second Level} [.{Third level} ]]]
\end{scope}
\end{tikzpicture}
\end{document}


-