1

These days I'm typesetting a lot of trees (in the graph-theoretic sense) using pst-jtree, which is essentially a collection of macros over pstricks. So, I might have the following.

\jtree
   \! = {A}! .
   \! = <left>[xunit=5em]{B}!b ^<right>[xunit=5em]{E}!c .
   \!b = : {m} {C} : {n} {D} : {o} {p} .
   \!c = : {q} {F} : {r} {G} : {s} {t} .
\endjtree

enter image description here

These are the easy cases. Sometimes I need to draw a vertex between nodes that are some distance apart. I usually do it with \nccurve, which is neat in the sense that I can use @ labels (or alternatively \rnode) to define the start-end points of a Bezier curve, and then manipulate it with angleA, angleB, and ncurv.

\jtree
   \! = {A}! .
   \! = <left>[xunit=5em]{B}!b ^<right>[xunit=5em]{E}!c .
   \!b = : {m} {C} : {n} {D}@D !d .
   \!c = : {q} {F} : {r} {G} : {s} {t}@t .
   \!d = <left>{o} .
\endjtree
\nccurve[angleA=-45,angleB=90,ncurvA=1.2,ncurvB=1.6]{-}{D:b}{t:t}

enter image description here

However, when trees get to a certain level of complexity, I want to have more control over my curves than I can get with \nccurve (for example, with \nccurve sometimes I have to choose between a curve that crosses over node labels (ugh) or one that has really tight and long arcs (ugh again)).

To me, the obvious solution is to use tikz to define a set of n points and then have it draw a smoothed curve over it.

\begin{tikzpicture}
   \draw plot [smooth,tension=1] coordinates { (0,0) (1,1) (2,-2) (3,0)};
\end{tikzpicture}

enter image description here

However, I don't know how to combine these two strategies. The main problem is that (as far as I know) \draw requires me to define (x,y) coordinates, rather than referring to @ or \rnode labels. Is there a way around this? Specifically, I want to be able to write something like

\begin{tikzpicture}
    \draw plot [smooth,tension=1] coordinates { (D:b) (1,1) (2,-2) (t:t)};
\end{tikzpicture}

The idea being that (0,0) is set to the bottom of the D label, (t:t) is set whatever (x,y) coordinate relative to (0,0), and then (1,1) and (2,-2) are set relative to (0,0), as usual.

Alan Munn
  • 218,180
Koldito
  • 913
  • The first step would be to switch from pstricks to tikz-qtree. Then you might be able to use tikz coordinates from the tree. – John Kormylo Oct 08 '15 at 15:17
  • Or forest. If you are typesetting complex trees, forest is more powerful than tikz-qtree, as I understand it. Both give you the full power of TikZ but forest allows you to manipulate the tree in various ways, to use relative nodes names and node walks etc. – cfr Oct 09 '15 at 01:47

1 Answers1

2

If you use forest, you can draw the curve by specifying it as part of the tree. Here, I use the current node's parent anchor ((.parent anchor)) as a value for shift so that the coordinates for the plot can be specified relative to that anchor. I then use the child anchor of a named node, t ((t.child anchor)) to specify the end point for the curve.

\documentclass[tikz,border=20pt]{standalone}
\usepackage{forest}
\begin{document}
\newlength\myex
\settoheight{\myex}{X}
\begin{forest}
  for tree={
    parent anchor=south,
    child anchor=north,
    anchor=mid,
    text height=\myex,
    tier/.wrap pgfmath arg={tier #1}{level()},
    s sep+=15pt,
  }
  [A
    [B
      [m]
      [C
        [n]
        [D, tikz={
          \draw [shift=(.parent anchor)] plot [smooth,tension=1] coordinates { (0,0) +(1.25,-.5) +(2.5,1) (t.child anchor)};
        }
          [o]
          [,phantom]
        ]
      ]
    ]
    [E
      [q]
      [F
        [r]
        [G
          [s]
          [t, name=t]
        ]
      ]
    ]
  ]
\end{forest}
\end{document}

plotted curve in <code>forest</code> tree

The manual for forest is good but a little intense at times. A brief introduction can be found in the second part of my answer to a related question. This explains how to specify a tree using the bracket notation and introduces some basic features of the package.

cfr
  • 198,882