Beispiel #1
0
 def ly_leaf_names(node):
     if node.is_leaf():
         spF = TextFace(node.species, fsize=10, fgcolor='#444444', fstyle='italic', ftype='Helvetica')
         add_face_to_node(spF, node, column=0, position='branch-right')
         if hasattr(node, 'genename'):
             geneF = TextFace(" (%s)" %node.genename, fsize=8, fgcolor='#777777', ftype='Helvetica')
             add_face_to_node(geneF, node, column=1, position='branch-right')
def mylayout(node):
    # If node is a leaf
    if node.is_leaf():
        # And a line profile
        add_face_to_node(profileFace, node, 0, aligned=True)
        node.img_style["size"] = 0
        add_face_to_node(nameFace, node, 1, aligned=True)

    # If node is internal
    else:
        print node
        print node.silhouette
        # If silhouette is good, creates a green bubble
        if node.silhouette > 0:
            validationFace = TextFace("Silh=%0.2f" % node.silhouette,
                                      "Verdana", 10, "#056600")
            node.img_style["fgcolor"] = "#056600"
        # Otherwise, use red bubbles
        else:
            validationFace = TextFace("Silh=%0.2f" % node.silhouette,
                                      "Verdana", 10, "#940000")
            node.img_style["fgcolor"] = "#940000"

        # Sets node size proportional to the silhouette value.
        node.img_style["shape"] = "sphere"
        if node.silhouette <= 1 and node.silhouette >= -1:
            node.img_style["size"] = 15 + int((abs(node.silhouette) * 10)**2)

        # If node is very internal, draw also a bar diagram
        # with the average expression of the partition
        add_face_to_node(validationFace, node, 0)
        if len(node) > 100:
            add_face_to_node(cbarsFace, node, 1)
Beispiel #3
0
def layout(node):
    node.img_style["size"] = 0
    node_name = node.name.replace(".bam", "")
    if node.is_leaf():
        col_country = header2column[sample_info["country"].get(node_name, "")]
        col_city = header2column[sample_info["city"].get(node_name, "")]
        ssize = 40
        countryF = RectFace(120, ssize, column_color[col_country],
                            column_color[col_country])
        cityF = RectFace(120, ssize, column_color[col_city],
                         column_color[col_city])

        if node_name in OBESITY:
            if OBESITY[node_name] == "obese":
                ocolor = "red"
            else:
                ocolor = "black"
            add_face_to_node(TextFace(OBESITY[node_name],
                                      fsize=18,
                                      fgcolor=ocolor),
                             node,
                             header2column["obesity"],
                             position="aligned")

        if node_name in DIABETES:
            ocolor = "purple"
            add_face_to_node(TextFace(DIABETES[node_name],
                                      fsize=18,
                                      fgcolor=ocolor),
                             node,
                             header2column["diabetes"],
                             position="aligned")

        add_face_to_node(countryF, node, col_country, position="aligned")
        add_face_to_node(cityF, node, col_city, position="aligned")
        add_face_to_node(TextFace("%s" % (node.name[:25]), fsize=20),
                         node,
                         0,
                         position='branch-right')
    else:
        if args.collapse_identical and len(node.children) > 50:
            node.img_style["draw_descendants"] = False
            node.img_style["size"] = 20
            node.img_style["shape"] = "square"
            node.img_style["hz_line_width"] = 5
            node.dist = 0.0001
            add_face_to_node(TextFace("%d samples without data" %
                                      len(node.children),
                                      fsize=20),
                             node,
                             0,
                             position='branch-right')
Beispiel #4
0
def main():

    args = parse_arguments()

    tree = Tree(args.input)
    midpoint_root = tree.get_midpoint_outgroup()

    if midpoint_root is None:
        print(
            'Warning: Was unable to assign midpoint outgroup - Likely consequence of too few OTUs'
        )
        print('Terminating tree building')
        sys.exit()

    tree.set_outgroup(midpoint_root)

    circle_size_dict = get_scaled_abundancy_dict(args.abundancies)
    label_dict = get_label_dict(args.labels)
    color_dict = get_color_dict(args.color_taxa)
    filtered_taxa_color_dict = get_filtered_taxa_color_dict(args.color_taxa)

    rename_labels(tree, label_dict, circle_size_dict, color_dict, font_size=11)

    style = get_tree_style(scale=400, vertical_margin=0)
    style.title.add_face(TextFace(TREE_TITLE, fsize=18), column=0)
    add_legend(style, filtered_taxa_color_dict)

    # tree.render(args.output + '.png', w=500, units='mm', tree_style=style)
    tree.render(args.output + '.svg', tree_style=style)
Beispiel #5
0
 def ly_tax_labels(node):
     if node.is_leaf():
         c = LABEL_START_COL
         largest = 0
         for tname in TRACKED_CLADES:
             if hasattr(node, "named_lineage") and tname in node.named_lineage:
                 linF = TextFace(tname, fsize=10, fgcolor='white')
                 linF.margin_left = 3
                 linF.margin_right = 2
                 linF.background.color = lin2color[tname]
                 add_face_to_node(linF, node, c, position='aligned')
                 c += 1
         
         for n in xrange(c, len(TRACKED_CLADES)):
             add_face_to_node(TextFace('', fsize=10, fgcolor='slategrey'), node, c, position='aligned')
             c+=1
Beispiel #6
0
def treelegendtext(whattoprint, color):
    text = TextFace(" %s " % whattoprint)
    text.hz_align = False
    text.fsize = 30
    text.fstyle = 'Bold'
    text.background.color = color
    return text
Beispiel #7
0
    def render_annotate(newick_path, output_path):
        """Render the annotated tree, showing internal node names.
           The output_path should end in .PNG, .PDF or .SVG: this will determine the format.

           To aid in testing, if output_path is None, the tree is shown rather than rendered.
        """
        tree = Tree(newick_path, format=1)

        ts = TreeStyle()
        ts.show_leaf_name = True
        ts.branch_vertical_margin = 15

        ns = NodeStyle()
        ns["size"] = 1

        edge = 0
        for node in tree.traverse():
            node.name = node.name.replace("'", "")
            node.name = node.name.replace("+", ",")
            if not node.is_leaf() and node.name != 'NoName':
                f = TextFace(node.name)
                f.margin_top = 5
                f.margin_bottom = 5
                f.margin_right = 10
                f.margin_left = 10
                edge += 1
                node.add_face(f, column=0, position="branch-top")

        if output_path is None:
            tree.show(tree_style=ts)
        else:
            tree.render(output_path)
Beispiel #8
0
def main():
    args = parser.parse_args()

    beta_metrics = args.beta_metrics.split(',')
    otu_widths = args.otu_widths.split(',')
    input_dir = args.input_dir
    output_fp = args.output_fp
    tree_fp = args.tree_fp

    nrows = len(beta_metrics)
    ncols = len(otu_widths)

    results_dict, labels_list = load_rug_dict(input_dir, beta_metrics,
                                              otu_widths)

    try:
        tree = Tree(tree_fp, format=3)
    except:
        tree = add_tip_branches(tree_fp)

    annotate_tree_with_rugs(tree, results_dict, labels_list)

    ts = TreeStyle()

    for row in range(len(labels_list)):
        for col in range(len(labels_list[row])):
            ts.legend.add_face(TextFace(labels_list[row][col], fsize=20),
                               column=col)

    tree.render(output_fp, tree_style=ts)
    tree.show(tree_style=ts)
def treelegendtext(cluster, color):
    text = TextFace(" %s " % cluster)
    text.hz_align = False
    text.fsize = 30
    text.fstyle = 'Bold'
    text.background.color = color
    return text
Beispiel #10
0
 def copyChildrenIntoOutput(treeNode, outputTreeNode):
     for child in treeNode.Children:
         outputChild = outputTreeNode.add_child()
         if child.isTip():
             outputChild.name = str("".join(child.reconstructed)) + " (" + cognateNameTable[int(child.Name)] + ")"
         else:
             outputChild.add_face(TextFace(str("".join(child.reconstructed))), column=0, position = "branch-right")
             copyChildrenIntoOutput(child, outputChild) 
Beispiel #11
0
def add_taxonomy_label(cotu_tree, potu_table):

    ts = TreeStyle()

    for row in range(len(labels_list)):
        for col in range(len(labels_list[row])):
            ts.legend.add_face(TextFace(labels_list[row][col], fsize=20),
                               column=col)
Beispiel #12
0
	def layout(node):
		if node.name in ckm_name_to_perc:
			ckm_perc = float(ckm_name_to_perc[node.name])
		else:
			ckm_perc = 0
		F = CircleFace(radius=3.14*math.sqrt(ckm_perc), color="RoyalBlue", style="sphere")
		F.border.width = None
		F.opacity = 0.6
		faces.add_face_to_node(F,node, 0, position="branch-right")
		if label_internal_nodes:
			faces.add_face_to_node(TextFace(node.name, fsize=7),node, 0, position="branch-top")
Beispiel #13
0
def prettifyTree(ete_tree,
                 leaf_font_size=32,
                 branch_support_size=20,
                 show_bootstraps=True,
                 title=None,
                 ts=None):
    ''' Perform standardized functions to make the ETE trees easier to read:
    - Make the branch support bigger
    - Make the leaf fonts bigger
    - Turn off elongating branches for visualization purposes (i.e. make sure the real branch lengths are represented)
    - Change both to standard font (Times)
    - Standardize the tree's width (calculate based on the maximum length from the root to a tip)
    - (optional) add title to tree
    '''

    for node in ete_tree.traverse():
        if node.is_leaf():
            # Make text faces with name = the existing node name but with big font.
            # A side effect of this is that we also get the annotations lined up
            F = faces.TextFace(node.name, ftype="Times", fsize=leaf_font_size)
            node.add_face(F, 0, position="aligned")
        else:
            if show_bootstraps:
                # Make branch support bigger
                F = faces.TextFace(node._support,
                                   ftype="Times",
                                   fsize=branch_support_size)
                node.add_face(F, 0, position="branch-top")

    #correct the long root node bug (fixed in next release)
    ete_tree.dist = 0

    # Optionally create a new TreeStyle if we are not passing in an old one.
    if ts is None:
        ts = TreeStyle()

    # This "fixes" the dashed line issue but makes the tree look terrible.
    # There may be no way around this (and it's likely other tree viewers do the same thing
    # but just don't tell you).
    #ts.optimal_scale_level = "full"

    # We made these bigger so lets turn off the default ones too.
    ts.show_branch_support = False
    ts.show_leaf_name = False

    if title is not None:
        ts.title.clear()
        title = TextFace(title)
        title.hz_align = True
        title.fsize = 52
        ts.title.add_face(title, 0)

    return ete_tree, ts
Beispiel #14
0
def add_legend(style, taxa_color_dict):
    """Adds legend to the tree style"""

    style.legend_position = 1
    circle_radius = 7

    for item in taxa_color_dict.items():
        taxa = item[0] + "  "
        color = item[1]
        style.legend.add_face(TextFace(taxa, fsize=14), column=0)
        style.legend.add_face(CircleFace(radius=circle_radius, color=color),
                              column=1)
Beispiel #15
0
def drawTree(nwfile, outfile):
    from ete2 import Tree, TreeStyle, TextFace
    ts = TreeStyle()
    ts.show_leaf_name = False
    ts.layout_fn = my_layout
    ts.branch_vertical_margin = 12.75
    ts.orientation = 1
    titleFace = TextFace("Phylogenetic Tree", fsize=18, fgcolor="white")
    titleFace.margin_top = 15
    ts.title.add_face(titleFace, column=1)

    t = Tree(nwfile)
    t.render(outfile, tree_style=ts)
def labelsOnTree(tree, splitChar=" "):
    if tree == None:
        return

    for n in tree.iter_leaves():
        #print n.name
        # if re.search("-", n.name) != None:
        #     splits = n.name.split("-")
        # else:
        #     splits = n.name.split(" ")
        splits = n.name.split(splitChar)
        if len(splits) == 1:
            T1 = TextFace(splits[0], fsize=FONTSIZE, fgcolor=leafNameColor)
            T2 = TextFace("0", fsize=FONTSIZE, fgcolor=leafCountsColor)
        else:
            T1 = TextFace(" ".join(splits[:-1]),
                          fsize=FONTSIZE,
                          fgcolor=leafNameColor)
            T2 = TextFace(splits[-1], fsize=FONTSIZE, fgcolor=leafCountsColor)
        n.add_face(T1, 0, position="aligned")

        n.add_face(T2, 1, position="aligned")
Beispiel #17
0
    def layout(node):
        # print node.rank
        # print node.sci_name
        if getattr(node, "rank", None):
            if (node.rank in ['order', 'class', 'phylum', 'kingdom']):
                rank_face = AttrFace("sci_name", fsize=7, fgcolor="indianred")
                node.add_face(rank_face, column=0, position="branch-top")
        if node.is_leaf():
            sciname_face = AttrFace("sci_name", fsize=9, fgcolor="steelblue")
            node.add_face(sciname_face, column=0, position="branch-right")
        if node.is_leaf() and not node.name == 'annotation':
            s = str(msa[taxids.index(int(node.name))].seq)
            seqFace = SeqMotifFace(
                s, [[0, len(s), "seq", 10, 10, None, None, None]],
                scale_factor=1)
            add_face_to_node(seqFace, node, 0, position="aligned")
            # gi=taxid2gi[int(node.name)]
            add_face_to_node(TextFace(' ' +
                                      msa[taxids.index(int(node.name))].id),
                             node,
                             column=1,
                             position="aligned")
            # add_face_to_node(TextFace('      '+str(int(node.name))+' '),node,column=2, position = "aligned")
            # add_face_to_node(TextFace('      '+str(gi2variant[gi])+' '),node,column=3, position = "aligned")

        if node.is_leaf() and node.name == 'annotation':
            if (annotation):
                s = annotation
                # get_hist_ss_in_aln_as_string(msa_tr)
            else:
                s = ' ' * len(msa[0].seq)
            seqFace = SeqMotifFace(
                s, [[0, len(s), "seq", 10, 10, None, None, None]],
                scale_factor=1)
            add_face_to_node(seqFace, node, 0, position="aligned")
            add_face_to_node(TextFace(' ' + 'SEQ_ID'),
                             node,
                             column=1,
                             position="aligned")
def layout(node):

	if not node.is_root():
		# give node name to all but the root
		faces.add_face_to_node(TextFace(node.name), node, 0)
		# and increase them with the wight
		if "weight" in node.features:
			# Creates a sphere face whose size is proportional to node's
			# feature "weight"
			C = CircleFace(radius=node.weight, color="RoyalBlue", style="sphere")
			# Let's make the sphere transparent 
			C.opacity = 0.34
			# And place as a float face over the tree
			faces.add_face_to_node(C, node, 0, position="float")
Beispiel #19
0
def layout(node):
	if not node.is_root():
		# Add node name to laef nodes
		#N = AttrFace("name", fsize=14, fgcolor="black")
		#faces.add_face_to_node(N, node, 0)
		#pass
		faces.add_face_to_node(TextFace(node.name), node, 0)
		if "weight" in node.features:
			# Creates a sphere face whose size is proportional to node's
			# feature "weight"
			C = CircleFace(radius=node.weight, color="RoyalBlue", style="sphere")
			# Let's make the sphere transparent 
			C.opacity = 0.3
			# And place as a float face over the tree
			faces.add_face_to_node(C, node, 0, position="float")
Beispiel #20
0
    def ly_basic(node):
        if node.is_leaf():
            node.img_style['size'] = 0
        else:
            node.img_style['size'] = 0
            node.img_style['shape'] = 'square'
            if len(MIXED_RES) > 1 and hasattr(node, "tree_seqtype"):
                if node.tree_seqtype == "nt":
                    node.img_style["bgcolor"] = "#CFE6CA"
                    ntF = TextFace("nt", fsize=6, fgcolor='#444', ftype='Helvetica')
                    add_face_to_node(ntF, node, 10, position="branch-bottom")
            if len(NPR_TREES) > 1 and hasattr(node, "tree_type"):
                node.img_style['size'] = 4
                node.img_style['fgcolor'] = "steelblue"

        node.img_style['hz_line_width'] = 1
        node.img_style['vt_line_width'] = 1
def addCoreDataToTree(ete_tree,
                      runid,
                      sanitized=False,
                      any_org=False,
                      all_org=False,
                      only_org=False,
                      none_org=False,
                      uniq_org=False,
                      color="Black"):
    '''A function to add data related to gene and organism distribution across clusters
    to a core gene tree.

    See http://packages.python.org/ete2/reference/reference_treeview.html#color-names for a list
    of valid color names.'''

    cl = getClusterOrgsByRun(runid)

    nodenum = 0
    nodeNumToClusterList = {}
    # The strategy really doesn't matter, it's just for aesthetics... and to make sure its always the same.
    for node in ete_tree.traverse("postorder"):
        nodenum += 1
        leafnames = node.get_leaf_names()
        clusters = findGenesByOrganismList(leafnames,
                                           runid,
                                           cl=cl,
                                           sanitized=True,
                                           all_org=all_org,
                                           any_org=any_org,
                                           only_org=only_org,
                                           none_org=none_org,
                                           uniq_org=uniq_org)
        numclusters = len(clusters)
        # This is mostly so that I can keep track of progress.
        sys.stderr.write("%d (N%d)\n" % (numclusters, nodenum))
        numFace = TextFace("%d (N%d)" % (numclusters, nodenum),
                           ftype="Times",
                           fsize=24,
                           fgcolor=color)
        node.add_face(numFace, 0, position="branch-bottom")
        nodeNumToClusterList[nodenum] = clusters

    return ete_tree, nodeNumToClusterList
    def apply_tss(node):
        node_style = NodeStyle()

        # gather label text and styles separately; we'll need to add this 
        # using a TextFace after all styles have been considered
        label_specs = {}
        label_specs['text'] = get_proper_node_label(node, otu_collections)

        for rule in node_rules:
            # Test this node against each selector
            if test_node_against_selector(node, rule.selector):
                node_style, node = apply_node_rule(rule, node_style, node, label_specs)
        node.set_style(node_style);

        # assign the final label with appropriate style
        if node.is_leaf():
            label_face = TextFace(**label_specs)
            node.add_face(label_face, 0)
        
        return node
Beispiel #23
0
    def __layout__(self, node):
        if node.is_leaf():
            # Add node name to laef nodes
            N = AttrFace("name", fsize=14, fgcolor="black")
            faces.add_face_to_node(N, node, 0)
            nstyle = NodeStyle()

            nstyle["size"] = 0
            node.set_style(nstyle)
        if "internalCount" in node.features:
            print node.name
            # Creates a sphere face whose size is proportional to node's
            # feature "weight"
            C = CircleFace(radius=int(node.internalCount) / 10,
                           color="RoyalBlue",
                           style="sphere")
            T = TextFace("10")
            # Let's make the sphere transparent
            C.opacity = 0.3
            # And place as a float face over the tree
            faces.add_face_to_node(C, node, 0, position="float")
            faces.add_face_to_node(T, node, 1)
Beispiel #24
0
def add_colored_host_label(symbiont_tree, otu_table, host_colors, count=True):
    for tip in symbiont_tree.iter_leaves():
        # filter otu_table to this cotu
        # iterate across nonzero entries and add a host face for that one

        i = 1

        for thing in otu_table.filter(lambda val, id_, md: id_ == tip.name,
                                      axis='observation',
                                      inplace=False).nonzero():
            host_lab = thing[1]

            if count:
                host_lab += "_%s" % otu_table.get_value_by_ids(
                    thing[0], thing[1])

            tip.add_face(TextFace(host_lab, fgcolor=host_colors[thing[1]]),
                         column=i,
                         position="branch-right")

            #i += 1

    return
Beispiel #25
0
def rename_labels(tree,
                  label_dict,
                  circle_size_dict,
                  color_dict,
                  font_size=12):
    """Changes the OTU-naming to taxa-naming for the leaves"""

    for node in tree.traverse():

        nstyle = NodeStyle()

        if node.is_leaf():
            otu = node.name
            taxa_name = label_dict[otu]
            nstyle['size'] = circle_size_dict[otu]
            color = color_dict[otu]

            node.add_face(TextFace(taxa_name, fsize=font_size, fgcolor=color),
                          0)

        else:
            nstyle['size'] = 0

        node.set_style(nstyle)
Beispiel #26
0
 def ly_supports(node):
     if not node.is_leaf() and node.up:
         supFace = TextFace("%0.2g" % (node.support),
                            fsize=7,
                            fgcolor='indianred')
         add_face_to_node(supFace, node, column=0, position='branch-top')
Beispiel #27
0
def draw_tree(tree, conf, outfile):
    try:
        from ete2 import (add_face_to_node, AttrFace, TextFace, TreeStyle,
                          RectFace, CircleFace, SequenceFace, random_color,
                          SeqMotifFace)
    except ImportError as e:
        print e
        return

    def ly_basic(node):
        if node.is_leaf():
            node.img_style['size'] = 0
        else:
            node.img_style['size'] = 0
            node.img_style['shape'] = 'square'
            if len(MIXED_RES) > 1 and hasattr(node, "tree_seqtype"):
                if node.tree_seqtype == "nt":
                    node.img_style["bgcolor"] = "#CFE6CA"
                    ntF = TextFace("nt",
                                   fsize=6,
                                   fgcolor='#444',
                                   ftype='Helvetica')
                    add_face_to_node(ntF, node, 10, position="branch-bottom")
            if len(NPR_TREES) > 1 and hasattr(node, "tree_type"):
                node.img_style['size'] = 4
                node.img_style['fgcolor'] = "steelblue"

        node.img_style['hz_line_width'] = 1
        node.img_style['vt_line_width'] = 1

    def ly_leaf_names(node):
        if node.is_leaf():
            spF = TextFace(node.species,
                           fsize=10,
                           fgcolor='#444444',
                           fstyle='italic',
                           ftype='Helvetica')
            add_face_to_node(spF, node, column=0, position='branch-right')
            if hasattr(node, 'genename'):
                geneF = TextFace(" (%s)" % node.genename,
                                 fsize=8,
                                 fgcolor='#777777',
                                 ftype='Helvetica')
                add_face_to_node(geneF,
                                 node,
                                 column=1,
                                 position='branch-right')

    def ly_supports(node):
        if not node.is_leaf() and node.up:
            supFace = TextFace("%0.2g" % (node.support),
                               fsize=7,
                               fgcolor='indianred')
            add_face_to_node(supFace, node, column=0, position='branch-top')

    def ly_tax_labels(node):
        if node.is_leaf():
            c = LABEL_START_COL
            largest = 0
            for tname in TRACKED_CLADES:
                if hasattr(node,
                           "named_lineage") and tname in node.named_lineage:
                    linF = TextFace(tname, fsize=10, fgcolor='white')
                    linF.margin_left = 3
                    linF.margin_right = 2
                    linF.background.color = lin2color[tname]
                    add_face_to_node(linF, node, c, position='aligned')
                    c += 1

            for n in xrange(c, len(TRACKED_CLADES)):
                add_face_to_node(TextFace('', fsize=10, fgcolor='slategrey'),
                                 node,
                                 c,
                                 position='aligned')
                c += 1

    def ly_full_alg(node):
        pass

    def ly_block_alg(node):
        if node.is_leaf():
            if 'sequence' in node.features:
                seqFace = SeqMotifFace(node.sequence, [])
                # [10, 100, "[]", None, 10, "black", "rgradient:blue", "arial|8|white|domain Name"],
                motifs = []
                last_lt = None
                for c, lt in enumerate(node.sequence):
                    if lt != '-':
                        if last_lt is None:
                            last_lt = c
                        if c + 1 == len(node.sequence):
                            start, end = last_lt, c
                            motifs.append([
                                start, end, "()", 0, 12, "slategrey",
                                "slategrey", None
                            ])
                            last_lt = None
                    elif lt == '-':
                        if last_lt is not None:
                            start, end = last_lt, c - 1
                            motifs.append([
                                start, end, "()", 0, 12, "grey", "slategrey",
                                None
                            ])
                            last_lt = None

                seqFace = SeqMotifFace(node.sequence,
                                       motifs,
                                       intermotif_format="line",
                                       seqtail_format="line",
                                       scale_factor=ALG_SCALE)
                add_face_to_node(seqFace, node, ALG_START_COL, aligned=True)

    TRACKED_CLADES = [
        "Eukaryota",
        "Viridiplantae",
        "Fungi",
        "Alveolata",
        "Metazoa",
        "Stramenopiles",
        "Rhodophyta",
        "Amoebozoa",
        "Crypthophyta",
        "Bacteria",
        "Alphaproteobacteria",
        "Betaproteobacteria",
        "Cyanobacteria",
        "Gammaproteobacteria",
    ]

    # ["Opisthokonta",  "Apicomplexa"]

    colors = random_color(num=len(TRACKED_CLADES), s=0.45)
    lin2color = dict([(ln, colors[i]) for i, ln in enumerate(TRACKED_CLADES)])

    NAME_FACE = AttrFace('name', fsize=10, fgcolor='#444444')

    LABEL_START_COL = 10
    ALG_START_COL = 40
    ts = TreeStyle()
    ts.draw_aligned_faces_as_table = False
    ts.draw_guiding_lines = False
    ts.show_leaf_name = False
    ts.show_branch_support = False
    ts.scale = 160

    ts.layout_fn = [ly_basic, ly_leaf_names, ly_supports, ly_tax_labels]

    MIXED_RES = set()
    MAX_SEQ_LEN = 0
    NPR_TREES = []
    for n in tree.traverse():
        if hasattr(n, "tree_seqtype"):
            MIXED_RES.add(n.tree_seqtype)
        if hasattr(n, "tree_type"):
            NPR_TREES.append(n.tree_type)
        seq = getattr(n, "sequence", "")
        MAX_SEQ_LEN = max(len(seq), MAX_SEQ_LEN)

    if MAX_SEQ_LEN:
        ALG_SCALE = min(1, 1000. / MAX_SEQ_LEN)
        ts.layout_fn.append(ly_block_alg)

    if len(NPR_TREES) > 1:
        rF = RectFace(4, 4, "steelblue", "steelblue")
        rF.margin_right = 10
        rF.margin_left = 10
        ts.legend.add_face(rF, 0)
        ts.legend.add_face(TextFace(" NPR node"), 1)
        ts.legend_position = 3

    if len(MIXED_RES) > 1:
        rF = RectFace(20, 20, "#CFE6CA", "#CFE6CA")
        rF.margin_right = 10
        rF.margin_left = 10
        ts.legend.add_face(rF, 0)
        ts.legend.add_face(TextFace(" Nucleotide based alignment"), 1)
        ts.legend_position = 3

    try:
        tree.set_species_naming_function(spname)
        annotate_tree_with_ncbi(tree)
        a = tree.search_nodes(species='Dictyostelium discoideum')[0]
        b = tree.search_nodes(species='Chondrus crispus')[0]
        #out = tree.get_common_ancestor([a, b])
        #out = tree.search_nodes(species='Haemophilus parahaemolyticus')[0].up
        tree.set_outgroup(out)
        tree.swap_children()
    except Exception:
        pass

    tree.render(outfile, tree_style=ts, w=170, units='mm', dpi=150)
    tree.render(outfile + '.svg', tree_style=ts, w=170, units='mm', dpi=150)
    tree.render(outfile + '.pdf', tree_style=ts, w=170, units='mm', dpi=150)
Beispiel #28
0
 def my_layout(node):
   F = TextFace(node.name, tight_text=True)
   add_face_to_node(F, node, column=0, position="branch-right")
Beispiel #29
0
def main():
    args = parse_args()

    if args.data:
        print "\nReading tree from " + args.tree + " and data matrix from " + args.data
        tree = ClusterTree(args.tree, text_array=args.data)
    else:
        print "\nReading tree from " + args.tree
        tree = Tree(args.tree)

    if args.midpoint:
        R = tree.get_midpoint_outgroup()
        tree.set_outgroup(R)
        print "- Applying midpoint rooting"
    elif args.outgroup:
        tree.set_outgroup(tree & args.outgroup)
        print "- Rooting using outgroup " + args.outgroup

    if not args.no_ladderize:
        tree.ladderize()
        print "- Ladderizing tree"

    table, column_list, column_values = readtable(args, tree.get_leaf_names())

    labels = []
    if args.labels:
        print "\nThese labels will be printed next to each strain:"
        for label in args.labels:
            if label in column_list:
                labels.append(label)
                print " " + label
            else:
                print "WARNING: specified label " + label + " was not found in the columns of the info file provided, " + args.info

    # set node styles
    # start by setting all to no shapes, black labels
    for n in tree.traverse():
        nstyle = NodeStyle()
        nstyle["fgcolor"] = "black"
        nstyle["size"] = 0
        n.set_style(nstyle)

    # add colour tags next to nodes
    if args.colour_tags:
        colour_tags = []
        print "\nThese columns will be used to generate colour tags:"
        for label in args.colour_tags:
            if label in column_list:
                colour_tags.append(label)
                print " " + label
            else:
                print "\tWARNING: specified label for colour tagging, " + label + ", was not found in the columns of the info file provided, " + args.info
        print(colour_tags)
        print("here")
        for i in range(0, len(colour_tags)):
            label = colour_tags[i]
            print(label)
            colour_dict = getColourPalette(column_values[label], args, label)

            print "- Adding colour tag for " + label

            for node in tree.get_leaves():
                this_face = Face()
                this_face.margin_left = args.padding
                node.add_face(this_face, column=0, position="aligned")

                if node.name in table:
                    this_label = table[node.name][label]
                    this_colour = colour_dict[this_label]
                else:
                    this_colour = "white"
                this_face = Face()
                this_face.background.color = this_colour
                this_face.margin_right = args.margin_right
                this_face.margin_left = args.margin_left
                this_face.margin_top = args.margin_top
                this_face.margin_bottom = args.margin_bottom
                this_face.border.width = args.border_width
                this_face.border.color = "white"
                node.add_face(this_face, column=i + 1, position="aligned")
        print
    else:
        colour_tags = []

    # add labels as columns
    for i in range(0, len(labels)):

        label = labels[i]

        print "- Adding label " + label
        if label == args.colour_nodes_by:
            print "  also colouring nodes by these values"
        print(column_values)
        print(args)
        colour_dict = getColourPalette(column_values[label], args, label)

        for node in tree.get_leaves():
            if node.name in table:
                this_label = table[node.name][label]
                this_colour = colour_dict[this_label]
            else:
                this_label = ""
                this_colour = "black"

            this_face = TextFace(text=this_label, fsize=args.font_size)
            if args.tags:
                this_face.background.color = this_colour
            elif label == args.colour_nodes_by:
                this_face.fgcolor = this_colour
            this_face.margin_right = args.padding
            if i == 0:
                this_face.margin_left = args.padding
            node.add_face(this_face,
                          column=i + len(colour_tags) + 1,
                          position="aligned")

            # set leaves to coloured circles
            node.img_style["size"] = args.node_size
            if label == args.colour_nodes_by:
                node.img_style["fgcolor"] = this_colour

    if args.colour_branches_by or args.colour_backgrounds_by or args.branch_support_colour:
        if args.colour_branches_by:
            print "- Colouring branches by label " + args.colour_branches_by
            colour_dict_br = getColourPalette(
                column_values[args.colour_branches_by], args,
                args.colour_branches_by)
        if args.colour_backgrounds_by:
            print "- Colouring node backgrounds by label " + args.colour_backgrounds_by
            colour_dict_bg = getColourPalette(
                column_values[args.colour_backgrounds_by], args,
                args.colour_backgrounds_by)
        if args.branch_support_colour:
            print "- Colouring branches by support values"
            # colours extracted from R using rgb( colorRamp(c("white","red", "black"))(seq(0, 1, length = 100)), max = 255)
            # support_colours = {0.0:"#FFFFFF",0.01:"#FFFFFF", 0.02:"#FFF9F9", 0.03:"#FFF4F4", 0.04:"#FFEFEF", 0.05:"#FFEAEA", 0.06:"#FFE5E5", 0.07:"#FFE0E0", 0.08:"#FFDADA", 0.09:"#FFD5D5", 0.1:"#FFD0D0", 0.11:"#FFCBCB", 0.12:"#FFC6C6", 0.13:"#FFC1C1", 0.14:"#FFBCBC", 0.15:"#FFB6B6", 0.16:"#FFB1B1", 0.17:"#FFACAC", 0.18:"#FFA7A7", 0.19:"#FFA2A2", 0.2:"#FF9D9D", 0.21:"#FF9797", 0.22:"#FF9292", 0.23:"#FF8D8D", 0.24:"#FF8888", 0.25:"#FF8383", 0.26:"#FF7E7E", 0.27:"#FF7979", 0.28:"#FF7373", 0.29:"#FF6E6E", 0.3:"#FF6969", 0.31:"#FF6464", 0.32:"#FF5F5F", 0.33:"#FF5A5A", 0.34:"#FF5454", 0.35:"#FF4F4F", 0.36:"#FF4A4A", 0.37:"#FF4545", 0.38:"#FF4040", 0.39:"#FF3B3B", 0.4:"#FF3636", 0.41:"#FF3030", 0.42:"#FF2B2B", 0.43:"#FF2626", 0.44:"#FF2121", 0.45:"#FF1C1C", 0.46:"#FF1717", 0.47:"#FF1212", 0.48:"#FF0C0C", 0.49:"#FF0707", 0.5:"#FF0202", 0.51:"#FC0000", 0.52:"#F70000", 0.53:"#F20000", 0.54:"#EC0000", 0.55:"#E70000", 0.56:"#E20000", 0.57:"#DD0000", 0.58:"#D80000", 0.59:"#D30000", 0.6:"#CE0000", 0.61:"#C80000", 0.62:"#C30000", 0.63:"#BE0000", 0.64:"#B90000", 0.65:"#B40000", 0.66:"#AF0000", 0.67:"#A90000", 0.68:"#A40000", 0.69:"#9F0000", 0.7:"#9A0000", 0.71:"#950000", 0.72:"#900000", 0.73:"#8B0000", 0.74:"#850000", 0.75:"#800000", 0.76:"#7B0000", 0.77:"#760000", 0.78:"#710000", 0.79:"#6C0000", 0.8:"#670000", 0.81:"#610000", 0.82:"#5C0000", 0.83:"#570000", 0.84:"#520000", 0.85:"#4D0000", 0.86:"#480000", 0.87:"#420000", 0.88:"#3D0000", 0.89:"#380000", 0.9:"#330000", 0.91:"#2E0000", 0.92:"#290000", 0.93:"#240000", 0.94:"#1E0000", 0.95:"#190000", 0.96:"#140000", 0.97:"#0F0000", 0.98:"#0A0000", 0.99:"#050000", 1:"#000000"}
            # rgb( colorRamp(c("red", "black"))(seq(0, 1, length = 100)), max = 255))
            support_colours = {}

            if args.branch_support_cutoff:
                for i in range(0, args.branch_support_cutoff):
                    support_colours[i] = "#FF0000"
                for i in range(args.branch_support_cutoff, 101):
                    support_colours[i] = "#000000"
            else:
                if args.branch_support_percent:
                    support_colours = {
                        0: "#FF0000",
                        1: "#FF0000",
                        2: "#FC0000",
                        3: "#F90000",
                        4: "#F70000",
                        5: "#F40000",
                        6: "#F20000",
                        7: "#EF0000",
                        8: "#EC0000",
                        9: "#EA0000",
                        10: "#E70000",
                        11: "#E50000",
                        12: "#E20000",
                        13: "#E00000",
                        14: "#DD0000",
                        15: "#DA0000",
                        16: "#D80000",
                        17: "#D50000",
                        18: "#D30000",
                        19: "#D00000",
                        20: "#CE0000",
                        21: "#CB0000",
                        22: "#C80000",
                        23: "#C60000",
                        24: "#C30000",
                        25: "#C10000",
                        26: "#BE0000",
                        27: "#BC0000",
                        28: "#B90000",
                        29: "#B60000",
                        30: "#B40000",
                        31: "#B10000",
                        32: "#AF0000",
                        33: "#AC0000",
                        34: "#AA0000",
                        35: "#A70000",
                        36: "#A40000",
                        37: "#A20000",
                        38: "#9F0000",
                        39: "#9D0000",
                        40: "#9A0000",
                        41: "#970000",
                        42: "#950000",
                        43: "#920000",
                        44: "#900000",
                        45: "#8D0000",
                        46: "#8B0000",
                        47: "#880000",
                        48: "#850000",
                        49: "#830000",
                        50: "#800000",
                        51: "#7E0000",
                        52: "#7B0000",
                        53: "#790000",
                        54: "#760000",
                        55: "#730000",
                        56: "#710000",
                        57: "#6E0000",
                        58: "#6C0000",
                        59: "#690000",
                        60: "#670000",
                        61: "#640000",
                        62: "#610000",
                        63: "#5F0000",
                        64: "#5C0000",
                        65: "#5A0000",
                        66: "#570000",
                        67: "#540000",
                        68: "#520000",
                        69: "#4F0000",
                        70: "#4D0000",
                        71: "#4A0000",
                        72: "#480000",
                        73: "#450000",
                        74: "#420000",
                        75: "#400000",
                        76: "#3D0000",
                        77: "#3B0000",
                        78: "#380000",
                        79: "#360000",
                        80: "#330000",
                        81: "#300000",
                        82: "#2E0000",
                        83: "#2B0000",
                        84: "#290000",
                        85: "#260000",
                        86: "#240000",
                        87: "#210000",
                        88: "#1E0000",
                        89: "#1C0000",
                        90: "#190000",
                        91: "#170000",
                        92: "#140000",
                        93: "#120000",
                        94: "#0F0000",
                        95: "#0C0000",
                        96: "#0A0000",
                        97: "#070000",
                        98: "#050000",
                        99: "#020000",
                        100: "#000000"
                    }
                else:
                    support_colours = {
                        0.0: "#FF0000",
                        0.01: "#FF0000",
                        0.02: "#FC0000",
                        0.03: "#F90000",
                        0.04: "#F70000",
                        0.05: "#F40000",
                        0.06: "#F20000",
                        0.07: "#EF0000",
                        0.08: "#EC0000",
                        0.09: "#EA0000",
                        0.1: "#E70000",
                        0.11: "#E50000",
                        0.12: "#E20000",
                        0.13: "#E00000",
                        0.14: "#DD0000",
                        0.15: "#DA0000",
                        0.16: "#D80000",
                        0.17: "#D50000",
                        0.18: "#D30000",
                        0.19: "#D00000",
                        0.2: "#CE0000",
                        0.21: "#CB0000",
                        0.22: "#C80000",
                        0.23: "#C60000",
                        0.24: "#C30000",
                        0.25: "#C10000",
                        0.26: "#BE0000",
                        0.27: "#BC0000",
                        0.28: "#B90000",
                        0.29: "#B60000",
                        0.3: "#B40000",
                        0.31: "#B10000",
                        0.32: "#AF0000",
                        0.33: "#AC0000",
                        0.34: "#AA0000",
                        0.35: "#A70000",
                        0.36: "#A40000",
                        0.37: "#A20000",
                        0.38: "#9F0000",
                        0.39: "#9D0000",
                        0.4: "#9A0000",
                        0.41: "#970000",
                        0.42: "#950000",
                        0.43: "#920000",
                        0.44: "#900000",
                        0.45: "#8D0000",
                        0.46: "#8B0000",
                        0.47: "#880000",
                        0.48: "#850000",
                        0.49: "#830000",
                        0.5: "#800000",
                        0.51: "#7E0000",
                        0.52: "#7B0000",
                        0.53: "#790000",
                        0.54: "#760000",
                        0.55: "#730000",
                        0.56: "#710000",
                        0.57: "#6E0000",
                        0.58: "#6C0000",
                        0.59: "#690000",
                        0.6: "#670000",
                        0.61: "#640000",
                        0.62: "#610000",
                        0.63: "#5F0000",
                        0.64: "#5C0000",
                        0.65: "#5A0000",
                        0.66: "#570000",
                        0.67: "#540000",
                        0.68: "#520000",
                        0.69: "#4F0000",
                        0.7: "#4D0000",
                        0.71: "#4A0000",
                        0.72: "#480000",
                        0.73: "#450000",
                        0.74: "#420000",
                        0.75: "#400000",
                        0.76: "#3D0000",
                        0.77: "#3B0000",
                        0.78: "#380000",
                        0.79: "#360000",
                        0.8: "#330000",
                        0.81: "#300000",
                        0.82: "#2E0000",
                        0.83: "#2B0000",
                        0.84: "#290000",
                        0.85: "#260000",
                        0.86: "#240000",
                        0.87: "#210000",
                        0.88: "#1E0000",
                        0.89: "#1C0000",
                        0.9: "#190000",
                        0.91: "#170000",
                        0.92: "#140000",
                        0.93: "#120000",
                        0.94: "#0F0000",
                        0.95: "#0C0000",
                        0.96: "#0A0000",
                        0.97: "#070000",
                        0.98: "#050000",
                        0.99: "#020000",
                        1.0: "#000000"
                    }
        for node in tree.traverse():
            nstyle = NodeStyle()
            nstyle["size"] = 0
            if node.name in table:
                #print "Colouring individual " + node.name
                if args.colour_branches_by:
                    nstyle["vt_line_color"] = colour_dict_br[table[node.name][
                        args.colour_branches_by]]  # set branch colour
                    nstyle["hz_line_color"] = colour_dict_br[table[node.name][
                        args.colour_branches_by]]
                if args.colour_backgrounds_by:
                    if args.colour_branches_by in table[node.name]:
                        if table[node.name][args.colour_branches_by] != "none":
                            if not args.colour_branches_by:
                                nstyle["hz_line_color"] = "black"
                                nstyle["vt_line_color"] = "black"
                            nstyle["bgcolor"] = colour_dict_bg[table[node.name][
                                args.
                                colour_backgrounds_by]]  # set background colour
                node.set_style(nstyle)
            else:
                # internal node
                descendants = node.get_leaves()
                descendant_labels_br = []
                descendant_labels_bg = []
                for d in descendants:
                    if args.colour_branches_by:
                        if d.name in table:
                            this_label_br = table[d.name][
                                args.colour_branches_by]
                            if this_label_br not in descendant_labels_br:
                                descendant_labels_br.append(this_label_br)
                        elif "none" not in descendant_labels_br:
                            descendant_labels_br.append("none")
                    if args.colour_backgrounds_by:
                        if d.name in table:
                            this_label_bg = table[d.name][
                                args.colour_backgrounds_by]
                            if this_label_bg not in descendant_labels_bg:
                                descendant_labels_bg.append(this_label_bg)
                        elif "none" not in descendant_labels_bg:
                            descendant_labels_bg.append("none")
#				nstyle = NodeStyle()
#				nstyle["size"] = 0
                if len(descendant_labels_br
                       ) == 1 and descendant_labels_br[0] != "none":
                    this_colour = colour_dict_br[descendant_labels_br[0]]
                    nstyle["vt_line_color"] = this_colour  # set branch colour
                    nstyle["hz_line_color"] = this_colour
                elif args.branch_support_colour and not node.is_leaf():
                    if int(node.support) in support_colours:
                        nstyle["vt_line_color"] = support_colours[int(
                            node.support)]  # take colour from support value
                        nstyle["hz_line_color"] = support_colours[int(
                            node.support)]
                    else:
                        print "  WARNING support values don't make sense. Note scale is assumed to be 0-1 unless using the --branch_support_percent flag."
                if len(descendant_labels_bg
                       ) == 1 and descendant_labels_bg[0] != "none":
                    this_colour = colour_dict_bg[descendant_labels_bg[0]]
                    nstyle["bgcolor"] = this_colour  # set background colour
                node.set_style(nstyle)

    if args.colour_nodes_by:
        if args.colour_nodes_by not in labels:
            print "- Colouring nodes by label " + args.colour_nodes_by
            colour_dict = getColourPalette(column_values[args.colour_nodes_by],
                                           args, args.colour_nodes_by)
            for node in tree.get_leaves():
                if node.name in table:
                    this_label = table[node.name][args.colour_nodes_by]
                    this_colour = colour_dict[this_label]
                    if this_colour != "None":
                        node.img_style["fgcolor"] = this_colour
                        node.img_style["size"] = args.node_size

    for node in tree.traverse():
        node.img_style["hz_line_width"] = args.branch_thickness
        node.img_style["vt_line_width"] = args.branch_thickness

    # matches = search_by_size(tree, 75)
    # print("matches")
    # node = matches[0]
    # node.swap_children()


########### COMENTADO PARA VER COMO QUEDA CON EL BARCODE. PORQUE ESE NO TIENE TODOS LOS NODOS

# rotate specific nodes
# matches = search_by_size(tree, 463)
# print("matches")
# node = matches[0]
# node.swap_children()

# matches = search_by_size(tree, 601)
# print("matches")
# node = matches[0]
# node.swap_children()

# matches = search_by_size(node, 7)
# print("matches")
# node = matches[1]
# node.swap_children()

# matches = search_by_size(node, 5)
# print("matches 5")
# node = matches[0]
# node.swap_children()

# matches = search_by_size(tree, 8)
# print("matches 8")
# node = matches[5]
# node.swap_children()

# matches = search_by_size(tree, 349)
# print("matches 349")
# node = matches[0]
# node.swap_children()

# matches = search_by_size(tree, 192)
# print("matches 192")
# node = matches[1]
# node.swap_children()

# matches = search_by_size(tree, 182)
# print("matches 182")
# node = matches[0]
# node.swap_children()

# matches = search_by_size(tree, 180)
# print("matches 180")
# node = matches[0]
# node.swap_children()

# matches = search_by_size(tree, 175)
# print("matches 175")
# node = matches[0]
# node.swap_children()

# matches = search_by_size(tree, 34)
# print("matches 34")
# node = matches[0]
# node.swap_children()

#### FIN ####

#for n in matches:
#	print n

# set tree style
    ts = TreeStyle()

    ts.draw_guiding_lines = True
    ts.guiding_lines_color = 'black'

    if args.show_leaf_names:
        ts.show_leaf_name = True
    else:
        ts.show_leaf_name = False

    if args.length_scale:
        ts.scale = args.length_scale

    if args.branch_padding:
        ts.branch_vertical_margin = args.branch_padding

    if args.branch_support_print:
        ts.show_branch_support = True

    if args.fan:
        ts.mode = "c"
        print "\nPrinting circular tree (--fan)"
    else:
        print "\nPrinting rectangular tree, to switch to circular use --fan"

    if args.title:
        title = TextFace(args.title, fsize=20)
        title.margin_left = 20
        title.margin_top = 20
        ts.title.add_face(title, column=1)

    if args.no_guiding_lines:
        ts.draw_guiding_lines = False

    if args.data:
        print "\nPrinting data matrix as " + args.data_type + " with range (" + str(
            args.mindata) + "->" + str(args.maxdata) + ";" + str(
                args.centervalue) + "), height " + str(
                    args.data_height) + ", width " + str(args.data_width)
        profileFace = ProfileFace(min_v=args.mindata,
                                  max_v=args.maxdata,
                                  center_v=args.centervalue,
                                  width=args.data_width,
                                  height=args.data_height,
                                  style=args.data_type)

        def mylayout(node):
            if node.is_leaf():
                add_face_to_node(profileFace, node, 0, aligned=True)

        ts.layout_fn = mylayout

    # set root branch length to zero
    tree.dist = 0

    if args.delete_branches:
        #print "Branches "+ args.delete_branches + " will not be shown"
        for branch in args.delete_branches:
            leaf = tree.get_leaves_by_name(branch)[0]  #SRR1173284
            leaf.delete()

    # render tree
    tree.render(args.output, w=args.width, dpi=400, units="mm", tree_style=ts)
    print "\n FINISHED! Tree plot printed to file " + args.output
    print

    if args.print_colour_dict:
        print colour_dict
        if args.colour_branches_by:
            print colour_dict_br
        if args.colour_backgrounds_by:
            print colour_dict_bg

    if args.interactive:
        print "\nEntering interactive mode..."
        tree.show(tree_style=ts)
Beispiel #30
0
def addCoreDataToTree(ete_tree,
                      runid,
                      sanitized=False,
                      any_org=False,
                      all_org=False,
                      only_org=False,
                      none_org=False,
                      uniq_org=False,
                      color="Black",
                      compare_to_adj_clade=False):
    '''A function to add data related to gene and organism distribution across clusters
    to a core gene tree.

    Optionally (with compare_to_adj_clade) instead of comparing to the organisms in the whole tree,
    we compare to only the organisms in the sister clade at each node.

    See http://packages.python.org/ete2/reference/reference_treeview.html#color-names for a list
    of valid color names.'''

    cl = getClusterOrgsByRun(runid)

    outgroup = None
    nodenum = 0
    nodeNumToClusterList = {}
    # The strategy really doesn't matter, it's just for aesthetics... and to make sure its always the same.
    for node in ete_tree.traverse("postorder"):
        nodenum += 1
        leafnames = node.get_leaf_names()

        if compare_to_adj_clade:
            outgroup = []
            if node.is_root():
                # The root node has no sisters
                continue
            else:
                # This is a list - there can be more than one sister node
                sisters = node.get_sisters()
                for sister in sisters:
                    outgroup += sister.get_leaf_names()
                    pass
                pass
            pass

        clusters = findGenesByOrganismList(leafnames,
                                           runid,
                                           cl=cl,
                                           sanitized=True,
                                           all_org=all_org,
                                           any_org=any_org,
                                           only_org=only_org,
                                           none_org=none_org,
                                           uniq_org=uniq_org,
                                           outgroup=outgroup)
        numclusters = len(clusters)
        # This is mostly so that I can keep track of progress.
        sys.stderr.write("%d (N%d)\n" % (numclusters, nodenum))
        numFace = TextFace("%d (N%d)" % (numclusters, nodenum),
                           ftype="Times",
                           fsize=24,
                           fgcolor=color)
        node.add_face(numFace, 0, position="branch-bottom")
        nodeNumToClusterList[nodenum] = clusters

    return ete_tree, nodeNumToClusterList