3

I am trying to change the growth direction midway while growing my tree with forest. Here is an MWE:

\documentclass{standalone}

\usepackage{forest}
\useforestlibrary{edges}
\forestapplylibrarydefaults{edges}

\begin{document}

\begin{forest}
    forked edges,
    for tree={grow'=east}
    [R
      [1 [a] [b]]
      [2 [c] [d]]
      [3 [e] [f]]
      [4 [g] [h]]
      [5 [i] [j]]
      [6 [k] [l]]]
\end{forest}

\end{document}

The result:

Output of MWE

What I would want is for the children 4, 5, and 6 of R to move over to the left side. So that I would have 3-3 children on each side. Is there a way to do this without hacking the position of child node 3 using before ... options? I would like the left side to be symmetrical.

1 Answer 1

4

Update 2:

A more general solution that wraps this up into a new option called multiple directions, which requires no manual placing of nodes can be found here.

Updated Solution:

After thinking about this some more, I realized that this can be done with no manual tweaking by placing two empty children of R at the root using before computing xy={l=0,s=0} and setting the grow direction of their subtrees. This can be placed into the main for tree using if level=1{<do this>}{<else do this>}

enter image description here

Here is the code:

\documentclass{article}

\usepackage{forest}
\useforestlibrary{edges}

\begin{document}

\begin{forest}
    for tree={forked edge, minimum height=3.7ex, minimum width=1em, anchor=center,
    if level=1{no edge, before computing xy={l=0,s=0}}{}}
    [R, 
      [, for tree={grow'=east}
        [1 [a] [b]]
        [2 [c] [d]]
        [3 [e] [f]]]
      [, for tree={grow=west}
        [4 [g] [h]]
        [5 [i] [j]]
        [6 [k] [l]]]]
\end{forest}

\end{document}

Old Solution:

Unfortunately, forest isn't designed to have subtrees grow in different directions. There has to be some manual tweaking to make it work. You need the 1, 2, 3 nodes to have a different parent than the 4, 5, 6 nodes. So give the R node two empty children, one that grows west and one that grow's east, and set the s sep to 0. Note that you need to set grow'=south for the R node so that the second subtree (4,5,6) is on the left and the first (1,2,3) is on the right.

Then adjust the position of the R node by lowering it into position with y-=3cm. To get the nodes in the left subtree aligned with the nodes on the right, all nodes must be the same height, so add minimum height=3.5ex to each node.

enter image description here

\documentclass{article}

\usepackage{forest}
\useforestlibrary{edges}

\begin{document}

\begin{forest}
    grow'=south, for tree={forked edge, minimum height=3.7ex,anchor=center}
    [R, s sep=0cm, before drawing tree={y-=3cm}
      [, for tree={grow'=east}, no edge
        [1 [a] [b]]
        [2 [c] [d]]
        [3 [e] [f]]]
      [, for tree={grow=west}, no edge
        [4 [g] [h]]
        [5 [i] [j]]
        [6 [k] [l]]]]
\end{forest}

\end{document}
5
  • Thank you. Your post answers my question, but this has the unpleasant side effect of the tree root R not being in the center vertically (not in line with children 5 and 2). It is frustrating, but it seems that I would be better off drawing this tree (which is more like a mind map) by hand, placing nodes and edges.
    – bp99
    May 3 at 14:38
  • 1
    @bp99: I edited my response. You just need to add anchor=center to the for tree. I also increased the minimum height to 3.7ex to make sure there is enough space in the node for the j, or any text that dips below the baseline.
    – Sandy G
    May 3 at 15:19
  • 1
    @bp99: I updated my solution (again). It's much simpler and more flexible now, and requires no manual placement of any nodes.
    – Sandy G
    May 4 at 20:50
  • Very nice, thanks!
    – bp99
    May 5 at 14:55
  • 1
    @bp99: Also, take a look at this solution, which automates the whole process.
    – Sandy G
    May 5 at 14:58

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.