如何tikz
在不影响树的其余部分的情况下将树/qtree的子树向右移动?
考虑下面的树:
\documentclass[tikz]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{tikz-qtree}
\usetikzlibrary{shapes, trees}
\begin{document}
\begin{tikzpicture}[
font=\footnotesize,
edge from parent/.style={draw, edge from parent fork down},
frontier/.style={distance from root=250},
level distance=25,
phrase/.style={draw, ellipse},
function/.style={draw, rectangle}
]
\Tree
[.\node[phrase] {S};
[.\node[function] {SB}; Tim ]
[.\node[function] {HD}; wurde ]
[.\node[function] {OC};
[.\node[phrase] {VP};
[.\node[function] {SBP};
[.\node[phrase] {PP};
[.\node[function] {AC}; von ]
[.\node[function] {NK};
[.\node[phrase] {NP};
[.\node[function] {NK}; den ]
[.\node[function] {NK}; Hunden ]
[.\node[function] {RC};
[.\node[phrase] {S};
[.\node[function] {SB}; ,die ]
[.\node[function] {MO}; laut ]
[.\node[function] {HD}; bellten. ]
]
]
]
]
]
]
[.\node[function] {HD}; erschreckt ]
]
]
]
\end{tikzpicture}
\end{document}
最后,HD>erschreckt
必须位于和之间NK>Hunden
,RC subtree
即树枝必须相交。我知道在tikz
树中这是不可能的。
我可以把 放在树HD>erschreckt
外面tikz
,稍后再画出来。但是,这需要RC subtree
将 移到右边,为 的绘制腾出空间HD>erschreckt
。这就是我被困住的地方。
和[missing]
之间的节点确实会导致 的右移,但也会将和向左移动,所以这似乎不是一个选择。NK>Hunden
RC subtree
RC subtree
NK>den
NK>Hunden
所以再说一遍:我怎样才能将其RC subtree
向右移动而不影响树的其余部分?
(使交叉点在视觉上明确可获得加分。)
感谢您的帮助
答案1
也许最好的做法是将作品放在erschrekt
您想要的位置,即 的左侧,die
。由于\node
是 的缩写,因此\path node
您可以在之后添加更多材料以绘制更多内容。使用positioning
库,您可以将节点彼此相对放置。将此代码放在适当的位置tikz
将负责移动树的其余部分:
\documentclass[tikz]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{tikz-qtree}
\usetikzlibrary{shapes, trees,calc,positioning}
\begin{document}
\begin{tikzpicture}[
font=\footnotesize,
edge from parent/.style={draw, edge from parent fork down},
frontier/.style={distance from root=250},
level distance=25,
phrase/.style={draw, ellipse},
function/.style={draw, rectangle}
]
\Tree
[.\node[phrase] {S};
[.\node[function] {SB}; Tim ]
[.\node[function] {HD}; wurde ]
[.\node[function] {OC};
[.\node[phrase] {VP};
[.\node[function] {SBP};
[.\node[phrase] {PP};
[.\node[function] {AC}; von ]
[.\node[function] {NK};
[.\node[phrase] {NP};
[.\node[function] {NK}; den ]
[.\node[function] {NK}; Hunden ]
[.\node[function] {RC};
[.\node[phrase] {S};
[.\node[function] {SB}; \node (die) {,die}
node[node distance=0cm,left=of die] (ert)
{\strut erschreckt}; ]
[.\node[function] {MO}; laut ]
[.\node[function] {HD}; bellten. ]
]
]
]
]
]
]
[.\node[function] (ers) {HD}; ]
]
]
];
\draw[red] (ers.south) |- ($(ers.south)!0.65!(ert.north)$)-| (ert.north);
\end{tikzpicture}
\end{document}
请注意,我添加了\strut
新节点以确保其具有统一的深度。其他tikz
方法是text height/depth
一般地指定您的节点。
第二种方法如果您需要进一步调整路径和节点的位置,那么我认为放弃树函数并从头开始绘制图表实际上更容易。树函数对子节点的放置方法相当简单。以下是执行此操作的一种方法:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{shapes,calc,matrix}
\begin{document}
\begin{tikzpicture}[font=\footnotesize,anchor=base,
phrase/.style={draw, ellipse},
function/.style={draw, rectangle}]
\matrix (b) [matrix of nodes,column sep=1ex,text height=7pt,text depth=2pt] {
Tim
&wurde
&von
&den
&Hunden
&erschrekt
&,die
&laut
&bellten \\
};
\node[function] (19) at (b-1-1 |- 0,9) {SB};
\node[function] (29) at (b-1-2 |- 0,9) {HD};
\node[function] (35) at (b-1-3 |- 0,5) {AC};
\node[function] (43) at (b-1-4 |- 0,3) {NK};
\node[function] (53) at (b-1-5 |- 0,3) {NK};
\node[function] (67) at (b-1-6 |- 0,7) {HD};
\node[function] (71) at (b-1-7 |- 0,1) {SB};
\node[function] (81) at (b-1-8 |- 0,1) {MO};
\node[function] (91) at (b-1-9 |- 0,1) {HD};
\node[phrase] (S2) at ($(71.base)!0.5!(91.base) + (0,1)$) {S};
\node[function] (R3) at ($(S2.base) + (0,1)$) {RC};
\node[phrase] (N4) at ($(43.base)!0.3!(R3.base) + (0,1)$) {NP};
\node[function] (N5) at ($(N4.base) + (0,1)$) {NK};
\node[phrase] (P6) at ($(35.base)!0.5!(N5.base) + (0,1)$) {PP};
\node[function] (S7) at ($(P6.base) + (0,1)$) {SBP};
\node[phrase] (V8) at ($(S7.base)!0.5!(67.base) + (0,1)$) {VP};
\node[function] (O9) at ($(V8.base) + (0,1)$) {OC};
\node[phrase] (S10) at ($(19.base)!0.5!(O9.base) + (0,1)$) {S};
\draw (b-1-1) -- (19) -- +(0,0.5) -| (S10);
\draw (b-1-2) -- (29) -- +(0,0.5);
\draw (b-1-3) -- (35) -- +(0,0.5) -| (P6) -- (S7) -- +(0,0.5) -| (V8)
-- (O9) -- +(0,0.5) -| (S10);
\draw (b-1-4) -- (43) -- +(0,0.5) -| (N4) -- (N5) -- +(0,0.5) -|
(P6);
\draw (b-1-5) -- (53) -- +(0,0.5);
\draw (b-1-7) -- (71) -- +(0,0.5) -| (S2) -- (R3) -- +(0,0.5) -| (N4);
\draw[white,double=black,line width=3pt,double distance=0.4pt,
shorten >=0.2pt] (b-1-6) -- (67); \draw (67) -- +(0,0.5) -| (V8);
\draw (b-1-8) -- (81) -- +(0,0.5);
\draw (b-1-9) -- (91) -- +(0,0.5) -| (S2);
\end{tikzpicture}
\end{document}
我习惯于\matrix
均匀地放置单词,并调整列间距以避免在图表中进一步重叠。然后,其他节点相对于矩阵条目放置,参考节点的基点以保持一致性。
该calc
库允许我们使用诸如表示和($(A)!0.5!(B)$)
中间点的表达式;该语法(不需要)找到 x 坐标为且 y 坐标为 的点。 (A)
(B)
(A |- B)
calc
(A)
(B)
我将节点垂直放置在(0,n)
与n
整数对应的级别上,并用以级别号结尾的名称标记它们;从节点出来的垂直线然后延伸到高度,(0,n+0.5)
然后连接到水平条;这些水平条只需要从其左端和右端的节点绘制。最后,交叉线被“双倍”绘制,带有宽的白色背景,在它穿过的水平线上形成一个洞。我还将它缩短了一点,这样它就不会与节点的边界重叠。 0.4pt
在这些情况下,已用作标准参考线宽。
答案2
forest
使您可以将图表指定为树,同时仍将子树移动到所需位置。诀窍是反向操作。RC
我们首先通过将其创建为 的兄弟节点来确保将其放置在我们想要的位置,而不是移动子树的位置HD
。然后我们通过更改子树与其他节点的关系来“移动”子树:我们根据需要使其成为 的子节点NP
。
这样做可以确保节点的位置已设置前子树被“移动”。本质上,这意味着它与其他节点的关系发生了变化,但它的位置没有改变:它在树结构方面移动,但在空间布局方面没有移动。因此,移动是在最后一刻完成的,就在使用钩子最终绘制树之前before drawing tree
。
节点phantom
用于帮助确定VP
节点相对于其子节点的间距,SBP
并且HD
。
树也可以指定得更加紧凑,尤其是通过指定几个 TikZ 样式。
\documentclass[tikz,border=5pt,multi]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{forest}
\usetikzlibrary{shapes}
\begin{document}
\tikzset{
phrase/.style={draw, ellipse},
function/.style={draw, rectangle}
}
\begin{forest}
for tree={
font=\footnotesize,
edge path={
\noexpand\path [draw, \forestoption{edge}] (!u.parent anchor) -- +(0,-5pt) -| (.child anchor)\forestoption{edge label};
},
parent anchor=south,
child anchor=north,
if n children=0{tier=terminus}{},% all terminal nodes need to be aligned
}
[S, phrase,
[SB, function,
[Tim]
]
[HD, function,
[wurde]
]
[OC, function,
[VP, phrase,
[SBP, function,
[PP, phrase,
[AC, function,
[von]
]
[NK, function,
[NP, phrase, before drawing tree={append={rc}}% this moves the subtree in terms of the tree structure, but it is done very late so it doesn't change its spatial location
[NK, function, tier=tier rc
[den]
]
[NK, function,
[Hunden]
]
]
]
]
]
[, phantom, calign with current]
[HD, function,
[erschreckt]
]
[RC, function, name=rc, tier=tier rc% name the node so we can move it and fix the horizontal alignment using tier specification
[S, phrase,
[SB, function,
[{,die}]
]
[MO, function,
[laut]
]
[HD, function,
[bellten.]
]
]
]
]
]
]
\end{forest}
\end{document}