3

Consider the following example that simulate the desired output:

mwe

\documentclass{article}
\usepackage[edges]{forest}
\begin{document}
\footnotesize\sffamily one~~~~~~~~two~~~~~~~~~~~~~~three~~~~~~~~~~~~~~four
\bigskip
\begin{forest}
forked edges, for tree={grow=0,  s sep=0pt, edge=thick,  anchor=base west,  font=\strut\footnotesize\sffamily}
[aaaa [bbb [eeeeeeeeeeee, tier=x, [fff]]] [ccc [gg, tier=x] [hhh, tier=x]] [ddddddddd [iii, tier=x]]]
\end{forest}
\end{document}

How make the level labels ("one","two",etc.) a true part of the forest diagram?

Of course, the labels must be automatically aligned with the tree nodes automatically, i.e., as do the tier option within the tree nodes.

This question seem very similar to Creating level labels for (horizontal) tikz trees, but the solution must be using forest at least to make the tree.

3 Answers 3

3

I define two new styles:

  • label tree tells Forest this tree should have labelled levels (if labels are provided);
  • level label=<label> sets the label for the current level to <label>.

Then

\begin{forest}
  label tree,
  ...
  [aaaa, level label=one [bbb, level label=two [eeeeeeeeeeee [fff, level label=four]]] [ccc [gg, level label=three] [hhh]] [ddddddddd [iii]]]
\end{forest}

produces

labelled tree

Complete code:

\documentclass[border=9pt]{standalone}     
\usepackage[edges]{forest}
\forestset{%
  label tree/.style={
    for tree={tier/.option=level},
    level label/.style={
      before typesetting nodes={
        for nodewalk={current,tempcounta/.option=level,group={root,tree breadth-first},ancestors}{if={>OR={level}{tempcounta}}{before drawing tree={label me=##1}}{}},
      }
    },
    before drawing tree={
      tikz+={\coordinate (a) at (current bounding box.north);},
    },
  },
  label me/.style={tikz+={\node [anchor=base west] at (.parent |- a) {#1};}},
}
\begin{document}
\begin{forest}
  forked edges,
  label tree,
  for tree={
    grow=0,  
    s sep'=0pt, 
    edge+=thick,  
    anchor=base west, 
    font=\strut\footnotesize\sffamily,
  },
  [aaaa, level label=one [bbb, level label=two [eeeeeeeeeeee [fff, level label=four]]] [ccc [gg, level label=three] [hhh]] [ddddddddd [iii]]]
\end{forest}
\end{document}

labelled tree

1
  • Nice solution too !
    – Fran
    Oct 12, 2019 at 19:14
2

This a first version of some code that does something like this. It gives each node an alias according to the level. (This alias gets overwritten but this does not matter as long as all nodes of the same level have west anchors with the same horizontal coordinate; for extensions one may want to make them distinguishable.) These nodes are used to indicate the level.

\documentclass{article}
\usepackage[edges]{forest}
\newcommand\engnum[1]{\ifcase#1
zero
\or
one
\or 
two
\or
three
\or
four
\or
five
\or
six
\or
seven
\or
eight
\or
nine
\fi}
\begin{document}
\begin{forest}
forked edges, for tree={grow=0,  s sep=0pt, edge=thick,  
anchor=base west,  font=\strut\footnotesize\sffamily,
alias/.wrap pgfmath arg={l-#1}{level}}
[aaaa [bbb [eeeeeeeeeeee, tier=x, [fff]]] [ccc [gg, tier=x] [hhh, tier=x]] [ddddddddd [iii, tier=x]]]
\path ([yshift=0.5ex]current bounding box.north) coordinate (N);
% 0.5ex can be changed to increase/decreas the vertical distance between the
% level indicators and the tree
\foreach \X  in {0,...,3}
{\node[anchor=south west,font=\strut\footnotesize\sffamily] at 
(l-\X.west|-N){\engnum{\the\numexpr\X+1}};}
\end{forest}
\end{document}

enter image description here

There are many ways in which one may extend this, which of them I will add, if any, depends on your input. ;-)

1
  • Nice. The only problem is that, although I can understand what it does, I will not remember that evil syntax when needed, but that's what the copy & paste is for :)
    – Fran
    Oct 11, 2019 at 6:11
2

Solutions of Schrödinger's cat and cfr worked for the MWE, but I faced problems with these approaches in more complex threes.

Fortunately, I have realized that a much simpler and apparently robust way is to make the root of the tree with a phantom node, so its branches are showed as independent trees, e.g.:

mwe2

[,phantom [A[B][C]][D[E][F]]]  

Now is possible to align the nodes of the two trees just using tier, because really are only parts of the same tree.

Then, for making the header labels is enough (1) add a ghostly root (2) add labels as a last branch [,phantom [...] [One[Two[Three[Four]]]]], (3) change the style of this branch (remove edges, etc.) and (4) finally, if needed, align nodes with tier:

mwe

\documentclass[tikz,border=10pt]{standalone}
\usepackage[edges]{forest}
\begin{document}
\begin{forest}                      
                                    %
forked edges,                       % Tree style 
for tree={grow=0, s sep=0pt, 
edge= thick,  
anchor=base west,  
font=\strut\footnotesize\sffamily},
                                    %
[,phantom                           % Paranormal root  (BOO!)
                                    %  
[aaaa                               % Real branch   
    [bbb,tier=b, 
        [eeeeeeeeeeee, tier=c 
            [fff, tier=d]]] 
    [ccc 
        [gg, tier=c] 
        [hhh, tier=c]] 
    [ddddddddd 
        [iii, tier=c]]]                          
                                    %
[One,for tree={color=gray,no edge}  % Ethereal branch 
[Two, tier=b                            
[Three,  tier=c                       
[Four, tier=d]]]]                   
                                    %  
]                                   % Closing poltergeist
                                    %
\end{forest}
\end{document}
3
  • Yes, this is the approach prooftrees uses, for example, to get line numbers and justifiecations aligned.
    – cfr
    Nov 10, 2019 at 3:37
  • @cfr Nice package. It could have been a solution too, but in my case the nodes will be long scientific names, and usually with several branches, so that the tree has grow horizontally, even when I need to turn 90º first levels to fit to the width of the page.
    – Fran
    Nov 10, 2019 at 10:57
  • No, prooftrees couldn't be a solution here. I just meant the method is the same.
    – cfr
    Nov 10, 2019 at 20:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .