Tikz/Forest: highlighting level background

I am using the Forest package and I am trying to paint a gray background for odd and even rows, as well as a label.

I already had a version of this diagram that I wrote "manually" with tikz. But it was laid out horizontally (I want it to be vertically laid out, as in the code), and there were also some changes I wanted to make. I was trying to do it from scratch using Forest...

The code I am stuck trying to draw the background .. (I can seem to be able to paint beneath the tree ..)

\documentclass{standalone}

\usepackage{forest}

\begin{document}

\begin{forest}
for tree={draw, circle, l sep+=0.5em, inner sep=0.05em}
[,fill
[{$-$}, edge label={node[midway,left]{$0.70$}}
[$-$, edge label={node[midway,left]{$0.78$}}
[$-$, edge label={node[midway,left]{$0.80$}}
[$-$, edge label={node[midway,left]{$0.82$}}]
[$+$, edge label={node[midway,right]{$0.18$}}]
]
[$+$, edge label={node[midway,right]{$0.20$}}
[$-$, edge label={node[midway,left]{$0.49$}}]
[$+$, edge label={node[midway,right]{$0.51$}}]
]
]
[$+$, edge label={node[midway,right]{$0.22$}}
[$-$, edge label={node[midway,left]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.70$}}]
[$+$, edge label={node[midway,right]{$0.30$}}]
]
[$+$, edge label={node[midway,right]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.57$}}]
[$+$, edge label={node[midway,right]{$0.43$}}]
]
]
]
[{$+$}, edge label={node[midway,right]{$0.30$}}
[$-$, edge label={node[midway,left]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.71$}}
[$-$, edge label={node[midway,left]{$0.75$}}]
[$+$, edge label={node[midway,right]{$0.25$}}]
]
[$+$, edge label={node[midway,right]{$0.29$}}
[$-$, edge label={node[midway,left]{$0.53$}}]
[$+$, edge label={node[midway,right]{$0.47$}}]
]
]
[$+$, edge label={node[midway,right]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.72$}}]
[$+$, edge label={node[midway,right]{$0.28$}}]
]
[$+$, edge label={node[midway,right]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.44$}}]
[$+$, edge label={node[midway,right]{$0.56$}}]
]
]
]
]
\draw[draw=none,fill=black!2] (-5,-2) rectangle (5,-3);
\end{forest}

\end{document}

• Do you want the tree to grow to the right (as in the picture) or grow down? – skpblack Sep 6 '14 at 18:37
• That was the old version. I prefer on this version for it to grow down, yes – Ricardo Cruz Sep 6 '14 at 20:00
• My only problem is to draw the gray highlighting beneath the nodes. In my code, it draws over the diagram .. – Ricardo Cruz Sep 6 '14 at 20:01

You can use the backgrounds library to shade behind the tree and the fit library to help fit it around the nodes. (You still need a manual adjustment to account for the labels but fit takes care of the vertical since you know the inner sep used in the tree.)

I've also spread the last nodes so that the labels are not typeset over each other.

Just for purposes of illustration, I've shaded the background in a darker grey since a 2% shading is almost invisible.

\documentclass{standalone}

\usepackage{forest}
\usetikzlibrary{backgrounds,fit}

\begin{document}

\begin{forest}
for tree={draw, circle, l sep+=0.5em, where level={3}{s sep+=1em}{}, inner sep=0.05em}
[,fill
[{$-$}, edge label={node[midway,left]{$0.70$}}
[$-$, edge label={node[midway,left]{$0.78$}}, name=a
[$-$, edge label={node[midway,left]{$0.80$}}, name=c
[$-$, edge label={node[midway,left]{$0.82$}}]
[$+$, edge label={node[midway,right]{$0.18$}}]
]
[$+$, edge label={node[midway,right]{$0.20$}}
[$-$, edge label={node[midway,left]{$0.49$}}]
[$+$, edge label={node[midway,right]{$0.51$}}]
]
]
[$+$, edge label={node[midway,right]{$0.22$}}
[$-$, edge label={node[midway,left]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.70$}}]
[$+$, edge label={node[midway,right]{$0.30$}}]
]
[$+$, edge label={node[midway,right]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.57$}}]
[$+$, edge label={node[midway,right]{$0.43$}}]
]
]
]
[{$+$}, edge label={node[midway,right]{$0.30$}}
[$-$, edge label={node[midway,left]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.71$}}
[$-$, edge label={node[midway,left]{$0.75$}}]
[$+$, edge label={node[midway,right]{$0.25$}}]
]
[$+$, edge label={node[midway,right]{$0.29$}}
[$-$, edge label={node[midway,left]{$0.53$}}]
[$+$, edge label={node[midway,right]{$0.47$}}]
]
]
[$+$, edge label={node[midway,right]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.72$}}]
[$+$, edge label={node[midway,right]{$0.28$}}]
]
[$+$, edge label={node[midway,right]{$0.50$}}, name=b
[$-$, edge label={node[midway,left]{$0.44$}}]
[$+$, edge label={node[midway,right]{$0.56$}}]
]
]
]
]
\begin{scope}[on background layer]
\node [fill=black!25, fit={(a.south) (c) (b)}, inner ysep=.05em, inner xsep=.75em, outer sep=0pt] {};
\end{scope}
\end{forest}

\end{document}


Update

To add the labels, you could use the positioning library as follows:

\documentclass{standalone}

\usepackage{forest}
\usetikzlibrary{backgrounds,fit,positioning}

\begin{document}

\begin{forest}
for tree={draw, circle, l sep+=0.5em, where level={3}{s sep+=1em}{}, inner sep=0.05em}
[,fill
[{$-$}, edge label={node[midway,left]{$0.70$}}, name=e
[$-$, edge label={node[midway,left]{$0.78$}}, name=a
[$-$, edge label={node[midway,left]{$0.80$}}, name=c
[$-$, edge label={node[midway,left]{$0.82$}}, name=d]
[$+$, edge label={node[midway,right]{$0.18$}}]
]
[$+$, edge label={node[midway,right]{$0.20$}}
[$-$, edge label={node[midway,left]{$0.49$}}]
[$+$, edge label={node[midway,right]{$0.51$}}]
]
]
[$+$, edge label={node[midway,right]{$0.22$}}
[$-$, edge label={node[midway,left]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.70$}}]
[$+$, edge label={node[midway,right]{$0.30$}}]
]
[$+$, edge label={node[midway,right]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.57$}}]
[$+$, edge label={node[midway,right]{$0.43$}}]
]
]
]
[{$+$}, edge label={node[midway,right]{$0.30$}}
[$-$, edge label={node[midway,left]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.71$}}
[$-$, edge label={node[midway,left]{$0.75$}}]
[$+$, edge label={node[midway,right]{$0.25$}}]
]
[$+$, edge label={node[midway,right]{$0.29$}}
[$-$, edge label={node[midway,left]{$0.53$}}]
[$+$, edge label={node[midway,right]{$0.47$}}]
]
]
[$+$, edge label={node[midway,right]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.50$}}
[$-$, edge label={node[midway,left]{$0.72$}}]
[$+$, edge label={node[midway,right]{$0.28$}}]
]
[$+$, edge label={node[midway,right]{$0.50$}}, name=b
[$-$, edge label={node[midway,left]{$0.44$}}]
[$+$, edge label={node[midway,right]{$0.56$}}]
]
]
]
]
\begin{scope}[on background layer]
\node [fill=black!25, fit={(a.south) (c) (b)}, inner ysep=.05em, inner xsep=.75em, outer sep=0pt] {};
\end{scope}
\node (p) [left=5pt of d] {memory 4};
\node at (p |- c) {memory 3};
\node at (p |- a) {memory 2};
\node at (p |- e) {memory 1};
\end{forest}

\end{document}


Use the rotate option if you want the nodes labelling the tree to run vertically. (I wasn't sure whether you wanted this or not.)

• Dear cfr, thank you! Do you know how can I add the "memory 1", "memory 2", .. to label each layer (as in the picture)? I need somehow to specify y relatively to one node, and x would be the origin of the picture .. – Ricardo Cruz Sep 9 '14 at 7:48
• @RicardoCruz See my updated answer. You can rotate the labels as I mention although you would then need to stagger them or something as they obviously won't fit otherwise. However, horizontal labels are probably more legible. – cfr Sep 9 '14 at 14:36
• Thank you. Just some minor tweaks to do, but now I can do it, the difficult part is done. :) – Ricardo Cruz Sep 9 '14 at 19:37