In [1]:
import toytree
# load a ToyTree object from string, file path, or URL;
tre1 = toytree.tree('(((a,b),(c,d,g,h)),e);')
tre2 = toytree.tree('(((a,c),(b,d,g,h)),e);')
#tre1 = toytree.tree('(((a,b),(c,d)),e);')
#tre2 = toytree.tree('(((a,c),(e,d)),b);')
# plot will display natively in jupyter notebooks
tre1.draw();
tre2.draw();
In [41]:
tre1.write(tree_format=6)
Out[41]:
In [42]:
toytree.tree(tre1.write(tree_format=10)).draw();
In [ ]:
tre1.treenode.iter_prepostorder()
In [53]:
tre1.treenode.is_leaf()
Out[53]:
In [ ]:
tre1.treenode.get_n
In [ ]:
In [6]:
c, a = tre1.draw(xbaseline=3, ybaseline = 2, orient='down', use_edge_lengths=False)
a.show = True
In [7]:
tre1.treenode.robinson_foulds(tre2.treenode,
expand_polytomies=False)
Out[7]:
In [19]:
tre1.treenode.robinson_foulds(tre2.treenode,
expand_polytomies=True)
Out[19]:
In [15]:
from toytree.RobinsonFoulds import Robinson_Foulds
self = Robinson_Foulds(
tre1.treenode, tre2.treenode,
"name", "name",
unrooted_trees=False,
expand_polytomies=True,
polytomy_size_limit=10,
skip_large_polytomies=False,
correct_by_polytomy_size=False,
min_support_t1=0,
min_support_t2=0,
)
rfs = self.compare_trees()
rfs[0], rfs[0] / rfs[1], rfs[:3]
Out[15]:
In [39]:
attr = "name"
for t1 in self.t1s:
t1_content = t1.get_cached_content()
t1_leaves = t1_content[t1]
# get edges of the tree: set of tuples on either side of splits
#t1_edges = self.get_edges(t1_content, t1_leaves, self.attr_t1)
edges = set()
for content in t1_content.values():
names1 = tuple(sorted(
getattr(node, attr) for node in content if
(
hasattr(node, attr) and \
(getattr(node, attr) in self.common_attrs)
)
))
edges.add(tuple(sorted(set(names1))))
edges.discard(())
edges
Out[39]:
In [55]:
edges = set()
for content in tx_content.values():
names1 = tuple(sorted(
getattr(node, attr) for node in content if
(
hasattr(node, attr) and \
(getattr(node, attr) in self.common_attrs)
)
))
edges.add(tuple(sorted(set(names1))))
edges.discard(())
In [53]:
for t1 in self.t1s:
#print(t1)
# a dictionary of {node: node.get_leaves()}
t1_content = t1.get_cached_content()
# a list of nodes descended from this one: [node0, node1, node2]
t1_leaves = t1_content[t1]
# get edges of the tree: set of tuples on either side of splits
t1_edges = self.get_edges(t1_content, t1_leaves, self.attr_t1)
print(t1_edges)
# get support on tree ...
t1_sdict = None
if self.min_support_t1:
t1_sdict = self.get_support_dict(t1_content, self.attr_t1)
In [144]:
t1 = aaa.treenode
attr_t1, attr_t2 = "name", "name"
common_attrs = set(aaa.get_tip_labels())
t1_content = t1.get_cached_content()
# a list of nodes descended from this one: [node0, node1, node2]
t1_leaves = t1_content[t1]
edges1 = set()
for content in t1_content.values():
names1 = tuple(sorted(
getattr(node, attr_t1) for node in content if
(
hasattr(node, attr_t1) and \
(getattr(node, attr_t1) in common_attrs)
)
))
edges1.add(tuple(sorted(set(names1))))
edges1.discard(())
edges1
Out[144]:
In [161]:
#aaa.get_edge_values("support")
In [173]:
cdict = {('a',): 100, ('a', 'b'): 99}
cdict.get(('g',), '3')
Out[173]:
In [162]:
for branch, content in t1_content.items():
print(branch, branch.support)
In [148]:
#%%timeit
t1 = aaa.treenode
attr_t1, attr_t2 = "name", "name"
common_attrs = set(aaa.get_tip_labels())
t1_content = t1.get_cached_content()
# a list of nodes descended from this one: [node0, node1, node2]
t1_leaves = t1_content[t1]
edges1 = set([
tuple(sorted([getattr(n, attr_t1) for n in content if hasattr(n, attr_t1) and getattr(n, attr_t1) in common_attrs]))
for content in six.itervalues(t1_content)])
edges1.discard(())
edges1
Out[148]:
In [ ]:
In [110]:
aaa.draw();
In [ ]:
[getattr(i, 'name') for i in content]
In [16]:
toytree.mtree(aaa.treenode.expand_polytomies()).draw_tree_grid(tree_style='s');
In [263]:
# recursive function to add leaves
def add_leaf(tree, label):
yield (label, tree)
if not isinstance(tree, TipTuple) and isinstance(tree, tuple):
for left in add_leaf(tree[0], label):
yield (left, tree[1])
for right in add_leaf(tree[1], label):
yield (tree[0], right)
# recursive function to take subtrees and return as...
def enum_unordered(labels):
if len(labels) == 1:
yield labels[0]
else:
for tree in enum_unordered(labels[1:]):
for new_tree in add_leaf(tree, labels[0]):
yield new_tree
In [266]:
import itertools
self = aaa.treenode
#map_attr = "name"
class TipTuple(tuple):
pass
# store {node: ...} mapping
n2subtrees = {}
# traverse tree from tips to root
for node in self.traverse("postorder"):
# store leaf name for tips
if node.is_leaf():
subtrees = [node.name]
else:
print('internal name', node.name)
subtrees = []
ich = itertools.product(*[n2subtrees[ch] for ch in node.children])
for childtrees in ich:
print('nchild', len(node.children))
print('ctres', childtrees)
print('enum', next(enum_unordered(childtrees)))
subtrees.extend([
TipTuple(subtree) for subtree in
enum_unordered([childtrees])
])
n2subtrees[node] = subtrees
["{};".format(nw) for nw in n2subtrees[aaa.treenode]]
Out[266]:
In [267]:
n2subtrees
Out[267]:
In [262]:
polytomy_size_limit = 5
map_attr = 'name'
class TipTuple(tuple):
pass
def add_leaf(tree, label):
yield (label, tree)
if not isinstance(tree, TipTuple) and isinstance(tree, tuple):
for left in add_leaf(tree[0], label):
yield (left, tree[1])
for right in add_leaf(tree[1], label):
yield (tree[0], right)
def enum_unordered(labels):
if len(labels) == 1:
yield labels[0]
else:
for tree in enum_unordered(labels[1:]):
for new_tree in add_leaf(tree, labels[0]):
yield new_tree
n2subtrees = {}
for n in self.traverse("postorder"):
if n.is_leaf():
subtrees = [getattr(n, map_attr)]
else:
subtrees = []
if len(n.children) > polytomy_size_limit:
if skip_large_polytomies:
for childtrees in itertools.product(*[n2subtrees[ch] for ch in n.children]):
subtrees.append(TipTuple(childtrees))
else:
raise TreeError("Found polytomy larger than current limit: %s" %n)
else:
for childtrees in itertools.product(*[n2subtrees[ch] for ch in n.children]):
subtrees.extend([TipTuple(subtree) for subtree in enum_unordered(childtrees)])
n2subtrees[n] = subtrees
ttt = (["%s;"%str(nw) for nw in n2subtrees[self]]) # tuples are in newick format ^_^
In [270]:
class TipTuple(tuple):
pass
# recursive function to add leaves
def add_leaf(tree, label):
yield (label, tree)
if not isinstance(tree, TipTuple) and isinstance(tree, tuple):
for left in add_leaf(tree[0], label):
yield (left, tree[1])
for right in add_leaf(tree[1], label):
yield (tree[0], right)
# recursive function to take subtrees and return as...
def enum_unordered(labels):
if len(labels) == 1:
yield labels[0]
else:
for tree in enum_unordered(labels[1:]):
for new_tree in add_leaf(tree, labels[0]):
yield new_tree
# traverse tree from tips to root
n2subtrees = {}
for n in self.traverse("postorder"):
# store leaf name for tips
if n.is_leaf():
subtrees = [getattr(n, map_attr)]
# get node descendants
else:
subtrees = []
# get ways of sampling the children
ich = itertools.product(*[n2subtrees[ch] for ch in n.children])
# if not above poly size limit
if len(n.children) <= polytomy_size_limit:
# store subtrees for all enum_ordered children
for childtrees in ich:
# get all resolutions of this subclade
resolutions = [
TipTuple(subtree) for subtree in
enum_unordered(childtrees)
]
subtrees.extend(resolutions)
# check if too big of polytomy
else:
if not skip_large_polytomies:
raise TreeError(
"Found polytomy larger than current limit: {}"
.format(len(n.children)))
else:
for childtrees in ich:
subtrees.append(TipTuple(childtrees))
# store nodename: [desc]
n2subtrees[n] = subtrees
In [290]:
toytree.tree(str(n2subtrees[n][0]).replace("'", "") + ";").draw()
Out[290]:
In [254]:
toytree.mtree(ttt).draw_tree_grid()
Out[254]:
In [34]:
def add(tree, label):
yield (label, tree)
In [105]:
add(aaa.treenode, 'h')
Out[105]:
In [2]:
tre.treenode.expand_polytomies()
In [ ]:
itertools.product(*[n2subtrees[ch] for ch in n.children]):
In [2]:
import toytree
# load a ToyTree object from string, file path, or URL;
tre = toytree.tree('(((a,b),(c,d)),e);')
# plot will display natively in jupyter notebooks
tre.draw();
# or, save returned objects to variables
canvas, axes = tre.draw()
In [3]:
# load tree from URL
import toytree
tre = toytree.tree("https://eaton-lab.org/data/Cyathophora.tre")
# root on shared character in outgroup clade names
rtre = tre.root(wildcard="prz")
# (a) draw tree with default style
rtre.draw();
# (b) draw tree with advanced styling
styledict = {node_sizes=..., node_colors=..., tip_labels=...}
rtre.draw(**styledict)
# (c) draw tree on same coordinates with other data
canvas = toyplot.Canvas()
ax0 = canvas.cartesian(grid=(1, 2, 0))
ax1 = canvas.cartesian(grid=(1, 2, 1))
rtre.draw(axes=ax0, **styledict)
ax1.scatterplot(data)
In [ ]:
# load tree from URL and root on outgroup
tre = toytree.tree("https://eaton-lab.org/data/Cyathophora.tre")
rtre = tre.root(wildcard="prz")
# get list of styled tip labels from tree in correct plot order
tip_labels = [
"<i>P. {}</i>".format(i.split("_")[1])
for i in rtre.get_tip_labels()
]
# get list of edge colors from tree in correct plot order
edge_colors = rtre.get_edge_values_from_dict({
24: toytree.colors[0],
16: toytree.colors[1],
})
# get list of node sizes in correct plot order
node_sizes = [8 if i else 0 for i in rtre.get_node_values()]
In [7]:
# construct a list of node colors based on support values returned in node plot order
node_colors = [
"grey" if i==100 else "lightgrey"
for i in tree.get_node_values("support")
]
# create a style dictionary w/ lists of values ordered in node plot order
styledict = {
"tip_labels_align": True,
"tip_labels": tip_labels,
"edge_colors": edge_colors,
"node_sizes": node_sizes,
"node_colors": node_colors,
"node_labels": node_labels,
"node_style": {"stroke": "#262626"},
}
# Figure 1a: draw tree with default style
tree.draw()
# Figure 1b: draw tree with style dictionary applied
tree.draw(**styledict)
In [5]:
# add styling to nodes, edges, tips and axes
rtre.draw(
# style tip labels, align, italicize, and trim accession
tip_labels_align=True,
tip_labels=tips,
# style nodes, exclude root and tips
node_sizes=[8 if i else 0 for i in rtre.get_node_values()],
node_style={"stroke": "#262626", "fill": "grey"},
# style node labels, shift support values from nodes
node_labels=rtre.get_node_values("support"),
node_labels_style={
"-toyplot-anchor-shift": "-10px",
"baseline-shift": "5px"
},
# style edge labels, color descendants of nodes by index
edge_colors=edges,
# add a scale bar to the x axis
scalebar=True,
);
In [25]:
mtre = toytree.mtree([toytree.rtree.coaltree(5) for i in range(10)])
mtre.draw_cloud_tree(use_edge_lengths=False);
In [34]:
trees = """\
(((a:1,b:1):1,(d:1.5,e:1.5):0.5):1,c:3);
(((a:1,d:1):1,(b:1,e:1):1):1.25,c:3.25);
(((b:1.5,d:1.5):0.75,(a:1,e:1):1.25):1.5,c:3.75);
(((a:1.5,b:1.5):1,(d:1,e:1):1.5):1,c:3.5);
(((a:1.25,b:1.25):0.75,(d:1,e:1):1):1,c:3);
(((a:1,b:1):1,(d:1.5,e:1.5):0.5):1,c:3);
(((a:1,b:1):1,(d:1.5,e:1.5):0.5):2,c:4);
(((a:1.5,b:1.5):0.5,(d:1,e:1):1):1,c:3);
"""
In [45]:
# load a multitree object from a list of newick strings
mtre = toytree.mtree(trees)
# Fig. 3a: draw a grid of trees
mtre.draw_tree_grid(nrows=1, ncols=3, edge_type='c');
# Fig. 3b: draw a grid of trees with fixed tip order to show discordance
mtre.draw_tree_grid(nrows=1, ncols=3, edge_type='c', fixed_order=True);
# Fig. 3c: draw a cloud of trees overlapping to show discordance
mtre.draw_cloud_tree(edge_style={"stroke-opacity": 0.1}, edge_type='c');