4

How can I increase the length of the edges in a forest tree so that they are (at least) the length of the edge label that I wish to give them.

For example, this code:

\documentclass{article}
\usepackage{forest}
\forestset{ew edges/.style={for tree={parent anchor = east, child anchor = west, grow' = east}}}
\begin{document}
\begin{forest} ew edges
    [96
        [48, edge label = {node [midway, above, sloped] {matched place} }]
        [48, edge label = {node [midway, below, sloped] {unmatched place} }]
    ]
\end{forest}
\end{document}

produces the following tree

enter image description here

How can I make the edges (at least) the length of "unmatched place" so that there isn't such overlap?

5
  • 1
    Easiest is probably to adjust the l sep and/or s sep so that the children are spaced further from the parent/siblings. Not sure if I've really understood what you want to do, though.
    – cfr
    Jan 6 '15 at 17:57
  • @cfr That's true (and if you want to add that as an answer, that sounds great), but I was honestly hoping for some automagical way of doing things. Though perhaps that will be more of a pain than it's worth.
    – Adam Liter
    Jan 6 '15 at 17:59
  • Note that the manual says 'The packing mechanism is not sensitive to edge labels.' on page 33.
    – cfr
    Jan 6 '15 at 21:37
  • @cfr Ah, I hadn't seen that. That's unfortunate. Hmm, maybe there is a way with tikz-qtree?
    – Adam Liter
    Jan 6 '15 at 21:41
  • I've never used tikz-qtree although I did used to use qtree. Not sure whether either would do better? If your labels are not terribly long, you can calculate the distance and adjust things using forest...
    – cfr
    Jan 6 '15 at 22:49
7

The packing system does not take account of edge labels, as explained on page 33. So the simplest way to do this is to adjust the minimum distance between levels (l sep) and/or the minimum distance between siblings (s sep) by hand.

For example, adding s sep+=50pt and l sep+=50pt to an expanded style, ew edges new, produces the following tree:

adjusted tree

Alternatively, it is possible to override the packing mechanism's decisions. To do this, you need to make adjustments after the packing stage but before the final positions are calculated. This can be done, for example, using before computing xy. Using a new style my edge label to adjust the distance between levels, for example, you can obtain a tree such as this:

auto-adjusted levels

This does require you to specify the edge label in a different way. Rather than specifying it using edge label directly, you need to use my edge label. (Obviously, you can use a different name - but you can't use edge label.) This is necessary because the new style manipulates the label to measure its width. This is then used to calculate an appropriate distance between the levels using Pythagoras' theorem.

Note that this second method cannot deal with labels which are too long because the dimensions involved in the calculation become too great. If you need to accommodate really long labels, you should probably adjust the calculation to minimise the sizes of the dimensions involved.

\documentclass[border=5pt, tikz, multi, varwidth]{standalone}
\usepackage{forest}
\standaloneenv{forest}
\begin{document}
\forestset{
  ew edges new/.style={
    for tree={
      parent anchor = east,
      child anchor = west,
      grow' = east,
      s sep+=50pt,
      l sep+=50pt
    }
  },
  ew edges/.style={
    for tree={
      parent anchor = east,
      child anchor = west,
      grow' = east,
    }
  },
  my edge label/.style={
    if={n>.5*(n_children("!u"))}{
      edge label = {node [midway, below, sloped] {#1}},
    }{
      edge label = {node [midway, above, sloped] {#1}},
    },
    TeX={\settowidth{\mylabelwidth}{#1}},
    before computing xy={
      if={
        (l)<(sqrt((\mylabelwidth)^2 - s^2) + 10pt)
      }{
        l={sqrt((\mylabelwidth)^2 - s^2) + 10pt},
      }{},
    },
  },
}
\newlength{\mylabelwidth}
\begin{forest}
  ew edges new
    [96
      [48, edge label = {node [midway, above, sloped] {matched place} }
        ]
        [48, edge label = {node [midway, below, sloped] {unmatched place} }
        ]
    ]
\end{forest}
\begin{forest}
  ew edges
    [96
        [48, my edge label = matched place
        ]
        [48, my edge label = unmatched place
        ]
    ]
\end{forest}
\end{document}
1
  • Thanks! This is a great answer. :)
    – Adam Liter
    Jan 7 '15 at 4:04

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.