2

I am trying to create a tree using the forest package, where the leaf nodes are all on the same tier.

However, the lines linking higher up nodes clip through other nodes. Is there any way to prevent this with this package?

Here is the relevant code snippet:

\begin{forest}    
    where n children=0{tier=word}{}    
    [equation, %for tree={parent anchor=south, child anchor=north}    
        [VARIABLE[y]]    
        [{=}]    
        [expression    
            [additionOrSubtraction    
                [multiplicationOrDivision    
                    [atom[VARIABLE[x]]]    
                ]    
                [{*}]    
                [atom    
                    [{(}]    
                    [expression    
                        [additionOrSubtraction    
                            [multiplicationOrDivision    
                                [atom[INTEGER[2]]]    
                            ]    
                            [{+}]    
                            [multiplicationOrDivision    
                                [atom[INTEGER[3]]]    
                                [{*}]    
                                [atom[VARIABLE[x]]]    
                            ]    
                        ]    
                    ]    
                    [{)}]    
                ]    
            ]    
        ]    
    ]        
\end{forest}

And here is an image of it: And here is an image of the problem

  • Please can you make your code compilable? – cfr Nov 18 '16 at 23:50
2

I first set the paths to use orthogonal edges (described in the edge path section, page 33 of the forest manual. Theoretically it would also be possible to use curved paths, but I think this would take exponentially more time.

Next, I enlarged the distance between children by increasing the s sep value (described on page 32 in the manual) on a case-by-case basis. On some levels, 10mm were sufficient, but in others, 20mm were necessary.

I was unsure whether you would replace the "multiplicationOrDivision" and similar strings with maybe symbols or icons (which I would recommend - or allow line breaks within these strings), so I did just a quick approximation of the distances. Of course for publication means they would still need to be fine tuned.

Unfortunately, the image has grown a little in size. Maybe a sidewaysfigure or a \resizebox could fit it to the context you need?

Result:Koltak's tree

Code:

 \documentclass{standalone}
\usepackage{forest}
\begin{document}
\begin{forest}for tree={% 
    edge path={\noexpand\path[\forestoption{edge}] (!u.parent anchor) -- +(0,-\baselineskip) -| (.child anchor)\forestoption{edge label};}},
    where n children=0{tier=word}{}    
    [equation, s sep=15mm %for tree={parent anchor=south, child anchor=north}    
        [VARIABLE[y]]    
        [{=}]    
        [expression    
            [additionOrSubtraction, s sep=20mm
                [multiplicationOrDivision
                    [atom[VARIABLE[x]]]    
                ]    
                [{*}]    
                [atom, s sep=20mm
                    [{(}]    
                    [expression    
                        [additionOrSubtraction, s sep=20mm
                            [multiplicationOrDivision    
                                [atom[INTEGER[2]]]    
                            ]    
                            [{+}]    
                            [multiplicationOrDivision, s sep=10mm  
                                [atom[INTEGER[3]]]    
                                [{*}]    
                                [atom[VARIABLE[x]]]    
                            ]    
                        ]    
                    ]    
                    [{)}]    
                ]    
            ]    
        ]    
    ]        
\end{forest}
\end{document}
  • Thank you, this looks great! I guess, I will fiddle around how shortening the longer strings will affect my other examples, but your answer is a great start! :) – Koltak Nov 18 '16 at 17:51
  • 1
    forked edges from the edges library would make this easier. (cc. @Koltak) – cfr Nov 18 '16 at 23:51
1

If squared edges are acceptable, they will probably make the neatest tree, as suggests.

However, there is no need to configure this manually as current Forest provides forked edges in its edges library.

\usepackage[edges,linguistics]{forest}

and in the tree's preamble

  forked edges,

I would also recommend fit=band which avoids the need to shift things around manually or figure out the right dimensions by trial-and-error.

  for tree={%
    fit=band,
  },

Setting inner xsep=0pt for all nodes bar the last tier may also help.

  where n children=0{%
    tier=word,
  }{%
    inner xsep=0pt,
  },

I've also split the ...Or... into multiline nodes. I don't know if this is acceptable for your use or not, but it does make for a more manageable diagram.

I recommend setting up a couple of macros: one for addition/subtraction and one for multiplication/division. This will allow you to experiment with different options by simply modifying the common macro definitions in the preamble.

For example:

\newcommand*\multordiv{Multiplication\\or\\Division}
\newcommand*\addorsub{Addition\\or\\Subtraction}

and something for the asterisks - should these be centred rather than at the top? You might want to consider using maths mode for the last tier of nodes.

\newcommand*\asthere{\textasteriskcentered}

Then the tree specification

  [equation
    [VARIABLE[y]]
    [{=}]
    [expression
      [\addorsub
        [\multordiv
          [atom
            [VARIABLE
              [x]
            ]
          ]
        ]
        [\asthere]
        [atom
          [{(}]
          [expression
            [\addorsub
              [\multordiv
                [atom
                  [INTEGER
                    [2]
                  ]
                ]
              ]
              [{+}]
              [\multordiv
                [atom
                  [INTEGER
                    [3]
                  ]
                ]
                [\asthere]
                [atom
                  [VARIABLE
                    [x]
                  ]
                ]
              ]
            ]
          ]
          [{)}]
        ]
      ]
    ]
  ]

produces something reasonably neat and, if not quite compact, at least much more contained.

more contained tree

Complete code:

\documentclass[border=5pt,tikz,multi]{standalone}
\usepackage[edges,linguistics]{forest}
\newcommand*\multordiv{Multiplication\\or\\Division}
\newcommand*\addorsub{Addition\\or\\Subtraction}
\newcommand*\asthere{\textasteriskcentered}
\begin{document}
\begin{forest}
  where n children=0{%
    tier=word,
  }{%
    inner xsep=0pt,
  },
  for tree={%
    fit=band,
  },
  forked edges,
  [equation
    [VARIABLE[y]]
    [{=}]
    [expression
      [\addorsub
        [\multordiv
          [atom
            [VARIABLE
              [x]
            ]
          ]
        ]
        [\asthere]
        [atom
          [{(}]
          [expression
            [\addorsub
              [\multordiv
                [atom
                  [INTEGER
                    [2]
                  ]
                ]
              ]
              [{+}]
              [\multordiv
                [atom
                  [INTEGER
                    [3]
                  ]
                ]
                [\asthere]
                [atom
                  [VARIABLE
                    [x]
                  ]
                ]
              ]
            ]
          ]
          [{)}]
        ]
      ]
    ]
  ]
\end{forest}
\end{document}

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.