summaryrefslogtreecommitdiff
path: root/usergrps/uktug/baskervi/6_3/trees.tex
blob: cb9f5ae40cc5e5a9f32099f4d9bcc08f45faa69c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
\catcode`\_=8 \catcode`\<=13
\def\CurrentPackages{spqr,pstcol}
\newcounter{myN}
\setlongtables
\author[Sebastian Rahtz]{Sebastian Rahtz\\Elsevier Science Ltd\\
Email: \texttt{s.rahtz@elsevier.co.uk}}
\title{An introduction to PSTricks, part 3}
\begin{Article}
%\section{Introduction}
%%\begin{multicols}{2}
\section{Tree diagrams}
\PST\ has an extremely rich environment for drawing trees, which
allows for very complex structures and presentation. The available
commands are listed in Table~\ref{PSTtree} and the graphical
parameters which apply especially to these are listed in
Table~\ref{PSTtreeparms}. As one might expect, most other commands and
parameters  are also available, from both the generalized drawing, and
the node connectors and labels. Each of the node types described
earlier is turned into a `tree' node, and named by prefixing it with a
`T' and removing the `node' suffix.

%\end{multicols}

\begin{small}
\begin{longtable}{lH{.5\textwidth}}
\caption{\protect\PST\ tree drawing commands\label{PSTtree}}\\
\hline
\endfirsthead
\multicolumn{2}{l}{\protect\PST\ tree drawing commands \emph{cont.}}\\
\hline
\endhead
\PSTCom \pstree{node}{subtrees}
& draws a node and subtrees connected to it\\
\PSTCom \psTree{rootnode} subtrees
%\endpsTree
& an `environment' form of \Lcs{psTree}\\
\PSTCom \Tn
& null tree node \\
\PSTCom \tspace{dim}
& leave gap of \emph{dim} before next level\\
\PSTComOpt \TC
& tree node like \Lcs{Cnode} node\\
\PSTComOpt \TR{something}
& tree node like \Lcs{Rnode} node\\
\PSTComOpt \Tcircle{something}
& tree node like \Lcs{circlenode} node\\
\PSTComOpt \Tc{dim}
& tree node like \Lcs{cnode} node\\
\PSTComOpt \Tdia{something}
& tree node like \Lcs{dianode} node\\
\PSTComOpt \Tdot
& tree node like \Lcs{dotnode} node\\
\PSTComOpt \Tf
& tree node like \Lcs{fnode} node\\
\PSTComOpt \Tfan
& draws a triangle with a top corner of the predecessor node\\
\PSTComOpt \Toval{something}
& tree node like \Lcs{ovalnode} node\\
\PSTComOpt \Tp
& tree node like \Lcs{pnode} node\\
\PSTComOpt \Tr{something}
& tree node like \Lcs{rnode} node\\
\PSTComOpt \Ttri{something}
& tree node like \Lcs{trinode} node\\
\PSTComOpt \skiplevel {nodes or subtrees}
& miss out entire levels in a particular subtree\\
\PSTComOpt \skiplevels{n} {nodes or subtrees}
& skip \emph{n} levels\\
\end{longtable}
\end{small}

\begin{small}
\begin{longtable}{llH{10cm}}
\caption{\protect\PST\ Graphical parameters for trees}
\label{PSTtreeparms}\\[1mm]
\emph{Parameter} & \emph{Default} & \emph{Explanation}\\
\hline
\endfirsthead
\protect\PST\ Graphical parameters for trees \emph{cont.}\\[1mm]
\emph{Parameter} & \emph{Default} & \emph{Explanation}\\
\hline
\endhead
\mbox{}\\
\endfoot
\Par{bbd=dim} ()
& set lower bounding box to \emph{dim}\\
\Par{bbh=dim} ()
& set upper bounding box to \emph{dim}\\
\Par{bbl=dim} ()
& set left bounding box to \emph{dim}\\
\Par{bbr=dim} ()
& set right bounding box to \emph{dim}\\
\Par{edge=command} (\ncline)
& the node connector used to join tree nodes\\
\Par{fansize=dim}   (1cm)
&size of base for \Lcs{Tfan} tree node\\
\Par{levelsep=*dim} (2cm)
& the distance between successive levels in a tree; the * makes the
dimension be \emph{in addition} to the size of the nodes (levels are
normally a fixed distance apart)\\
\Par{showbbox=true/false} (false)
& draw a dotted frame showing the enclosing rectangle of trees\\
\Par{thislevelsep=*dim} ()
& like \emph{levelsep} but applies only to the current tree\\
\Par{thistreefit=tight/loose} ()
& like \emph{treefit} but applies only to the current tree\\
\Par{thistreenodesize=dim} ()
& like \emph{treenodesize} but applies only to the current tree\\
\Par{thistreesep=dim} ()
& like \emph{treesep} but applies only to the current tree\\
\Par{tndepth=dim} ()
& the minimum depth of tree node labels\\
\Par{tnheight=dim} ()
& the minimum height of tree node labels\\
\Par{tnpos=l/r/a/b} (b)
& the position of tree node labels relative to the node (left, right,
above, below) \\
\Par{tnsep=dim} ()
& the gap between tree node labels and the node (by default the same as
\emph{labelsep} \\
\Par{treefit=tight/loose} (tight)
& if tight, \emph{treesep} is the minimum distance between nodes on any level; i
f loose, \emph{treesep} is the distance between the enclosing
bounding boxes of subtrees\\
\Par{treeflip=true/false} (false)
& does a mirror image of the free, flipping the nodes\\
\Par{treemode=R/L/U/D} (D)
& the direction of tree growth (right, left, up and down)\\
\Par{treenodes=dim} ($-$1pt)
& if positive, this sets a fixed size for tree nodes, regardless of content\\
\Par{treesep=dim} (0.75cm)
& the distance between successive nodes in a tree\\
\Par{xbbd=dim} ()
& increase lower bounding box by \emph{dim}\\
\Par{xbbh=dim} ()
& increase upper bounding box by \emph{dim}\\
\Par{xbbl=dim} ()
& increase left bounding box by \emph{dim}\\
\Par{xbbr=dim} ()
& increase right bounding box by \emph{dim}\\
\end{longtable}
\end{small}

%\begin{multicols}{2}
The fundamental concept in \PST\ trees is the \emph{nesting} of trees;
a simple tree  consists of a root, and one or more nodes:
\begin{example*}
\pstree{\TC}{\TC\TC}
\end{example*}
\noindent but each node can itself be a tree:
\begin{example*}
\pstree{\TC}{\pstree{\TC}{\TC \TC}
 \pstree{\TC}{\TC \TC}}
\end{example*}
This simple construct allows very complicated structures to be
erected, as the examples below show.

The following tree is a version of that shown in the \emph{\LaTeX\ Companion},
section 10.5.2, which was drawn using the \Lpack{ecltree} package; the
ease of notation is roughly similar. As often in \LaTeX, the
readability depends a great deal on how the code is laid out.  The
only change to the defaults is to lessen the vertical space between
trees, and add some extra space around nodes.
\begin{example*}
\pstree[nodesep=2pt,
  levelsep=20pt]{\TR{grandfather}}
{
 \pstree{\TR{uncle}}{\TR{cousin}}
 \pstree{\TR{father}}
   {
   \pstree{\TR{brother}}{\TR{nephew}}
   \pstree{\TR{Me}}
     {
      \pstree{\TR{son}}{\TR{grandson}}
     }
   }
}
\end{example*}

If we now consider another tree drawing package described in
the \emph{\LaTeX\ Companion}, Vanroose's \Lpack{trees}, the example in section
10.2.3 is a little harder to reproduce. The skeleton is trivial:
\begin{example*}
\pstree{\Tdot}
{
\Tdot
\pstree{\Tdot}
 {
 \pstree{\Tdot}
  {
   \Tdot
   \Tdot
   \Tdot
  }
  \Tdot
 }
}
\end{example*}

\noindent but when  we come to add in all the node and connector labels, and
change a few parameters to make the result nicer, the markup becomes a
little complex, though the quantity is roughly similar to that of Vanroose:

\begin{example*}
\psset{labelsep=2pt,tnpos=a,radius=2pt}
\pstree[treemode=R]{\TC*~{25}}
{
\TC*~{5}~[tnpos=r]{$L_a$}
\taput{$a$}
\pstree{\TC*~{20}\tbput{$b$}}
 {
 \pstree{\TC*~{15}\taput{$a$}}
  {
   \TC*~{7}~[tnpos=r]{$L_{baa}$}\taput{$a$}
   \TC*~{5}~[tnpos=r]{$L_{bab}$}\taput{$b$}
   \TC*~{3}~[tnpos=r]{$L_{bac}$}\tbput{$c$}
  }
  \TC*~{5}~[tnpos=r]{$L_{bb}$}
  \tbput{$b$}
 }
}
\end{example*}

The node connectors in a tree are created by running
the macro \Lcs{psedge} with the two nodes; the definition of
\Lcs{psedge} can be overridden explicitly by a redefinition, or by
using the \emph{edge} parameter. Here we redefine \Lcs{psedge} to be a
curve, arrange the angles (bearing in mind that the tree is to grow
upwards), and obtain a pleasing result. Note also the explicit links
between named nodes, as well as the regular connections.
%\end{multicols}

\noindent\hrule

\begin{example*}
\footnotesize
\def\psedge{\nccurve}
\newcommand{\Female}[2][]{\TR[#1]{\emph{#2}}}
\newcommand{\Male}[2][]{\TR[#1]{#2}}
\psset{nodesep=2pt,angleA=90,angleB=-90,unit=.6cm}
\pstree[treemode=U]{\Female{{\bfseries Matilde}}}{
 \pstree{\Male{Sebastian}}{
  \pstree{\Male[name=P]{Philip}}{\Male{Frederick}\Female{Ethel}}
  \pstree{\Female[name=W]{Mary}}{\Male{Lionel}\Female{Agnes}}}
 \pstree{\Female{Leonor}}{
  \pstree{\Male[name=R]{Ra\'ul}}{\Male{Joaquim}\Female{J\'ulia}}
  \pstree{\Female[name=A]{Am\'elia}}{\Male{Melo}\Female{Augusta}}}
}
\psset{doubleline=true,linestyle=dotted}
\ncline{P}{W}\nbput{1940}
\ncline{R}{A}\nbput{1950}
\end{example*}
%\begin{multicols}{2}
We said earlier that \PST\ does not always work out the extent of
objects correctly, and this is illustrated by the connectors in the
following example. Turning on \emph{showbbox}, we can see that without
the use of \emph{xbbl} etc in the second incarnation, the bounding box
is not correct:
\begin{example*}
\psset{angleB=-90,arrows=->,nrot=:U}
\def\molesworth#1{%
 \pstree[#1]{\Tdia{ }}
 {
  \Tp[arrows=->,edge={\ncbar[angleA=180]}]
  \nbput{Gabbitas}
  {\psset{linestyle=dashed,arrows=-} \Tp }
  \Tp[arrows=->,edge={\ncbar}]
  \naput{Thring}
 }
}
\psset{showbbox=true}
\begin{tabular}{l}
\molesworth{}\\[10pt]
\molesworth{xbbl=1cm,xbbr=1cm}
\end{tabular}
\end{example*}

The technique  of redefining edges is also necessary if we want
right-angled joins, rather than straight lines. Again, we need to take
care of the \emph{angleA} and \emph{angleB}, and ensure that in this
left-right tree the nodes all line up on their left edges, using the
\emph{ref} parameter. If this is not done, the \Lcs{ncangle} edges
produce strange results.
\begin{example*}
\def\Item#1{\Tr[ref=l]{%
 \psframebox[linestyle=none]{#1}}}
\def\psedge{\ncangle}
\psset{xbbd=1.5cm,treemode=R,
  angleB=-180,angleA=0,levelsep=72pt}
\pstree{\Item{langs}}{%
  \Item{german}
  \pstree{\Item{greek}}{%
    \Item{hamilton-kelly}
    \pstree{\Item{levy}}{%
      \Item{doc}
      \Item{src}
       }
    }
  \Item{italian}
  \pstree{\Item{portuguese}}{
    \Item{hyphenation}
   }
  \pstree{\Item{turkish}}{%
    \Item{doc}
    \Item{hyphen}
    \Item{inputs}
    \Item{mf}
    \Item{misc}
   }
\Item{xettex}
}
\end{example*}

This allows us to remake the small family again, but this time with
nicer connectors:
\begin{example*}
\def\XX#1{%
 \Tr{\psframebox{\rule{0pt}{9pt}#1}}%
}
\def\psedge{\ncangle}
\psset{angleB=90,angleA=-90,
   levelsep=36pt,armB=14pt}
\pstree{\XX{grandmother}}
{%
\pstree{\XX{aunt}}{\XX{cousin}}
\pstree{\XX{mother}}
   {
 \pstree{\XX{sister}}{\XX{niece}}
 \pstree{\XX{Me}}
    {
    \pstree{\XX{daughter}}
    {\XX{granddaughter}}
  }
 }
}
\end{example*}
The node connectors are, of course, standard \PST\ objects, so they
obey all the normal parameters; here we draw the lower part of the
tree with dashed lines, and each node content is set in math mode.
\begin{example*}
\footnotesize
\psset{nodesep=2pt}
\def\XX#1#2{%
 \TR{\ensuremath{#1_{\mbox{#2}}}}%
}
\pstree[xbbr=1.5cm]{\XX{R}{AMSU}}
 {
  \XX{S}{RawData}
  \pstree{\XX{S}{combine}
          \trput{\ensuremath{\oplus}}
          \tlput{\ensuremath{\oplus}}}
   {
   \psset{linestyle=dashed}
   \XX{R}{Modes}
   \XX{R}{Normal}
   \XX{R}{Vertical}
   \XX{R}{Latched}
   \XX{R}{Tripped}
   }
  \XX{S}{GenerateData}
 }
\end{example*}

If we want to hang distinct-looking trees off one node,
the \emph{ncangle} connector, with some offsets, produces the right result.
 \begin{example*}
\psset{framearc=.2,levelsep=4cm,
  armB=1cm,angleB=-180}
\def\psedge{\ncangle}
\def\TreeBox#1{\Tr{\psframebox{#1}}}
\pstree[treemode=R]{\TreeBox{Monitor}}
{
 \psset{offsetA=4pt}
 \TreeBox{Attitude Generator}
 \naput[npos=2.5]{{\small init}}
 \nbput[npos=2.5]{{\small stop}}
 \psset{offsetA=-4pt}
 \TreeBox{Normal Generator}
}
\end{example*}

With simple connectors, we do not need to worry about the offsets or
angles; what this example shows is how nested trees can change direction:

\begin{example*}
\psset{arrows=->,framearc=.2}
\def\Treebox#1{%
 \Tr{\psframebox{#1}}
}
\pstree[treemode=R]
{\Treebox{A$\rightarrow$B}}{
\pstree{
   \Treebox{B$\rightarrow$C}
         }{
 \Treebox{A$\rightarrow$D}
\pstree[treemode=L]
 {\Treebox{B$\rightarrow$E}}
 {\Tn\TC[arrows=<-]}
      }
}
\end{example*}

Finally, let us not forget the simple empty node:
\begin{example*}
\pstree{\Tp}{
 \Tcircle{A}
 \Tcircle{B}
}
\end{example*}
%\catcode`\<=12
\end{Article}