6

how can I shift a subtree of a tikztree/qtree to the right without affecting the rest of the tree?

Consider the following tree:

\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}

In the end the HD>erschreckt has to go between the NK>Hunden and the RC subtree, i. e. branches have to intersect. I understand that this is not possible within a tikz tree.

I could leave the HD>erschreckt out of the tikz tree and draw it later on. However that would require the RC subtree to be shifted to the right to make room for the drawing of the HD>erschreckt. And that is where I am stuck.

A [missing] node between the NK>Hunden and the RC subtree does cause the right shift of the RC subtree but also shifts the NK>den and NK>Hunden to the left, so that does not seem to be an option.

So again: How can I shift the RC subtree to the right without affecting the rest of the tree?

(Bonus points for making the intersection visually unambiguous.)

Thank you for your help

4

Perhaps the best thing to do is place the work erschrekt where you want it, to the left of ,die. Since \node is an abbreviation for \path node you can add further material afterwards to draw more. Using the positioning library you can place nodes relative to each other. Putting this code in the appropriate place tikz will take care of moving the rest of the tree:

Sample output

\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}

Note that I added \strut to the new node to ensure it has a uniform depth. Other tikz approaches would be to specify text height/depth for your nodes generally.

Second Approach If you need adjust placement of paths and nodes even more, then I think it is actually easier to abandon the tree functions and draw the diagram essentially from scratch. The tree functions have a rather simplistic approach to placement of the child nodes. Here is one way to do this:

Second sample output

\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}

I have used \matrix to place the words evenly, and adjusted the column separation at avoid overlaps further up in the diagram. Other nodes are then place relative to the matrix entries, referring to base points of nodes for consistency.

The calc library allows us to use expressions such as ($(A)!0.5!(B)$) for the point half way between (A) and (B); the syntax (A |- B) (which does not require calc) finds the point whose x-coordinate is that of (A) and y-coordinate of that of (B).

I have placed nodes vertically on levels correspanding to (0,n) with n a whole number and labelled them with names that end in the level number; the vertical line out of a node then goes to height (0,n+0.5) before being joined to a horizontal bar; these horizontal bars need only been drawn from the nodes at their left and right ends. Finally, the crossing line has be drawn "doubled" with a wide white background creating a hole in the horizontal line it crosses. I have also shortened it a bit so that it does not overlap the border of the nodes. 0.4pt has been used as the standard reference line width in these cases.

  • Thanks for the notion that it is possible to insert extra nodes. However the result is not what I need. The whole HD>erschreckt has to be left of the RC subtree, not just the leaf "erschreckt". I currently consider drawing two trees on top of each other with different visible and [missing] subtrees, but have not tried it yet. – svenhuebner Jun 21 '13 at 13:37
  • Drawing from scratch works of course. I would rather have avoided that but I also do not want to spend any more time on such a small issue. Thank you for your helpful answers. – svenhuebner Jun 22 '13 at 10:57
0

forest enables you to specify the diagram as a tree and still move the subtree into the desired location. The trick is to do things backwards. Rather than moving the location of the RC subtree, we first ensure that it is placed where we want it by creating it as a sibling of HD. We then 'move' The subtree by changing its relationship with the other nodes: we make it a child of NP as desired.

Doing this, we ensure that the positions of the nodes are set before the subtree is 'moved'. Essentially, this means that its relations to the other nodes change but it does not change location: it moves in terms of the tree structure, but not in terms of the spatial layout. The move is therefore done at the last minute, right before the tree is finally drawn using the before drawing tree hook.

A phantom node is used to help with the spacing of the VP node relative to its children, SBP and HD.

The tree can also be specified much more compactly, especially with the specification of a couple of TikZ styles.

\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}

structural without spatial moves

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.