tikz 不守规矩的树

tikz 不守规矩的树

请原谅我提出的问题过于具体,可能对其他人没有帮助。我需要绘制一种决策树。我正在努力控制。

我从点 (graphviz) 树开始。经过大量修改后,我几乎将其调整到了我想要的位置...

graphviz 点中的不守规矩的树

除了 graphviz 中的一个错误弄乱了进入级联框的最右侧箭头的位置:C3R4 应该在 C3R3 和 C3R5 之间,而不是在 C3R1 上方。(C2R1 也应该在更高的位置。)[请忽略框颜色。] graphviz 非常接近,但没有成功。

在尝试通过将其转换为 tikz 之后dot2tex,我放弃了,并决定改用 tikz 进行原生转换。

像往常一样,我尝试在网上找到一个类似的例子并对其进行修改。我最好的结果是

\documentclass[border=30pt]{standalone}

\usepackage{charter}
\usepackage{tikz}
\usetikzlibrary{arrows}

\tikzset{
  treenode/.style = {shape=rectangle, rounded corners, draw, align=center,
                     top color=white, bottom color=blue!20},
  root/.style     = {treenode, font=\Large, bottom color=red!30},
  fancy/.style    = {circle,draw},
  prect/.style    = {rectangle,draw},
  dot/.style      = {draw},
}


\begin{document}

\begin{tikzpicture}
  [
    grow                    = right,
    sibling distance        = 10em,
    level distance          = 10em,
    edge from parent/.style = {draw, -latex},
    % every node/.style       = {font=\footnotesize},
    sloped  %% for the labels, according to angle of link
  ]

  \node [root] {START}
  child {
    node [fancy] {R11}
    edge from parent node [below] {$\ell1$}
  }
    % 
  child {
    node [fancy] {A11}
    child {
      node [prect] {coin}
      child {
        node [fancy] {R33}
        child { node {A4L5} } % edge from parent node [above] {$h2XA5$}
        child { node {A4L6} } % edge from parent node [above] {$h2XA6$}
        edge from parent node [below] {1/2}
      }
      child {
        node [fancy] {A32}
        child {
          node {A4X1} } % edge from parent node [above] {$h35$}
        child {
          node {A4X2} }  % edge from parent node [above] {$h36$}
        edge from parent node [above] {1/2}
      }
      edge from parent node [below] {$\ell2$}
    }
%
    child {
      node [dot] {}
      child {
        node [fancy] {A31}
        child { node {A41}  }
        child { node {A42} }
      }
      edge from parent node [above] {h2}
    }
    edge from parent node [above] {$h1$}
  };
\end{tikzpicture}

\end{document}

这让我

tikz 中不守规矩的树尝试

现在连一支烟都没有

  1. 我需要 C1R1 和 C2R1 之间的小矩形消失(并且 C2R1 需要保持在 C2R2 上方);
  2. 我需要 C2R1 位于更高的位置(并且仍然链接到 C3R1 和 C3R2);
  3. 我需要C2R2继续链接到附近的C3R3和C3R4;
  4. 我显然不希望 C3R6 和 C3R4 共享一个插槽。
  5. 我甚至还没有尝试在 C3R1 到 C3R4 周围绘制带有文本的虚线框。

我尝试了sibling angle=xx一些子节点,但似乎被忽略了。(级别距离起作用了。)我还没有进行视觉微调,兄弟角度和级别距离可以提供帮助。

滋扰:如何用(更大的)椭圆形替换圆形?

非常感谢您的建议...

答案1

我的方法是使用tikz

tikz 树 v02

\documentclass[border=5pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{calc,fit,shapes,backgrounds}
\usepackage{makecell}

\tikzset{%
    every node/.style={font=\small},
}
\tikzstyle{arrowline}=[-latex, shorten >=2pt, shorten <=2pt]
\tikzstyle{elor}=[ellipse, minimum width=20pt, minimum height=10pt, fill=orange!50!red!50!white]
\tikzstyle{elwh}=[draw, fill=white, ellipse, minimum width=20pt, minimum height=10pt]
\tikzstyle{elcy}=[ellipse, minimum width=20pt, minimum height=10pt, fill=cyan!25!white]
\tikzstyle{cicy}=[fill=cyan!25!white, circle, inner sep=5pt]

\begin{document}
    \begin{tikzpicture}
        
        %nodes
        
        \node (a1) [cicy] at (0,0) {};
        \node (b1) [elwh, anchor=west] at ($ (a1.east) + (2,1) $) {C1R1};
        \node (b2) [elwh, anchor=west] at ($ (a1.east) + (2,-1) $) {C1R2};
        \node (c1) [draw, minimum width=40pt, anchor=west] at ($ (b1.east)!0.5!(b2.east) + (2,0) $) {\makecell[c]{coin \\ flip}};
        \node (d2) [elwh, anchor=west] at ($ (c1.east) + (2,0) $) {C2R2};
        \node (d1) [elwh] at ($ (d2) + (0,3) $) {C2R1};
        \node (d3) [elcy] at ($ (d2) + (0,-3) $) {C2R3};
        \node (e1) [elor] at ($ (d1.east) + (2,2) $)  {C3R1};
        \node (e2) [elor] at ($ (e1) + (0,-2) $)  {C3R2};
        \node (e3) [elor] at ($ (e2) + (0,-2) $) {C3R3};
        \node (e4) [elor] at ($ (e3) + (0,-2) $)  {C3R4};
        \node (e5) [elwh] at ($ (e4) + (0,-2) $) {C3R5};
        \node (e6) [elwh] at($ (e5) + (0,-2) $) {C3R6};
        
        % arrows
        
        \draw[arrowline] (a1) edge node [pos=0.5, above] {h1} (b1);
        \draw[arrowline] (a1) edge node [pos=0.5, below] {l1} (b2);
        \draw[arrowline] (b1) edge node [pos=0.5, above] {l2} (c1);
        \draw[arrowline] (b1) edge node [pos=0.5, above] {h2} (d1);
        \draw[arrowline] (c1) edge node [pos=0.5, above] {1/2} (d2);
        \draw[arrowline] (c1) edge node [pos=0.5, above] {1/2} (d3);
        \draw[arrowline] (d1) edge node [pos=0.5, above] {h3} (e1);
        \draw[arrowline] (d1) edge node [pos=0.5, above] {l3} (e2);
        \draw[arrowline] (d2) edge node [pos=0.5, above] {h4} (e3); 
        \draw[arrowline] (d2) edge node [pos=0.5, above] {h4} (e4);
        \draw[arrowline] (d3) edge node [pos=0.5, above] {h5} (e5);
        \draw[arrowline] (d3) edge node [pos=0.5, above] {l5} (e6);
        
        \begin{pgfonlayer}{background}
            \node[fit=(e1)(e4), densely dashed, draw=blue, inner sep=5pt, label=above:cascade, rounded corners=5pt] {};
        \end{pgfonlayer}
    
    \end{tikzpicture}
\end{document}

答案2

当某物是一棵树时,使用forest。:) 椭圆形样式来自 Excelsior 的答案。边缘标签代码来自这里

仔细阅读您的问题,似乎您在 GraphViz 中生成的树实际上并不是您想要的样子。如果是这样,这里有一个更常规的树版本,没有交叉分支和错位的 C3R4 节点。

\documentclass{article}
\usepackage{forest}
\forestset{start/.style={draw, shape=rectangle, rounded corners, align=center,
                     top color=white, bottom color=blue!20, content=START},
           ell/.style={ellipse, minimum width=20pt, minimum height=10pt,draw,},
           orangefill/.style={fill=orange!50!red!50!white},
           bluefill/.style={fill=cyan!30!white},
           % edge label code from https://tex.stackexchange.com/a/425271/2693
           my edge label/.style={
    if={
      > O_= {n'}{1}
    }{
      edge label={node [midway, above] {$#1$} }
    }{
      edge label={node [midway, below,] {$#1$} }
    },
  },
  my tree/.style={where n children=0{tier=leaf}{},
    for tree={s sep=.5in,l=1in,grow=east, edge={->,thick}},
    before typesetting nodes={
      for tree={
        split option={content}{:}{content, my edge label},
      },
    }}}
\begin{document}
\begin{forest}my tree
      [,start [C1R2:l1,ell,tier=two,]
        [C1R1:h1,ell,
            [{coin flip}:l2,draw 
                [C2R3:1/2,ell,bluefill,tier=three
                     [C3R6:l5,ell] 
                     [C3R5:h5,ell]] 
                [C2R2:1/2,ell,name=C2R2,tier=three
                    [C3R4:l4,ell,orangefill,name=C3R4]
                    [C3R3:h4,ell,orangefill ]]] 
             [C2R1:h2,ell,tier=three
                [C3R2:l3,ell,orangefill]
                [C3R1:h3,ell,orangefill,name=C3R1]
            ]]]
\node[draw=blue,very thick,dashed,rounded corners, fit=(C3R1) (C3R4),label=above:cascade] {};
\end{forest}
\end{document}

代码输出

替代版本

如果你(或其他人)想了解如何重现 GraphViz 图片,这里也有该代码:

\documentclass{article}
\usepackage{forest}
\forestset{start/.style={draw, shape=rectangle, rounded corners, align=center,
                     top color=white, bottom color=blue!20, content=START},
           ell/.style={ellipse, minimum width=20pt, minimum height=10pt,draw,},
           orangefill/.style={fill=orange!50!red!50!white},
           bluefill/.style={fill=cyan!30!white},
           % edge label code from https://tex.stackexchange.com/a/425271/2693
           my edge label/.style={
    if={
      > O_= {n'}{1}
    }{
      edge label={node [midway, above] {$#1$} }
    }{
      edge label={node [midway, below,] {$#1$} }
    },
  },
  my tree/.style={where n children=0{tier=leaf}{},
    for tree={s sep=.5in,l=1in,grow=east, edge={->,thick}},
    before typesetting nodes={
      for tree={
        split option={content}{:}{content, my edge label},
      },
    }}}
\begin{document}
\begin{forest}my tree
      [,start 
        [C1R2:l1,ell,tier=two,]
        [C1R1:h1,ell,
            [{coin flip}:l2,draw 
                [C2R3:1/2,ell,bluefill,tier=three
                     [C3R6:l5,ell] 
                     [C3R5:h5,ell]] 
                [C2R2:1/2,ell,name=C2R2,tier=three
                    [C3R3:h4,ell,orangefill,name=C3R3 ]]]
             [C2R1:h2,ell,tier=three
                [C3R2:l3,ell,orangefill]
                [C3R1:h3,ell,orangefill]
                [C3R4,ell,orangefill,no edge,name=C3R4]
            ]]]
\draw[->,thick] (C2R2.north) [in=180,out=60,] to node [near start,left] {$l4$} (C3R4.west);
\node[draw=blue,very thick,dashed,rounded corners, fit=(C3R3) (C3R4),label=above:cascade] {};
\end{forest}
\end{document}

代码输出

相关内容