Пример #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
Пример #2
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)
Пример #3
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)
            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)
Пример #5
0
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