3

How can I highlight some specific regions in my TikZ tree?

First picture shows my tree, and the second picture shows the idea of my desired outcome (but the rounded grey rectangles should be behind the nodes and edges, in the background, so that still the whole tree is visible). Furthermore on top (but still inside) of each rounded grey rectangle there should be the possibility to type a short text/name.

Hope you can help me!

enter image description here enter image description here

\documentclass[border=0.1cm]{standalone}
\usepackage[dvipsnames]{xcolor}

\usepackage[utf8x]{inputenc}
\usepackage{tikz}
\usetikzlibrary{trees}
\begin{document}


% Set the overall layout of the tree
\tikzstyle{level 1}=[level distance=5.5cm, sibling distance=3.5cm]
\tikzstyle{level 2}=[level distance=4.5cm, sibling distance=3cm]
\tikzstyle{level 3}=[level distance=4.5cm, sibling distance=4cm]

\tikzstyle{terminal} = [rectangle, rounded corners=0.1cm, fill=BrickRed!40]
\tikzstyle{other} = [rectangle, rounded corners=0.1cm,fill=MidnightBlue!40]


\begin{tikzpicture}[grow=right, sloped]
\node[other] {sf}
        child {
                node[other] {daeda}        
                        child {
                                node[other] {aedae}
                                child {
                                        node[terminal] {Zae}
                                        edge from parent
                                        node[above] {aeae}
                                    }
                                child {
                                        node[terminal] {ae}
                                        edge from parent
                                        node[above] {a}
                                        node[below] {a}
                                    }       
                                edge from parent
                            node[above] {}
                            node[below] {ae}
                        }
                        child {
                                node[terminal] {ad}
                                edge from parent
                                node[above] {}
                        }
                        child {
                                node[terminal] {a}
                                edge from parent
                                node[above] {}
                        }
                        edge from parent 
                        node[above]  {}
        };


\end{tikzpicture}

\end{document}
Zarko
  • 296,517
d4rty
  • 779

2 Answers2

4

Here is a method using the powerful forest package for drawing trees. The nice thing about this is that, once you've got the styles defined, specifying the tree itself can be done very concisely.

In this case, the actual tree is specified using just

  [sf, my box=box 1
    [daeda, my box=box 2
      [aedae, my edge label'=ae, my box=box 3
        [Zae, my edge label=aeae]
        [ae, my double edge labels={a}{a}, my box=box 4]
      ]
      [ad]
      [a]
    ]
  ]

which draws the nodes, styles them appropriately, adds the edge labels and draws the background boxes with their labels.

The preamble for this particular tree is

  for tree={
    if n children=0{terminal}{other},
    grow=0,
    l sep+=30pt,
    s sep+=30pt,
  },
  highlight tree

which tells forest that terminal nodes should use the terminal style, other nodes should use other, the tree should grow east and the distances between levels and siblings should be increased by 30pt. The final line highlight tree is doing most of the work. This invokes a style which sets up the overall configuration for the tree.

In particular, highlight tree enables my box=<label for box> which can be used wherever appropriate to draw a labelled box behind nodes at that level.

In addition, my edge label={<edge label above>} my edge label'={<edge label below>} and my double edge labels={<edge label above>}{<edge label below>} make it easier to add the labels on the edges of the tree.

background highlighting

For a brief introduction to forest and instructions for turning a tree into the bracket syntax used by the package, see the second part of my answer here.

Complete code:

\documentclass[tikz,border=10pt,dvipsnames]{standalone}
\usepackage{forest}
\usetikzlibrary{backgrounds,shadows}
\begin{document}
\tikzset{
  terminal/.style = {rounded corners=0.1cm, inner color=BrickRed!35, outer color=BrickRed!45, draw=BrickRed, drop shadow},
  other/.style = {rounded corners=0.1cm, inner color=MidnightBlue!35, outer color=MidnightBlue!45, draw=MidnightBlue, drop shadow},
  auto edge label/.style={midway, anchor=center, sloped},
  my box width/.store in=\myboxwidth,
  my box width=4em,
  highlight tree/.code={
    \forestset{
      my box/.style={
        before drawing tree={
          tikz+={
            \scoped[on background layer]{
              \fill [gray!25, rounded corners, draw=gray!50] () +(-.5*\myboxwidth,0) coordinate (c1) -- (tree top -| c1) -- +(\myboxwidth,0) |- (c1 |- tree bot) -- cycle;
            }
            \node [anchor=mid] at ([yshift=.5em]tree bot -| ) {##1};
          },
        },
      },
      before drawing tree={
        tikz={%
          \coordinate (tree top) at ([yshift=1em]current bounding box.north);
          \coordinate (tree bot) at ([yshift=-2em]current bounding box.south);}
      },
    }
  }
}
\forestset{
  my edge label/.style={
    edge label={node [auto edge label, above] {#1}},
  },
  my edge label'/.style={
    edge label={node [auto edge label, below] {#1}},
  },
  my double edge labels/.style n args=2{
    edge label={node [auto edge label, above] {#1} node [auto edge label, below] {#2}},
  },
  highlight tree/.style={/tikz/highlight tree},
}

\begin{forest}
  for tree={
    if n children=0{terminal}{other},
    grow=0,
    l sep+=30pt,
    s sep+=30pt,
  },
  highlight tree
  [sf, my box=box 1
    [daeda, my box=box 2
      [aedae, my edge label'=ae, my box=box 3
        [Zae, my edge label=aeae]
        [ae, my double edge labels={a}{a}, my box=box 4]
      ]
      [ad]
      [a]
    ]
  ]
\end{forest}
\end{document}
cfr
  • 198,882
  • Thank you very much for this alternative using forest. Looks much better than using trees/tikz. – d4rty Nov 13 '15 at 11:25
  • Yes, it is kind of neat. There will be a new version soon, too, which is looking as if it will be even better. It is definitely worth a look if you are drawing more than one or two trees. – cfr Nov 13 '15 at 13:32
2

Do you mean this:

enter image description here

For above picture you need to ad two more TikZ libraries: backgrounds and fit and named nodes, which you like to highlight:

\documentclass[border=5mm]{standalone}
    \usepackage[dvipsnames]{xcolor}
    \usepackage[utf8x]{inputenc}
    \usepackage{tikz}
    \usetikzlibrary{backgrounds,fit,trees}

    \begin{document}
\begin{tikzpicture}[grow=right, sloped,
  level 1/.style = {level distance=5.5cm, sibling distance=3.5cm},
  level 2/.style = {level distance=4.5cm, sibling distance=3cm},
  level 3/.style = {level distance=4.5cm, sibling distance=4cm},
%
 terminal/.style = {rectangle, rounded corners=0.1cm, fill=BrickRed!40},
    other/.style = {rectangle, rounded corners=0.1cm,fill=MidnightBlue!40},
%
highlight/.style = {minimum width=16mm,% fixed width
                    rounded corners, fill = gray!30,
                    inner ysep=2mm},
                    ]

\node (sf) [other] {sf}
    child {
            node (daeda) [other] {daeda}
                    child {
                            node (aedae) [other] {aedae}
                            child {
                                    node (zae) [terminal] {Zae}
                                    edge from parent
                                    node[above] {aeae}
                                }
                            child {
                                    node[terminal] {ae}
                                    edge from parent
                                    node[above] {a}
                                    node[below] {a}
                                }
                            edge from parent
                        node[above] {}
                        node[below] {ae}
                    }
                    child {
                            node[terminal] {ad}
                            edge from parent
                            node[above] {}
                    }
                    child {
                            node (a) [terminal] {a}
                            edge from parent
                            node[above] {}
                    }
                    edge from parent
                    node[above]  {}
    };
% highlights
\begin{scope}[on background layer]
    \node[highlight,label=above:my label,
          fit=(sf) (sf |- a.north) (sf |- zae.south)] {};
    \node[highlight,fit=(daeda) (daeda |- a.north) (daeda |- zae.south)] {};
    \node[highlight,fit=(aedae) (aedae |- a.north) (aedae |- zae.south)] {};
   \node[highlight,fit=(zae) (zae |- a.north)] {};
\end{scope}
\end{tikzpicture}
    \end{document}
Zarko
  • 296,517
  • Yes almost. Is there a way that the width of the grey boxes is firstly equal to all other boxes and secondly variable (like giving an absolut value for the widht)? – d4rty Nov 12 '15 at 17:29
  • The width of gray boxes is for inner sep wider than widest box inside it. Of course it can be fixed manually to be equal. See edit of my answer. – Zarko Nov 12 '15 at 18:00
  • Great, one last thing: how can I now simple add text on top of each grey box? – d4rty Nov 12 '15 at 18:10
  • how would it work when the nodes in the tree are not labeled unique? – d4rty Nov 12 '15 at 19:46
  • This is easy to imagine, isn't it? Names should be unique. Maybe now is time, that you with example in my answer make some experiments and "learn by doing": change names, use the same names for different nodes, change font appearance, change distances etc. If in this you will meet new difficulties, just ask new, specific question. Otherwise, we will soon reach allowed number of comments to some question/answer ... – Zarko Nov 12 '15 at 19:56
  • OK I got it over the night. Thank you for your answer! – d4rty Nov 13 '15 at 11:23