Node labels

Node labels are markers plotted on the nodes (vertices) of a tree and can be highly modified, including the addition of interactive features which are useful not only for producing final production-quality figures but also for exploring metadata on trees.


In [1]:
import toytree
import toyplot
import numpy as np

In [8]:
# newick tree string with edge lengths and support values
newick = """
((apple:2,orange:4)100:2,(((tomato:2,eggplant:1)100:2,pepper:3)90:1,tomatillo:2)100:1);
"""

# load toytree
tre = toytree.tree(newick)

Hide/Show node labels

The argument node_labels can be entered as a list of names or left as None or False in which case the node labels are not shown. If you enter True a special feature is applied to the nodes in which case they will become interactive and show information for all available features (node values stored in the Tree object metadata) in the Tree. Hover your cursor over the green node labels below for an example.


In [9]:
## no node labels
tre.draw();

## default node labels
tre.draw(node_labels=True);


eggplanttomatopeppertomatilloorangeapple
eggplanttomatopeppertomatilloorangeappleidx: 0 name: eggplant dist: 1 support: 100 height: 10idx: 1 name: tomato dist: 2 support: 100 height: 01idx: 2 name: pepper dist: 3 support: 100 height: 12idx: 3 name: tomatillo dist: 2 support: 100 height: 33idx: 4 name: orange dist: 4 support: 100 height: 04idx: 5 name: apple dist: 2 support: 100 height: 25idx: 6 name: 6 dist: 2 support: 100 height: 26idx: 7 name: 7 dist: 1 support: 90 height: 47idx: 8 name: 8 dist: 1 support: 100 height: 58idx: 9 name: 9 dist: 2 support: 100 height: 49idx: 10 name: 10 dist: 1 support: 100 height: 610

Node plot order

The order in which nodes and node values are plotted can be accessed from toytrees directly using .get_node_values(). By linking this function to the tree itself we can be sure that the node labels will be returned in the correct order regardless of whether the tree has been pruned, or rotated, or any other modification.

Node features

"feature" argument that is provided. All trees will always have the features ["idx", "name", "support", "dist", "height"] available. Below we grab the 'height' values and plot them on the nodes of the tree. The .get_node_values() function does not return values for the root node or for leaves by default, since these often are not meaningful on trees where the values represent support values or distances (i.e, the values are actually relevant to edges not nodes), but we want those values here, so we enter True for those arguments.


In [10]:
## get node index (idx) values
heights = tre.get_node_values("height", show_root=True, show_tips=False)

## plot tree with node values
tre.draw(node_labels=heights, tip_labels_align=True, orient='down');


eggplanttomatopeppertomatilloorangeapple24546

Show specific node features

Similarly, in this case we are plotting support values so we will let the default arguments to .get_node_values() hide the values at the tips and root of the tree.


In [12]:
## plot tree with node values
tre.draw(
    node_labels=tre.get_node_values("support"), 
    node_sizes=24, 
    node_labels_style={"font-size": "10px"},
    );


eggplanttomatopeppertomatilloorangeapple10090100100

Add/modify/del node features


In [14]:
## traverse tree and add a new feature to each node
for node in tre.treenode.traverse():
    if node.dist > 1:
        node.add_feature("is_long_branch", True)
    else:
        node.add_feature("is_long_branch", False)

In [16]:
## get new feature in node plot order
feature = tre.get_node_values("is_long_branch", 0, 0)

## plot tree with node values
tre.draw(
    width=350, 
    node_labels=feature,
    node_sizes=25,
    use_edge_lengths=True,
    node_labels_style={"font-size": "9px"},
    );


eggplanttomatopeppertomatilloorangeappleTrueFalseFalseTrue

Node colors

Here we apply different colors to each node based on its value for the feature that we assigned to the nodes above, is_long_branch. We also use the magic argument node_labels=True which assigns interactive information to each node. Hover your cursor over the nodes in the plot below to see how the colors match up with the features of the node.


In [18]:
## get new feature in node plot order
feature = tre.get_node_values("is_long_branch", 0, 0)
colors = ["orange" if i else "lightgrey" for i in feature]

## plot tree with node values
tre.draw(
    width=300, 
    node_labels=None,
    node_sizes=12,
    node_colors=colors,
    node_style={"stroke":"black"},
    );


eggplanttomatopeppertomatilloorangeapple

Node styling

...


In [20]:
## get new feature in node plot order
feature = tre.get_node_values("is_long_branch", 0, 0)
colors = ["white" if i else "lightgrey" for i in feature]

## plot tree with node values
tre.draw(
    node_labels=True,
    node_sizes=20,
    node_colors=colors,
    node_style={"stroke": "darkcyan", "stroke-width": "2px"},
    );


eggplanttomatopeppertomatilloorangeappleidx: 0 name: eggplant dist: 1 support: 100 height: 1 is_long_branch: False0idx: 1 name: tomato dist: 2 support: 100 height: 0 is_long_branch: True1idx: 2 name: pepper dist: 3 support: 100 height: 1 is_long_branch: True2idx: 3 name: tomatillo dist: 2 support: 100 height: 3 is_long_branch: True3idx: 4 name: orange dist: 4 support: 100 height: 0 is_long_branch: True4idx: 5 name: apple dist: 2 support: 100 height: 2 is_long_branch: True5idx: 6 name: 6 dist: 2 support: 100 height: 2 is_long_branch: True6idx: 7 name: 7 dist: 1 support: 90 height: 4 is_long_branch: False7idx: 8 name: 8 dist: 1 support: 100 height: 5 is_long_branch: False8idx: 9 name: 9 dist: 2 support: 100 height: 4 is_long_branch: True9idx: 10 name: 10 dist: 1 support: 100 height: 6 is_long_branch: False10

Creating new node features

To store new node features it is easiest to interact with the TreeNode object itself. This allows you to iteratively traverse over nodes and to access data about the tree structure itself.


In [ ]: