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 want to create labels and the corresponding lines cutting through the branch levels of a (horizontal) tikz-qtree. Here's the idea.

enter image description here

I tried for quite some time and searched the net, but could not find anything for further progress...

The following code produces the original tikz-tree.

\begin{figure}[bh!]
\centering
\begin{tikzpicture}[ level distance=1cm, growth parent anchor=east, grow=right,scale=0.78, 
level distance=1cm,
]

\tikzstyle{every node}=[font=\footnotesize, text width=5mm,anchor=east]

\Tree[.{0} [.{1} [.{1} [.{1} [.{1} [.{2} [.{7} [.{9} [.{4} [.{33} ] [.{474} ] ] [.{478} ] ] [.{487} ] ] [.{494} ] ] [.{496} ] ] [.{497} ] ] [.{498} ] ] [.{499} ] ] [.{4} [.{13} [.{4} [.{4} [.{7} [.{25} [.{9} [.{120} [.{314} ] [.{314} ] ] [.{434} ] ] [.{443} ] ] [.{468} ] ] [.{475} ] ] [.{479} ] ] [.{483} ] ] [.{496} ] ] [.{1} [.{2} [.{18} [.{39} [.{2} [.{55} [.{56} [.{327} ] [.{327} ] ] [.{383} ] ] [.{438} ] ] [.{440} ] ] [.{479} ] ] [.{497} ] ] [.{499} ] ] [.{3} [.{10} [.{2} [.{3} [.{6} [.{8} [.{7} [.{16} [.{32} ] [.{445} ] ] [.{461} ] ] [.{468} ] ] [.{476} ] ] [.{482} ] ] [.{485} ] ] [.{487} ] ] [.{497} ] ] [.{6} [.{9} [.{7} [.{1} [.{3} [.{3} [.{9} [.{14} [.{24} ] [.{448} ] ] [.{462} ] ] [.{471} ] ] [.{474} ] ] [.{477} ] ] [.{478} ] ] [.{485} ] ] [.{494} ] ] [.{444} [.{56} ] [.{56} ] ] ]

\end{tikzpicture}
\end{figure}
share|improve this question
add comment

1 Answer 1

up vote 6 down vote accepted

Here is a solution which reproduces the figure you want to get. The solution involves to manually "mark" some nodes to give them a name, so that you can refer to them later when you annotate the tree, so it is a solution very specific to the original question. I don't know if you wanted a more general solution.

My solution works as follows. I manually look up a node in the last level (I choose the one with value 448) and give it a name: \node(levelz){448};. I do the same for a node at previous level: \node(levelz-1){462}. I also give a name to the root node: \node(Root){0}.

These names can be used in different ways. I can use them directly in any TikZ drawing command, as for example: \fill[red] (Root) circle(2pt); and this would place a red dot on the root node. But it can be used also as argument to \subtreeof command, in which case the selected node is no longer Root, but the whole tree. This allows me to get the coordinates of the bounding box of the whole tree. For example \subtreeof{Root}.north would give me the coordinate of the top.

Combining these coordinates through the use of the -| operator, I can get the coordinates at which draw your required lines, as the following code shows:

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

\begin{document}
\begin{tikzpicture}[ level distance=1cm, growth parent anchor=east, grow=right,scale=0.78,
level distance=1cm,
]

\tikzstyle{every node}=[font=\footnotesize, text width=5mm,anchor=east]

\Tree [.\node(Root){0}; [.{1} [.{1} [.{1} [.{1} [.{2} [.{7} [.{9} [.{4} [.{33} ] [.{474} ] ] [.{478} ] ] [.{487} ] ] [.{494} ] ] [.{496} ] ] [.{497} ] ] [.{498} ] ] [.{499} ] ] [.{4} [.{13} [.{4} [.{4} [.{7} [.{25} [.{9} [.{120} [.{314} ] [.{314} ] ] [.{434} ] ] [.{443} ] ] [.{468} ] ] [.{475} ] ] [.{479} ] ] [.{483} ] ] [.{496} ] ] [.{1} [.{2} [.{18} [.{39} [.{2} [.{55} [.{56} [.{327} ] [.{327} ] ] [.{383} ] ] [.{438} ] ] [.{440} ] ] [.{479} ] ] [.{497} ] ] [.{499} ] ] [.{3} [.{10} [.{2} [.{3} [.{6} [.{8} [.{7} [.{16} [.{32} ] [.{445} ] ] [.{461} ] ] [.{468} ] ] [.{476} ] ] [.{482} ] ] [.{485} ] ] [.{487} ] ] [.{497} ] ] [.{6} [.{9} [.{7} [.{1} [.{3} [.{3} [.{9} [.{14} [.{24} ] [.\node(levelz){448}; ] ] [.\node(levelz-1){462}; ] ] [.{471} ] ] [.{474} ] ] [.{477} ] ] [.{478} ] ] [.{485} ] ] [.{494} ] ] [.{444} [.{56} ] [.{56} ] ] ]

\draw[blue, dashed] (\subtreeof{Root}.south -| levelz.west) -- (\subtreeof{Root}.north -| levelz.west)
  node[right, text width=] {Level $z$};
\draw[blue, dashed] (\subtreeof{Root}.south -| levelz-1.west) -- (\subtreeof{Root}.north -| levelz-1.west)
  node[left, text width=] {Level $z-1$};
\end{tikzpicture}
\end{document}

Which produces:

Output tree

UPDATE

As you can see in the previous example, the vertical dashed lines pass through the end of the edges. Reading again your question you said you wanted them to go "through the branch" level. This admits three intepretations. The first one is what I did above. The second one is to consider the left end of the edges (the point at which the fork happens). The third one is to consider the middle point of the edges.

All these options are easy to implement with the same technique. For the second option, you name a node at level z-1 as branchz for example, and a node at level z-2 and name it branchz-1. Using the east anchor of those nodes you get the coordinate at which forks happen.

For the third option you need to combine the two previous options and compute the midpoint of those coordinates.

The following code implements all the options and draw the lines in different colors (also marking with a big dot the selected coordinates). I used two nested loops. The outer one is for each level we want to label in the tree (assuming that appropiates nodes with names levelz, levelz-1, branchz, branchz-1 and so on exist in the Tree). The inner loop is to paint the three options for each level.

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-qtree}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}[ level distance=1cm, growth parent anchor=east, 
                     grow=right,scale=0.78, level distance=1cm,
]

\tikzstyle{every node}=[font=\footnotesize, text width=5mm,anchor=east]

\Tree [.\node(Root){0}; [.{1} [.{1} [.{1} [.{1} [.{2} [.{7} [.{9} [.{4} [.{33} ] [.{474} ] ] [.{478} ] ] [.{487} ] ] [.{494} ] ] [.{496} ] ] [.{497} ] ] [.{498} ] ] [.{499} ] ] [.{4} [.{13} [.{4} [.{4} [.{7} [.{25} [.{9} [.{120} [.{314} ] [.{314} ] ] [.{434} ] ] [.{443} ] ] [.{468} ] ] [.{475} ] ] [.{479} ] ] [.{483} ] ] [.{496} ] ] [.{1} [.{2} [.{18} [.{39} [.{2} [.{55} [.{56} [.{327} ] [.{327} ] ] [.{383} ] ] [.{438} ] ] [.{440} ] ] [.{479} ] ] [.{497} ] ] [.{499} ] ] [.{3} [.{10} [.{2} [.{3} [.{6} [.{8} [.{7} [.{16} [.{32} ] [.{445} ] ] [.{461} ] ] [.{468} ] ] [.{476} ] ] [.{482} ] ] [.{485} ] ] [.{487} ] ] [.{497} ] ] [.{6} [.{9} [.{7} [.{1} [.{3} [.{3} [.\node(branchz-1){9}; [.\node(branchz){14}; [.{24} ] [.\node(levelz){448}; ] ] [.\node(levelz-1){462}; ] ] [.{471} ] ] [.{474} ] ] [.{477} ] ] [.{478} ] ] [.{485} ] ] [.{494} ] ] [.{444} [.{56} ] [.{56} ] ] ]

\foreach \level in {z,z-1} {
  \coordinate (option1) at (level\level.west) {};
  \coordinate (option2) at (branch\level.east) {};
  \coordinate (option3) at ($(branch\level.east)!.5!(level\level.west)$) {};
  \foreach \i/\c in {1/red, 2/blue, 3/green} {
     \fill[\c] (option\i) circle (2pt);
     \draw[\c,dashed] (\subtreeof{Root}.south -| option\i) 
                   -- (\subtreeof{Root}.north -| option\i);
     }
}
\end{tikzpicture}
\end{document}

A close up at the interesting part:

Result

share|improve this answer
    
Thank you so much for your comprehensive answer! If I could vote up your answer multiple times I would do so :) This solves exactly what I was looking for. –  Eric Jul 18 '12 at 11:22
add comment

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.