Exemple #1
0
    def draw(self,
             file,
             colors,
             color_internal_nodes=True,
             legend_labels=(),
             show_branch_support=True,
             show_scale=True,
             legend_scale=1,
             mode="c",
             neighbours=None,
             neighbours_block=None):
        max_color = len(colors)

        used_colors = set()
        for node in self.tree.traverse():
            if not (color_internal_nodes or node.is_leaf()): continue
            color = colors[min(node.color, max_color - 1)]
            node.img_style['bgcolor'] = color
            used_colors.add(color)

        ts = TreeStyle()
        ts.mode = mode
        ts.scale = self.scale
        # Disable the default tip names config
        ts.show_leaf_name = False
        ts.show_branch_support = show_branch_support

        # ts.branch_vertical_margin = 20
        ts.show_scale = show_scale
        cur_max_color = max(v.color for v in self.tree.traverse())
        current_colors = colors[0:cur_max_color + 1]

        for i, (label, color_) in enumerate(zip(legend_labels,
                                                current_colors)):
            if color_ not in used_colors: continue
            rf = RectFace(20 * legend_scale, 16 * legend_scale, color_, color_)
            rf.inner_border.width = 1
            rf.margin_right = 14
            rf.margin_left = 14

            tf = TextFace(label, fsize=26 * legend_scale)
            tf.margin_right = 14

            ts.legend.add_face(rf, column=0)
            ts.legend.add_face(tf, column=1)

        if neighbours:
            old_tree = self.tree.copy()
            self.draw_neighbours(neighbours, neighbours_block)

        self.tree.render(file, w=1000, tree_style=ts)

        if neighbours:
            self.tree = old_tree
Exemple #2
0
def get_tree_style():
    ts = TreeStyle()
    ts.show_leaf_name = False  # True
    ts.layout_fn = layout
    ts.rotation = 90
    ts.branch_vertical_margin = 10
    ts.show_scale = False
    # ts.mode = "c"
    ts.scale = 50

    ts.title.add_face(TextFace(" ", fsize=20), column=0)

    # for n in t.traverse():
    #     nstyle = NodeStyle()
    #     nstyle["fgcolor"] = "red"
    #     nstyle["size"] = 15
    #     n.set_style(nstyle)

    # ts.show_leaf_name = True
    ts.legend.add_face(TextFace("  "), column=0)
    ts.legend.add_face(TextFace("  "), column=1)
    ts.legend.add_face(RectFace(20, 20, NO_SUPPORT_COLOR, NO_SUPPORT_COLOR),
                       column=0)
    ts.legend.add_face(TextFace("  Topic with no support (u(t)=0)"), column=1)
    ts.legend.add_face(TextFace("  "), column=0)
    ts.legend.add_face(TextFace("  "), column=1)
    ts.legend.add_face(RectFace(20, 20, "#90ee90", "#90ee90"), column=0)
    ts.legend.add_face(TextFace("  Topic with minor support 0<u(t)<=0.4"),
                       column=1)
    ts.legend.add_face(TextFace("  "), column=0)
    ts.legend.add_face(TextFace("  "), column=1)
    ts.legend.add_face(RectFace(20, 20, "green", "green"), column=0)
    ts.legend.add_face(
        TextFace(u"  Topic with medium support 0.4<u(t)<=0.6   "), column=1)
    ts.legend.add_face(TextFace("  "), column=0)
    ts.legend.add_face(TextFace("  "), column=1)
    ts.legend.add_face(RectFace(20, 20, "#004000", "#004000"), column=0)
    ts.legend.add_face(TextFace("  Topic with high support u(t)>0.6"),
                       column=1)
    ts.legend.add_face(TextFace("  "), column=0)
    ts.legend.add_face(TextFace("  "), column=1)
    ts.legend.add_face(CircleFace(10, "red"), column=0)
    ts.legend.add_face(TextFace("  Gap"), column=1)
    ts.legend.add_face(TextFace("  "), column=0)
    ts.legend.add_face(TextFace("  "), column=1)
    ts.legend.add_face(RectFace(40, 40, "#004000", "#004000"),
                       column=0)  # green
    # ts.legend.add_face(CircleFace(15, "green"), column=1)
    ts.legend.add_face(TextFace("  Head subject or offshoot"), column=1)
    ts.legend_position = 4

    # ts.title.add_face(TextFace(" ", fsize=20), column=0)

    return ts
def render_tree(tree, mode, cluster, colourDict, width, position):
    duplicates = ["'EBOV|EMLab-RT|KG12||GIN|Boke|?|MinION_LQ05|2015-05-27'", "'EBOV|EMLab-RT|KG45||GIN|Boke|?|MinION_LQ10|2015-06-09'", "'EBOV|EMLab-RT|KG90||GIN|Boke|?|MinION_LQ05|2015-06-19'", "'EBOV|EMLab-RT|KG91||GIN|Boke|?|MinION_LQ05|2015-06-20'"]
    print('Running %s: %s cluster' %(mode, cluster))
    if mode == 'small':
        #delete unwanted leaves
        keep_leaves = []
        b = ["'" + clusters[cluster][0] + "'", "'" + clusters[cluster][1] + "'"]
        for a in tree.get_common_ancestor(b).get_leaves():
            keep_leaves.append(a.name)
        delete_leaves = [leaf for leaf in tree.get_leaf_names() if leaf not in keep_leaves]
        #if cluster == 'Boke':
        #    delete_leaves.extend(duplicates)
        print('Keeping %s leaves' %len(keep_leaves))
        for leaf in delete_leaves:
            if tree.search_nodes(name=leaf)[0]:
                n = tree.search_nodes(name=leaf)[0]
                #if leaf in duplicates:
                #    n.delete(preserve_branch_length=True)
                #else:
                n.delete()
                #print 'Removed %s' %(n.get_leaf_names()[0])
        tree.ladderize()
        tree.write(outfile=sys.argv[1] + '_' + cluster + '.nwk')

    for n in tree.get_leaves():
        display_name = n.get_leaf_names()[0][1:-1]
        country = metadata[display_name]['country']
        instrument = metadata[display_name]['instrument']
        #if cluster == 'Boke':
        if mode == 'big':
            n.add_face(MyTextFace(metadata[display_name]['short_id'], ftype="Helvetica", fsize=size[mode]), column=0, position="aligned")
            n.add_face(MyTextFace(metadata[display_name]['prefec'], ftype="Helvetica", fsize=size[mode]), column=1, position="aligned")
            n.add_face(MyTextFace(metadata[display_name]['date'], ftype="Helvetica", fsize=size[mode]), column=2, position="aligned")
        if country == 'GUI' or country == 'GIN':
            if instrument == 'MinION':
                C = CircleFace(radius=size[mode]/2, color=colourDict[metadata[display_name]['prefec']])
            else:
                C = CircleFace(radius=size[mode]/2, color='#F1F1F1')
        elif country == 'SLE':
            if instrument == 'MinION':
                C = RectFace(width=size[mode], height=size[mode], bgcolor=colourDict[metadata[display_name]['prefec']], fgcolor='#FFFFFF')
            else:
                C = RectFace(width=size[mode], height=size[mode], bgcolor='#D3D3D3', fgcolor='#FFFFFF')
        elif country == 'LIB' or country == 'LBR':
            if instrument == 'MinION':
                C = RectFace(triangle=True, width=size[mode], height=size[mode], bgcolor=colourDict[metadata[display_name]['prefec']], fgcolor='#FFFFFF')
            else:
                C = RectFace(triangle=True, width=size[mode], height=size[mode], bgcolor='#939393', fgcolor='#FFFFFF')
        n.add_face(C, column=1, position=position)
    tree.render(file_name=sys.argv[1] + '_' + cluster + '.pdf', tree_style=ts, w=width)
def layout(node):
    if node.is_leaf():
        N = AttrFace("sci_name", fsize=30)
        faces.add_face_to_node(N, node, 0, position="branch-right")
        circle = RectFace(100, 100, "black", "black")

        faces.add_face_to_node(circle, position="aligned", column=0, node=node)
        if "coli" in node.sci_name:
            circle = RectFace(100, 100, "red", "red")
            faces.add_face_to_node(circle,
                                   position="aligned",
                                   column=1,
                                   node=node)
        if "Salm" in node.sci_name:
            circle = RectFace(100, 100, "blue", "blue")
            faces.add_face_to_node(circle,
                                   position="aligned",
                                   column=2,
                                   node=node)
Exemple #5
0
def get_example_tree():
    # Performs a tree reconciliation analysis
    gene_tree_nw = '((Dme_001,Dme_002),(((Cfa_001,Mms_001),((Hsa_001,Ptr_001),Mmu_001)),(Ptr_002,(Hsa_002,Mmu_002))));'
    t = PhyloTree(gene_tree_nw)
    ts = TreeStyle()
    # disable default PhyloTree Layout
    ts.layout_fn = lambda x: True

    t.link_to_alignment(alg)
    node2content = t.get_cached_content()
    for node in t.traverse():
        node.img_style["size"] = 0

        if not node.is_leaf():
            leaves = node2content[node]
            # get columns with different aa
            subseqs, relevant_columns  = mutation_columns([lf.sequence for lf in leaves])
            for seq in subseqs:
                f = SeqMotifFace(seq, seq_format="seq", width=10, height=8)
                f.margin_top = 2
                f.margin_right = 6
                node.add_face(f, column=0, position="branch-bottom")
            for j, col in enumerate(relevant_columns):
                col_f = RectFace(10, 10, fgcolor=None, bgcolor=None,
                                 label={"text":str(col), "fonttype":"Courier", "color":"black", "fontsize":6})
                node.add_face(col_f, column=j, position="branch-top")
                col_f.margin_bottom = 2
        else:
            f = SeqMotifFace(node.sequence, seq_format="seq", width=6)
            node.add_face(f, column=0, position="aligned")

    alg_length = len(lf.sequence)
    ts.draw_aligned_faces_as_table = False
    for colnum in xrange(alg_length):
        col_f = RectFace(10, 10, fgcolor=None, bgcolor=None,
                         label={"text":str(colnum), "fonttype":"Courier", "color":"black", "fontsize":6})
        ts.aligned_header.add_face(col_f, column=colnum)
    return t, ts
Exemple #6
0
def layout(node):
    if node.is_leaf():
        if node.name=="A":
            node.color="Blue"
            node.attr2="Green"
        elif node.name=="B":
            node.color="Red"
            node.attr2="Orange"
        else:
            node.color="Grey"
            node.attr2="Yellow"
            
        faces.add_face_to_node( CircleFace(radius=5, color=node.color), node, column=1)
        faces.add_face_to_node( RectFace(width=10, height=10, fgcolor=node.attr2, bgcolor=node.attr2),   node, column=2)
def draw_tree(pstrains, names=False, subset=None):
    evol = {x.rstrip() for x in open('input/evolution_experiment.txt')}

    tree = get_tree('input/tree.nwk')

    strains = {x.name for x in tree.traverse() if x.name != ''}
    if subset is None:
        subset = strains
    evol_tree = {x.name for x in tree.traverse() if x.name in evol}

    commensals = {}
    for x in strains:
        if pstrains[x] == 'Commensal strain':
            commensals[x] = colors.cnames['blue']
        elif pstrains[x] == 'Pathogenic strain':
            commensals[x] = colors.cnames['red']
        else:
            commensals[x] = colors.cnames['white']

    ref = NodeStyle()
    ref['fgcolor'] = sns.xkcd_rgb['light red']
    inner = NodeStyle()
    inner['size'] = 0
    for n in tree.traverse():
        if not n.is_leaf():
            n.set_style(inner)
            continue
        if n.name not in subset:
            continue
        if not names:
            r = RectFace(10, 3, commensals[n.name], commensals[n.name])
            n.add_face(r, 0, position="aligned")
        ev = NodeStyle()
        ev["fgcolor"] = "black"
        ev['size'] = 3
        n.set_style(ev)

    circular_style = TreeStyle()
    circular_style.mode = "c"
    if not names:
        circular_style.scale = 1300
    else:
        circular_style.scale = 7300
    circular_style.show_leaf_name = names
    return tree, circular_style
Exemple #8
0
def visualize_tree(ete_tree_obj,
                   genotypes={},
                   metadata={},
                   cansnp_supported_nodes={}):
    """
    Function for visualization of cannonical snp supported clades
    Parameters
    ----------
    ete_tree_obj
    cansnp_supported_nodes

    Returns
    -------

    """

    # Basic tree style
    ts = TreeStyle()
    ts.show_leaf_name = True

    # Draws nodes as small red spheres of diameter equal to 10 pixels

    for n in ete_tree_obj.traverse():
        nstyle = NodeStyle()
        nstyle["shape"] = "sphere"
        nstyle["fgcolor"] = "darkred"

        if n.name in cansnp_supported_nodes:
            print("Found")
            #nstyle["fgcolor"] = "blue"
            #nstyle["size"] = cansnp_supported_nodes[n.name]['size']
            #nstyle["bgcolor"] =cansnp_supported_nodes[n.name]['bgcolor']
            face = RectFace(width=100,
                            height=100,
                            fgcolor='red',
                            bgcolor='green')

            n.add_face(face, column=1)
        n.set_style(nstyle)

    ete_tree_obj.show(tree_style=ts)
Exemple #9
0
def setup_heatmap(tree,
                  tree_style,
                  header,
                  center_value=0,
                  nameMap={},
                  nameLabel='',
                  color_up=0.7,
                  color_down=0.2,
                  color_center="white"):
    DEFAULT_COLOR_SATURATION = 0.5
    BASE_LIGHTNESS = 0.7

    def gradient_color(value, max_value, saturation=0.5, hue=0.1):
        def rgb2hex(rgb):
            return '#%02x%02x%02x' % rgb

        def hls2hex(h, l, s):
            return rgb2hex(
                tuple(map(lambda x: int(x * 255), colorsys.hls_to_rgb(h, l,
                                                                      s))))

        lightness = 1 - (value * BASE_LIGHTNESS) / max_value
        return hls2hex(hue, lightness, DEFAULT_COLOR_SATURATION)

    # Calculate max gradient value from the ClusterTree matrix
    maxv = abs(center_value - tree.arraytable._matrix_max)
    minv = abs(center_value - tree.arraytable._matrix_min)
    if center_value <= tree.arraytable._matrix_min:
        MAX_VALUE = minv + maxv
    else:
        MAX_VALUE = max(maxv, minv)

    # Add heatmap colors to tree
    cols_add_before_heat = 0
    if nameMap:
        cols_add_before_heat = 1
    for lf in tree:
        if nameMap:
            longNameFace = faces.TextFace(nameMap.get(lf.name, lf.name))
            lf.add_face(longNameFace, column=0, position="aligned")

        for i, value in enumerate(getattr(lf, "profile", [])):
            if value > center_value:
                color = gradient_color(abs(center_value - value),
                                       MAX_VALUE,
                                       hue=color_up)
            elif value < center_value:
                color = gradient_color(abs(center_value - value),
                                       MAX_VALUE,
                                       hue=color_down)
            else:
                color = center_value
                #color = "LightGreen"
            lf.add_face(RectFace(25, 25, "white", color),
                        position="aligned",
                        column=i + cols_add_before_heat)
            # Uncomment to add numeric values to the matrix
            #lf.add_face(TextFace("%0.2f "%value, fsize=5), position="aligned", column=i)
        lf.add_face(nameFace,
                    column=i + cols_add_before_heat + 1,
                    position="aligned")

    if nameMap and nameLabel:
        nameF = TextFace(nameLabel, fsize=10)
        #nameF.rotation = -90
        tree_style.aligned_header.add_face(nameF, column=0)
    # Add header
    for i, name in enumerate(header):
        nameF = TextFace(name, fsize=10)
        nameF.rotation = -90
        tree_style.aligned_header.add_face(nameF,
                                           column=i + cols_add_before_heat)
Exemple #10
0
def draw_tree(tree, conf, outfile):
    try:
        from ete3 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 range(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)
Exemple #11
0
    def plot(self, placement, togjson, outdir, cfg):
        """
        plot a plcement in the tree
        show all pplacer placements and the LCA and HCA node
        as well as the inferred lineage
        """
        from ete3 import NodeStyle, TreeStyle
        from ete3 import CircleFace, TextFace, RectFace

        logging.debug("Plotting trees now")
        # with no X display this needs to be set
        os.environ["QT_QPA_PLATFORM"] = "offscreen"
        info = self.loadInfo(togjson)

        def defaultNodeStyle():
            return NodeStyle()

        nodeStyles = defaultdict(defaultNodeStyle)

        no = 0
        for LCAp, HPAp in zip(placement["LCA"], placement["HPA"]):

            plotpath = os.path.join(outdir, f"tree_{no}.png")

            # make shallow copy
            t = self.t

            LCA = LCAp["node"]
            HPA = HPAp["node"]
            # define basic tree style
            ts = TreeStyle()
            # hide leave names
            ts.show_leaf_name = False
            ts.root_opening_factor = 1
            # circular tree
            ts.mode = "c"
            ts.rotation = 210
            ts.arc_start = 0  # 0 degrees = 3 o'clock
            ts.arc_span = 350

            highlightsize = 80
            nodesize = 10

            # define styles for special nodes
            # at the moment hard coded, but could be accesible for the user

            # LCA style
            LCAstyle = NodeStyle()
            LCAstyle["fgcolor"] = "#33a02c"
            LCAstyle["bgcolor"] = "#b2df8a"
            LCAstyle["size"] = highlightsize

            # HPA style
            HPAstyle = NodeStyle()
            HPAstyle["fgcolor"] = "#1f78b4"
            HPAstyle["bgcolor"] = "#a6cee3"
            HPAstyle["size"] = highlightsize

            # default node
            defaultStyle = NodeStyle()
            defaultStyle["fgcolor"] = "gray"
            defaultStyle["size"] = nodesize

            # add legend
            ts.legend_position = 1
            ts.legend.add_face(CircleFace(40, LCAstyle["fgcolor"]), column=1)
            ts.legend.add_face(TextFace(f"LCA", fsize=50), column=2)
            ts.legend.add_face(CircleFace(40, HPAstyle["fgcolor"]), column=1)
            ts.legend.add_face(TextFace(f"HPA", fsize=50), column=2)
            i = 1
            ts.legend.add_face(TextFace(f"p = {i}", fsize=50), column=1)
            while i > 0:
                temp_face = RectFace(60,
                                     10,
                                     fgcolor=p_to_color(i),
                                     bgcolor=p_to_color(i))
                temp_face.margin_top = -4
                ts.legend.add_face(temp_face, column=1)
                i -= 0.01
            ts.legend.add_face(TextFace(f"p = {cfg['minPlacementLikelyhood']}",
                                        fsize=50),
                               column=1)

            # add highlights for each placed protein
            for n in t.traverse():
                if n.name.startswith("PTHR"):
                    # set color based on posterior prob:
                    x = (info[n.name]["post_prob"] -
                         cfg["minPlacementLikelyhood"]) / (
                             1 - cfg["minPlacementLikelyhood"])
                    # orange to purple gradient from 0 to 1 posterior propability
                    he = p_to_color(x)
                    nodeStyles[he]["bgcolor"] = he
                    # define back color of locations
                    n.set_style(nodeStyles[he])

                elif n.name == LCA:
                    n.set_style(LCAstyle)
                elif n.name == HPA:
                    n.set_style(HPAstyle)
                else:
                    n.set_style(defaultStyle)

            # plot to disk
            _ = t.render(plotpath, w=320, units="mm", tree_style=ts)
            no = no + 1
Exemple #12
0
def heatmap_view(tree, orthologous_groups, save_dir):
    """Generates a heatmap of regulation states in all species."""
    light_tree = copy.deepcopy(tree)  # Tree copy for the light heatmap
    # Heat map settings
    rect_face_fgcolor = 'black'
    locus_tag_len = max(
        len(gene.locus_tag) + 5 for ortho_grp in orthologous_groups
        for gene in ortho_grp.genes)
    rect_face_width = locus_tag_len * 8
    light_rect_face_width = 20
    rect_face_height = 20
    rotation = 90

    # Sort orthologous groups by the number of regulated genes in each group
    orthologous_groups = filter_and_sort_orthologous_grps(orthologous_groups)

    # For each species and its gene in each orthologous group, draw a rectangle
    for node, light_node in zip(tree.get_leaves(), light_tree.get_leaves()):
        for i, orthologous_grp in enumerate(orthologous_groups, start=1):
            #get all orthologs in group
            matching_genes = [g for g in orthologous_grp.genes \
            if g.genome.strain_name == node.name]

            #if there is ortholog
            if len(matching_genes) > 0:
                # Get the first ortholog from the genome in the group
                #this is the one with higher probability of regulation.
                #so this probability will be displayed for the group
                gene = matching_genes[0]
                p_regulation = gene.operon.regulation_probability
                p_notregulation = 1.0 - p_regulation
                p_absence = 0
            # No ortholog from this genome
            else:
                gene = None
                p_regulation = 0
                p_notregulation = 0
                p_absence = 1

            # Color of the rectangle is based on probabilities
            rect_face_bgcolor = rgb2hex(p_notregulation, p_regulation,
                                        p_absence)
            rect_face_text = ('%s [%d]' %
                              (gene.locus_tag, gene.operon.operon_id)
                              if gene else '')
            rect_face_label = {
                'text': rect_face_text,
                'font': 'Courier',
                'fontsize': 8,
                'color': 'black'
            }
            # Create the rectangle
            rect_face = RectFace(rect_face_width,
                                 rect_face_height,
                                 rect_face_fgcolor,
                                 rect_face_bgcolor,
                                 label=rect_face_label)
            light_rect_face = RectFace(light_rect_face_width,
                                       rect_face_height,
                                       rect_face_fgcolor,
                                       rect_face_bgcolor,
                                       label='')
            rect_face.rotation = -rotation
            light_rect_face.rotation = -rotation
            # Add the rectangle to the corresponding column
            node.add_face(rect_face, column=i, position='aligned')
            light_node.add_face(light_rect_face, column=i, position='aligned')

    ts = TreeStyle()
    # Add orthologous group descriptions
    descriptions = ['-'.join([grp.description, \
        str([item['ID'] for item in grp.COGs]) if len(grp.COGs)>0 else '', \
        str([item['ID'] for item in grp.NOGs]) if len(grp.NOGs)>0 else '', \
        str([item['ID'] for item in grp.PFAMs])] if len(grp.PFAMs)>0 else '')\
                    for grp in orthologous_groups]
    max_description_len = max(map(len, descriptions))
    descriptions = [
        '[%d]' % i + description + ' ' *
        (max_description_len - len(description))
        for i, description in enumerate(descriptions, start=1)
    ]
    for i, description in enumerate(descriptions, start=1):
        text_face = TextFace(description, ftype='Courier')
        text_face.hz_align = 1
        text_face.vt_align = 1
        text_face.rotation = -rotation
        ts.aligned_header.add_face(text_face, column=i)

    # Rotate the generated heatmap.
    ts.margin_left = 10
    ts.margin_top = 20
    ts.rotation = rotation
    ts.show_scale = False
    # For some reason, it can't render to PDF in color
    tree.render(os.path.join(save_dir, 'heatmap.svg'), tree_style=ts)
    light_tree.render(os.path.join(save_dir, 'heatmap_light.svg'),
                      tree_style=ts)
Exemple #13
0
def draw_tree(the_tree, colour, back_color, label, out_file, the_scale, extend,
              bootstrap, group_file, grid_options, the_table, pres_abs,
              circular):
    t = Tree(the_tree, quoted_node_names=True)
    #    t.ladderize()
    font_size = 8
    font_type = 'Heveltica'
    font_gap = 3
    font_buffer = 10
    o = t.get_midpoint_outgroup()
    t.set_outgroup(o)
    the_leaves = []
    for leaves in t.iter_leaves():
        the_leaves.append(leaves)
    groups = {}
    num = 0
    # set cutoff value for clades as 1/20th of the distance between the furthest two branches
    # assign nodes to groups
    last_node = None
    ca_list = []
    if not group_file is None:
        style = NodeStyle()
        style['size'] = 0
        style["vt_line_color"] = '#000000'
        style["hz_line_color"] = '#000000'
        style["vt_line_width"] = 1
        style["hz_line_width"] = 1
        for n in t.traverse():
            n.set_style(style)
        with open(group_file) as f:
            group_dict = {}
            for line in f:
                group_dict[line.split()[0]] = line.split()[1]
        for node in the_leaves:
            i = node.name
            for j in group_dict:
                if j in i:
                    if group_dict[j] in groups:
                        groups[group_dict[j]].append(i)
                    else:
                        groups[group_dict[j]] = [i]
        coloured_nodes = []
        for i in groups:
            the_col = i
            style = NodeStyle()
            style['size'] = 0
            style["vt_line_color"] = the_col
            style["hz_line_color"] = the_col
            style["vt_line_width"] = 2
            style["hz_line_width"] = 2
            if len(groups[i]) == 1:
                ca = t.search_nodes(name=groups[i][0])[0]
                ca.set_style(style)
                coloured_nodes.append(ca)
            else:
                ca = t.get_common_ancestor(groups[i])
                ca.set_style(style)
                coloured_nodes.append(ca)
                tocolor = []
                for j in ca.children:
                    tocolor.append(j)
                while len(tocolor) > 0:
                    x = tocolor.pop(0)
                    coloured_nodes.append(x)
                    x.set_style(style)
                    for j in x.children:
                        tocolor.append(j)
            ca_list.append((ca, the_col))
        if back_color:
            # for each common ancestor node get it's closest common ancestor neighbour and find the common ancestor of those two nodes
            # colour the common ancestor then add it to the group - continue until only the root node is left
            while len(ca_list) > 1:
                distance = float('inf')
                for i, col1 in ca_list:
                    for j, col2 in ca_list:
                        if not i is j:
                            parent = t.get_common_ancestor(i, j)
                            getit = True
                            the_dist = t.get_distance(i, j)
                            if the_dist <= distance:
                                distance = the_dist
                                the_i = i
                                the_j = j
                                the_i_col = col1
                                the_j_col = col2
                ca_list.remove((the_i, the_i_col))
                ca_list.remove((the_j, the_j_col))
                rgb1 = strtorgb(the_i_col)
                rgb2 = strtorgb(the_j_col)
                rgb3 = ((rgb1[0] + rgb2[0]) / 2, (rgb1[1] + rgb2[1]) / 2,
                        (rgb1[2] + rgb2[2]) / 2)
                new_col = colorstr(rgb3)
                new_node = t.get_common_ancestor(the_i, the_j)
                the_col = new_col
                style = NodeStyle()
                style['size'] = 0
                style["vt_line_color"] = the_col
                style["hz_line_color"] = the_col
                style["vt_line_width"] = 2
                style["hz_line_width"] = 2
                new_node.set_style(style)
                coloured_nodes.append(new_node)
                ca_list.append((new_node, new_col))
                for j in new_node.children:
                    tocolor.append(j)
                while len(tocolor) > 0:
                    x = tocolor.pop(0)
                    if not x in coloured_nodes:
                        coloured_nodes.append(x)
                        x.set_style(style)
                        for j in x.children:
                            tocolor.append(j)
    elif colour:
        distances = []
        for node1 in the_leaves:
            for node2 in the_leaves:
                if node1 != node2:
                    distances.append(t.get_distance(node1, node2))
        distances.sort()
        clade_cutoff = distances[len(distances) / 4]
        for node in the_leaves:
            i = node.name
            if not last_node is None:
                if t.get_distance(node, last_node) <= clade_cutoff:
                    groups[group_num].append(i)
                else:
                    groups[num] = [num, i]
                    group_num = num
                    num += 1
            else:
                groups[num] = [num, i]
                group_num = num
                num += 1
            last_node = node
        for i in groups:
            num = groups[i][0]
            h = num * 360 / len(groups)
            the_col = hsl_to_str(h, 0.5, 0.5)
            style = NodeStyle()
            style['size'] = 0
            style["vt_line_color"] = the_col
            style["hz_line_color"] = the_col
            style["vt_line_width"] = 2
            style["hz_line_width"] = 2
            if len(groups[i]) == 2:
                ca = t.search_nodes(name=groups[i][1])[0]
                ca.set_style(style)
            else:
                ca = t.get_common_ancestor(groups[i][1:])
                ca.set_style(style)
                tocolor = []
                for j in ca.children:
                    tocolor.append(j)
                while len(tocolor) > 0:
                    x = tocolor.pop(0)
                    x.set_style(style)
                    for j in x.children:
                        tocolor.append(j)
            ca_list.append((ca, h))
        # for each common ancestor node get it's closest common ancestor neighbour and find the common ancestor of those two nodes
        # colour the common ancestor then add it to the group - continue until only the root node is left
        while len(ca_list) > 1:
            distance = float('inf')
            got_one = False
            for i, col1 in ca_list:
                for j, col2 in ca_list:
                    if not i is j:
                        parent = t.get_common_ancestor(i, j)
                        getit = True
                        for children in parent.children:
                            if children != i and children != j:
                                getit = False
                                break
                        if getit:
                            the_dist = t.get_distance(i, j)
                            if the_dist <= distance:
                                distance = the_dist
                                the_i = i
                                the_j = j
                                the_i_col = col1
                                the_j_col = col2
                                got_one = True
            if not got_one:
                break
            ca_list.remove((the_i, the_i_col))
            ca_list.remove((the_j, the_j_col))
            new_col = (the_i_col + the_j_col) / 2
            new_node = t.get_common_ancestor(the_i, the_j)
            the_col = hsl_to_str(new_col, 0.5, 0.3)
            style = NodeStyle()
            style['size'] = 0
            style["vt_line_color"] = the_col
            style["hz_line_color"] = the_col
            style["vt_line_width"] = 2
            style["hz_line_width"] = 2
            new_node.set_style(style)
            ca_list.append((new_node, new_col))
    # if you just want a black tree
    else:
        style = NodeStyle()
        style['size'] = 0
        style["vt_line_color"] = '#000000'
        style["hz_line_color"] = '#000000'
        style["vt_line_width"] = 1
        style["hz_line_width"] = 1
        for n in t.traverse():
            n.set_style(style)
    color_list = [(240, 163, 255), (0, 117, 220), (153, 63, 0), (76, 0, 92),
                  (25, 25, 25), (0, 92, 49), (43, 206, 72), (255, 204, 153),
                  (128, 128, 128), (148, 255, 181), (143, 124, 0),
                  (157, 204, 0), (194, 0, 136), (0, 51, 128), (255, 164, 5),
                  (255, 168, 187), (66, 102, 0), (255, 0, 16), (94, 241, 242),
                  (0, 153, 143), (224, 255, 102), (116, 10, 255), (153, 0, 0),
                  (255, 255, 128), (255, 255, 0), (255, 80, 5), (0, 0, 0),
                  (50, 50, 50)]
    up_to_colour = {}
    ts = TreeStyle()
    column_list = []
    width_dict = {}
    if not grid_options is None:
        colour_dict = {}
        type_dict = {}
        min_val_dict = {}
        max_val_dict = {}
        leaf_name_dict = {}
        header_count = 0
        the_columns = {}
        if grid_options == 'auto':
            with open(the_table) as f:
                headers = f.readline().rstrip().split('\t')[1:]
                for i in headers:
                    the_columns[i] = [i]
                    type_dict[i] = 'colour'
                    colour_dict[i] = {'empty': '#FFFFFF'}
                    width_dict[i] = 20
                    up_to_colour[i] = 0
                    column_list.append(i)
        else:
            with open(grid_options) as g:
                for line in g:
                    if line.startswith('H'):
                        name, type, width = line.rstrip().split('\t')[1:]
                        if name in the_columns:
                            the_columns[name].append(name + '_' +
                                                     str(header_count))
                        else:
                            the_columns[name] = [
                                name + '_' + str(header_count)
                            ]
                        width = int(width)
                        name = name + '_' + str(header_count)
                        header_count += 1
                        colour_dict[name] = {'empty': '#FFFFFF'}
                        type_dict[name] = type
                        width_dict[name] = width
                        column_list.append(name)
                        up_to_colour[name] = 0
                        min_val_dict[name] = float('inf')
                        max_val_dict[name] = 0
                    elif line.startswith('C'):
                        c_name, c_col = line.rstrip().split('\t')[1:]
                        if not c_col.startswith('#'):
                            c_col = colorstr(map(int, c_col.split(',')))
                        colour_dict[name][c_name] = c_col
        val_dict = {}
        with open(the_table) as f:
            headers = f.readline().rstrip().split('\t')[1:]
            column_no = {}
            for num, i in enumerate(headers):
                if i in the_columns:
                    column_no[num] = i
            for line in f:
                name = line.split('\t')[0]
                leaf_name = None
                for n in t.traverse():
                    if n.is_leaf():
                        if name.split('.')[0] in n.name:
                            leaf_name = n.name
                if leaf_name is None:
                    continue
                else:
                    leaf_name_dict[leaf_name] = name
                vals = line.rstrip().split('\t')[1:]
                if name in val_dict:
                    sys.exit('Duplicate entry found in table.')
                else:
                    val_dict[name] = {}
                for num, val in enumerate(vals):
                    if num in column_no and val != '':
                        for q in the_columns[column_no[num]]:
                            column_name = q
                            if type_dict[column_name] == 'colour':
                                val_dict[name][column_name] = val
                                if not val in colour_dict[column_name]:
                                    colour_dict[column_name][val] = colorstr(
                                        color_list[up_to_colour[column_name] %
                                                   len(color_list)])
                                    up_to_colour[column_name] += 1
                            elif type_dict[column_name] == 'text':
                                val_dict[name][column_name] = val
                            elif type_dict[column_name] == 'colour_scale_date':
                                year, month, day = val.split('-')
                                year, month, day = int(year), int(month), int(
                                    day)
                                the_val = datetime.datetime(
                                    year, month, day, 0, 0,
                                    0) - datetime.datetime(
                                        1970, 1, 1, 0, 0, 0)
                                val_dict[name][
                                    column_name] = the_val.total_seconds()
                                if the_val.total_seconds(
                                ) < min_val_dict[column_name]:
                                    min_val_dict[
                                        column_name] = the_val.total_seconds()
                                if the_val.total_seconds(
                                ) > max_val_dict[column_name]:
                                    max_val_dict[
                                        column_name] = the_val.total_seconds()
                            elif type_dict[column_name] == 'colour_scale':
                                the_val = float(val)
                                val_dict[name][column_name] = the_val
                                if the_val < min_val_dict[column_name]:
                                    min_val_dict[column_name] = the_val
                                if the_val > max_val_dict[column_name]:
                                    max_val_dict[column_name] = the_val
                            else:
                                sys.exit('Unknown column type')
        if not out_file is None:
            new_desc = open(out_file + '.new_desc', 'w')
        else:
            new_desc = open('viridis.new_desc', 'w')
        ts.legend_position = 3
        leg_column = 0
        for num, i in enumerate(column_list):
            nameF = TextFace(font_gap * ' ' + i.rsplit('_', 1)[0] +
                             ' ' * font_buffer,
                             fsize=font_size,
                             ftype=font_type,
                             tight_text=True)
            nameF.rotation = -90
            ts.aligned_header.add_face(nameF, column=num + 1)
            new_desc.write('H\t' + i.rsplit('_', 1)[0] + '\t' + type_dict[i] +
                           '\t' + str(width_dict[i]) + '\n')
            x = num * 200
            if type_dict[i] == 'colour':
                ts.legend.add_face(TextFace(
                    font_gap * ' ' + i.rsplit('_', 1)[0] + ' ' * font_buffer,
                    fsize=font_size,
                    ftype=font_type,
                    tight_text=True),
                                   column=leg_column + 1)
                ts.legend.add_face(RectFace(width_dict[i], 20, '#FFFFFF',
                                            '#FFFFFF'),
                                   column=leg_column)
                for num2, j in enumerate(colour_dict[i]):
                    new_desc.write('C\t' + j + '\t' + colour_dict[i][j] + '\n')
                    ts.legend.add_face(TextFace(font_gap * ' ' + j +
                                                ' ' * font_buffer,
                                                fsize=font_size,
                                                ftype=font_type,
                                                tight_text=True),
                                       column=leg_column + 1)
                    ts.legend.add_face(RectFace(width_dict[i], 20,
                                                colour_dict[i][j],
                                                colour_dict[i][j]),
                                       column=leg_column)
                leg_column += 2
            elif type_dict[i] == 'colour_scale':
                ts.legend.add_face(TextFace(
                    font_gap * ' ' + i.rsplit('_', 1)[0] + ' ' * font_buffer,
                    fsize=font_size,
                    ftype=font_type,
                    tight_text=True),
                                   column=leg_column + 1)
                ts.legend.add_face(RectFace(width_dict[i], 20, '#FFFFFF',
                                            '#FFFFFF'),
                                   column=leg_column)
                for num2 in range(11):
                    y = num2 * 20 + 30
                    val = (max_val_dict[i] - min_val_dict[i]) * num2 / 10.0
                    h = val / (max_val_dict[i] - min_val_dict[i]) * 270
                    s = 0.5
                    l = 0.5
                    colour = hsl_to_str(h, s, l)
                    ts.legend.add_face(TextFace(font_gap * ' ' + str(val) +
                                                ' ' * font_buffer,
                                                fsize=font_size,
                                                ftype=font_type,
                                                tight_text=True),
                                       column=leg_column + 1)
                    ts.legend.add_face(RectFace(width_dict[i], 20, colour,
                                                colour),
                                       column=leg_column)
                leg_column += 2
            elif type_dict[i] == 'colour_scale_date':
                ts.legend.add_face(TextFace(
                    font_gap * ' ' + i.rsplit('_', 1)[0] + ' ' * font_buffer,
                    fsize=font_size,
                    ftype=font_type,
                    tight_text=True),
                                   column=leg_column + 1)
                ts.legend.add_face(RectFace(width_dict[i], 20, '#FFFFFF',
                                            '#FFFFFF'),
                                   column=leg_column)
                for num2 in range(11):
                    y = num2 * 20 + 30
                    val = (max_val_dict[i] - min_val_dict[i]) * num2 / 10.0
                    h = val / (max_val_dict[i] - min_val_dict[i]) * 360
                    s = 0.5
                    l = 0.5
                    colour = hsl_to_str(h, s, l)
                    days = str(int(val / 60 / 60 / 24)) + ' days'
                    ts.legend.add_face(TextFace(font_gap * ' ' + days +
                                                ' ' * font_buffer,
                                                fsize=font_size,
                                                ftype=font_type,
                                                tight_text=True),
                                       column=leg_column + 1)
                    ts.legend.add_face(RectFace(width_dict[i], 20, colour,
                                                colour),
                                       column=leg_column)
                leg_column += 2
            for n in t.traverse():
                if n.is_leaf():
                    name = leaf_name_dict[n.name]
                    if i in val_dict[name]:
                        val = val_dict[name][i]
                    else:
                        val = 'empty'
                    if type_dict[i] == 'colour':
                        n.add_face(RectFace(width_dict[i], 20,
                                            colour_dict[i][val],
                                            colour_dict[i][val]),
                                   column=num + 1,
                                   position="aligned")
                    elif type_dict[i] == 'colour_scale' or type_dict[
                            i] == 'colour_scale_date':
                        if val == 'empty':
                            colour = '#FFFFFF'
                        else:
                            h = (val - min_val_dict[i]) / (
                                max_val_dict[i] - min_val_dict[i]) * 360
                            s = 0.5
                            l = 0.5
                            colour = hsl_to_str(h, s, l)
                        n.add_face(RectFace(width_dict[i], 20, colour, colour),
                                   column=num + 1,
                                   position="aligned")
                    elif type_dict[i] == 'text':
                        n.add_face(TextFace(font_gap * ' ' + val +
                                            ' ' * font_buffer,
                                            fsize=font_size,
                                            ftype=font_type,
                                            tight_text=True),
                                   column=num + 1,
                                   position="aligned")
    if not pres_abs is None:
        starting_col = len(column_list) + 1
        subprocess.Popen('makeblastdb -out tempdb -dbtype prot -in ' +
                         pres_abs[0],
                         shell=True).wait()
        folder = pres_abs[1]
        len_dict = {}
        gene_list = []
        ts.legend.add_face(TextFace(font_gap * ' ' + 'Gene present/absent' +
                                    ' ' * font_buffer,
                                    fsize=font_size,
                                    ftype=font_type,
                                    tight_text=True),
                           column=starting_col + 1)
        ts.legend.add_face(RectFace(20, 20, '#FFFFFF', '#FFFFFF'),
                           column=starting_col)
        ts.legend.add_face(TextFace(font_gap * ' ' + 'Gene present/absent' +
                                    ' ' * font_buffer,
                                    fsize=font_size,
                                    ftype=font_type,
                                    tight_text=True),
                           column=starting_col + 1)
        ts.legend.add_face(RectFace(20, 20, "#5ba965", "#5ba965"),
                           column=starting_col)
        ts.legend.add_face(TextFace(font_gap * ' ' + 'Gene present/absent' +
                                    ' ' * font_buffer,
                                    fsize=font_size,
                                    ftype=font_type,
                                    tight_text=True),
                           column=starting_col + 1)
        ts.legend.add_face(RectFace(20, 20, "#cb5b4c", "#cb5b4c"),
                           column=starting_col)
        with open(pres_abs[0]) as f:
            for line in f:
                if line.startswith('>'):
                    name = line.split()[0][1:]
                    gene_list.append(name)
                    len_dict[name] = 0
                    nameF = TextFace(font_gap * ' ' + name + ' ' * font_buffer,
                                     fsize=font_size,
                                     ftype=font_type,
                                     tight_text=True)
                    nameF.rotation = -90
                    ts.aligned_header.add_face(nameF,
                                               column=starting_col +
                                               len(gene_list) - 1)
                else:
                    len_dict[name] += len(line.rstrip())
        min_length = 0.9
        min_ident = 90
        for n in t.iter_leaves():
            the_name = n.name
            if the_name[0] == '"' and the_name[-1] == '"':
                the_name = the_name[1:-1]
            if the_name.endswith('.ref'):
                the_name = the_name[:-4]
            if not os.path.exists(folder + '/' + the_name):
                for q in os.listdir(folder):
                    if q.startswith(the_name):
                        the_name = q
            if not os.path.exists(the_name + '.blast'):
                subprocess.Popen(
                    'blastx -query ' + folder + '/' + the_name +
                    ' -db tempdb -outfmt 6 -num_threads 24 -out ' + the_name +
                    '.blast',
                    shell=True).wait()
            gotit = set()
            with open(the_name + '.blast') as b:
                for line in b:
                    query, subject, ident, length = line.split()[:4]
                    ident = float(ident)
                    length = int(length)
                    if ident >= min_ident and length >= min_length * len_dict[
                            subject]:
                        gotit.add(subject)
            for num, i in enumerate(gene_list):
                if i in gotit:
                    colour = "#5ba965"
                else:
                    colour = "#cb5b4c"
                n.add_face(RectFace(20, 20, colour, colour),
                           column=num + starting_col,
                           position="aligned")
        # for num, i in enumerate(gene_list):
        #     x = (starting_col + num) * 200
        #     svg.writeString(i, x+50, 20, 12)
        #     y = 30
        #     svg.drawOutRect(x + 50, y, 12, 12, strtorgb('#5ba965'), strtorgb('#5ba965'), lt=0)
        #     svg.writeString('present', x + 70, y + 12, 12)
        #     y = 50
        #     svg.drawOutRect(x + 50, y, 12, 12, strtorgb('#cb5b4c'), strtorgb('#cb5b4c'), lt=0)
        #     svg.writeString('absent', x + 70, y + 12, 12)

    # Set these to False if you don't want bootstrap/distance values
    ts.show_branch_length = label
    ts.show_branch_support = bootstrap
    ts.show_leaf_name = False
    for node in t.traverse():
        if node.is_leaf():
            node.add_face(AttrFace("name",
                                   fsize=font_size,
                                   ftype=font_type,
                                   tight_text=True,
                                   fgcolor='black'),
                          column=0,
                          position="aligned")

    ts.margin_left = 20
    ts.margin_right = 100
    ts.margin_top = 20
    ts.margin_bottom = 20
    if extend:
        ts.draw_guiding_lines = True
    ts.scale = the_scale
    if not circular is None:
        ts.mode = "c"
        ts.arc_start = 0
        ts.arc_span = 360
    if out_file is None:
        t.show(tree_style=ts)
    else:
        t.render(out_file, w=210, units='mm', tree_style=ts)
    def create_circle(self,
                      filename,
                      title,
                      name2color=None,
                      name2class_dic=None,
                      class2color_dic=None,
                      vector=None,
                      ignore_branch_length=True):

        plt.clf()
        axis_font = {'size': '3'}
        plt.rc('xtick', labelsize=0.1)
        plt.rc('ytick', labelsize=0.1)
        plt.rc({'font.size': 0.1})

        # legend creation
        if name2class_dic and class2color_dic:
            leg = []
            for cls, color in class2color_dic.items():
                leg.append(mpatches.Patch(color=color, label=cls))

        t = Tree(self.nwk)
        # iterate over tree leaves only
        for l in t.iter_leaves():
            ns = NodeStyle()
            if name2color:
                ns["bgcolor"] = name2color[
                    l.name] if l.name in name2color else 'white'
            elif name2class_dic and class2color_dic:
                ns["bgcolor"] = class2color_dic[name2class_dic[
                    l.name]] if l.name in name2class_dic else 'white'
            # Gray dashed branch lines
            #ns["hz_line_type"] = 1
            #ns["hz_line_color"] = "#cccccc"
            #
            l.img_style = ns
            F = TextFace(l.name)
            F.ftype = 'Times'
            #if vector:
            #    if l.name in vector:
            l.add_features(profile=[random.random()
                                    for x in range(10)])  #vector[l.name])
            l.add_features(deviation=[0 for x in range(10)
                                      ])  #len(vector[l.name]))])
            l.add_face(ProfileFace(max_v=1,
                                   min_v=0.0,
                                   center_v=0.5,
                                   width=200,
                                   height=40,
                                   style='heatmap',
                                   colorscheme=5),
                       column=0,
                       position='aligned')
        # Create an empty TreeStyle
        ts = TreeStyle()

        # Set our custom layout function
        ts.layout_fn = VisualizeCircularTree.layout

        # Draw a tree
        ts.mode = "c"

        # We will add node names manually
        ts.show_leaf_name = False
        # Show branch data
        ts.show_branch_length = True
        ts.show_branch_support = True
        ts.force_topology = ignore_branch_length
        ts.title.add_face(TextFace(title, fsize=20, ftype='Times'), column=15)

        # legend creation
        if name2class_dic and class2color_dic:
            for k, (cls, col) in enumerate(class2color_dic.items()):
                x = RectFace(8, 8, 'black', col)
                #x.opacity=0.5
                ts.legend.add_face(x, column=8)
                ts.legend.add_face(TextFace(' ' + cls + '   ',
                                            fsize=9,
                                            ftype='Times'),
                                   column=9)

        t.render(filename + '.pdf', tree_style=ts, dpi=5000)
big_tree.ladderize()

ts = TreeStyle()
ts.show_leaf_name = False
#ts.show_branch_support = True
ts.scale = 100000
if mode == 'small':
    ts.scale = 750000

#add legend
for each in list(colourDict.keys()):
    ts.legend.add_face(CircleFace(radius=size[mode]/2, color=colourDict[each]), column=0)
    ts.legend.add_face(TextFace(each, ftype="Helvetica", fsize=size[mode]), column=1)
ts.legend.add_face(CircleFace(radius=size[mode]/2, color='#F1F1F1'), column=0)
ts.legend.add_face(TextFace('Guinea', ftype="Helvetica", fsize=size[mode]), column=1)
ts.legend.add_face(RectFace(width=size[mode], height=size[mode], bgcolor='#D3D3D3', fgcolor='#FFFFFF'), column=0)
ts.legend.add_face(TextFace('Sierra Leone', ftype="Helvetica", fsize=size[mode]), column=1)
ts.legend.add_face(RectFace(triangle=True, width=size[mode], height=size[mode], bgcolor='#939393', fgcolor='#FFFFFF'), column=0)
ts.legend.add_face(TextFace('Liberia', ftype="Helvetica", fsize=size[mode]), column=1)

#reset nodes
ns = NodeStyle()
ns['size'] = 0
ns['hz_line_width'] = 2
ns['vt_line_width'] = 2
if mode =='big':
    ns['hz_line_width'] = 0
    ns['vt_line_width'] = 0
for n in big_tree.traverse():
        n.set_style(ns)
def format( tree , genedict , detection , includenames , filename , speciescolors = None):
	print 'final output...'
	red = Color('red')
	blue = Color('blue')
	colorvec = list(red.range_to(blue, len(genedict.keys())))
	colormap = {}
	columnmap = {}
	for i,ref in enumerate(genedict):
		if ref not in detection:	
			columnmap[ref] = 3
			if 'hybrid' in ref.lower():
				columnmap[ref] = 0
			if 'eff' in ref.lower():
				columnmap[ref] = 1
			if 'hap' in ref.lower():
				columnmap[ref] = 2
			colormap[ref] = colorvec[i].hex
	for i,ref in enumerate(detection):
		columnmap[ref] = 3 + i
		colormap[ref] = colorvec[i].hex 

	print columnmap
	print colormap

	circledict = {}
	for n in t.traverse():
		
		nst = NodeStyle()
		nst["size"] = 0
		nst["fgcolor"] = 'black'
		nst["hz_line_width"] = 4
		nst["vt_line_width"]= 4
		nst.show_name = False
		if n.is_leaf():
			if speciescolors != None and n.name in speciescolors:
				nst["bgcolor"] = colors[n.name]
			nst.show_name = True			
			n.add_face( AttrFace(attr = 'name', ftype='Helvetica', fgcolor='black', fsize =18 ,fstyle = 'normal'   ), column =0 )
			refs = json.loads(n.refs)
			for ref in genedict:
				if ref in refs and ref in detection:
					n.add_face( CircleFace ( 10 , colormap[ref]), column =  2 + columnmap[ref] )
					n.img_style = nst
				if ref in refs and ref not in detection:
					n.add_face( RectFace ( 20 , 20 , colormap[ref], colormap[ref] ), column =  2 + columnmap[ref] )
					n.img_style = nst
				if ref not in refs and ref not in detection:
					n.add_face( RectFace ( 20 , 20 , colormap[ref], 'white' ), column =  2 + columnmap[ref] )
					n.img_style = nst
			###color by species
			if n.name in speciescolors:
				nst['bgcolor'] = speciescolors[n.name]
		else:
			if n.name.strip() in includenames:
				n.add_face( AttrFace(attr = 'name', ftype='Helvetica', fgcolor='black', fsize =20 ,fstyle = 'normal'   ), column =0 )
				nst.size = 2
				n.img_style = nst
			else:
				nst.size = 0
				n.img_style = nst 
	ts = TreeStyle()
	for i,ref in enumerate(colormap.keys()):
		if 'ubi' not in ref:
			ts.title.add_face(TextFace(ref, fsize=12), column=0)
			ts.title.add_face( RectFace(10 , 10 , colormap[ref] , colormap[ref]), column = 1)
	ts.show_leaf_name=False 

	"""ts.mode = "c"
				ts.arc_start = 270
				ts.arc_span = 359
				ts.root_opening_factor = 1
			"""
	ts.scale =  190
	
	t.show(tree_style = ts)
	t.render(filename + ".png", tree_style = ts)
	t.render( filename +".svg" , tree_style = ts)
Exemple #17
0
        if "coli" in node.sci_name:
            circle = RectFace(100, 100, "red", "red")
            faces.add_face_to_node(circle,
                                   position="aligned",
                                   column=1,
                                   node=node)
        if "Salm" in node.sci_name:
            circle = RectFace(100, 100, "blue", "blue")
            faces.add_face_to_node(circle,
                                   position="aligned",
                                   column=2,
                                   node=node)


ts = TreeStyle()
ts.branch_vertical_margin = 10
ts.allow_face_overlap = False
ts.show_scale = False
ts.show_leaf_name = False
ts.layout_fn = layout
ts.mode = "c"
ts.root_opening_factor = .25
ts.optimal_scale_level = "full"
ts.force_topology = True
for i, j in enumerate(lineage_colors.keys()):
    ts.legend.add_face(RectFace(10000, 300, lineage_colors[j],
                                lineage_colors[j]),
                       column=i)
    ts.legend.add_face(TextFace(j, fsize=600), column=i)
tree.show(tree_style=ts)
Exemple #18
0
def run(args):
    if args.text_mode:
        from ete3 import Tree
        for tindex, tfile in enumerate(args.src_tree_iterator):
            #print tfile
            if args.raxml:
                nw = re.sub(":(\d+\.\d+)\[(\d+)\]", ":\\1[&&NHX:support=\\2]",
                            open(tfile).read())
                t = Tree(nw)
            else:
                t = Tree(tfile)

            print(
                t.get_ascii(show_internal=args.show_internal_names,
                            attributes=args.show_attributes))
        return

    import random
    import re
    import colorsys
    from collections import defaultdict
    from ete3 import (Tree, PhyloTree, TextFace, RectFace, faces, TreeStyle,
                      add_face_to_node, random_color)

    global FACES

    if args.face:
        FACES = parse_faces(args.face)
    else:
        FACES = []

    # VISUALIZATION
    ts = TreeStyle()
    ts.mode = args.mode
    ts.show_leaf_name = True
    ts.tree_width = args.tree_width

    for f in FACES:
        if f["value"] == "@name":
            ts.show_leaf_name = False
            break

    if args.as_ncbi:
        ts.show_leaf_name = False
        FACES.extend(
            parse_faces([
                'value:@sci_name, size:10, fstyle:italic',
                'value:@taxid, color:grey, size:6, format:" - %s"',
                'value:@sci_name, color:steelblue, size:7, pos:b-top, nodetype:internal',
                'value:@rank, color:indianred, size:6, pos:b-bottom, nodetype:internal',
            ]))

    if args.alg:
        FACES.extend(
            parse_faces([
                'value:@sequence, size:10, pos:aligned, ftype:%s' %
                args.alg_type
            ]))

    if args.heatmap:
        FACES.extend(
            parse_faces(['value:@name, size:10, pos:aligned, ftype:heatmap']))

    if args.bubbles:
        for bubble in args.bubbles:
            FACES.extend(
                parse_faces([
                    'value:@%s, pos:float, ftype:bubble, opacity:0.4' % bubble,
                ]))

    ts.branch_vertical_margin = args.branch_separation
    if args.show_support:
        ts.show_branch_support = True
    if args.show_branch_length:
        ts.show_branch_length = True
    if args.force_topology:
        ts.force_topology = True
    ts.layout_fn = lambda x: None

    for tindex, tfile in enumerate(args.src_tree_iterator):
        #print tfile
        if args.raxml:
            nw = re.sub(":(\d+\.\d+)\[(\d+)\]", ":\\1[&&NHX:support=\\2]",
                        open(tfile).read())
            t = PhyloTree(nw)
        else:
            t = PhyloTree(tfile)

        if args.alg:
            t.link_to_alignment(args.alg, alg_format=args.alg_format)

        if args.heatmap:
            DEFAULT_COLOR_SATURATION = 0.3
            BASE_LIGHTNESS = 0.7

            def gradient_color(value, max_value, saturation=0.5, hue=0.1):
                def rgb2hex(rgb):
                    return '#%02x%02x%02x' % rgb

                def hls2hex(h, l, s):
                    return rgb2hex(
                        tuple([
                            int(x * 255) for x in colorsys.hls_to_rgb(h, l, s)
                        ]))

                lightness = 1 - (value * BASE_LIGHTNESS) / max_value
                return hls2hex(hue, lightness, DEFAULT_COLOR_SATURATION)

            heatmap_data = {}
            max_value, min_value = None, None
            for line in open(args.heatmap):
                if line.startswith('#COLNAMES'):
                    pass
                elif line.startswith('#') or not line.strip():
                    pass
                else:
                    fields = line.split('\t')
                    name = fields[0].strip()

                    values = [float(x) if x else None for x in fields[1:]]

                    maxv = max(values)
                    minv = min(values)
                    if max_value is None or maxv > max_value:
                        max_value = maxv
                    if min_value is None or minv < min_value:
                        min_value = minv
                    heatmap_data[name] = values

            heatmap_center_value = 0
            heatmap_color_center = "white"
            heatmap_color_up = 0.3
            heatmap_color_down = 0.7
            heatmap_color_missing = "black"

            heatmap_max_value = abs(heatmap_center_value - max_value)
            heatmap_min_value = abs(heatmap_center_value - min_value)

            if heatmap_center_value <= min_value:
                heatmap_max_value = heatmap_min_value + heatmap_max_value
            else:
                heatmap_max_value = max(heatmap_min_value, heatmap_max_value)

        # scale the tree
        if not args.height:
            args.height = None
        if not args.width:
            args.width = None

        f2color = {}
        f2last_seed = {}
        for node in t.traverse():
            node.img_style['size'] = 0
            if len(node.children) == 1:
                node.img_style['size'] = 2
                node.img_style['shape'] = "square"
                node.img_style['fgcolor'] = "steelblue"

            ftype_pos = defaultdict(int)

            for findex, f in enumerate(FACES):
                if (f['nodetype'] == 'any'
                        or (f['nodetype'] == 'leaf' and node.is_leaf()) or
                    (f['nodetype'] == 'internal' and not node.is_leaf())):

                    # if node passes face filters
                    if node_matcher(node, f["filters"]):
                        if f["value"].startswith("@"):
                            fvalue = getattr(node, f["value"][1:], None)
                        else:
                            fvalue = f["value"]

                        # if node's attribute has content, generate face
                        if fvalue is not None:
                            fsize = f["size"]
                            fbgcolor = f["bgcolor"]
                            fcolor = f['color']

                            if fcolor:
                                # Parse color options
                                auto_m = re.search("auto\(([^)]*)\)", fcolor)
                                if auto_m:
                                    target_attr = auto_m.groups()[0].strip()
                                    if not target_attr:
                                        color_keyattr = f["value"]
                                    else:
                                        color_keyattr = target_attr

                                    color_keyattr = color_keyattr.lstrip('@')
                                    color_bin = getattr(
                                        node, color_keyattr, None)

                                    last_seed = f2last_seed.setdefault(
                                        color_keyattr, random.random())

                                    seed = last_seed + 0.10 + random.uniform(
                                        0.1, 0.2)
                                    f2last_seed[color_keyattr] = seed

                                    fcolor = f2color.setdefault(
                                        color_bin, random_color(h=seed))

                            if fbgcolor:
                                # Parse color options
                                auto_m = re.search("auto\(([^)]*)\)", fbgcolor)
                                if auto_m:
                                    target_attr = auto_m.groups()[0].strip()
                                    if not target_attr:
                                        color_keyattr = f["value"]
                                    else:
                                        color_keyattr = target_attr

                                    color_keyattr = color_keyattr.lstrip('@')
                                    color_bin = getattr(
                                        node, color_keyattr, None)

                                    last_seed = f2last_seed.setdefault(
                                        color_keyattr, random.random())

                                    seed = last_seed + 0.10 + random.uniform(
                                        0.1, 0.2)
                                    f2last_seed[color_keyattr] = seed

                                    fbgcolor = f2color.setdefault(
                                        color_bin, random_color(h=seed))

                            if f["ftype"] == "text":
                                if f.get("format", None):
                                    fvalue = f["format"] % fvalue

                                F = TextFace(fvalue,
                                             fsize=fsize,
                                             fgcolor=fcolor or "black",
                                             fstyle=f.get('fstyle', None))

                            elif f["ftype"] == "fullseq":
                                F = faces.SeqMotifFace(seq=fvalue,
                                                       seq_format="seq",
                                                       seqtail_format="seq",
                                                       height=fsize)
                            elif f["ftype"] == "compactseq":
                                F = faces.SeqMotifFace(
                                    seq=fvalue,
                                    seq_format="compactseq",
                                    seqtail_format="compactseq",
                                    height=fsize)
                            elif f["ftype"] == "blockseq":
                                F = faces.SeqMotifFace(
                                    seq=fvalue,
                                    seq_format="blockseq",
                                    seqtail_format="blockseq",
                                    height=fsize,
                                    fgcolor=fcolor or "slategrey",
                                    bgcolor=fbgcolor or "slategrey",
                                    scale_factor=1.0)
                                fbgcolor = None
                            elif f["ftype"] == "bubble":
                                try:
                                    v = float(fvalue)
                                except ValueError:
                                    rad = fsize
                                else:
                                    rad = fsize * v
                                F = faces.CircleFace(radius=rad,
                                                     style="sphere",
                                                     color=fcolor
                                                     or "steelblue")

                            elif f["ftype"] == "heatmap":
                                if not f['column']:
                                    col = ftype_pos[f["pos"]]
                                else:
                                    col = f["column"]

                                for i, value in enumerate(
                                        heatmap_data.get(node.name, [])):
                                    ftype_pos[f["pos"]] += 1

                                    if value is None:
                                        color = heatmap_color_missing
                                    elif value > heatmap_center_value:
                                        color = gradient_color(
                                            abs(heatmap_center_value - value),
                                            heatmap_max_value,
                                            hue=heatmap_color_up)
                                    elif value < heatmap_center_value:
                                        color = gradient_color(
                                            abs(heatmap_center_value - value),
                                            heatmap_max_value,
                                            hue=heatmap_color_down)
                                    else:
                                        color = heatmap_color_center
                                    node.add_face(RectFace(
                                        20, 20, color, color),
                                                  position="aligned",
                                                  column=col + i)
                                    # Add header
                                    # for i, name in enumerate(header):
                                    #    nameF = TextFace(name, fsize=7)
                                    #    nameF.rotation = -90
                                    #    tree_style.aligned_header.add_face(nameF, column=i)
                                F = None

                            elif f["ftype"] == "profile":
                                # internal profiles?
                                F = None
                            elif f["ftype"] == "barchart":
                                F = None
                            elif f["ftype"] == "piechart":
                                F = None

                            # Add the Face
                            if F:
                                F.opacity = f['opacity'] or 1.0

                                # Set face general attributes
                                if fbgcolor:
                                    F.background.color = fbgcolor

                                if not f['column']:
                                    col = ftype_pos[f["pos"]]
                                    ftype_pos[f["pos"]] += 1
                                else:
                                    col = f["column"]
                                node.add_face(F, column=col, position=f["pos"])

        if args.image:
            t.render("t%d.%s" % (tindex, args.image),
                     tree_style=ts,
                     w=args.width,
                     h=args.height,
                     units=args.size_units)
        else:
            t.show(None, tree_style=ts)
def traitTestTrees(scenarios, traits, mapper, outDir, treePath, floatSwitch=0):

    # styles for convergent and transition nodes
    styleConv = NodeStyle()
    styleConv["fgcolor"] = "black"
    styleConv["size"] = 0
    styleConv["hz_line_width"] = branchWidth
    styleConv["vt_line_width"] = branchWidth
    styleConv["hz_line_color"] = "orange"
    styleConv["vt_line_color"] = "orange"

    styleTran = NodeStyle()
    styleTran["fgcolor"] = "black"
    styleTran["size"] = 0
    styleTran["hz_line_width"] = branchWidth
    styleTran["vt_line_width"] = branchWidth
    styleTran["vt_line_color"] = "orange"

    # face object indicating a transition
    block = RectFace(4, 20, "blue", "blue")
    block.margin_right = 2

    def rgb2hex(r, g, b):
        hex = "#{:02x}{:02x}{:02x}".format(r, g, b)
        return hex

    # loop thru trees
    for cutoff in sorted(scenarios.keys()):
        tree = init_tree(treePath)

        #tree.convert_to_ultrametric(tree_length=1)

        # parse scenario
        manual_mode_nodes = {"T": [], "C": []}
        p_events = scenarios[cutoff].strip().split("/")
        for e in p_events:
            l_e = map(int, e.split(","))
            manual_mode_nodes["T"].append(l_e[0])
            manual_mode_nodes["C"].extend(l_e[1:])

        # loop thru nodes
        for n in tree.traverse():

            #outline for the circle node
            #ol = CircleFace(11, color = "black")#
            #n.add_face(ol, column=1, position="float-behind") #float-behind

            # draw circle face with mapped color
            nd = CircleFace(
                14, color=rgb2hex(*[int(val) for val in mapper(traits[n.ND])]))
            nd.background.color = None
            nd.border.width = None

            if manual_mode_nodes:
                if n.ND in manual_mode_nodes["T"]:
                    n.set_style(styleTran)
                    n.add_face(block, column=0, position="float")
                elif n.ND in manual_mode_nodes["C"]:
                    n.set_style(styleConv)
                else:
                    n.set_style(nstyle)
            else:
                nd.background.color = "white"

            n.add_face(nd, column=2, position="float")  # float
            # this is necessary for some reason to keep the tree from collapsing
            n.add_face(TextFace("       "), column=2, position="branch-bottom")
            n.img_style["size"] = 0

        outFile = str(round(cutoff, floatSwitch)).replace('.', '_') + ".pdf"

        # prepend path to filename
        outFile = outDir + '/' + outFile
        tree.render(outFile, h=6, units="in", tree_style=tree_style)
        print >> sys.stderr, outFile
def draw_tree(variant_dict, profile_dict, the_tree, ref_name):
    major_alleles, minor_alleles = profile_dict
    t = Tree(the_tree, quoted_node_names=True)
    font_size = 8
    font_type = 'Heveltica'
    font_gap = 3
    font_buffer = 10
    ts = TreeStyle()
    position_list = None
    allele_count = {}
    max_major = 0
    max_minor = 0
    max_combo = 0
    max_major_minor = 0
    for n in t.iter_leaves():
        the_name = n.name
        if the_name == ref_name:
            t.set_outgroup(n)
        if position_list is None:
            position_list = list(variant_dict[the_name])
            position_list.sort()
            for num, i in enumerate(position_list):
                nameF = TextFace(font_gap * ' ' + str(i) + ' ' * font_buffer,
                                 fsize=font_size,
                                 ftype=font_type,
                                 tight_text=True)
                nameF.rotation = -90
                ts.aligned_header.add_face(nameF, column=num)
        minor_allele, major_allele, missing = 0, 0, 0
        for num, i in enumerate(position_list):
            if i in major_alleles and variant_dict[the_name][
                    i] in major_alleles[i]:
                s, l = 0.0, 0.1
                major_allele += 1
            elif i in minor_alleles and variant_dict[the_name][
                    i] in minor_alleles[i]:
                s, l = 0.0, 0.5
                minor_allele += 1
            else:
                s, l = 0.0, 0.9
                missing += 1
            if variant_dict[the_name][i] == 'a':
                colour = colorstr(hsl_to_rgb(0, s, l))
                #colour = "#65dad0"
            elif variant_dict[the_name][i] == 't':
                colour = colorstr(hsl_to_rgb(140, s, l))
                #colour = "#daa3dc"
            elif variant_dict[the_name][i] == 'c':
                colour = colorstr(hsl_to_rgb(220, s, l))
                #colour = "#9bd686"
            elif variant_dict[the_name][i] == 'g':
                colour = colorstr(hsl_to_rgb(300, s, l))
                #colour = "#e1b86f"
            else:
                colour = "#ffffff"
            #colour = colorstr(hsl_to_rgb(h, s, l))
            n.add_face(RectFace(20, 20, colour, colour),
                       column=num,
                       position="aligned")
        allele_count[the_name] = (major_allele, minor_allele, missing)
        if major_allele > max_major:
            max_major = major_allele
        if minor_allele + major_allele >= max_combo:
            max_combo = minor_allele + major_allele
        if minor_allele >= max_minor:
            max_minor = minor_allele
            if major_allele > max_major_minor:
                max_major_minor = major_allele
    nst1 = NodeStyle()
    nst1["bgcolor"] = "LightSteelBlue"
    nst2 = NodeStyle()
    nst2["bgcolor"] = "Moccasin"
    with open(args.out_text, 'w') as o:
        for n in t.iter_leaves():
            the_name = n.name
            major_allele, minor_allele, missing = allele_count[the_name]
            if major_allele == max_major:
                o.write("max_major\t%s\t%d\t%d\t%d\n" %
                        (the_name, major_allele, minor_allele, missing))
                n.img_style["bgcolor"] = "#cb6a49"
            elif minor_allele == max_minor and major_allele == max_major_minor:
                o.write("max_minor\t%s\t%d\t%d\t%d\n" %
                        (the_name, major_allele, minor_allele, missing))
                n.img_style["bgcolor"] = "#7aa457"
            elif minor_allele + major_allele == max_combo:
                o.write("max_combo\t%s\t%d\t%d\t%d\n" %
                        (the_name, major_allele, minor_allele, missing))
                n.img_style["bgcolor"] = "#a46cb7"
            n.add_face(TextFace('%d/%d/%d' %
                                (major_allele, minor_allele, missing),
                                fsize=font_size,
                                ftype=font_type,
                                tight_text=True),
                       column=len(position_list),
                       position="aligned")

    ts.legend.add_face(TextFace('A',
                                fsize=font_size,
                                ftype=font_type,
                                tight_text=True),
                       column=0)
    s = 0.5
    ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(0, s, 0.3)),
                                colorstr(hsl_to_rgb(0, s, 0.3))),
                       column=1)
    ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(0, s, 0.5)),
                                colorstr(hsl_to_rgb(0, s, 0.5))),
                       column=2)
    ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(0, s, 0.8)),
                                colorstr(hsl_to_rgb(0, s, 0.8))),
                       column=3)
    ts.legend.add_face(TextFace('T',
                                fsize=font_size,
                                ftype=font_type,
                                tight_text=True),
                       column=0)
    ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(140, s, 0.3)),
                                colorstr(hsl_to_rgb(140, s, 0.3))),
                       column=1)
    ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(140, s, 0.5)),
                                colorstr(hsl_to_rgb(140, s, 0.5))),
                       column=2)
    ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(140, s, 0.8)),
                                colorstr(hsl_to_rgb(140, s, 0.8))),
                       column=3)
    ts.legend.add_face(TextFace('C',
                                fsize=font_size,
                                ftype=font_type,
                                tight_text=True),
                       column=0)
    ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(220, s, 0.3)),
                                colorstr(hsl_to_rgb(220, s, 0.3))),
                       column=1)
    ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(220, s, 0.5)),
                                colorstr(hsl_to_rgb(220, s, 0.5))),
                       column=2)
    ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(220, s, 0.8)),
                                colorstr(hsl_to_rgb(220, s, 0.8))),
                       column=3)
    ts.legend.add_face(TextFace('G',
                                fsize=font_size,
                                ftype=font_type,
                                tight_text=True),
                       column=0)
    ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(300, s, 0.3)),
                                colorstr(hsl_to_rgb(300, s, 0.3))),
                       column=1)
    ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(300, s, 0.5)),
                                colorstr(hsl_to_rgb(300, s, 0.5))),
                       column=2)
    ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(300, s, 0.8)),
                                colorstr(hsl_to_rgb(300, s, 0.8))),
                       column=3)
    ts.legend.add_face(TextFace('-',
                                fsize=font_size,
                                ftype=font_type,
                                tight_text=True),
                       column=0)
    ts.legend.add_face(RectFace(20, 20, "#cccccc", "#cccccc"), column=1)
    t.render(args.out_file, w=210, units='mm', tree_style=ts)
Exemple #21
0

for output_string, mode, layout_fn in zip(
    [
        "tree_symbols",
        "tree_symbols",
        "tree_arrows",
    ], ["c", "r", "r"],
    [botstrap_lower_right, botstrap_lower_right, botstrap_symbols]):
    stars_style = TreeStyle()
    stars_style.layout_fn = layout_fn
    stars_style.orientation = tree_orientation
    stars_style.mode = mode
    for subtype in subtype_color_dict:
        stars_style.legend.add_face(RectFace(10, 10,
                                             subtype_color_dict[subtype],
                                             subtype_color_dict[subtype]),
                                    column=0)
        stars_style.legend.add_face(TextFace(
            subtype, fgcolor=subtype_color_dict[subtype], bold=True),
                                    column=1)
    stars_style.legend_position = 2
    ref_tree.render(file_name="plots/{}_{}_{}.pdf".format(
        plot_prefix, output_string, mode),
                    tree_style=stars_style)
print("Done.")

# dataframe for bootstrap values plotting
shared_edge_df = pd.DataFrame(shared_edge_support_values)
# "top-right" of scatter plot
high_support_df = shared_edge_df[
Exemple #22
0
def draw_tree(tree, conf, outfile):
    try:
        from ete3 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 range(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)
Exemple #23
0
    def create_circle(self, filename, title, ignore_branch_length=True):

        plt.clf()
        axis_font = {'size': '29'}
        plt.rc('xtick', labelsize=0.1)
        plt.rc('ytick', labelsize=0.1)
        plt.rc({'font.size': 0.2})
        plt.rc('text', usetex=True)

        # legend creation
        if self.motif2struct and self.struct2color_dic:
            leg = []
            for cls, color in self.struct2color_dic.items():
                leg.append(mpatches.Patch(color=color, label=str(cls)))

        t = Tree(self.nwk)
        node_to_keep = []
        for l in t.iter_leaves():
            if len(l.name) > 1:
                node_to_keep.append(l.name)
        t.prune(tuple(node_to_keep))
        # iterate over tree leaves only
        for l in t.iter_leaves():
            ns = NodeStyle()
            if self.motif2struct and self.struct2color_dic:
                ns["bgcolor"] = self.struct2color_dic[self.motif2struct[
                    l.
                    name]] if l.name in self.motif2struct and self.motif2struct[
                        l.name] in self.struct2color_dic else 'white'
            # Gray dashed branch lines
            #ns["hz_line_type"] = 1
            #ns["hz_line_color"] = "#cccccc"
            #

            l.img_style = ns
            if self.propVec:
                if l.name in self.propVec:
                    l.add_features(profile=self.propVec[l.name])
                    l.add_features(deviation=[
                        0 for x in range(len(self.propVec[l.name]))
                    ])
                    l.add_face(ProfileFace(max_v=1,
                                           min_v=-1,
                                           center_v=0,
                                           width=200,
                                           height=40,
                                           style='heatmap',
                                           colorscheme=2),
                               column=3,
                               position='aligned')
            l.name = "  " + l.name + "  "

        # Create an empty TreeStyle
        ts = TreeStyle()

        # Set our custom layout function
        ts.layout_fn = VisualizeTreeOfMotifs.layout

        # Draw a tree
        ts.mode = "c"

        # We will add node names manually
        ts.show_leaf_name = False
        # Show branch data
        ts.show_branch_length = False
        ts.show_branch_support = False
        ts.force_topology = ignore_branch_length
        ts.title.add_face(TextFace(title, fsize=20, ftype='Times'), column=15)

        # legend creation
        if self.motif2struct and self.struct2color_dic:
            for k, (cls, col) in enumerate(self.struct2color_dic.items()):
                x = RectFace(15, 15, 'black', col)
                #x.opacity=0.5
                ts.legend.add_face(x, column=8)
                ts.legend.add_face(TextFace(' ' + str(cls) + '   ',
                                            fsize=30,
                                            ftype='Times'),
                                   column=9)
        ts.legend.add_face(TextFace('--- Properties vector order ↓',
                                    fsize=30,
                                    ftype='Times'),
                           column=10)
        for y in [
                'Mean molecular weight of amino acids',
                'Mean flexibility of amino acids',
                'Mean DIWV instability index of sequence',
                'Mean surface accessibility of amino acids',
                'Mean KD hydrophobicity', 'Mean hydrophilicity of amino acids'
        ]:
            x = RectFace(5, 5, 'black', 'black')
            #x.opacity=0.5
            ts.legend.add_face(x, column=11)
            ts.legend.add_face(TextFace(' ' + y + '   ',
                                        fsize=25,
                                        ftype='Times'),
                               column=12)

        t.render(filename + '.pdf', tree_style=ts, dpi=5000)
		columnmap[fasta] = i
		colormap[fasta] = colorvec[i].hex
	annotated = [] 
	print speciescolors
	for fasta in genedict:
		for leaf in t.get_leaves():

			nst = NodeStyle()
			nst["size"] = 0
			nst["fgcolor"] = 'black'
			nst["hz_line_width"] = 2
			nst["vt_line_width"]= 2
			nst.show_name = True
			if leaf.name.split('/')[0] in genedict[fasta]:
				if 'HH' not in fasta and 'LOMETS' not in fasta: 
					leaf.add_face( RectFace ( 10 , 10 , colormap[fasta], colormap[fasta] ), column = columnmap[fasta] )
					if leaf not in annotated:
						try:
							face = leaf.add_face( TextFace ( text = genedict[fasta][leaf.name.split('/')[0]][2]) , column = 10  )
							annotated.append(leaf)
						except:
							print genedict[fasta][leaf.name.split('/')[0]]	
					
					if colorSepcies == True:
						lineage = genedict[fasta][leaf.name.split('/')[0]][3].split(';') + [genedict[fasta][leaf.name.split('/')[0]][2]] + genedict[fasta][leaf.name.split('/')[0]][2].split()
						
						for taxa in lineage[-1:]:
							if taxa in speciescolors:
								print taxa
								print speciescolors[taxa]
								nst['bgcolor'] = speciescolors[taxa]	
def draw_lifting_tree_inline(filename: str) -> None:

    ts = TreeStyle()
    ts.show_leaf_name = False
    ts.layout_fn = layout_lift
    ts.rotation = 90
    ts.branch_vertical_margin = 10
    ts.show_scale = False
    ts.scale = 50
    ts.title.add_face(TextFace(" ", fsize=20), column=0)

    ts.legend.add_face(TextFace("  "), column=0)
    ts.legend.add_face(TextFace("  "), column=1)
    ts.legend.add_face(TextFace("  "), column=2)
    ts.legend.add_face(TextFace("  "), column=3)

    ts.legend.add_face(TextFace("              "), column=0)
    ts.legend.add_face(TextFace("Node shape and size:"), column=1)
    ts.legend.add_face(TextFace("              "), column=2)
    ts.legend.add_face(TextFace("Node color - membership value:"), column=3)

    ts.legend.add_face(TextFace("  "), column=0)
    ts.legend.add_face(TextFace("  "), column=1)
    ts.legend.add_face(TextFace("  "), column=2)
    ts.legend.add_face(TextFace("  "), column=3)

    ts.legend.add_face(PieChartFace([100], 20, 20, colors=['white'], line_color='black'), column=0)
    ts.legend.add_face(TextFace("  topics that relate to the cluster"), column=1)

    ts.legend.add_face(RectFace(30, 10, "#90ee90", "#90ee90"), column=2)
    ts.legend.add_face(TextFace("  topic with minor membership 0<u(t)<=0.2"), column=3)

    ts.legend.add_face(TextFace("  "), column=0)
    ts.legend.add_face(TextFace("  "), column=1)
    ts.legend.add_face(TextFace("  "), column=2)
    ts.legend.add_face(TextFace("  "), column=3)

    ts.legend.add_face(PieChartFace([100], 40, 40, colors=['white'], line_color='black'), column=0)
    ts.legend.add_face(TextFace("  head subject"), column=1)

    ts.legend.add_face(RectFace(30, 10, "green", "green"), column=2)
    ts.legend.add_face(TextFace(u"  topic with medium membership 0.2<u(t)<=0.4   "), column=3)

    ts.legend.add_face(TextFace("  "), column=0)
    ts.legend.add_face(TextFace("  "), column=1)
    ts.legend.add_face(TextFace("  "), column=2)
    ts.legend.add_face(TextFace("  "), column=3)

    ts.legend.add_face(RectFace(20, 20, "black", "white"), column=0)
    ts.legend.add_face(TextFace("  topics that don't refer to cluster                     "), \
                       column=1)

    ts.legend.add_face(RectFace(30, 10, "#004000", "#004000"), column=2)
    ts.legend.add_face(TextFace("  topic with high membership u(t)>0.4"), column=3)

    ts.legend.add_face(TextFace("  "), column=0)
    ts.legend.add_face(TextFace("  "), column=1)
    ts.legend.add_face(TextFace("  "), column=2)
    ts.legend.add_face(TextFace("  "), column=3)

    ts.legend.add_face(TextFace("  "), column=1)
    ts.legend.add_face(TextFace("  "), column=1)

    ts.legend.add_face(RectFace(30, 10, "red", "red"), column=2)
    ts.legend.add_face(TextFace("  topic with no membership (u(t)=0)"), column=3)

    ts.legend_position = 3

    ete3_desc = read_ete3_from_file(filename)
    tree = Tree(ete3_desc, format=1)

    # tree.show(tree_style=ts)
    return tree.render("%%inline",tree_style=ts)
Exemple #26
0
def heatmap_view(tree, orthologous_groups, save_dir):
    """Generates a heatmap of regulation states in all species."""
    light_tree = copy.deepcopy(tree)  # Tree copy for the light heatmap
    # Heat map settings
    rect_face_fgcolor = 'black'
    locus_tag_len = max(len(gene.locus_tag) + 5
                        for ortho_grp in orthologous_groups
                        for gene in ortho_grp.genes)
    rect_face_width = locus_tag_len * 8
    light_rect_face_width = 20
    rect_face_height = 20
    rotation = 90

    # Sort orthologous groups by the number of regulated genes in each group
    orthologous_groups = filter_and_sort_orthologous_grps(orthologous_groups)

    # For each species and its gene in each orthologous group, draw a rectangle
    for node, light_node in zip(tree.get_leaves(), light_tree.get_leaves()):
        for i, orthologous_grp in enumerate(orthologous_groups, start=1):
            #get all orthologs in group
            matching_genes = [g for g in orthologous_grp.genes \
            if g.genome.strain_name == node.name]

            #if there is ortholog
            if len(matching_genes) > 0:
                # Get the first ortholog from the genome in the group
                #this is the one with higher probability of regulation.
                #so this probability will be displayed for the group
                gene = matching_genes[0]
                p_regulation = gene.operon.regulation_probability
                p_notregulation = 1.0 - p_regulation
                p_absence = 0
            # No ortholog from this genome
            else:
                gene = None
                p_regulation = 0
                p_notregulation = 0
                p_absence = 1

            # Color of the rectangle is based on probabilities
            rect_face_bgcolor = rgb2hex(
                p_notregulation, p_regulation, p_absence)
            rect_face_text = ('%s [%d]' % (gene.locus_tag, gene.operon.operon_id)
                              if gene else '')
            rect_face_label = {'text': rect_face_text,
                               'font': 'Courier',
                               'fontsize': 8,
                               'color': 'black'}
            # Create the rectangle
            rect_face = RectFace(rect_face_width, rect_face_height,
                                 rect_face_fgcolor, rect_face_bgcolor,
                                 label=rect_face_label)
            light_rect_face = RectFace(light_rect_face_width, rect_face_height,
                                       rect_face_fgcolor, rect_face_bgcolor,
                                       label='')
            rect_face.rotation = -rotation
            light_rect_face.rotation = -rotation
            # Add the rectangle to the corresponding column
            node.add_face(rect_face, column=i, position='aligned')
            light_node.add_face(light_rect_face, column=i, position='aligned')

    ts = TreeStyle()
    # Add orthologous group descriptions
    descriptions = ['-'.join([grp.description, str(grp.NOGs)]) for grp in orthologous_groups]
    max_description_len = max(map(len, descriptions))
    descriptions = [
        '[%d]' % i + description + ' '*(max_description_len-len(description))
        for i, description in enumerate(descriptions, start=1)]
    for i, description in enumerate(descriptions, start=1):
        text_face = TextFace(description, ftype='Courier')
        text_face.hz_align = 1
        text_face.vt_align = 1
        text_face.rotation = -rotation
        ts.aligned_header.add_face(text_face, column=i)

    # Rotate the generated heatmap.
    ts.margin_left = 10
    ts.margin_top = 20
    ts.rotation = rotation
    ts.show_scale = False
    # For some reason, it can't render to PDF in color
    tree.render(os.path.join(save_dir, 'heatmap.svg'), tree_style=ts)
    light_tree.render(os.path.join(save_dir, 'heatmap_light.svg'), tree_style=ts)
            def nodeLayoutFunc(node):
                taxid = int(node.name)

                if taxid in taxidsToKeep:
                    taxGroupName = ncbiTaxa.get_taxid_translator(
                        [taxid]
                    )[taxid]  # There has to be an easier way to look up names...

                    row = None
                    rangeRows = None

                    print(len(ranges))

                    if (len(ranges) == 1):
                        row = df[(df['ExplanatoryVar'] == var)
                                 & (df['TaxGroup'] == taxid) &
                                 (df['Range'] == ranges[0])]
                        assert (len(row) == len(ranges))
                    elif len(ranges) > 1:
                        row = df[(df['ExplanatoryVar'] == var)
                                 & (df['TaxGroup'] == taxid) &
                                 (df['Range'] == 0)]
                        assert (len(row) == 1)
                        rangeRows = df[(df['ExplanatoryVar'] == var)
                                       & (df['TaxGroup'] == taxid) &
                                       (df['Range'].isin(set(ranges)))]
                    else:
                        assert (False)

                    overallPval = float(row['Pvalue'].values[0])

                    name = TextFace("%s" % taxGroupName,
                                    fsize=baseFontSize * 2.5)
                    name.tight_text = True
                    name.margin_left = 20
                    name.margin_right = 0
                    name.margin_top = 40
                    name.margin_bottom = 12
                    faces.add_face_to_node(name, node, column=0)

                    #print(rangeRows)

                    # For each range to be included in this plot, add a bar
                    for rangeId in ranges:
                        #print("rangeId = %s" % (rangeId))

                        rowForThisRange = None

                        if len(ranges) == 1:
                            rowForThisRange = row
                        else:
                            rowForThisRange = rangeRows[rangeRows['Range'] ==
                                                        rangeId]

                        assert (len(rowForThisRange) == 1)

                        # Extract p-value and "effect-size" (signed R^2)
                        effectSize = float(
                            rowForThisRange['EffectSize'].values[0])
                        pval = float(rowForThisRange['Pvalue'].values[0])

                        # Set bar-graph color and significance markers
                        barColor = ""
                        significanceMarker = ""
                        if (pval < significanceLevel):
                            significanceMarker = " %s" % unichr(0x2731)

                            if effectSize < 0:
                                barColor = "#1133ff"
                            else:
                                barColor = "#ff3311"
                        else:  # not significant
                            if effectSize < 0:
                                barColor = "#b0b0f0"
                            else:
                                barColor = "#ccb090"

                        # Add the minus sign if needed
                        signChar = ""
                        if effectSize < 0:
                            signChar = unichr(
                                0x2212
                            )  # minus sign (more legible than a hypen...)

                        v = RectFace(width=abs(effectSize) * barScale,
                                     height=baseFontSize * 3.5,
                                     fgcolor=barColor,
                                     bgcolor=barColor,
                                     label={
                                         "text":
                                         "%s%.2g %s" %
                                         (signChar, abs(effectSize),
                                          significanceMarker),
                                         "fontsize":
                                         baseFontSize * 1.8,
                                         "color":
                                         "black"
                                     })
                        #v.rotation = -90
                        v.margin_top = 1
                        v.margin_left = 30
                        v.margin_right = 8
                        v.margin_bottom = 12
                        faces.add_face_to_node(v, node, column=0)

                    details = TextFace(
                        "N=%d" % row['NumSpecies'], fsize=baseFontSize *
                        1.5)  #, fsize=baseFontSize) #, fstyle="italic")
                    details.background.color = "#dfdfdf"
                    details.margin_left = 6
                    details.margin_right = 20
                    #details.margin_top=5
                    #details.margin_bottom=0
                    faces.add_face_to_node(details, node, column=1)

                    nstyle = NodeStyle()
                    nstyle["size"] = 0

                    node.set_style(nstyle)