1

I got a cool solution to my question drawing complex dependency diagrams with tikz / forest and want to reuse this style for drawing a condensed version of the diagram that is supposed to look like this:

enter image description here

I now tried the following:

\documentclass{article}
\usepackage{forest}

\usetikzlibrary{arrows.meta,bending}

\tikzset{
    connect/.style={{Stealth[bend]}-{Stealth[bend]}, draw=green, shorten <=-3pt, shorten >=-3pt}
  }

\forestset{
  wg/.style={
    for tree={
      no edge,
      draw,
      outer ysep=1pt,
    },
    copy label/.style={
      for children={
        if content={}{
            content/.pgfmath={content("!u")},
            calign with current,
            edge={draw,{-Triangle[open,reversed]}},
            copy label,
            !u.content/.pgfmath={content},
            !u.content+=',
        }{
          copy label,
        }
      }
    },
    delay={
      copy label,
      for tree={name/.pgfmath={content}},
    },
    for tree={content format={\strut\forestoption{content}}},
    where n children={0}{
      tier=word,
    }{},
  },
}
\tikzset{deparrow/.style={-Latex,blue}}
\begin{document}

\begin{forest}
  wg
  [
   [small]    
   [children]
   [were]
   [playing]
   [outside]
  ]
%  \draw[deparrow] (were.north) [bend.left] to ([xshift=-10pt]children.north);
  \draw[deparrow] (were) to[out=north, in=north] ([xshift=-10pt]children);
  \draw[deparrow] (children) to[out=north, in=north] (small);
  \draw[deparrow] (were) to[out=north, in=north] (playing);
  \draw[deparrow] (playing) to[out=north, in=north] (children);
  \draw[deparrow] (playing) to[out=north, in=north] (outside);
\end{forest}




\end{document}

This produces:

enter image description here

Shifting the node does not work.

Also for the simple diagram the following tree may be more appropriate:

\begin{forest}
  [were
    [children
        [small]
      ]
    [playing
        [outside]
    ]
  ]
\end{forest}

enter image description here

This corresponds to the arrows in the original figure (with one arrow from playing to children not being represented).

Comparing this tree with the tree from drawing complex dependency diagrams with tikz / forest

enter image description here

it seems to be possible to draw all the arrows (except the playing-children one) via the style. If this would work, one could have the simplex case as a condensed version of the complex case and the arrows (with the exception of one) would be drawn automatically.

Edit: This is what I did after the first answer:

enter image description here

  • I really don't understand the second part of this question. Do you not want the nodes horizontally aligned? If that structure works better, why not use it? And what is 'the simplex case'? – cfr Jul 23 '15 at 15:53
  • 1
    I'm not sure that a tree structure (and henceforth forest) is the best tool for the task at hand, i.e. drawing a linear structure, except if you aim for designing a simple switch between a hierarhical and flat representation of the same structure. As for the arrows: I believe that it will be difficult to create nice-looking curved arrows programmatically ... once they start overlapping, all hell breaks loose ... – Sašo Živanović Jul 25 '15 at 11:24
  • I think the pure dependency structure (that is the one with the arrows not the one with the triangle lines) corresponds to a tree. But you are right, if there are additional dependencies, it is not trivial to leave the room one would require for such additional dependencies. (for instance the one from playing to children above). – Stefan Müller Jul 31 '15 at 12:56
1

You can adapt the existing style so the example works just by using phantom for the root and specifying the appropriate anchor for children:

\documentclass[tikz,border=10pt,multi]{standalone}
\usepackage{forest}
\usetikzlibrary{arrows.meta,bending}
\tikzset{
    connect/.style={{Stealth[bend]}-{Stealth[bend]}, draw=green, shorten <=-3pt, shorten >=-3pt},
    deparrow/.style={-Latex,blue}
  }

\forestset{
  wg/.style={
    for tree={
      no edge,
      draw,
      outer ysep=1pt,
    },
    copy label/.style={
      for children={
        if content={}{
            content/.pgfmath={content("!u")},
            calign with current,
            edge={draw,{-Triangle[open,reversed]}},
            copy label,
            !u.content/.pgfmath={content},
            !u.content+=',
        }{
          copy label,
        }
      }
    },
    delay={
      copy label,
      for tree={name/.pgfmath={content}},
    },
    for tree={content format={\strut\forestoption{content}}},
    where n children={0}{
      tier=word,
    }{},
  },
}
\begin{document}

\begin{forest}
  wg
  [,phantom
   [small]
   [children]
   [were]
   [playing]
   [outside]
  ]
%  \draw[deparrow] (were.north) [bend.left] to ([xshift=-10pt]children.north);
  \draw[deparrow] (were) to[out=north, in=north] ([xshift=-10pt]children.north);
  \draw[deparrow] (children) to[out=north, in=north] (small);
  \draw[deparrow] (were) to[out=north, in=north] (playing);
  \draw[deparrow] (playing) to[out=north, in=north] (children);
  \draw[deparrow] (playing) to[out=north, in=north] (outside);
\end{forest}

\end{document}

adapted

For something a little closer to the target:

  \draw[deparrow] ([xshift=-5pt]were.north) to[out=north, in=north] ([xshift=5pt]children.north);
  \draw[deparrow] ([xshift=-5pt]children.north) to[out=north, in=north] ([xshift=5pt]small.north);
  \draw[deparrow] ([xshift=5pt]were.north) to[out=north, in=north] ([xshift=-5pt]playing.north);
  \draw[deparrow] ([xshift=-3.5pt, yshift=2.5pt]playing.north) to[out=north, in=north] ([xshift=3.5pt, yshift=2.5pt]children.north);
  \draw[deparrow] ([xshift=5pt]playing.north) to[out=north, in=north] ([xshift=-5pt]outside.north);

modified further

I don't fully understand the second part of your question, I'm afraid.

EDIT

You can partially automate drawing the arrows by adding the following code to the wg style:

    hop left/.style={
      tikz+={
        \draw[deparrow] ([xshift=-5pt].north) to[out=north, in=north] ([xshift=5pt]!p.north);
      },
    },
    hop right/.style={
      tikz+={
        \draw[deparrow] ([xshift=5pt].north) to[out=north, in=north] ([xshift=-5pt]!n.north);
      },
    },

Then you can specify the tree as follows:

\begin{forest}
  wg
  [,phantom
   [small]
   [children, hop left]
   [were, hop left, hop right]
   [playing, hop right]
   [outside]
  ]
  \draw[deparrow] ([xshift=-3.5pt, yshift=2.5pt]playing.north) to[out=north, in=north] ([xshift=3.5pt, yshift=2.5pt]children.north);
\end{forest}

But you cannot do much more than this without at least some algorithm determining which way arrows should go i.e. when should they hop left, when hop right, when both and when neither. Unless you are drawing a lot of trees like this and the pattern of hops is extremely uniform, it will be easier to specify the hops manually and less prone to error. In the tree posted, for example, you'd need to implement something like this:

for the phantom root node:
  if it has an odd number of children then
    for each of its children
      if the child's number is half of the parent's number of children incremented by one and divided by two, then hop both right and left
        else if the child's number is less than half of the parent's number of children incremented by one and divided by two and the child is not the first child, then hop left
          else if the child is not the last child, then hop right
            else do nothing
  else do nothing

Then you'd presumably also have a specification of what to do if the root has an even number of children. If you are drawing hundreds of trees with the same pattern of arrows, it is probably worth doing. Otherwise, it seems easier to just say hop left and hop right.

  • OK. Thanks! After adding the phantom node the shifting worked again. This is what I was missing. @Sašo Živanović is probably right that the general problem cannot be solved by styles. So I mark this question answered. – Stefan Müller Jul 31 '15 at 13:00
  • @StefanMüller Have you looked at the chains library? Maybe that would work better here? You could draw some of the arrows automatically but it is hard to do so and avoid having them collide without leaving ugly gaps. – cfr Jul 31 '15 at 13:21
  • 1
    @StefanMüller See also edit. – cfr Jul 31 '15 at 23:34
  • yes, I think that the structure that is needed for this is the tree given in the question. This tree contains the information from where to where the dependenc arrows have to be drawn. It does not contain information about linearization of the words though. Interestingly this information is contained in the second tree with the empty nodes. So it may be possible to draw the figure automatically from this. Anyway, for my purposes your answer is sufficient and it would be only make sense to invest further work if we would like to solve this problem for the DG community. Thanks for the solu – Stefan Müller Aug 16 '15 at 11:55

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.