我有以下代码
\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-qtree}
\begin{document}
\begin{tikzpicture}
\tikzset{grow'=right, level distance=32pt}
\tikzset{execute at begin node=\strut}
\tikzset{every tree node/.style={anchor=base west}}
\Tree [ [.J [.J ] [.S ] ]
[.S [.J ]
[.S ] ] ] ]
\end{tikzpicture}
\end{document}
这给了我以下信息:
然而,我想让它看起来如下所示:
我该如何调整我的代码以便让标签位于边缘旁边?
答案1
这是一棵树,所以我会使用 Forest。labelled tree
下面定义的样式允许您以以下形式编写每个节点
<content>:<label for edge>
代码应该自动找出要做什么以及将标签放在哪里。
例如,我们可以写:
\begin{forest}
for tree={
grow'=0,
parent anchor=children,
child anchor=parent,
l sep'+=20pt,
},
delay={
where content={}{}{
content/.wrap value={\strut #1},
},
},
labelled tree,
sloped labels,
[
[J:0.3
[J:0.3]
[S:0.7]
]
[S:0.7
[J:0.3]
[S:0.7]
]
]
\end{forest}
生产
完整代码labelled tree
:
\documentclass[border=10pt,multi,tikz]{standalone}
\usepackage{forest}
\forestset{
declare boolean register=sloped labels,
not sloped labels,
my edge label/.style={
tempcountc/.option=grow,
if reversed={
tempcountc-/.register=tempcountb,
}{
tempcountc+/.register=tempcountb,
},
if sloped labels={
temptoksa=sloped,
}{
temptoksa=,
},
edge label/.expanded={node [midway, shift=(\foresteregister{tempcountc}:10pt), \foresteregister{temptoksa}] {#1}}
},
labelled tree/.style={
before typesetting nodes={
where={(n_children())>1}{
tempcounta/.pgfmath={int(((n_children())+1)/2)},
if={isodd(n_children())}{
for n/.wrap pgfmath arg={{##1}{calign with current}}{(tempcounta)},
}{},
for nodewalk={
n=1,
filter={current and siblings}{n()<(tempcounta)},
}{
for nodewalk={
c,
while={int(n_children())==1}{
on invalid={fake}{n=1},
}{},
}{
tempcountb'=-90,
split option={content}{:}{content,my edge label},
},
},
for nodewalk={
n'=1,
filter={current and siblings}{n()>=(tempcounta)},
}{
for nodewalk={
c,
while={int(n_children())==1}{
on invalid={fake}{n=1},
}{},
}{
tempcountb'=-270,
split option={content}{:}{content,my edge label},
},
},
}{},
for nodewalk={
fake=r,
while={int(n_children())==1}{
on invalid={fake}{n=1},
}{},
}{
tempcountb'=-270,
split option={content}{:}{content,my edge label},
},
},
},
}
\begin{document}
\begin{forest}
for tree={
grow'=0,
parent anchor=children,
child anchor=parent,
l sep'+=20pt,
},
delay={
where content={}{}{
content/.wrap value={\strut #1},
},
},
labelled tree,
sloped labels,
[
[J:0.3
[J:0.3]
[S:0.7]
]
[S:0.7
[J:0.3]
[S:0.7]
]
]
\end{forest}
\end{document}
但是,如果您的树遵循问题中所示的结构,您可能不想费心为每个节点添加内容和标签,因为这些总是相同的。
在这种情况下,您可能会对recursive tree
自动添加这些内容的样式感兴趣。要指定标签和节点内容,只需写入,
recursive tree,
first option=<content>:<probability>,
second option=<content>:<probability>,
在树的序言中。例如,
\begin{forest}
for tree={
grow'=0,
l sep'+=20pt,
},
recursive tree,
first option=S:0.7,
second option=J:0.3,
[
[
[]
[]
]
[
[]
[]
]
]
\end{forest}
产生与上面相同的输出。
即使这样也显得没有必要那么冗长。如果我们可以告诉 Forest 要实现多少次递归,然后让样式完成剩下的工作,那就太好了。我们可以使用键
recur=<integer>,
这将<integer>
在根节点下方(或右侧)添加级别。也就是说,
\begin{forest}
before packing={
for tree={
grow'=0,
l sep'+=20pt,
},
},
recursive tree,
first option=S:0.7,
second option=J:0.3,
recur'=2,
[
]
\end{forest}
将创建与上面相同的输出。此外,
\begin{forest}
before packing={
for tree={
grow'=0,
l sep'+=20pt,
},
},
recursive tree,
first option=Health:0.89,
second option=Disease:0.11,
recur'=5,
[
]
\end{forest}
将产生
对于相对较少的代码来说,这是一个很大的树!
完整代码recursive tree
:
\documentclass[border=10pt,tikz]{standalone}
\usepackage{forest}
\forestset{
declare boolean register=sloped labels,
not sloped labels,
declare toks register=first option,
first option=A:0.5,
declare toks register=second option,
second option=B:0.5,
declare toks register=first option name,
declare toks register=second option name,
declare toks register=first option probability,
declare toks register=second option probability,
first option name=first,
second option name=second,
first option probability=1,
second option probability=0,
declare count register=recur,
recur'=0,
my edge label/.style={
tempcountc/.option=grow,
if reversed={
tempcountc-/.register=tempcountb,
}{
tempcountc+/.register=tempcountb,
},
if sloped labels={
temptoksa=sloped,
}{
temptoksa=,
},
edge label/.expanded={node [midway, shift=(\foresteregister{tempcountc}:10pt), \foresteregister{temptoksa}] {#1}}
},
recursive tree/.style={
sloped labels,
before typesetting nodes={
split register={first option}{:}{first option name,first option probability},
split register={second option}{:}{second option name,second option probability},
where n=1{
content/.register=first option name,
before packing={
tempcountb'=-90,
my edge label/.register=first option probability,
},
}{
if n'=1{
content/.register=second option name,
before packing={
tempcountb'=-270,
my edge label/.register=second option probability,
},
}{}
},
for tree={
parent anchor=children,
child anchor=parent,
},
},
delay={
if recur=0{}{
tempcountd'=1,
repeat={(recur)}{
delay n/.wrap pgfmath arg={%
{####1}{
where n children=0{
append={[]},
prepend={[]},
}{},
}%
}{(tempcountd)},
tempcountd+=1,
},
},
},
},
}
\begin{document}
\begin{forest}
for tree={
grow'=0,
l sep'+=20pt,
},
recursive tree,
first option=S:0.7,
second option=J:0.3,
[
[
[]
[]
]
[
[]
[]
]
]
\end{forest}
\begin{forest}
before packing={
for tree={
grow'=0,
l sep'+=20pt,
},
},
recursive tree,
first option=S:0.7,
second option=J:0.3,
recur'=2,
[
]
\end{forest}
\begin{forest}
before packing={
for tree={
grow'=0,
l sep'+=20pt,
},
},
recursive tree,
first option=Health:0.89,
second option=Disease:0.11,
recur'=5,
[
]
\end{forest}
\end{document}
答案2
注释可以通过\edge
命令插入,参见“5 显式边缘”部分tikz-qtree
,例如:
\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-qtree}
\begin{document}
\begin{tikzpicture}
\tikzset{grow'=right, level distance=32pt}
\tikzset{execute at begin node=\strut}
\tikzset{every tree node/.style={anchor=base west}}
\Tree [
\edge node[above]{.3};
[.J
\edge node[above]{.3}; [.J ]
\edge node[below]{.7}; [.S ]
]
\edge node[below]{.7};
[.S
\edge node[above]{.3}; [.J ]
\edge node[below]{.7}; [.S ]
]
]
\end{tikzpicture}
\end{document}
源文件和结果的表示都更加紧凑:
\documentclass{article}
\usepackage{tikz-qtree}
\begin{document}
\begin{tikzpicture}[
grow'=right, level distance=32pt,
J/.style={above=.2em, node contents={.3}},
S/.style={below=.2em, node contents={.7}},
]
\Tree [
\edge node[J]; [.J
\edge node[J]; [.J ]
\edge node[S]; [.S ]
]
\edge node[S]; [.S
\edge node[J]; [.J ]
\edge node[S]; [.S ]
]
]
\end{tikzpicture}
\end{document}