[Tex/LaTex] Tikz/Forest: highlighting level background

foresttikz-pgftrees

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…

tree result

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}

Best Answer

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}

shade behind tree

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}

labelled

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.)

Related Question