3

I want to label single edges and branching ones with some style: enter image description here

For example, instead of

edge label={node[right,midway,font=\scriptsize]{9}}

I want to have \labelA[right]{\scriptsize}{9} and instead of

node options={label={[label distance=7pt,font=\scriptsize]-90:0}}

\labelB[7pt]{\scriptsize}{0}

I tried example in the package about decision tree but I did not get it completely and I do not want to commit to decision trees.

MWE:

\documentclass[10pt,a4paper]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{forest}
\begin{document}

\begin{forest}
%  decision edge label/.style n args=3{
%    edge label/.expanded={node[midway,auto=#1,anchor=#2,\forestoption{elo}]{\strut$\unexpanded{#3}$}}
%  },
for tree={  align=center, 
            parent anchor=south, 
            child anchor=north, 
            l sep=10mm,
            s sep=10mm}         
[A\\B\rule{0mm}{4mm}
 ,baseline
 [C\\D
  ,edge label={node[right,midway,font=\scriptsize]{9}}
  ,node options={label={[label distance=7pt,font=\scriptsize]-90:0}}
  [E
   [F
    ,edge label={node[left,midway,font=\scriptsize]{3}}
   ]
  ]
  [M
   [P
    ,edge label={node[left,midway,font=\scriptsize]{1}} 
   ]
  ]
 ]
]  
\end{forest}

\end{document}
4
  • What are \labelA and \labelB?
    – user30471
    May 10, 2016 at 20:18
  • Doing it with a macro is not the best approach. A custom style is a better option.
    – cfr
    May 10, 2016 at 22:37
  • @Andrew those are assumed to be undefined macros that I would like to have in order to emulate more lengthy script. May 10, 2016 at 22:57
  • @cfr I see your point. I tried some possibilities borrowed from tex.stackexchange.com/questions/278171/… but I couldn't make it work. I could not realize your comment there. It seems unclear for me how to modify only and all of those nodes that are in the label of edges. May 10, 2016 at 23:02

1 Answer 1

4

Note first that node options is rarely needed.

label={[label distance=7pt,font=\scriptsize]-90:0} 

is equivalent. You would only need node options here if you wanted multiple labels.

A macro is not, I think, the best way to do this. In particular, a macro with a standard optional argument of the kind you have in mind is definitely not going to work because the square brackets will confuse the parser, so you'd at least have to protect them.

But there's a more basic issue. Where, exactly, would \labelA or \labelB go? Consider

[node text \labelA...
]

Here the label specification will be parsed as part of the contents of the node. Forest won't mind this, but it won't give the result you want so that's not much use.

Alternatively

[node text, \labelA...
]

Here, \labelA... will be read as a key-value option, which it isn't. Forest will not be at all happy. Nor will TikZ, which Forest will try passing the buck to if it manages to parse things at all.

The only remaining spot is

[node text
]\labelA...

which will result in the macro being entirely ignored, I think.

So even a simple macro, without an optional argument, is not going to work here.

Instead, you should use a custom style as the example you cited suggests. However, you don't need anything as complex as the style the manual gives because you are not trying to automate the customisation or the placement and/or content of the labels.

You probably want something like the following.

We define 2 styles, labelA and labelB. Each takes 3 arguments.

  • \labelA={<direction>}{<font>}{<content>} creates an edge label given by the <direction> (e.g. left, right) in the relevant <font> (e.g. \scriptsize, \sffamily) containing the specified <content> (e.g. 9, exotic paper towels).

  • labelB={<distance>}{<font>}{<content>} creates a label underneath the main node at a distance of <distance> (e.g. 7pt, 3mm) in the relevant <font> (e.g. \large, \bfseries) containing the specified <content> (e.g. 0, tranquil Malteasers).

For example,

    labelA={right}{\scriptsize}{9},
    labelB={7pt}{\scriptsize}{0},

recreates the labels in the original example for the C\\D node.

labels with styles

Coode:

\documentclass[tikz, border=5pt, multi]{standalone}
\usepackage{forest}
\begin{document}
\begin{forest}
  labelA/.style n args=3{%
    edge label/.expanded={%
      node [midway, auto=#1, font=\unexpanded{#2}] {#3}%
    },
  },
  labelB/.style n args=3{%
    label={%
      [label distance=#1, font=\unexpanded{#2}]-90:{#3}%
    },
  },
  for tree={
    align=center,
    parent anchor=children,
    child anchor=parent,
    l sep'=10mm,
    s sep'=10mm,
  }
  [A\\B\rule{0mm}{4mm},
   baseline
   [C\\D,
    labelA={right}{\scriptsize}{9},
    labelB={7pt}{\scriptsize}{0},
    [E
     [F,
       labelA={left}{\scriptsize}{3}
     ]
    ]
    [M
     [P,
       labelA={left}{\scriptsize}{1}
     ]
    ]
   ]
  ]
\end{forest}
\end{document}
3
  • Thanks, one of the best answers! The macro issue was very clear and detailed. May 12, 2016 at 1:26
  • if I change the current example as:labelA/.style n args=1{%...auto=right, font=\unexpanded{\scriptsize}] {#1}%.. and use labelA={lab}, it prints only the first letter; labelA={$lab$} even causes an error. May 12, 2016 at 13:22
  • Just use font=\scriptsize in that case and labelA/.style={....
    – cfr
    May 12, 2016 at 20:30

You must log in to answer this question.

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