# tikz curves with labeled nodes as start and end points

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


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}


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}


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.

• 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 8 '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 9 '15 at 1:47

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}


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.