Quadripartition methods¶
The iter_quadripartitions()
function in the .enum
subpackage returns all possible quadripartitions of a tree. Quadripartitions are defined by an internal focal edge
, from which the tree is split into four partitions. Each partition stems from the children of the 2 nodes on either side of the focal edge
. The quadripartitions are yielded in Node idxorder traversal in a nested format: a tuple of two tuples of two sets, e.g. (({e0},{e1}), ({e2},{e3}))
, with the contents representing the tip Nodes descending from each of the four partition stems. In this example, e0
through e3
are the partition stems and are each children of the nodes being split along the focal edge
. The order in which the partitions of a particular quadripartition are ordered is (child-left, child-right, sister, up) in relation to the Node directly below the focal edge
.
Note: Sets are used by default, which means when there are multiple nodes in a partition, they will not be sorted. This can be modified by using an ordered datatype like type=tuple
or type=list
. This will sort the nodes in alphabetical or index order (depending on whether feature="name"
or feature="idx"
.)
Simple example¶
import toytree
#define tree with simple Newick string
newick = "((a,b)X,((c,d)Y,e)Z)R;"
tree = toytree.tree(newick)
tree.draw('r'); #draw tree in R-style
#iteratively return all quadripartitions in phylogenetic tree
for q in toytree.enum.iter_quadripartitions(tree):
print(q)
(({'a'}, {'b'}), ({'d', 'c'}, {'e'})) (({'c'}, {'d'}), ({'e'}, {'b', 'a'}))
In this example, the only internal edges available to make quadripartitions from are the edges directly above Y
and Z
(or X
, but it has the same result as Z
). These two quadripartitions are given in tuples of tuples of sets to denotate the first (tuple) and second (sets) bipartitions that create the quadripartition.
Sorting and formatting¶
When type=
is set to an ordered datatype (i.e. tuple, list), iter_quadripartitions
will automatically sort the values within each partition. The user can choose to sort the quadripartition further, ordering each partition within its bipartitions and each bipartition within its quadripartition, by using sort=True
. This first orders them in size order (small to large), and if the sizes are equal, then by the lowest value Node present.
#build tree from simple newick string and visualize it
tree = toytree.tree("(a,b,((c,d)CD,(e,f)EF)X)AB;")
tree.draw()
#return quadripartitions as list, with each partition returned in a tuple (instead of a set), including the internal nodes of each partition
unordered = list(tree.enum.iter_quadripartitions(type=tuple,
include_internal_nodes=True,
feature="idx"))
ordered = list(tree.enum.iter_quadripartitions(type=tuple,
include_internal_nodes=True,
feature="idx",
sort=True))
print(unordered)
print(ordered)
[(((2,), (3,)), ((4, 5, 7), (0, 1))), (((4,), (5,)), ((2, 3, 6), (0, 1))), (((2, 3, 6), (4, 5, 7)), ((0,), (1,)))] [(((2,), (3,)), ((0, 1), (4, 5, 7))), (((4,), (5,)), ((0, 1), (2, 3, 6))), (((0,), (1,)), ((2, 3, 6), (4, 5, 7)))]
The user can also choose to return more or less information about each quadripartition, ranging from all tips and internal nodes using include_internal_nodes=True
, to only the stems of each partition (contract_partitions=True
). To specify what information is returned, use the feature=
argument with any available Node feature.
Example¶
Lots of information¶
import toytree
#define tree with simple Newick string
newick = "((alfred,bob)Xiang,((cindy,david)Yasmin,ellis)Zoro)Randy;"
tree = toytree.tree(newick)
tree.draw('r'); #draw tree in R-style
for q in toytree.enum.iter_quadripartitions(tree,
include_internal_nodes=True,
feature="name"):
print(q)
(({'alfred'}, {'bob'}), ({'david', 'Yasmin', 'cindy'}, {'ellis'})) (({'cindy'}, {'david'}), ({'ellis'}, {'bob', 'Xiang', 'alfred'}))
Little information¶
import toytree
#define tree with simple Newick string
newick = "((alfred,bob)Xiang,((cindy,david)Yasmin,ellis)Zoro)Randy;"
tree = toytree.tree(newick)
tree.draw('r'); #draw tree in R-style
for q in toytree.enum.iter_quadripartitions(tree,
contract_partitions=True,
feature="idx",
sort=True):
print(q)
(({0}, {1}), ({6}, {4})) (({2}, {3}), ({7}, {4}))
Both of these quadripartition sets represent the same quadripartitions from the same tree, just expressed in different formats.