编辑

编辑

我正在使用 LaTeX 中的“forest”包来创建具有多个决策的决策树。除了两件事外,我基本上已经得到了我想要的结果:

  1. 我希望树叶上的圆圈是三角形。
  2. 我希望标签位于线条的中心并且不与矩形或圆形重叠。

一个简单的例子(使用 Beamer):

\documentclass{beamer}

\usepackage{beamerstyle}

\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},
  }

\begin{document}


\begin{frame}[fragile]

\scalebox{0.85}{
 \begin{forest}
   my label/.style={
      edge label={node[auto,sloped,pos=.75,anchor=south]{#1}}
    },
    for tree={
      grow=0,
      child anchor=west,
      parent anchor=east,
      line width=0.2pt,
      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={},
          chance,
        },
      }{},
      edge path={
         \noexpand\path[\forestoption{edge}]
         (!u.parent anchor) -- ([xshift=-1.6cm].child anchor) --    
         (.child anchor)\forestoption{edge label};
  },
    }
    [, decision
      [,decision,my label=Route 1
        [,chance,my label=Fast
           [-900, my label=Accident]
           [100, my label=No Accident]
        ]
        [,chance,my label=Slow
           [-700, my label=Accident]
           [50, my label=No Accident]
        ]
      ]
      [,decision,my label=Route 2
        [,chance,my label=Fast
           [-600, my label=Accident]
           [80, my label=No Accident]
        ]
        [,chance,my label=Slow
           [-500, my label=Accident]
           [70, my label=No Accident]
        ]
      ]
    ]
\end{forest}
}

\end{frame}





\end{document}

在此处输入图片描述

编辑:感谢@AlanMunn 帮助我处理三角形。我把它们翻转过来了。还去掉了斜线,这样标签看起来更好看。我更喜欢斜线,但看起来不太好看。

\documentclass{beamer}

%\usepackage{beamerstyle}

\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}
  }

\begin{document}


\begin{frame}[fragile]

\scalebox{0.85}{
 \begin{forest}
   my label/.style={
      edge label={node[auto, sloped,pos=.75,anchor=south]{#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 [draw, \forestoption{edge}] (!u.parent anchor) |- (.child anchor)\forestoption{edge label};
       % alternatively, with angled lines
        %\noexpand\path[\forestoption{edge}]
        % (!u.parent anchor) -- ([xshift=-2.6cm].child anchor) --    
        % (.child anchor)\forestoption{edge label};
  },
    }
    [, decision
      [,decision,my label=Route 1
        [,chance,my label=Fast
           [-900, my label=Accident]
           [100, my label=No Accident]
        ]
        [,chance,my label=Slow
           [-700, my label=Accident]
           [50, my label=No Accident]
        ]
      ]
      [,decision,my label=Route 2
        [,chance,my label=Fast
           [-600, my label=Accident]
           [80, my label=No Accident]
        ]
        [,chance,my label=Slow
           [-500, my label=Accident]
           [70, my label=No Accident]
        ]
      ]
    ]
\end{forest}
}

\end{frame}
\end{document}

在此处输入图片描述

答案1

这里有一种方法,它保留了线末端的标签,但改变了它们的锚点,右对齐了标记三角形的数字,并对直线方法进行了少许调整:

\documentclass{beamer}
\usepackage{forest}
\usetikzlibrary{shapes}

\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}
  }

\begin{document}

\begin{frame}[fragile]

\scalebox{0.85}{
 \begin{forest}
   my label/.style={
     edge label={node[auto, pos=1, anchor=south east]{#1}}
   },
   for tree={
     grow=0,
     child anchor=west,
     anchor=west,
     text ragged,
     inner sep=1mm,
     edge={ultra thick, draw=blue, rounded corners=2pt},
     l sep+=30mm,
     s sep+=5mm,
     if n children=0{
       before typesetting nodes={
         label/.wrap pgfmath arg={[align=right, text width=25pt]right:#1}{content()},
         content={},
         leaf-chance,
       },
     }{},
     edge path={
       \noexpand\path [draw, \forestoption{edge}] (!u.parent anchor) |- (.child anchor)\forestoption{edge label};
     },
   }
    [, decision
      [,decision,my label=Route 1
        [,chance,my label=Fast
           [-900, my label=Accident]
           [100, my label=No Accident]
        ]
        [,chance,my label=Slow
           [-700, my label=Accident]
           [50, my label=No Accident]
        ]
      ]
      [,decision,my label=Route 2
        [,chance,my label=Fast
           [-600, my label=Accident]
           [80, my label=No Accident]
        ]
        [,chance,my label=Slow
           [-500, my label=Accident]
           [70, my label=No Accident]
        ]
      ]
    ]
\end{forest}
}

\end{frame}
\end{document}

直线

或者,用有角度的线条,也许像这样?

斜线

\documentclass{beamer}
\usepackage{forest}
\usetikzlibrary{shapes}

\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}
  }

\begin{document}

\begin{frame}[fragile]

\scalebox{0.85}{
 \begin{forest}
   my label/.style={
     edge label={node[auto, pos=1, anchor=south east]{#1}}
   },
   for tree={
     grow=0,
     child anchor=west,
     anchor=west,
     text ragged,
     inner sep=1mm,
     edge={thick, draw=blue, rounded corners=2pt},
     s sep+=5mm,
     l sep+=30mm,
     if n children=0{
       before typesetting nodes={
         label/.wrap pgfmath arg={[align=right, text width=25pt]right:#1}{content()},
         content={},
         leaf-chance,
       },
     }{
     },
     edge path={
       \noexpand\path[\forestoption{edge}]
       (!u.parent anchor) -- ([xshift=-22.5mm].child anchor) --  (.child anchor)\forestoption{edge label};
     }
   }
    [, decision
      [,decision,my label=Route 1
        [,chance,my label=Fast
           [-900, my label=Accident]
           [100, my label=No Accident]
        ]
        [,chance,my label=Slow
           [-700, my label=Accident]
           [50, my label=No Accident]
        ]
      ]
      [,decision,my label=Route 2
        [,chance,my label=Fast
           [-600, my label=Accident]
           [80, my label=No Accident]
        ]
        [,chance,my label=Slow
           [-500, my label=Accident]
           [70, my label=No Accident]
        ]
      ]
    ]
\end{forest}
}

\end{frame}
\end{document}

编辑

如果您不喜欢输入,以下代码可以更自动地生成上面的第二棵树:

 \begin{forest}
   my label/.style={
     edge label={node[auto, pos=1, anchor=south east]{#1}}
   },
   for tree={
     grow=0,
     child anchor=west,
     anchor=west,
     text ragged,
     inner sep=1mm,
     edge={thick, draw=blue, rounded corners=2pt},
     s sep+=5mm,
     l sep+=30mm,
     if n children=0{
       if n=1{my label=Accident}{my label=No Accident},
       before typesetting nodes={
         label/.wrap pgfmath arg={[align=right, text width=25pt]right:#1}{content()},
         content={},
         leaf-chance,
       },
     }{
       if level=2{
         chance,
         if n=1{my label=Fast}{my label=Slow}
       }{decision}
     },
     edge path={
       \noexpand\path[\forestoption{edge}]
       (!u.parent anchor) -- ([xshift=-22.5mm].child anchor) --  (.child anchor)\forestoption{edge label};
     }
   }
    [
      [,my label=Route 1
        [
           [-900]
           [100]
        ]
        [
           [-700]
           [50]
        ]
      ]
      [,my label=Route 2
        [
           [-600]
           [80]
        ]
        [
           [-500]
           [70]
        ]
      ]
    ]
\end{forest}

答案2

我认为,对于您的边缘标签,没有最佳解决方案。最简单的解决方案是使用参数将它们稍微向左移动pos=。在这里,我将其设置为.4适应“无事故”标签的长度。要制作三角形,您可以使用形状添加另一种样式isosceles triangle

\documentclass{beamer}

%\usepackage{beamerstyle} % not standard style

\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, fill=black!30!white, thick, inner sep=0pt}
  }

\begin{document}

\begin{frame}[fragile]

\scalebox{0.85}{
 \begin{forest}
   my label/.style={
      edge label={node[sloped,pos=.4,anchor=south]{#1}}
    },
    for tree={
      grow=0,
      child anchor=west,
      parent anchor=east,
      line width=0.2pt,
      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=-1.6cm].child anchor) --    
         (.child anchor)\forestoption{edge label};
  },
    }
    [, decision
      [,decision,my label=Route 1
        [,chance,my label=Fast
           [-900, my label=Accident]
           [100, my label=No Accident]
        ]
        [,chance,my label=Slow
           [-700, my label=Accident]
           [50, my label=No Accident]
        ]
      ]
      [,decision,my label=Route 2
        [,chance,my label=Fast
           [-600, my label=Accident]
           [80, my label=No Accident]
        ]
        [,chance,my label=Slow
           [-500, my label=Accident]
           [70, my label=No Accident]
        ]
      ]
    ]
\end{forest}
}

\end{frame}

\end{document}

代码输出

相关内容