为(水平)tikz 树创建级别标签

为(水平)tikz 树创建级别标签

我想创建标签和对应的线,穿过 (水平) tikz-qtree 的分支层。这是想法。

在此处输入图片描述

我尝试了很长时间并在网上搜索,但没有找到任何进一步的进展......

以下代码生成原始的 tikz 树。

\begin{figure}[bh!]
\centering
\begin{tikzpicture}[ level distance=1cm, growth parent anchor=east, grow=right,scale=0.78, 
level distance=1cm,
]

\tikzstyle{every node}=[font=\footnotesize, text width=5mm,anchor=east]

\Tree[.{0} [.{1} [.{1} [.{1} [.{1} [.{2} [.{7} [.{9} [.{4} [.{33} ] [.{474} ] ] [.{478} ] ] [.{487} ] ] [.{494} ] ] [.{496} ] ] [.{497} ] ] [.{498} ] ] [.{499} ] ] [.{4} [.{13} [.{4} [.{4} [.{7} [.{25} [.{9} [.{120} [.{314} ] [.{314} ] ] [.{434} ] ] [.{443} ] ] [.{468} ] ] [.{475} ] ] [.{479} ] ] [.{483} ] ] [.{496} ] ] [.{1} [.{2} [.{18} [.{39} [.{2} [.{55} [.{56} [.{327} ] [.{327} ] ] [.{383} ] ] [.{438} ] ] [.{440} ] ] [.{479} ] ] [.{497} ] ] [.{499} ] ] [.{3} [.{10} [.{2} [.{3} [.{6} [.{8} [.{7} [.{16} [.{32} ] [.{445} ] ] [.{461} ] ] [.{468} ] ] [.{476} ] ] [.{482} ] ] [.{485} ] ] [.{487} ] ] [.{497} ] ] [.{6} [.{9} [.{7} [.{1} [.{3} [.{3} [.{9} [.{14} [.{24} ] [.{448} ] ] [.{462} ] ] [.{471} ] ] [.{474} ] ] [.{477} ] ] [.{478} ] ] [.{485} ] ] [.{494} ] ] [.{444} [.{56} ] [.{56} ] ] ]

\end{tikzpicture}
\end{figure}

答案1

这是一个可以重现您想要的图形的解决方案。该解决方案涉及手动“标记”一些节点以给它们命名,以便您稍后在注释树时可以引用它们,因此这是一个非常针对原始问题的解决方案。我不知道您是否想要一个更通用的解决方案。

我的解决方案如下。我手动查找最后一级的节点(我选择值为 448 的节点)并为其命名:\node(levelz){448};。我对上一级的节点执行相同操作:\node(levelz-1){462}。我还为根节点命名:\node(Root){0}

这些名称可以以不同的方式使用。我可以直接在任何 TikZ 绘图命令中使用它们,例如:\fill[red] (Root) circle(2pt);这会在根节点上放置一个红点。但它也可以用作\subtreeof命令的参数,在这种情况下,选定的节点不再是Root,而是整个树。这使我能够获得整个树的边界框的坐标。例如\subtreeof{Root}.north会给我顶部的坐标。

通过使用运算符将​​这些坐标组合起来-|,我可以得到绘制所需线条的坐标,如下面的代码所示:

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-qtree}

\begin{document}
\begin{tikzpicture}[ level distance=1cm, growth parent anchor=east, grow=right,scale=0.78,
level distance=1cm,
]

\tikzstyle{every node}=[font=\footnotesize, text width=5mm,anchor=east]

\Tree [.\node(Root){0}; [.{1} [.{1} [.{1} [.{1} [.{2} [.{7} [.{9} [.{4} [.{33} ] [.{474} ] ] [.{478} ] ] [.{487} ] ] [.{494} ] ] [.{496} ] ] [.{497} ] ] [.{498} ] ] [.{499} ] ] [.{4} [.{13} [.{4} [.{4} [.{7} [.{25} [.{9} [.{120} [.{314} ] [.{314} ] ] [.{434} ] ] [.{443} ] ] [.{468} ] ] [.{475} ] ] [.{479} ] ] [.{483} ] ] [.{496} ] ] [.{1} [.{2} [.{18} [.{39} [.{2} [.{55} [.{56} [.{327} ] [.{327} ] ] [.{383} ] ] [.{438} ] ] [.{440} ] ] [.{479} ] ] [.{497} ] ] [.{499} ] ] [.{3} [.{10} [.{2} [.{3} [.{6} [.{8} [.{7} [.{16} [.{32} ] [.{445} ] ] [.{461} ] ] [.{468} ] ] [.{476} ] ] [.{482} ] ] [.{485} ] ] [.{487} ] ] [.{497} ] ] [.{6} [.{9} [.{7} [.{1} [.{3} [.{3} [.{9} [.{14} [.{24} ] [.\node(levelz){448}; ] ] [.\node(levelz-1){462}; ] ] [.{471} ] ] [.{474} ] ] [.{477} ] ] [.{478} ] ] [.{485} ] ] [.{494} ] ] [.{444} [.{56} ] [.{56} ] ] ]

\draw[blue, dashed] (\subtreeof{Root}.south -| levelz.west) -- (\subtreeof{Root}.north -| levelz.west)
  node[right, text width=] {Level $z$};
\draw[blue, dashed] (\subtreeof{Root}.south -| levelz-1.west) -- (\subtreeof{Root}.north -| levelz-1.west)
  node[left, text width=] {Level $z-1$};
\end{tikzpicture}
\end{document}

其结果为:

输出树

更新

正如您在上一个示例中看到的,垂直虚线穿过边的末端。再次阅读您的问题,您说您希望它们“穿过分支”级别。这允许三种解释。第一种是我上面所做的。第二种是考虑边的左端(分叉发生的点)。第三种是考虑边的中点。

所有这些选项都很容易用相同的技术实现。对于第二个选项,您可以将级别为的节点命名z-1为例如branchz,将级别为的节点z-2命名为branchz-1。使用east这些节点的锚点,您可以获得分叉发生的坐标。

对于第三个选项,您需要结合前两个选项并计算这些坐标的中点。

以下代码实现了所有选项,并用不同的颜色绘制线条(还用大点标记所选坐标)。我使用了两个嵌套循环。外层循环用于我们想要在树中标记的每个级别(假设中存在名称为levelzlevelz-1branchz等的适当节点)。内层循环用于为每个级别绘制三个选项。branchz-1Tree

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-qtree}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}[ level distance=1cm, growth parent anchor=east, 
                     grow=right,scale=0.78, level distance=1cm,
]

\tikzstyle{every node}=[font=\footnotesize, text width=5mm,anchor=east]

\Tree [.\node(Root){0}; [.{1} [.{1} [.{1} [.{1} [.{2} [.{7} [.{9} [.{4} [.{33} ] [.{474} ] ] [.{478} ] ] [.{487} ] ] [.{494} ] ] [.{496} ] ] [.{497} ] ] [.{498} ] ] [.{499} ] ] [.{4} [.{13} [.{4} [.{4} [.{7} [.{25} [.{9} [.{120} [.{314} ] [.{314} ] ] [.{434} ] ] [.{443} ] ] [.{468} ] ] [.{475} ] ] [.{479} ] ] [.{483} ] ] [.{496} ] ] [.{1} [.{2} [.{18} [.{39} [.{2} [.{55} [.{56} [.{327} ] [.{327} ] ] [.{383} ] ] [.{438} ] ] [.{440} ] ] [.{479} ] ] [.{497} ] ] [.{499} ] ] [.{3} [.{10} [.{2} [.{3} [.{6} [.{8} [.{7} [.{16} [.{32} ] [.{445} ] ] [.{461} ] ] [.{468} ] ] [.{476} ] ] [.{482} ] ] [.{485} ] ] [.{487} ] ] [.{497} ] ] [.{6} [.{9} [.{7} [.{1} [.{3} [.{3} [.\node(branchz-1){9}; [.\node(branchz){14}; [.{24} ] [.\node(levelz){448}; ] ] [.\node(levelz-1){462}; ] ] [.{471} ] ] [.{474} ] ] [.{477} ] ] [.{478} ] ] [.{485} ] ] [.{494} ] ] [.{444} [.{56} ] [.{56} ] ] ]

\foreach \level in {z,z-1} {
  \coordinate (option1) at (level\level.west) {};
  \coordinate (option2) at (branch\level.east) {};
  \coordinate (option3) at ($(branch\level.east)!.5!(level\level.west)$) {};
  \foreach \i/\c in {1/red, 2/blue, 3/green} {
     \fill[\c] (option\i) circle (2pt);
     \draw[\c,dashed] (\subtreeof{Root}.south -| option\i) 
                   -- (\subtreeof{Root}.north -| option\i);
     }
}
\end{tikzpicture}
\end{document}

近距离观察有趣的部分:

结果

相关内容