编辑

编辑

我想在用 构建的树中添加额外信息forest。我可以制作以下树,但符号未垂直对齐...我的箭头也有类似的问题。

在此处输入图片描述

这是我使用的丑陋代码,问题来自于我只是在树叶中添加符号......

\documentclass{article}
\usepackage[utf8x]{inputenc}
\usepackage{ucs}
\usepackage{wasysym}
\usepackage{amssymb}
\usepackage{forest}
\useforestlibrary{linguistics}

\begin{document}
\pagestyle{empty}

\begin{forest}
    for tree = {
        sn edges,
        grow'=0,
        l=2.5cm,
        s sep=0.2cm,
        anchor=west,
        child anchor=west}
    [
        [O
            [R
                [T $\longrightarrow$ ORT \quad $\newmoon$]
            ]
            [T
                [R $\longrightarrow$ OTR \quad $\newmoon$]
            ]
        ]
        [R
            [O
                [T $\longrightarrow$ ROT \quad $\blacksquare$ \quad $\blacktriangle$]
            ]
            [T
                [O $\longrightarrow$ RTO \quad $\blacktriangle$]
            ]
        ]
        [T
            [O
                [R $\longrightarrow$ TOR]
            ]
            [R
                [O $\longrightarrow$ TRO]
            ]
        ]
    ]
\end{forest}

\end{document}

如何添加装饰物使它们垂直对齐?

答案1

我也会将箭头集成到树中,但由于所有且只有终点节点才有箭头,因此我会以编程方式添加它们。

最初,我建议使用 Forest 选项添加符号。为了方便起见,我为此label使用了一种样式,该样式还将其值包装在其中,以避免在每种情况下重复它们。symb$ ... $

但是,这会导致错位,因为最终级别的节点宽度不相等。如果节点大小非常相似且可预测,则可以将text width=<some dimension>这些节点与 一起设置edge=->。但是,更优雅的解决方案是将符号本身添加到单独的节点中。

如果我们创建一个新的 Forest 选项symb,那么我们可以在解析树之后但在排版节点之前将其添加到节点中。我已经使用过,anchor=parent但如果愿意,您显然可以使用其他选项。这样做的好处部分在于自定义 Forest 选项是一个巧妙的技巧,但主要是它比 更灵活label,并且与labels 不同,Forest 将以通常的方式跟踪这些节点及其所需的空间。

\documentclass[border=10pt,multi,tikz,dvipsnames]{standalone}
\usepackage{wasysym,amssymb}
\usepackage{forest}
\useforestlibrary{linguistics}
\forestset{%
  declare toks={symb}{},
  symb tree/.style={%
    for tree = {%
      sn edges,
      grow'=0,
      l=2.5cm,
      s sep=0.2cm,
      anchor=parent,
      if n children=0{%
        edge=->,
      }{},
    },
    before typesetting nodes={%
      where n children=0{%
        append/.wrap pgfmath arg={[$##1$, no edge, grow'=0, anchor=parent, l=0em]}{symb()},
      }{},
    },
  },
}
\begin{document}
\begin{forest}
  symb tree,
  [
    [O
      [R
        [T [ORT, symb=\newmoon]
        ]
      ]
      [T
        [R [OTR, symb=\newmoon]
        ]
      ]
    ]
    [R
      [O
        [T [ROT, symb=\blacksquare \quad \blacktriangle]
        ]
      ]
      [T
        [O [RTO, symb=\blacktriangle]
        ]
      ]
    ]
    [T
      [O
        [R [TOR]
        ]
      ]
      [R
        [O [TRO]
        ]
      ]
    ]
  ]
\end{forest}
\end{document}

带符号注释的树

编辑

另一个问题,您询问了关于环绕节点组的问题。我认为演示一些扩展上述示例以执行此操作的选项可能会有所帮助。

下面的代码使用该库为节点组添加阴影并将其圈出backgrounds

修改内容\forestset{}如下。

我们首先添加几个其他自定义选项。一个是布尔值(开或关 - 默认为关)。我们使用它来跟踪符号的位置。另一个跟踪环绕节点的颜色,默认为红色。

  declare boolean={symb here}{0},
  declare toks={circle colour}{red},

然后我们稍微修改symb tree一下样式。我们修改代码,为包含符号的节点before typesetting nodes添加一个标记。symb here

          append/.wrap pgfmath arg={[$##1$, no edge, grow'=0, anchor=parent, l=0em, symb here]}{symb()},

我们还定义了一个自定义的 nodewalk 步骤,用于挑选带有symb here标记的节点。如果我们愿意的话,这将让我们能够圈出所有且仅圈出符号节点。

  define long step={symb tree symbs}{}{fake=root, filter={tree}{symb_here} },

现在来定义一个样式来圈出符号。它需要一个可选的颜色参数。

  circle symbols/.style={%
    before drawing tree={%
      !r.tikz+={%
        \scoped[on background layer]{\node [circle me, #1, fit to=symb tree symbs] {};}
      },
    },
  },

这是一个围绕当前节点子树的节点,同样带有一个可选的颜色参数。

  circle subtree/.style={%
    before drawing tree={%
      tikz+={%
        \scoped[on background layer]{\node [circle me, #1, fit to=tree] {};}
      },
    },
  },

现在我们想要一个通用的circle fit to样式来包围其他东西。这个需求参数:要圈出的内容。因此,这里不能将颜色设置为参数。但是,circle colour=<colour>如果我们不想要默认颜色,我们仍然可以使用 更改颜色。

  circle fit to/.style={%
    before drawing tree={%
      tikz+={%
        \scoped[on background layer]{\node [circle me, fit to={#1}] {};}
      },
    },
  },

这是一个 Ti圆形节点的 Z 样式。它使用 来circle colour绘制和填充,但填充只有 10% 不透明。

  /tikz/circle me/.style={%
    draw=\forestoption{circle colour}, fill=\forestoption{circle colour}, inner sep=0pt, rounded corners, thick, fill opacity=.10, draw opacity=1,
  },

现在,我们可以使用这些样式和选项从上方装饰我们的树。

\begin{forest}
  symb tree,

我们想用 圈出所有符号blue

  circle symbols=blue,
  [

我们希望O的后代都能被纳入其中magenta

    [O, circle fit to=descendants, circle colour=magenta
      [R
        [T [ORT, symb=\newmoon]
        ]
      ]
      [T
        [R [OTR, symb=\newmoon]
        ]
      ]
    ]

R我们希望子树中低于三级的所有节点都R用默认颜色圈出来。

    [R, circle fit to={relative level=3}
      [O

T我们希望T在 中突出显示 的祖父母和祖父母的第二个孩子blue!50!cyan。显然,这也会捕获 的T父母和第二个孩子的孩子,仅仅是因为矩形节点的形状。

        [T, circle fit to={c,uu,2}, circle colour=blue!50!cyan [ROT, symb=\blacksquare \quad \blacktriangle]
        ]
      ]
      [T
        [O [RTO, symb=\blacktriangle]
        ]
      ]
    ]

T的子树应该在中突出显示green!75!black

    [T, circle subtree=green!75!black,
      [O
        [R [TOR]
        ]
      ]
      [R
        [O [TRO]
        ]
      ]
    ]
  ]
\end{forest}

我们的树看起来如下。

装饰树

完整代码:

\documentclass[border=10pt,multi,tikz,dvipsnames]{standalone}
\usepackage{wasysym,amssymb}
\usepackage{forest}
\useforestlibrary{linguistics}
\usetikzlibrary{backgrounds}
\makeatletter
\forestset{%
  declare toks={symb}{},
  declare boolean={symb here}{0},
  declare toks={circle colour}{red},
  symb tree/.style={%
    for tree = {%
      sn edges,
      grow'=0,
      l=2.5cm,
      s sep=0.2cm,
      anchor=parent,
      if n children=0{%
        edge=->,
      }{},
    },
    before typesetting nodes={%
      where n children=0{%
        if symb={}{}{%
          append/.wrap pgfmath arg={[$##1$, no edge, grow'=0, anchor=parent, l=0em, symb here]}{symb()},
        },
      }{},
    },
  },
  define long step={symb tree symbs}{}{fake=root, filter={tree}{symb_here} },
  circle symbols/.style={%
    before drawing tree={%
      !r.tikz+={%
        \scoped[on background layer]{\node [circle me, #1, fit to=symb tree symbs] {};}
      },
    },
  },
  circle subtree/.style={%
    before drawing tree={%
      tikz+={%
        \scoped[on background layer]{\node [circle me, #1, fit to=tree] {};}
      },
    },
  },
  circle fit to/.style={%
    before drawing tree={%
      tikz+={%
        \scoped[on background layer]{\node [circle me, fit to={#1}] {};}
      },
    },
  },
  /tikz/circle me/.style={%
    draw=\forestoption{circle colour}, fill=\forestoption{circle colour}, inner sep=0pt, rounded corners, thick, fill opacity=.10, draw opacity=1,
  },
}
\makeatother
\begin{document}
\begin{forest}
  symb tree,
  circle symbols=blue,
  [
    [O, circle fit to=descendants, circle colour=magenta
      [R
        [T [ORT, symb=\newmoon]
        ]
      ]
      [T
        [R [OTR, symb=\newmoon]
        ]
      ]
    ]
    [R, circle fit to={relative level=3}
      [O
        [T, circle fit to={c,uu,2}, circle colour=blue!50!cyan [ROT, symb=\blacksquare \quad \blacktriangle]
        ]
      ]
      [T
        [O [RTO, symb=\blacktriangle]
        ]
      ]
    ]
    [T, circle subtree=green!75!black,
      [O
        [R [TOR]
        ]
      ]
      [R
        [O [TRO]
        ]
      ]
    ]
  ]
\end{forest}
\end{document}

答案2

这是由 forest 包绘制箭头的变体。使用 tikz 直接添加附加符号,以在距离内绘制额外的节点1cm(或可选参数指定的任何值)。

在此处输入图片描述

\documentclass{article}
\usepackage{wasysym,amssymb}
\usepackage{forest}
\useforestlibrary{linguistics}
\begin{document}

\newcommand\symb[2][1cm]{\draw () ++(#1,0) node{#2};}
\begin{forest}
    for tree = {sn edges, grow'=0, l=2.5cm, s sep=0.2cm, anchor=west, child anchor=west}
    [ [O [R [T [ORT,edge=->] {\symb{$\newmoon$}}]]
         [T [R [OTR,edge=->] {\symb{$\newmoon$}}]]
      ]
      [R [O [T [ROT,edge=->] {\symb{$\blacksquare$}\symb[2cm]{$\blacktriangle$}}]]
         [T [O [RTO,edge=->] {\symb{$\blacktriangle$}}]]
      ]
      [T [O [R [TOR,edge=->]]]
         [R [O [TRO,edge=->]]]
      ]
    ]
\end{forest}

\end{document}

相关内容