Consensus trees¶
import toytree
import numpy as np
Same topology, variable edge lengths, non-ultrametric trees¶
This is an example of a set of trees you might get as a result of running phylogenetic inference on a collection of different data sets for the same taxa using a non-clock model. A consensus tree approach provides a simple and fast way to compare trees by finding the most commonly supported clades, and their frequency. It may also be of interest to see the relative branch lengths which are stored in features like dist_mean
and dist_std
for each node. With this type of dataset you would most likely want to apply a species tree inference approach, such as ASTRAL, as a model-based approach of examining the agreement among trees.
# a single starting tree
tree = toytree.rtree.unittree(6, seed=123)
# create set of trees by randomly modifying root, internal, and tip edges
trees = [
tree
.mod.edges_set_node_heights({i: np.random.uniform(-0.2, 0) for i in range(tree.ntips)})
.mod.edges_multiplier(10)
.mod.edges_slider(0.1)
for i in range(20)
]
# create a multitree
mtree = toytree.mtree(trees)
# draw a few trees to examine variation
mtree.draw(ts='c', shared_axes=True, scale_bar=True);
# get consensus tree
ctree = mtree.get_consensus_tree()
# root the tree
# ctree = ctree.mod.root_on_midpoint()
ctree = ctree.root(8, root_dist=0.28)
# draw it
ctree.draw('p');
# add node bars to show std of node heights
# ...
<Node(idx=8)> 0.28418659898121107 0.5737607504385339 <Node(idx=8)> 0.2583728055227246 0.562271718955612 <Node(idx=8)> 0.20776634990990392 0.4417576575275013 <Node(idx=8)> 0.4966666903202328 0.9634437598395291 <Node(idx=8)> 0.2796030913115508 0.5440066126849977 <Node(idx=8)> 0.2209731809351428 0.4515257945911898 <Node(idx=8)> 0.3956792138033278 0.8500737537447055 <Node(idx=8)> 0.38938404955162453 0.8933688023632044 <Node(idx=8)> 0.2496431351720949 0.48560838839973897 <Node(idx=8)> 0.32479826910645115 0.642429483482034 <Node(idx=8)> 0.515842588816714 1.1002762107273165 <Node(idx=8)> 0.3205299499335021 0.6543663667441568 <Node(idx=8)> 0.4478923071928977 0.9368206321841088 <Node(idx=8)> 0.36392653442839135 0.7001000440964242 <Node(idx=8)> 0.40437951030086616 0.8180741068442078 <Node(idx=8)> 0.5482530379692488 1.029027637683661 <Node(idx=8)> 0.45342139503569173 0.8789492137708874 <Node(idx=8)> 0.5096151196401049 0.9989612640708907 <Node(idx=8)> 0.24484891580343765 0.5114797463792604 <Node(idx=8)> 0.24782437249402905 0.5478674408967885
c = mtree1.get_consensus_tree(ultrametric=0)
c = c.mod.root_on_midpoint()
c = c.set_node_data("height", {i: 0 for i in range(c.ntips)})
c = c.set_node_data("height", {i: c[i].height_mean for i in range(c.ntips, c.nnodes - 2)})
c = c.set_node_data("height", {c.treenode.idx: c[c.treenode.idx - 1].height_mean})
c = c.set_node_data("height", {c.treenode.idx - 1: c.treenode.height - c[c.treenode.idx - 2].dist})
# c = c.set_node_data("height", {5: 1.208333, 6: 1.250000, 7: 1.25 + 1.0}) # 0 for i in range(5)})
c.get_node_data()
mtree1[0].style.edge_colors = "red"
mtree1[0].style.edge_widths = 10
mtree1[0].style.edge_style.stroke_opacity = 1.0
mtree1[1].style.edge_style.stroke = "blue"
mtree1[1].style.edge_style.stroke_opacity = 1.0
cons.draw(axes=a, tip_labels=False, edge_colors="red", edge_type='b');
c
tree = toytree.rtree.unittree(ntips=20)
tree[0].name = "A-really-long-string-that-becomes-cutoff-on-pdf-exporting"
c, a, m1 = tree.draw(width=500);
c, a, m2 = tree.draw(width=500, shrink=500);
import toyplot.pdf
toyplot.pdf.render(c, "/tmp/longname.pdf")
canvas, axes, mark = tree.draw(width=500, tip_labels=False)
axes.text(
[0] * tree.ntips,
range(tree.ntips),
tree.get_tip_labels(),
annotation=False,
style={"text-anchor": "start", "fill": "black", "-toyplot-anchor-shift": 10},
)
<toyplot.mark.Text at 0x7fcbba798970>
Example: Xiphophorus fishes¶
Data set for reconstructing a densitree figure from Cui et al. (2013). I’ve taken the nexus file from the paper’s dryad repository and converted it to newick and saved it online so it can be easily downloaded. The file contains 160 trees representing mrbayes consensus trees inferred for different genomic regions.