具有边标签和选项的 tikz 树的清晰易读的语法样式

具有边标签和选项的 tikz 树的清晰易读的语法样式

我对 tikz 和 TeX 还不太熟悉,但编写树的代码没有问题。我只是想要一个人类可读的树。以下是没有边标签或选项的树的最小示例:

\begin{tikzpicture}

\tikzstyle{every node}=[draw,shape=circle,fill=black,inner sep=0pt,minimum size=2mm]
\tikzstyle{level 1}=[sibling distance =35mm,level distance=20mm]
\tikzstyle{level 2}=[sibling distance = 18mm,level distance=15mm]
\tikzstyle{level 3}=[sibling distance = 12mm,level distance=10mm]
\tikzstyle{level 4}=[sibling distance = 7mm]

\node {}
  [grow=right]
  child { node {} 
    child { node {} } 
    child { node {} 
      child { node {} }
      child { node {} 
        child { node {} }
        child { node {} } } } }
  child { node {} 
    child { node {} }
    child { node {} } };

\end{tikzpicture}

这是同一棵树,只是带有附加选项和边标签:

\begin{tikzpicture}

\tikzstyle{every node}=[draw,shape=circle,fill=black,inner sep=0pt,minimum size=2mm]
\tikzstyle{level 1}=[sibling distance =28mm,level distance=15mm]
\tikzstyle{level 2}=[sibling distance = 18mm,level distance=15mm]
\tikzstyle{level 3}=[sibling distance = 12mm,level distance=15mm]
\tikzstyle{level 4}=[sibling distance = 7mm,level distance=15mm]

\node {}
  [grow=right]
  child { node {} 
    child { node {} 
      child[level distance=30mm] { node {} edge from parent node [below=1mm,fill=none,draw=none] { $1-w_i$ } }
      child { node {} 
        child { node {} edge from parent node [below=0.02mm,fill=none,draw=none] { $1-g_i$ } }
        child { node {} edge from parent node [above=1mm,fill=none,draw=none] { $g_i$ } } 
      edge from parent node [above=1mm,fill=none,draw=none] { $w_i$ } }
    edge from parent node [below=1mm,fill=none,draw=none] { $1-a$ } }
    child[level distance=45mm] { node {} edge from parent node [above=1mm,fill=none,draw=none] { $a$ } } 
  edge from parent node [below=1mm,fill=none,draw=none] { $1-c$ } }
  child { node {} 
    child[level distance=45mm] { node {} edge from parent node     [below=1mm,fill=none,draw=none] { $1-a$ } }
    child[level distance=45mm] { node {} edge from parent node [above=1mm,fill=none,draw=none] { $a$ } } 
  edge from parent node [above=1mm,fill=none,draw=none] { $c$ } };

\end{tikzpicture}

在我看来,这棵树现在几乎无法阅读。特别是由于 tikz 的语法要求我在子节点的末尾插入边标签。我很可能会把这棵树交给别人进一步使用和改编,但我担心这棵树在这种状态下会毫无用处。发现错误或更改某些内容似乎非常非常危险且容易出错。事实上,犯错后,对我来说,开始一棵新树通常比调试现有树更容易。但是,对于更大的树,我无法做到这一点。

所以,我的问题是:您能否建议使用宏、样式定义或其他任何东西来简化这棵树并使其再次可读?

注意:由于压力很大,我无法使用其他软件包,因为我想在本周内完成这个项目。因此,现在学习新语法效率不高。但是,请随意为可能偶然发现这篇文章的其他用户提供建议。

编辑:如果有人知道如何编写语法以使其变得不那么模糊,我也会很高兴。

答案1

使用 tikz 键,你可以用更简洁的方式表达同一棵树

\begin{tikzpicture}[
    tree node/.style={
        draw,
        shape=circle,
        fill=black,
        inner sep=0pt,
        minimum size=2mm},
    every child node/.style={tree node},
    root/.style={tree node},
    level/.style={sibling distance=30mm/#1,level distance=15mm},
    % Skip a level in the tree
    skip level/.default={1},
    skip level/.style={
        level distance=\tikzleveldistance*#1+\tikzleveldistance},
    skip level spaced/.default={1},
    skip level spaced/.style={
        skip level=#1,
        sibling distance=\tikzsiblingdistance*#1+\tikzsiblingdistance},
    % Probability on edge:
    prob/.style={
        insert path={edge from parent node[prob label] {$#1$}}},
    prob label/.style={outer sep=.5mm},
]
    \node[root] {}
      [grow=right]
      child { node {} 
        child { node {} 
          child[skip level spaced] {
              node {} [below, prob=1-w_i]}
          child { node {} 
            child { node {} [below, prob=1-g_i] }
            child { node {} [above, prob=g_i] } 
          [above, prob=w_i ] }
        [below, prob=1-a] }
        child[skip level=2,yshift=3mm] {
            node {} [above, prob=a] } 
      [below left, prob=1-c] }
      child { node {} 
        child[skip level=2] { node {} [below, prob=1-a] }
        child[skip level=2] { node {} [above, prob=a] } 
      [above,prob=c] };
\end{tikzpicture}

唯一遗憾的是,边缘标签必须设置在子节点的末尾,在存在子树的情况下,将其与它引用的子指令分开。然而,缩进可以帮助匹配它们。

该解决方案提供:

  1. 清理样式
  2. 一些新的键使树表达式更加“语义化”并且噪音更少

清理

我更喜欢遵循 ​​tikz 手册并tikzpicture使用pgfkeys' 语法在可选参数中设置样式。every child node样式允许您避免draw=none,fill=none在边缘标签节点中进行设置。

样式root只是一个同义词,使代码可读(您需要tree node手动在根上安装样式,因为它不是子节点)。

我没有手动设置每个级别的距离,而是将公共部分分解出来level distance并计算sibling distance当前级别的 wrt(存储在中#1)。

和风格probskip level

prob我假设边缘标签代表概率,并定义了设置它们的样式。我无法使用label它,因为它已经用于不同的目的,但您可以根据标签的实际含义随意重命名它。

prob样式注入边缘操作,创建一个以数学内容作为参数传递的节点。

skip level=N样式将当前子节点N级别在树中下移。您可以使用移位(或其他样式)进一步操纵节点的高度。

相关内容