2

I am trying to make some modificatons to a decision tree model in tikz taken from here. The code I am using is exactly the same as that post with the only change in \documentclass[]{article}

Code:

\documentclass[]{article}

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

\tikzset{
  font=\Large\sffamily\bfseries,
  red arrow/.style={
    midway,red,sloped,fill, minimum height=3cm, single arrow, single arrow head extend=.5cm, single arrow head indent=.25cm,xscale=0.3,yscale=0.15,
    allow upside down
  },
  black arrow/.style 2 args={-stealth, shorten >=#1, shorten <=#2},
  black arrow/.default={1mm}{1mm},
  tree box/.style={draw, rounded corners, inner sep=1em},
  node box/.style={white, draw=black, text=black, rectangle, rounded corners},
}

\begin{document}
\begin{forest}
  for tree={l sep=3em, s sep=3em, anchor=center, inner sep=0.7em, fill=blue!50, circle, where level=2{no edge}{}}
  [
  Training Data, node box
  [sample and feature bagging, node box, alias=bagging, above=4em
  [,red!70,alias=a1[[,alias=a2][]][,red!70,edge label={node[above=1ex,red arrow]{}}[[][]][,red!70,edge label={node[above=1ex,red arrow]{}}[,red!70,edge label={node[below=1ex,red arrow]{}}][,alias=a3]]]]
  [,red!70,alias=b1[,red!70,edge label={node[below=1ex,red arrow]{}}[[,alias=b2][]][,red!70,edge label={node[above=1ex,red arrow]{}}]][[][[][,alias=b3]]]]
  [~~$\dots$~,scale=2,no edge,fill=none,yshift=-4em]
  [,red!70,alias=c1[[,alias=c2][]][,red!70,edge label={node[above=1ex,red arrow]{}}[,red!70,edge label={node[above=1ex,red arrow]{}}[,alias=c3][,red!70,edge label={node[above=1ex,red arrow]{}}]][,alias=c4]]]]
  ]
  \node[tree box, fit=(a1)(a2)(a3)](t1){};
  \node[tree box, fit=(b1)(b2)(b3)](t2){};
  \node[tree box, fit=(c1)(c2)(c3)(c4)](tn){};
  \node[below right=0.5em, inner sep=0pt] at (t1.north west) {Tree 1};
  \node[below right=0.5em, inner sep=0pt] at (t2.north west) {Tree 2};
  \node[below right=0.5em, inner sep=0pt] at (tn.north west) {Tree $n$};
  \path (t1.south west)--(tn.south east) node[midway,below=4em, node box] (mean) {mean in regression or majority vote in classification};
  \node[below=3em of mean, node box] (pred) {prediction};
  \draw[black arrow={5mm}{4mm}] (bagging) -- (t1.north);
  \draw[black arrow] (bagging) -- (t2.north);
  \draw[black arrow={5mm}{4mm}] (bagging) -- (tn.north);
  \draw[black arrow={5mm}{5mm}] (t1.south) -- (mean);
  \draw[black arrow] (t2.south) -- (mean);
  \draw[black arrow={5mm}{5mm}] (tn.south) -- (mean);
  \draw[black arrow] (mean) -- (pred);
\end{forest}
\end{document}

I have been trying to do a few things:

  1. Make the tikz diagram fit inside a \documentclass[]{article} instead of a \documentclass[tikz]{standalone}
  2. I have been trying to change the colors to match the following tree

enter image description here

Where the terminal nodes are coloured in green and red and all of the other nodes are the same colour but cannot seem to figure this part out (currently the trees in the code are red when the arrows are red. I would like to keep the arrows but just make all the colors the same - apart from the terminal nodes).

  1. I can change the circle to rectangle by modifying the following line for tree={l sep=3em, s sep=3em, anchor=center, inner sep=0.7em, fill=blue!50, rectangle, where level=2{no edge}{}} but it turns out to be a square.

EDIT:

enter image description here

2
  1. Well, it's too wide, so you need to make things narrower. For example by reducing the s sep.

  2. The color of the nodes and the color of the arrows are not connected, if a node is red it's because you've added ,red!70 for that specific node. So you just need to remove a lot of those ,red!70s.

  3. You need to set the width and height separately:

      inner sep=0,
      minimum width=1em,
      minimum height=0.5em,
    

No inner sep, so there is no padding, then set minimum width/height to suitable values. You may want to modify them.

I also set s sep in the sample and feature bagging, node, to space the subtrees a bit more, and I added two phantom nodes for additional space between the second and third. And I added the \dots later, by placing a node midway between t2 and tn.

I'd probably set the mean in regression.. node directly below t2, but I'll leave that for you to decide.

The frame in this screenshot is made by the showframe package, and indicates the width of the text block.

enter image description here

\documentclass[]{article}

\usepackage{
  forest,
 % showframe
 }
\usetikzlibrary{fit,positioning}

\tikzset{
  font=\large\sffamily\bfseries,
  red arrow/.style={
    midway,red,sloped,fill, minimum height=3cm, single arrow, single arrow head extend=.5cm, single arrow head indent=.25cm,xscale=0.3,yscale=0.15,
    allow upside down
  },
  black arrow/.style 2 args={-stealth, shorten >=#1, shorten <=#2},
  black arrow/.default={1mm}{1mm},
  tree box/.style={draw, rounded corners, inner sep=1em},
  node box/.style={white, draw=black, text=black, rectangle, rounded corners},
}

\begin{document}
\begin{center}
\begin{forest}
  for tree={
     l sep=2em,
     s sep=2mm,
     anchor=center,
     inner sep=0,
     minimum width=1em,
     minimum height=0.5em,
     fill=blue!50,
     rectangle,
     where level=2{no edge}{}}
  [
  Training Data, node box
  [sample and feature bagging, node box, alias=bagging, above=4em,s sep=1.1cm
  [,alias=a1[[,alias=a2][]][,edge label={node[above=1ex,red arrow]{}}[[][]]
  [,edge label={node[above=1ex,red arrow]{}}[,red!70,edge label={node[below=1ex,red arrow]{}}][,alias=a3]]]]
  [,alias=b1[,edge label={node[below=1ex,red arrow]{}}[[,alias=b2][]][,red!70,edge label={node[above=1ex,red arrow]{}}]][[][[][,alias=b3]]]]
  [,phantom]
  [,phantom]
  [,alias=c1[[,alias=c2][]][,edge label={node[above=1ex,red arrow]{}}[,edge label={node[above=1ex,red arrow]{}}[,alias=c3][,red!70,edge label={node[above=1ex,red arrow]{}}]][,alias=c4]]]]
  ]
  \node[tree box, fit=(a1)(a2)(a3)](t1){};
  \node[tree box, fit=(b1)(b2)(b3)](t2){};
  \node[tree box, fit=(c1)(c2)(c3)(c4)](tn){};
  \begin{scope}[every node/.append style={below right=0.5em, inner sep=0pt, font=\normalsize\sffamily\bfseries}]
  \node at (t1.north west) {Tree 1};
  \node at (t2.north west) {Tree 2};
  \node at (tn.north west) {Tree $n$};
  \end{scope}
  \path (t1.south west)--(tn.south east) node[midway,below=4em, node box] (mean) {mean in regression or majority vote in classification};
  \node[below=3em of mean, node box] (pred) {prediction};
  \draw[black arrow={5mm}{4mm}] (bagging) -- (t1.north);
  \draw[black arrow] (bagging) -- (t2.north);
  \draw[black arrow={5mm}{4mm}] (bagging) -- (tn.north);
  \draw[black arrow={5mm}{5mm}] (t1.south) -- (mean);
  \draw[black arrow] (t2.south) -- (mean);
  \draw[black arrow={5mm}{5mm}] (tn.south) -- (mean);
  \draw[black arrow] (mean) -- (pred);
  \path (t2) -- node {\dots} (tn); % <-- new node
\end{forest}
\end{center}
\end{document}
2
  • Thanks! and thanks for the additional things, it makes it looks much nicer. I am trying to do one final thing with the tikz image. I can modify one of the terminal nodes but I cannot seem to modify all of the colours of the terminal nodes. I see that you are adding red!70 just before edge text. How can I identify the terminal nodes? I added a second graphic in the original post under EDIT to illustrate what I mean.
    – user113156
    Sep 4 '20 at 15:35
  • @user113156 It's possible to set a specific style for all leaf nodes (tex.stackexchange.com/a/248583), but I don't know if you can do it for only some leaves. Other than knowing from how you specify the tree, I don't have any ideas. (Also, I don't think I added the colour, you did.) Sep 4 '20 at 21:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.