tikz-qtree 中文本点的自动连接

tikz-qtree 中文本点的自动连接

我经常要画如下这样的图:

在此处输入图片描述

我想使用tikz-qtree,因为我有很多树,这个包大大简化了事情。现在我使用以下代码,因为不可能在节点中拥有节点并使tikz-qtree树元素成为节点。所以我使用来自的网格代码如何在 TikZ 中自动按网格显示坐标?并从绝对位置到其他绝对位置绘制线条。这很耗时,而且看起来总是不对,字体大小改变时我必须重做。有没有更好的方法?

\documentclass{minimal}

\usepackage{tikz-qtree}
\tikzset{every roof node/.append style={inner sep=0.1pt,text height=2ex,text depth=0.3ex}}

\newcommand{\sliste}[1]{%
\mbox{%
$\left\langle\mbox{\scshape #1}\right\rangle$}%
}


\begin{document}

\begin{tikzpicture}
\tikzset{level 1+/.style={level distance=3\baselineskip}}
\tikzset{frontier/.style={distance from root=12\baselineskip}}
%\draw (-3,-5) to[grid with coordinates] (4,0);
\Tree[.S
        [.{V \sliste{ S$\!/\!/$V }} 
          [.V liest$_k$ ] ]
        [.{S$\!/\!/$V}
           [.NP Jens ]
           [.{V$'$$\!/\!/$V}
             [.NP \edge[roof]; {das Buch} ]
             [.{V$\!/\!/$V} \_$_k$ ] ] ] ]
\draw[semithick,<->,color=green] (3.1,-3.9) ..controls +(south east:.5) and +(south west:.5)..(2.7,-3.9);
\draw[semithick,<->,color=green] (3.5,-3.7) ..controls +(east:.5) and +(east:.5)..(2.8,-2.5);
\draw[semithick,<->,color=green] (2.8,-2.3) ..controls +(east:.5) and +(east:.5)..(1.7,-1.1);
\draw[semithick,<->,color=green] (1.5,-0.9) ..controls +(north:.5) and +(north:.5)..(-0.8,-0.9);
\draw[semithick,<->,color=green] (-0.7,-1.1) ..controls +(south east:.2) and +(north east:.5)..(-1.0,-2.4);
\end{tikzpicture}



\end{document}

编辑:

我遵循建议并使用了tikzmark\subnode

\documentclass{minimal}


\usepackage{tikz-grid}


\usepackage{tikz-qtree}
\tikzset{every roof node/.append style={inner sep=0.1pt,text height=2ex,text depth=0.3ex}}

\usetikzlibrary{tikzmark}

\newcommand{\sliste}[1]{%
\mbox{%
$\left\langle\mbox{\scshape #1}\right\rangle$}%
}


\begin{document}

\begin{tikzpicture}
\tikzset{level 1+/.style={level distance=3\baselineskip}}
\tikzset{frontier/.style={distance from root=12\baselineskip}}
\Tree[.S
        [.{V \sliste{ S$/\!/$\subnode{vcomp}{V} }} 
          [.{\subnode{vliest}{V}} liest$_k$ ] ]
        [.{S$/\!/$\subnode{vs}{V}}
           [.NP Jens ]
           [.{V$'$$\!/\!/$\subnode{vbar}{V}}
             [.NP \edge[roof]; {das Buch} ]
             [.{\subnode{vzero}{V}$\!/\!/$\subnode{vdsl}{V}} \_$_k$ ] ] ] ]
\draw[semithick,<->,color=green] (vcomp.east) ..controls +(south east:.2) and +(north east:.5)..(vliest.east);
\end{tikzpicture}



\end{document}

结果很有趣:如果我使用pdflatexAUX 文件,并且没有 AUX 文件,它就会工作。只要有 AUX 文件,代码就会生成两个页面,或者箭头会分布在页面上。嗯。

编辑2:

我按照 Allen Mun 的建议进一步研究了类似的例子:

\documentclass{minimal}


\usepackage{tikz-grid}


\usepackage{tikz-qtree}
\tikzset{every roof node/.append style={inner sep=0.1pt,text height=2ex,text depth=0.3ex}}

\usetikzlibrary{tikzmark}

\newcommand{\sliste}[1]{%
\mbox{%
$\left\langle\mbox{\scshape #1}\right\rangle$}%
}

\newcommand{\trace}{\raisebox{0.2ex}{\_}\rule{0cm}{0.7em}}

\begin{document}

\begin{tikzpicture}[
level 1+/.style={level distance=3\baselineskip},
frontier/.style={distance from root=15\baselineskip},
connect/.style={semithick,<->,color=green}]
\Tree[.S
        [.\node (NP) {NP}; \edge[roof]; {das Buch} ]
        [.\node (S/NP) {S/NP};
          [.{V \sliste{ S/$\!$/V }} 
            [.V liest$_k$ ] ]
           [.\node (S//V/NP) {S$/\!/$V/NP};
             [.\node (NP/NP) {NP/NP}; \trace{} ]
             [.{V$'$$\!/\!/$V}
               [.NP Jens ]
               [.{V$\!/\!/$V} \_$_k$ ] ] ] ] ] ]
\draw[connect] (NP/NP) [bend right] to (S//V/NP.south east);
\draw[connect] (S//V/NP.north east) [bend right] to (S/NP.east);
\draw[connect] (S/NP.north east) [bend right] to (NP);
\end{tikzpicture}


\end{document}

第二张图包含其他需要分享的信息

此图的意图是显示 NP 信息是共享的。因此,如果能够直接连接到 NP 节点,那就太好了。

答案1

即使forest它可以自动完成很多事情,也需要一定程度的手动调整。它根本无法知道节点的内容方法。但是,forest确实允许您将循环集成到树中,这在某些情况下可能很有吸引力。

例如:

\documentclass[tikz,border=5pt]{standalone}
\usetikzlibrary{tikzmark, arrows.meta, bending}
\usepackage{forest}

\begin{document}

  \tikzset{
    connect/.style={{Stealth[bend]}-{Stealth[bend]}, draw=green, shorten <=-3pt, shorten >=-3pt}
  }
  \newlength\txtht
  \settoheight\txtht{B}
  \begin{forest}
    for tree={
      parent anchor=south,
      child anchor=north,
      if n children=0{tier=t, text height=\txtht}{},
    },
    [S
      [NP, tikz={\draw [connect] (.north east) [bend left] to ([xshift=-10pt]np1.north east);}
        [das Buch, triangle]
      ]
      [S/NP, name=np1, tikz={\draw [connect] (.east) [bend left] to ([xshift=-10pt]np2.north east);}
        [V (S//V), tikz={\draw [connect] ([xshift=-10pt].south east) [bend left] to (v1.north east);}
          [V, name=v1
            [liest$_k$]
          ]
        ]
        [S//V/NP, name=np2
          [NP/NP, tikz={\draw [connect] (.east) [bend right] to ([xshift=-10pt]np2.south east);}
            [-]
          ]
          [V$'$//V, tikz={\draw [connect] (.east) [bend left] to ([xshift=-5pt]v2.north east);}
            [NP
              [Jens]
            ]
            [V//V, name=v2, tikz={\draw [connect] ([xshift=5pt].south west) [out=-105, in=-75] to ([xshift=-5pt].south east);}
              [${}_{-k}$]
            ]
          ]
        ]
      ]
    ]
  \end{forest}

\end{document}

<code>森林</code> 连接

答案2

没必要这么复杂。任何tikz-qtree节点标签都可以是显式的 TikZ\node命令,因此您可以命名节点而无需做太多额外工作。我还对箭头使用了更简单的语法,这样您就不需要指定控件(我认为这也使箭头变得更美观)。即使是较小的箭头也不需要子节点,因为它们可以用键缩短shorten(如示例中的 V//V 箭头)。

正如 Qrrbrbirlbel 所说,使用该forest包可以使这个过程稍微容易一些,因为它允许您简单地为任何节点指定一个标签而无需使用明确的\node命令,但除此之外基本过程是相同的。

\documentclass{article}

\usepackage{tikz-qtree}
\tikzset{every roof node/.append style={inner sep=0.1pt,text height=2ex,text depth=0.3ex}}

\newcommand{\sliste}[1]{%
\mbox{%
$\left\langle\mbox{\scshape #1}\right\rangle$}%
}


\begin{document}


\begin{tikzpicture}[
level 1+/.style={level distance=3\baselineskip},
frontier/.style={distance from root=12\baselineskip},
connect/.style={semithick,<->,color=green}]
\Tree[.S
        [.\node (V1) {V \sliste{ S$\!/\!/$V }}; 
          [.\node(V){V}; liest$_k$ ] ]
        [.\node (S/V) {S$\!/\!/$V};
           [.NP Jens ]
           [.\node(V'V) {V$'$$\!/\!/$V};
             [.NP \edge[roof]; {das Buch} ]
             [.\node(V/V) {V$\!/\!/$V}; \_$_k$ ] ] ] ]
\draw[connect,shorten >=.5em,shorten <=.5em] (V/V.south east) [bend left] to (V/V.south west) ;
\draw[connect] (V/V.north east) [bend right] to (V'V.east);
\draw[connect] (V'V.north east) [bend right] to (S/V.east);
\draw[connect,shorten <=.5em] (S/V.north east) to [bend right] (V1) ;
\draw[connect] (V1) to [bend left] (V);
\end{tikzpicture}




\end{document}

代码输出

相关内容