# Decision Tree with Labels on Both Sides of Line

I am trying to generate a decision tree similar to this scanned example:

Notice that some branches have text on the top as well as the bottom. I have not figured out how to do this. I can get text on the top or bottom, but not both.

I am enclosing a partial solution. I try to Add "Outbreak" as the top label and "0.060" as the bottom label, but it causes the first label to disappear.

   \documentclass{beamer}

\usepackage{tikz}
\usetikzlibrary{trees,shapes,snakes}
\usepackage{forest}

\tikzset{
decision/.style={rectangle, minimum height=10pt, minimum width=10pt, draw=black, fill=black!30!white, thick, inner sep=0pt},
chance/.style={circle, minimum width=10pt, draw=black, fill=black!30!white, thick, inner sep=0pt},
leaf-chance/.style={isosceles triangle, minimum width=10pt, draw=black, thick, fill=white, inner sep=0pt, shape border rotate=180, outer sep=-\pgflinewidth}
}

\newsavebox\notgood
\sbox\notgood{\textbardbl}
\forestset{
declare toks={optimality}{},
sub optimal/.style={
optimality={
node [midway, sloped] {\usebox\notgood}
}
}
}

\begin{document}

\begin{frame}[fragile]

\scalebox{0.85}{
\begin{forest}
%my label/.style={
%   edge label={node[auto, sloped,pos=.75,anchor=south]{#1}}
% },
my label/.style={
edge label={node[midway,above,font=\scriptsize,text width=1.5cm,align=center]{#1}}
},
my below/.style={
edge label={node[midway,below,font=\scriptsize,text width=1.5cm,align=center]{#1}}
},
for tree={
grow=0,
child anchor=west,
anchor=west,
text ragged,
inner sep=1mm,
edge={thick, draw=blue},
l sep+=30mm,
s sep+=5mm,
if n children=0{
before typesetting nodes={
label/.wrap pgfmath arg={right:#1}{content()},
content={},
leaf-chance,
},
}{},
edge path={
\noexpand\path[\forestoption{edge}]
(!u.parent anchor) -- ([xshift=-22.5mm].child anchor)\forestove{optimality} --  (.child anchor)\forestoption{edge label};
},
}
[,decision
[0.8351,chance,my label=Insure]
[,chance,my label=Don't Insure, sub optimal
[0.8394,chance,my label=No outbreak
]
[,chance,my label=Outbreak, my below=0.060
[0.8334,chance,my label=Bans only
]
[0.6663,chance,my label=Slaughter
]
]
]
]
\end{forest}
}

\end{frame}
\end{document}


I found this previous answer helpful in switching between above/below, but doesn't show how to get both: https://tex.stackexchange.com/a/177254/80455

Also, this is the same example as Adding Short Lines Across Decision Tree Branch (but a different question).

• Do you want to have also only above and only below? – Alenanno Jun 21 '15 at 22:31
• Yes, I would like the flexibility to have above, below, both, or none. – fraserbc Jun 21 '15 at 23:02

edge label will override any previous value for any particular node. So the first label disappears. But we can use the same method as I used for the sub optimal style i.e. declare another option, just like edge label and then add it to the redefinition of edge path.

\documentclass{beamer}

\usepackage{etex,forest}
\usetikzlibrary{shapes,snakes}

\tikzset{
decision/.style={rectangle, minimum height=10pt, minimum width=10pt, draw=black, fill=black!30!white, thick, inner sep=0pt},
chance/.style={circle, minimum width=10pt, draw=black, fill=black!30!white, thick, inner sep=0pt},
leaf-chance/.style={isosceles triangle, minimum width=10pt, draw=black, thick, fill=white, inner sep=0pt, shape border rotate=180, outer sep=-\pgflinewidth}
}

\newsavebox\notgood
\sbox\notgood{\textbardbl}
\forestset{
declare toks={optimality}{},
sub optimal/.style={
optimality={
node [midway, sloped] {\usebox\notgood}
}
},
declare toks={edge label below}{},
}

\begin{document}

\begin{frame}[fragile]
\scalebox{0.85}{%
\begin{forest}
my label/.style={
edge label={node[midway,above,font=\scriptsize,text width=1.5cm,align=center]{#1}}
},
my below/.style={
edge label below={node[midway,below,font=\scriptsize,text width=1.5cm,align=center]{#1}}
},
for tree={
grow=0,
child anchor=west,
anchor=west,
text ragged,
inner sep=1mm,
edge={thick, draw=blue},
l sep+=30mm,
s sep+=5mm,
if n children=0{
before typesetting nodes={
label/.wrap pgfmath arg={right:#1}{content()},
content={},
leaf-chance,
},
}{},
edge path={
\noexpand\path[\forestoption{edge}]
(!u.parent anchor) -- ([xshift=-22.5mm].child anchor)\forestove{optimality} --  (.child anchor)\forestoption{edge label below}\forestoption{edge label};
},
}
[,decision
[0.8351,chance,my label=Insure]
[,chance,my label=Don't Insure, sub optimal
[0.8394,chance,my label=No outbreak
]
[,chance,my label=Outbreak, my below=0.060
[0.8334,chance,my label=Bans only
]
[0.6663,chance,my label=Slaughter
]
]
]
]
\end{forest}%
}%
\end{frame}
\end{document}


To avoid the crowding, either allow longer labels (increase or remove text width) or increase the value of s sep.

Removing the restriction on text width:

   my label/.style={
edge label={node[midway,above,font=\scriptsize,align=center]{#1}}
},
my below/.style={
edge label below={node[midway,below,font=\scriptsize,align=center]{#1}}
},


Increasing s sep:

  s sep+=7.5mm,


• Thank you! Great solution, including the help on spacing. – fraserbc Jun 22 '15 at 2:35
• @fraserbc I'm somewhat obsessed with forest ;). After I finally figured out how to use it (with some help from this site). – cfr Jun 22 '15 at 2:46

This is a bit of a "hack", but you can simply set an extra label without the above or below keys. Then using \\ when you want to switch to the "other line", they will show one above, one below.

So basically, you'll have:

• my above
• my below
• my label (both)

As far as you've showed, this will work. If there is some situation where this behaviour breaks, please specify it.

## Code

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{trees,shapes,snakes}
\usepackage{forest}

\tikzset{
decision/.style={rectangle, minimum height=10pt, minimum width=10pt, draw=black, fill=black!30!white, thick, inner sep=0pt},
chance/.style={circle, minimum width=10pt, draw=black, fill=black!30!white, thick, inner sep=0pt},
leaf-chance/.style={isosceles triangle, minimum width=10pt, draw=black, thick, fill=white, inner sep=0pt, shape border rotate=180, outer sep=-\pgflinewidth}
}

\newsavebox\notgood
\sbox\notgood{\textbardbl}
\forestset{
declare toks={optimality}{},
sub optimal/.style={
optimality={
node [midway, sloped] {\usebox\notgood}
}
}
}

\begin{document}

\begin{frame}[fragile]

\scalebox{0.85}{
\begin{forest}
my above/.style={
edge label={node[midway,above,font=\scriptsize,align=center]{#1}}
},
my below/.style={
edge label={node[midway,below,font=\scriptsize,align=center]{#1}}
},
my label/.style={
edge label={node[midway,font=\scriptsize,align=center]{#1}}
},
for tree={
grow=0,
child anchor=west,
anchor=west,
text ragged,
inner sep=1mm,
edge={thick, draw=blue},
l sep+=30mm,
s sep+=5mm,
if n children=0{
before typesetting nodes={
label/.wrap pgfmath arg={right:#1}{content()},
content={},
leaf-chance,
},
}{},
edge path={
\noexpand\path[\forestoption{edge}]
(!u.parent anchor) -- ([xshift=-22.5mm].child anchor)\forestove{optimality} --  (.child anchor)\forestoption{edge label};
},
}
[,decision
[0.8351,chance,my above=Insure]
[,chance,my below=Don't Insure, sub optimal
[0.8394,chance,my above=No outbreak
]
[,chance,my label=Outbreak\\0.060
[0.8334,chance,my above=Bans only
]
[0.6663,chance,my below=Slaughter
]
]
]
]
\end{forest}
}
\end{frame}
\end{document}

• @cfr It will go on. But then the diagram would be badly constructed if you need a label that long for a small path. I'd redesign the diagram. – Alenanno Jun 21 '15 at 23:17
• @cfr Oh that stuck around. I'll remove it. – Alenanno Jun 21 '15 at 23:18
• Actually, I see the text width is in the original code in the question.... – cfr Jun 21 '15 at 23:18
• @cfr Yes, but with it the labels are not properly centered. – Alenanno Jun 21 '15 at 23:19
• (+1) I think it is better without, too. [I'm not sure if I'm the one who introduced them in the first place!] – cfr Jun 21 '15 at 23:24