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 am trying to draw a tree for a game theory problem. The problem is that the label p1=0.5 crosses label I.

I would like to adjust the level distance of the first level, but the \tikzset{level distance=2cm] command changes all the distances.

Have also tried \tikzstyle{level 1}=[level distance=2cm], but it does not work. What should I do?

I am new to TikZ (2 days only) so will happily accept any other comments.

\documentclass{article}

\usepackage{tikz}
\usepackage{tikz-qtree}

\begin{document}
 \tikzset{edge from parent/.style=
 {draw, edge from parent path={(\tikzparentnode) -- (\tikzchildnode)}}}

\begin{tikzpicture}[grow=down] % game tree
\tikzstyle{mydot} = [circle, minimum width=2pt,fill, inner sep=0pt] % decision node style
\tikzstyle{mystart} = [circle, minimum width=3pt, fill, inner sep=0pt] % starting node style
% \tikzset{level distance=2cm} % attempt to adjust level distance 
\Tree 
    [.\node[mystart, label=above: {N}] {}; 
        \edge node[left] {$p_1=0.5$}; [.\node[mydot, label=above left:I] {}; 
            \edge node[left] {$a$}; \node[mydot, label=below: {$5,1$}] {};  
            \edge node[right] {$b$}; [.\node[mydot, label=above right:II] {};  
                \edge node[left] {$m$}; \node[mydot, label=below: {$1,2$}] {}; 
                \edge node[right] {$n$}; \node[mydot, label=below: {$2,3$}] {}; ]   ]
        \edge node[right] {$p_2=0.5$}; [.\node[mydot, label=above right:II] {};  
            \edge node[left] {$c$}; [.\node[mydot] (a) {};  
                \edge node[left] {$z$}; \node[mydot, label=below: {$1,0$}] {}; 
                \edge node[right] {$t$}; \node[mydot, label=below: {$2,2$}] {}; ] 
            \edge node[right] {$d$}; [.\node[mydot] (b) {}; 
                \edge node[left] {$z$}; \node[mydot, label=below: {$3,1$}] {}; 
                \edge node[right] {$t$}; \node[mydot, label=below: {$0,0$}] {}; ]   ]   ]
\draw[dashed] (a)--node[label=above:I] {}(b);
\end{tikzpicture}
\end{document}
share|improve this question
    
Would it be sufficient just to raise the $p_1=0.5$ and $p_2=0.5$ nodes? You could do this by positioning them with [above left] and [above right] respectively. –  Alan Munn Dec 22 '11 at 15:29
    
The origin of the +500 bounty is the question in tikz-qtree | Several Lines per Node which has been posted today at LaTeX-Community.org. –  Stefan Kottwitz Apr 18 '12 at 21:09

2 Answers 2

up vote 12 down vote accepted

There isn't a way that I know of to specify the level distance for particular levels using tikz-qtree. Of course you could use the regular tikz methods, but tikz-qtree is generally much more efficient in its input. The simplest solution to your problem is to simply move the labels slightly. You can do this by positioning them [above left] and [above right].

I've also made some simplification to your code which will give you less to type: you can make every tree node have your mydot style, and then just override the style for the start node. This means you don't need to add mydot to each of the node commands in the tree. I also removed the [grow down] specification on the tikzpicture, since that is the default growth direction for tikz-qtree.

\documentclass{article}

\usepackage{tikz}
\usepackage{tikz-qtree}

\begin{document}
\begin{tikzpicture}
\tikzstyle{mydot} = 
[circle, minimum width=2pt,fill, inner sep=0pt] % decision node style
\tikzstyle{mystart} = 
[circle, minimum width=3pt, fill, inner sep=0pt] % starting node style

\tikzset{edge from parent/.style=
{draw, 
 edge from parent path={(\tikzparentnode) -- (\tikzchildnode)}},
 every tree node/.style={mydot}} 
 % make every tree node a decision node; then you only have to override the start node

\Tree 
    [.\node[mystart, label=above: {N}] {};  
        \edge node[above left] {$p_1=0.5$}; [.\node[ label=above left:I] {}; 
            \edge node[left] {$a$}; \node[label=below: {$5,1$}] {};  
            \edge node[right] {$b$}; [.\node[ label=above right:II] {};  
                \edge node[left] {$m$}; \node[ label=below: {$1,2$}] {}; 
                \edge node[right] {$n$}; \node[ label=below: {$2,3$}] {}; ]   ]
        \edge node[above right] {$p_2=0.5$}; [.\node[ label=above right:II] {};  
            \edge node[left] {$c$}; [.\node[mydot] (a) {};  
                \edge node[left] {$z$}; \node[ label=below: {$1,0$}] {}; 
                \edge node[right] {$t$}; \node[ label=below: {$2,2$}] {}; ] 
            \edge node[right] {$d$}; [.\node[] (b) {}; 
                \edge node[left] {$z$}; \node[ label=below: {$3,1$}] {}; 
                \edge node[right] {$t$}; \node[ label=below: {$0,0$}] {}; ]   ]   ]
\draw[dashed] (a)--node[label=above:I] {}(b);
\end{tikzpicture}
\end{document}

output of code

share|improve this answer
    
Thank you very much! –  Roah Dec 23 '11 at 5:15

The modifications suggested in this answer have now been subsumed into the tikz-qtree package (version 1.2 or higher). See the documentation for details on how to accomplish this with the latest version.

(This happened in April 2012.)


Looking through the code for tikz-qtree then it appears* that it completely reimplements the tree-planting routines. Therefore, the standard TikZ keys for trees are not guaranteed to work. This is why level 2/.style={something} doesn't work for tikz-qtree.

Whilst it might be possible to hack something together with styles and keys so that each node knows what level it is at, this seems like it would be quite a useful addition to the main code and it is certainly simpler to do by small modifications to that. The first is to the tree-generation system. The trees are generated by a recursion and the code does not currently track the level of recursion. Fortunately, that's simple to correct: we need a new count which we set to 0 at the top of the tree and increment as we go down. Our increments are local to ensure that whenever we return to a level (after processing a child's sublevels), our index is at the right place.

--- pgftree.tex.orig    2010-12-31 00:50:24.000000000 +0100
+++ pgftree.tex 2012-04-19 10:34:57.286252337 +0200
@@ -82,11 +82,14 @@
 \newdimen\pgftree@savechildy
 \newcount\pgftree@childi
 \newcount\pgftree@savechildi
+\newcount\pgftree@level

 %%% \pgftree{subtree}

 \def\pgftree#1{%
 \def\nodename{r}%
+\pgftree@level=0\relax
+\pgfkeys{/pgf/qtree/every level/.try,/pgf/qtree/level \the\pgftree@level/.try}%
 #1%
 \pgfplacesubpicture
 }
@@ -108,6 +111,8 @@
 \pgftree@savechildx=\pgftree@childx
 \pgftree@savechildy=\pgftree@childy
 \pgftree@savechildi=\pgftree@childi
+\advance\pgftree@level by 1\relax
+\pgfkeys{/pgf/qtree/every level/.try,/pgf/qtree/level \the\pgftree@level/.try}%
 % Build subpicture with all the children and their subtrees
 {\pgftree@childx=0pt%
 \pgftree@childy=0pt%

That now allows us to track the level of our tree. The root of the tree ends up at level 1.

Now we need to use that information to execute keys according to the level. To do this, we need to insert some key processing at the relevant stages. There are a couple of places where we could do this: directly in the pgftree code or in the tikz-qtree code. I'm not sure which seems more natural, and the two places where the code makes sense have different effects (one lasts just for the level, the other also has an effect on all subsequent parts of the tree), so I've added code for both. To be consistent with the separation of PGF and TikZ, the keys in the pgftree part are of the form /pgf/qtree/level n and in the tikz-qtree are of the form /tikz/level n. I've also provided a TikZ-level access to the lower-level one by adding a /pgf/qtree/every level key which in tikz-qtree has appended to it the style /tikz,level \the\pgftree@level\space onwards.

The inheritance factor means that to get the desired style, one either does:

\tikzset{level 1/.style={level distance=2cm}}

or one does:

\tikzset{level 1 onwards/.style={level distance=2cm}}
\tikzset{level 2 onwards/.style={level distance=1cm}}

The patch for the pgftree part is included above. The tikz-qtree part follows:

--- tikz-qtree.tex.orig 2011-10-10 23:53:59.000000000 +0200
+++ tikz-qtree.tex  2012-04-19 10:39:02.516300095 +0200
@@ -75,9 +75,9 @@
 }
 \def\@@@@@@subtree{%
 \@ifequal{\the\root@node}{\pgfutil@empty}%
-\edef\act{\noexpand\@result={\noexpand\pgfsubtree{\noexpand\path coordinate (\noexpand\nodename);}{\the\child@list}}}%
+\edef\act{\noexpand\@result={\noexpand\pgfsubtree{\noexpand\tikzset{level \noexpand\the\pgftree@level/.try}\noexpand\path coordinate (\noexpand\nodename);}{\the\child@list}}}%
 \else
-\edef\act{\noexpand\@result={\noexpand\pgfsubtree{\the\root@node}{\the\child@list}}}%
+\edef\act{\noexpand\@result={\noexpand\pgfsubtree{\noexpand\tikzset{level \noexpand\the\pgftree@level/.try}\the\root@node}{\the\child@list}}}%
 \fi
 \act
 \@return}
@@ -117,7 +117,7 @@
 \def\@interior.{\@result{\node[alias=\nodename][every tree node,every internal node]}\@label}

 \def\@leaf{\@call\@label\@@leaf}
-\def\@@leaf{\edef\act{\noexpand\@result{\noexpand\pgfsubtree{\noexpand\node[alias=\noexpand\nodename][every tree node,every leaf node]\the\@result}{}}}\act\@return}
+\def\@@leaf{\edef\act{\noexpand\@result{\noexpand\pgfsubtree{\noexpand\tikzset{level \noexpand\the\pgftree@level/.try}\noexpand\node[alias=\noexpand\nodename][every tree node,every leaf node]\the\@result}{}}}\act\@return}

 \def\@edge\edge #1;{%
 \@result{\edge@adapter{#1}}%
@@ -179,3 +179,4 @@
 % predefined roof style
 \tikzset{roof/.style={edge from parent path=\roof@edge{\tikzparentnode}{\tikzchildnode}}}

+\pgfkeys{/pgf/qtree/every level/.append style={/tikz,level \the\pgftree@level\space onwards/.try}}

It is entirely possible that I've missed some places where keys should be set! So use with caution.

Here's your code with these new keys included:

\documentclass{article}
%\url{http://tex.stackexchange.com/q/39103/86}
\usepackage{tikz}
\usepackage{tikz-qtree}

\begin{document}
 \tikzset{edge from parent/.style=
 {draw, edge from parent path={(\tikzparentnode) -- (\tikzchildnode)}}}
\tikzset{got called/.code={\message{got called}}}

\begin{tikzpicture}[grow=down]% game tree
\tikzset{mydot/.style={circle, minimum width=2pt,fill, inner sep=0pt}} % decision node style
\tikzset{mystart/.style={circle, minimum width=3pt, fill, inner sep=0pt}} % starting node style
\Tree 
    [.\node[mystart, label=above: {N}] {}; 
        \edge node[left] {$p_1=0.5$}; [.\node[mydot, label=above left:I] {}; 
            \edge node[left] {$a$}; \node[mydot, label=below: {$5,1$}] {};  
            \edge node[right] {$b$}; [.\node[mydot, label=above right:II] {};  
                \edge node[left] {$m$}; \node[mydot, label=below: {$1,2$}] {}; 
                \edge node[right] {$n$}; \node[mydot, label=below: {$2,3$}] {}; ]   ]
        \edge node[right] {$p_2=0.5$}; [.\node[mydot, label=above right:II] {};  
            \edge node[left] {$c$}; [.\node[mydot] (a) {};  
                \edge node[left] {$z$}; \node[mydot, label=below: {$1,0$}] {}; 
                \edge node[right] {$t$}; \node[mydot, label=below: {$2,2$}] {}; ] 
            \edge node[right] {$d$}; [.\node[mydot] (b) {}; 
                \edge node[left] {$z$}; \node[mydot, label=below: {$3,1$}] {}; 
                \edge node[right] {$t$}; \node[mydot, label=below: {$0,0$}] {}; ]   ]   ]
\draw[dashed] (a)--node[label=above:I] {}(b);
\end{tikzpicture}
\begin{tikzpicture}[grow=down]% game tree
\tikzset{mydot/.style={circle, minimum width=2pt,fill, inner sep=0pt}} % decision node style
\tikzset{mystart/.style={circle, minimum width=3pt, fill, inner sep=0pt}} % starting node style
\tikzset{level 1/.style={level distance=2cm}}
\Tree 
    [.\node[mystart, label=above: {N}] {}; 
        \edge node[left] {$p_1=0.5$}; [.\node[mydot, label=above left:I] {}; 
            \edge node[left] {$a$}; \node[mydot, label=below: {$5,1$}] {};  
            \edge node[right] {$b$}; [.\node[mydot, label=above right:II] {};  
                \edge node[left] {$m$}; \node[mydot, label=below: {$1,2$}] {}; 
                \edge node[right] {$n$}; \node[mydot, label=below: {$2,3$}] {}; ]   ]
        \edge node[right] {$p_2=0.5$}; [.\node[mydot, label=above right:II] {};  
            \edge node[left] {$c$}; [.\node[mydot] (a) {};  
                \edge node[left] {$z$}; \node[mydot, label=below: {$1,0$}] {}; 
                \edge node[right] {$t$}; \node[mydot, label=below: {$2,2$}] {}; ] 
            \edge node[right] {$d$}; [.\node[mydot] (b) {}; 
                \edge node[left] {$z$}; \node[mydot, label=below: {$3,1$}] {}; 
                \edge node[right] {$t$}; \node[mydot, label=below: {$0,0$}] {}; ]   ]   ]
\draw[dashed] (a)--node[label=above:I] {}(b);
\end{tikzpicture}

\begin{tikzpicture}[grow=down]% game tree
\tikzset{mydot/.style={circle, minimum width=2pt,fill, inner sep=0pt}} % decision node style
\tikzset{mystart/.style={circle, minimum width=3pt, fill, inner sep=0pt}} % starting node style
\tikzset{level distance=2cm}
\tikzset{level 2 onwards/.style={level distance=1cm}}
\Tree 
    [.\node[mystart, label=above: {N}] {}; 
        \edge node[left] {$p_1=0.5$}; [.\node[mydot, label=above left:I] {}; 
            \edge node[left] {$a$}; \node[mydot, label=below: {$5,1$}] {};  
            \edge node[right] {$b$}; [.\node[mydot, label=above right:II] {};  
                \edge node[left] {$m$}; \node[mydot, label=below: {$1,2$}] {}; 
                \edge node[right] {$n$}; \node[mydot, label=below: {$2,3$}] {}; ]   ]
        \edge node[right] {$p_2=0.5$}; [.\node[mydot, label=above right:II] {};  
            \edge node[left] {$c$}; [.\node[mydot] (a) {};  
                \edge node[left] {$z$}; \node[mydot, label=below: {$1,0$}] {}; 
                \edge node[right] {$t$}; \node[mydot, label=below: {$2,2$}] {}; ] 
            \edge node[right] {$d$}; [.\node[mydot] (b) {}; 
                \edge node[left] {$z$}; \node[mydot, label=below: {$3,1$}] {}; 
                \edge node[right] {$t$}; \node[mydot, label=below: {$0,0$}] {}; ]   ]   ]
\draw[dashed] (a)--node[label=above:I] {}(b);
\end{tikzpicture}
\end{document}

Here's the sample output:

tikz-qtree with level changing styles

I would like to add that Ryan Reich's fantastic trace-pgfkeys package was absolutely essential in doing the above. In particular, it made it easy to see that the standard level n keys were not getting processed, which gave me the hint to look deeper into the code to see what exactly was going on. See How do I debug pgfkeys? for more on this most excellent package.

* I've not gone through the code extensively so my deductions could be false. However, they agree with the results of my experiments so I'm prepared to accept them as a working hypothesis.

share|improve this answer
    
Very good! I contacted the package author David and already got positive feedback. As the same problem exists for the silbling distance, are you able to extend the patch for silblings? –  Stefan Kottwitz Apr 19 '12 at 18:27
    
From my experiments, it seems that you have to change the sibling distance using the level <n> onwards key, in which case it needs to be cancelled by the next one to have it only apply to one level. I can't see an easy way to make it non-inheritable due to how the code is implemented. –  Loop Space Apr 19 '12 at 18:58

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.