我遇到了问题,因为 (1) 我从来没有画过像这样的具有 90º 度分支的树形图,并且 (2) 我从来没有画过带有编号示例的树形图。我尝试使用tikz-qtree
和forest
,但没有任何进展。所以我尝试使用tabbing
环境来解决编号示例问题,但现在我不知道使用哪个包来绘制线条。这是我当前(写得很糟糕)的代码:
\documentclass[]{article}
\begin{document}
\begin{tabbing}
\hspace{0em} $(20)$ \= \hspace{2em} $n$ \= \hspace{1em} $s/(n)[n]$ \=
\hspace{1em} $n/[s]$ \= \hspace{1em} $n$ \= \hspace{1em} $s/(n)$ \=
\hspace{1em} $s/(n)//(s/(n))$ \= \hspace{1em} $s/(n)//(s/(n))[n]$ \=
\hspace{1em} $n$ \= \hspace{1em} $n/(n)$\\~\\
\hspace{0em} $(21)$\= \hspace{37.5em} $n$\\~\\
\hspace{0em} $(22)$\= \hspace{17.5em} $s/(n)$\\~\\
\hspace{0em} $(23)$\= \hspace{30em} $s/(n)$\\~\\
\hspace{0em} $(24)$\= \hspace{20,5em} $s$\\~\\
\hspace{0em} $(25)$\= \hspace{14em} $n$\\~\\
\hspace{0em} $(26)$\= \hspace{6em} $s$\\
\end{tabbing}
\end{document}
答案1
这是使用的版本forest
。
\documentclass{article}
\usepackage[edges]{forest}
\forestset{
declare count register=labelcount,
enumerate/.style={labelcount=#1,
for tree={content/.pgfmath=labelcount, labelcount-=1},
}
}
\begin{document}
\begin{forest}for tree={grow=north,forked edge,math content}
[
[s,no edge
[n
[s
[s/(n)
[n,tier=21
[n/(n), tier=top]
[n,tier=top]]
[{s/(n)//(s/(n))[n]},tier=top ]
[s/(n)
[s/(n)//(s/(n))),tier=top ]
[s/(n),tier=top ]
]
]
[n,tier=top]
]
[{n/[s]},tier=top ]
]
[{s/(n)[n]},tier=top ]
[n,tier=top ]
]
[,for tree=no edge,delay={enumerate={26},for tree={content={(#1)}}}
[[[[[,tier=21 [,tier=top ]]]]]]]
]
\end{forest}
\end{document}
代码解释
- 我们使用
edges
来自的库来forest
制作简单的方形分支。 - 我们习惯
grow=north
把树倒过来。 - 使用
tier
密钥可以将树的所有终端节点对齐到树的顶部。它还用于将行 (21) 与 (22) 分开,因为在树中它们处于同一嵌入级别,但在编号上则不是。通过将树中的节点与编号中的节点对齐,我们可以实现所需的结果。 - 编号是通过本质上控制树和数字的幻影根节点来完成的。
- 这些数字是半自动计算的,通过使用密钥给出根节点的数字
enumerate=...
并从那里倒数。同样,tier
密钥用于保持对齐正确。
答案2
\documentclass[border = 5pt]{standalone}
\usepackage{tikz-qtree}
\begin{document}
\begin{tikzpicture}[grow' = up]
\tikzset{
edge from parent/.style = {draw,
edge from parent path={(\tikzparentnode.north)
-| (\tikzchildnode)}},
frontier/.style = {distance from root = 180pt},
}
% tree
\Tree [.s [n ]
[s/(n)[n] ]
[.n [n/[s] ]
[.s [n ]
[.s/(n) [.s/(n) [s/(n) ]
[s/(n)//(s/(n)) ] ]
[s/(n)//(s/(n))[n] ]
[ [.n [.n ]
[.n/(n) ] ] ] ] ] ] ]
% labels
\foreach \y/\lbl in {0/26,30/25,60/24,90/23,120/22,150/21,180/20} {
\node[xshift = -3cm, yshift = \y pt] at (0, 0){\small(\lbl)};
}
\end{tikzpicture}
\end{document}
答案3
这是改编自Alan Munn 的回答它的用途更加方便用户使用。要生成树,只需添加
enumerated,
enum'=<start line number>
其中<start line number>
是第一行的编号。样式enumerated
将尝试确定需要多少行,格式化树并对行进行编号。无需明确添加幻像根或节点来获取编号:这些节点都将自动添加。
唯一需要您提供帮助的情况是需要额外线路的情况,因为处于同一结构级别的两个节点应该放在不同的线路上。
结果是
\begin{forest}
enumerated,
enum'=20,
[S
[n
[s
[s/(n)
[n,tier=21
[n/(n)]
[n]]
[{s/(n)//(s/(n))[n]} ]
[s/(n),tier=22
[s/(n)//(s/(n))) ]
[s/(n) ]
]
]
[n]
]
[{n/[s]} ]
]
[{s/(n)[n]} ]
[n ]
]
\end{forest}
生产
代码:
\documentclass[border=10pt]{standalone}
\usepackage[edges]{forest}
\forestset{% addaswyd o gôd Alan Munn: https://tex.stackexchange.com/a/433753/
declare count register=enum,
enum'=100,
declare toks register=enum tiers,
enum tiers=,
declare boolean register=enum toggle,
not enum toggle,
enumerated/.style={
enum tiers=enum@tier@\foresteregister{enum},
for tree={
math content,
grow=90,
},
forked edges,
delay={
tempcountc/.max={level}{tree},
tempcountc'+=1,
tempcountb/.register=enum,
while={
>R_> {tempcountc}{0}
}{
tempcountc'-=1,
not enum toggle,
where={
> O R = {level} {tempcountc}
}{
if n children=0{
tier/.process={Rw{enum}{enum@tier@##1}}
}{
if tier={}{
tier/.process={Rw{tempcountb}{enum@tier@##1}},
if={>R! RR=! & {enum toggle} {tempcountb}{enum} }{ +enum tiers/.process={Rw{tempcountb}{enum@tier@##1,}}, enum toggle } {}
}{
+enum tiers/.process={Ow{tier}{##1,}}
}
},
}{},
tempcountb'+=1,
},
},
before typesetting nodes={
replace by={[, phantom, for tree={grow=90}, append, temptoksa/.option=name, split register={enum tiers}{,}{enum label}
]%
},
},
before packing={
delay={
tempcounta/.register=enum,
for nodewalk={reverse={fake=r,while nodewalk valid={l}{l}}}{content/.process={Rw{tempcounta}{(##1)}}, typeset node, tempcounta'+=1},
}
}
},
enum label/.style={
prepend={[, grow=90, tier=#1, no edge, name=#1]},
enum parent/.process={Rw{temptoksa}{{##1}{#1}}},
temptoksa=#1,
},
enum parent/.style 2 args={
before packing={
for nodewalk={name=#1}{append=#2}
},
},
}
\begin{document}
\begin{forest}
enumerated,
enum'=20,
[S
[n
[s
[s/(n)
[n,tier=21
[n/(n)]
[n]]
[{s/(n)//(s/(n))[n]} ]
[s/(n),tier=22
[s/(n)//(s/(n))) ]
[s/(n) ]
]
]
[n]
]
[{n/[s]} ]
]
[{s/(n)[n]} ]
[n ]
]
\end{forest}
\end{document}