我用forest
它来绘制决策树,如果一个节点有两个分支,那么一切都会正常显示。但是,一旦一个节点有三个分支,则顶部的两个分支会显示在节点上方。
以下是我所说的一个例子
\usepackage{pgfplots}
\pgfplotsset{width=12cm,compat=1.10}
\usetikzlibrary{patterns}
\usepackage{adjustbox}
\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}
}
\forestset{
declare toks={optimality}{},
declare toks={edge label below}{},
}
\begin{document}
\begin{center}
\begin{frame}
\scalebox{0.85}{
\begin{forest}
my label/.style={
edge label={node[auto, sloped,pos=.75,anchor=south]{#1}}
},
my below/.style={
edge label below={node[midway,below, pos = 0.75, font = \scriptsize,align = center]{#1}}
%edge label={node[auto, sloped,pos=1.75,anchor=south]{#1}}
},
for tree={
grow=0,
child anchor=west,
anchor=west,
text ragged,
inner sep=1mm,
edge={thick, draw=black},
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 [draw, \forestoption{edge}] (!u.parent anchor) |- (.child anchor)\forestoption{edge label below}\forestoption{edge label};
},
}
[, decision, label = left: Getting ice cream,
[,chance,my label=TSweets
[{$5-2=3$}, my label = Rain $\rightarrow$ Rocky Road, my below = 0.10, tier = word]
[5, my label = No rain $\rightarrow$ Rocky Road, my below = 0.90, tier = word]
]
[,chance,my label=Bent Spoon
[, chance, my label = Rain, my below = 0.30
[{$10-2=8$}, my label = Chocolate cardamom, my below = 0.10, tier = word]
[{$7-2=5$}, my label = Blueberry sorbet, my below = 0.25, tier = word]
[{$1-2=-1$}, my label = Other flavors, my below = 0.65, tier = word]
]
[, chance, my label = No Rain, my below = 0.70
[10, my label = Chocolate cardamom, my below = 0.10, tier = word]
[7, my label = Blueberry sorbet, my below = 0.25, tier = word]
[1, my label = Other flavors, my below = 0.65, tier = word]
]
]
]
\end{forest} }
\end{frame}
\end{center}
您可以看到具有两个分支的决策节点和机会节点可以正确显示。具有两个以上分支的节点则无法正确显示。
谢谢!
答案1
欢迎使用 TeX-SE!路径的某些连接位于节点之上的原因是森林对父节点的锚点感到困惑。然而,解决这个问题并不太难。使用calc
森林自动加载的 ,可以找出子节点的 y 值是高于、低于还是与父节点相同,并相应地设置锚点。
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage[edges]{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}
}
\forestset{
declare toks={optimality}{},
declare toks={edge label below}{},
}
\begin{document}
\begin{forest}
my label/.style={
edge label={node[auto, sloped,pos=.75,anchor=south]{#1}}
},
my below/.style={
edge label below={node[midway,below, pos = 0.75, font = \scriptsize,align = center]{#1}}
%edge label={node[auto, sloped,pos=1.75,anchor=south]{#1}}
},
for tree={
grow=0,
child anchor=west,
anchor=west,
text ragged,
inner sep=1mm,
edge={thick, draw=black},
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'={
let \noexpand\p1=($(.child anchor)-(!u)$),\noexpand\n1={sign(\noexpand\y1)} in
\noexpand\ifdim\noexpand\y1>0pt
(!u.north)
\noexpand\else
\noexpand\ifdim\noexpand\y1<0pt
(!u.south)
\noexpand\else
(!u.east)
\noexpand\fi
\noexpand\fi
|- (.child anchor)},
}
[, decision, label = left: Getting ice cream,
[,chance,my label=TSweets
[{$5-2=3$}, my label = Rain $\rightarrow$ Rocky Road, my below = 0.10, tier = word]
[5, my label = No rain $\rightarrow$ Rocky Road, my below = 0.90, tier = word]
]
[,chance,my label=Bent Spoon
[, chance, my label = Rain, my below = 0.30
[{$10-2=8$}, my label = Chocolate cardamom, my below = 0.10, tier = word]
[{$7-2=5$}, my label = Blueberry sorbet, my below = 0.25, tier = word]
[{$1-2=-1$}, my label = Other flavors, my below = 0.65, tier = word]
]
[, chance, my label = No Rain, my below = 0.70
[10, my label = Chocolate cardamom, my below = 0.10, tier = word]
[7, my label = Blueberry sorbet, my below = 0.25, tier = word]
[1, my label = Other flavors, my below = 0.65, tier = word]
]
]
]
\end{forest}
\end{document}
或者
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage[edges]{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}
}
\forestset{
declare toks={optimality}{},
declare toks={edge label below}{},
}
\begin{document}
\begin{forest}
my label/.style={
edge label={node[auto, sloped,pos=.75,anchor=south]{#1}}
},
my below/.style={
edge label below={node[midway,below, pos = 0.75, font = \scriptsize,align = center]{#1}}
%edge label={node[auto, sloped,pos=1.75,anchor=south]{#1}}
},
for tree={
grow=0,
child anchor=west,
anchor=west,
text ragged,
inner sep=1mm,
edge={thick, draw=black},
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 let \noexpand\p1=($(.child anchor)-(!u)$),\noexpand\n1={sign(\noexpand\y1)} in
[draw, \forestoption{edge}]
\noexpand\ifdim\noexpand\y1>0pt
(!u.north)
\noexpand\else
\noexpand\ifdim\noexpand\y1<0pt
(!u.south)
\noexpand\else
(!u.east)
\noexpand\fi
\noexpand\fi
|- (.child anchor)\forestoption{edge label below}\forestoption{edge label};
},
}
[, decision, label = left: Getting ice cream,
[,chance,my label=TSweets
[{$5-2=3$}, my label = Rain $\rightarrow$ Rocky Road, my below = 0.10, tier = word]
[5, my label = No rain $\rightarrow$ Rocky Road, my below = 0.90, tier = word]
]
[,chance,my label=Bent Spoon
[, chance, my label = Rain, my below = 0.30
[{$10-2=8$}, my label = Chocolate cardamom, my below = 0.10, tier = word]
[{$7-2=5$}, my label = Blueberry sorbet, my below = 0.25, tier = word]
[{$1-2=-1$}, my label = Other flavors, my below = 0.65, tier = word]
]
[, chance, my label = No Rain, my below = 0.70
[10, my label = Chocolate cardamom, my below = 0.10, tier = word]
[7, my label = Blueberry sorbet, my below = 0.25, tier = word]
[1, my label = Other flavors, my below = 0.65, tier = word]
]
]
]
\end{forest}
\end{document}