Random Tree Generators¶
The .rtree subpackage allows the user to quickly generate random topologies in a variety of methods.
Simple rtree¶
The function rtree.rtree()
is the fastest method provided to generate a random topology, and works by iteratively bifurcating a random tip (starting from a single root) until there are the desired number of tips provided by the ntips=
argument.
import toytree
random_tree = toytree.rtree.rtree(ntips=10)
random_tree.draw('s');
Note: by default, the tips are ordered by name value as seen above. This can be changed using the setting random_names=True
toytree.rtree.rtree(ntips=10, random_names=True).draw('s');
Additionally, reproduceable results can be attained using an rng seed as shown below.
toytree.rtree.rtree(ntips=10, seed=123).draw('s');
toytree.rtree.rtree(ntips=10, seed=123).draw('s');
Unit rtree¶
This variation, rtree.unittree()
, generates an ultrametric tree where all internal edges are of equal distance. External edges are extended to make the tree ultrametric. The total tree height can be scaled to any arbitrary height, and other Nodes are scaled proportionately.
unit_tree = toytree.rtree.unittree(10)
unit_tree.draw(scale_bar=True, ts='s', node_hover=True);
Imbalanced rtree¶
One extreme possibility for a topography is a fully imbalanced tree, generated using rtree.imbtree()
, in which each internal node has one child bifurcating and one child that is a tip. This creates a ladder-like shape as seen below.
unit_tree = toytree.rtree.imbtree(10)
unit_tree.draw(scale_bar=True, ts='s', node_hover=True);
Balanced rtree¶
Conversely, the other extreme topographical possibility is that of a completely balanced tree. rtree.baltree()
generates a balanced tree, so the only real random part of this generator is the tip names if random_names = True
. The number of tips must be even to generate a fully balanced tree.
unit_tree = toytree.rtree.baltree(20, random_names=True)
unit_tree.draw(scale_bar=True, ts='s', node_hover=True);
Birth/death rtree¶
The function rtree.bdtree()
generates a parametric birth/death tree. This means that birth or death events are randomly sampled beginning with a single ancestor until a stopping criterion is reached (either stop='taxa'
or stop='time'
). If the tree goes extinct, it is restarted. The waiting time to the next speciation event is exponential with rate equal to the parameter b=
, and the same goes for extinction events with parameter d=
. The events do not happen in parallel, so the waiting type for the next event regardless of type is exponential with rate $b+d$, and the probability that it is a speciation event is $\frac{b}{b+d}$ and the probability that it is an extinction event is $\frac{d}{b+d}$
tree = toytree.rtree.bdtree(ntips=40, b=1.0, d=0.5, verbose=True)
tree.draw('c');
time 7.863758 ntips 40.000000 b 74.000000 d 35.000000 b/d 1.472973 resets 0.000000 dtype: float64
Coalescent rtree¶
Finally, the function rtree.coaltree()
generates a random ToyTree under the n-coalescent model. Waiting times between coalescent events under this model follow the distribution:
$$
\frac{4N}{k*(k-1)}
$$
Where $k$ is the number of samples at present time and $N$ is the diploid effective population size $N_e$
A tree is constructed by randomly sampling waiting times from an exponential distribution at each value of k from k to 1, and randomly joining Nodes at each coalescent interval. Note that the expected root height is $4N$.
The number of tips (usually ntips) is given by k=
, which represents the number of samples at present time, and the diploid effective population size is given by N=
.
tree = toytree.rtree.coaltree(k=40, N=10)
tree.draw('c');