Exemple #1
0
    def ete_draw(self, fname=None):
        """ Draws the tree and saves it to a file.  If `fname` is None,
            show the tree instead of saving it.

            Args:
                fname: filename to save to (default=None)
        """
        if Cfg.USE_ETE3:
            def layout(node):
                faces.add_face_to_node(AttrFace("name"), node, column=0,
                                       position="branch-right")

            ts = TreeStyle()
            ts.show_leaf_name = False
            ts.layout_fn = layout
            ts.rotation = 90
            
            tree = EteTree(self.ete_str(), format=8)

            if fname:
                tree.render(fname, tree_style=ts)
            else:
                tree.show(tree_style=ts)
        else:
            # TODO maybe throw an error?
            pass
def tree_show(Newick_string, output_format=1, rotation=-90):
    '''
    Построение и вывод дерева.

    :param Newick_string: скобочная последовательность (The Newick format).
    :type Newick_string:  str

    :param output_format: Формат вывода. (default 1)
    :type output_format:  int
    #output_format = 0: - сохранение в PNG формате.
    #output_format = 1: - Вывод на экран (интерактивный режим).

    :param rotation: Поворот дерева в градусах. (default -90)
    :type rotation:  int
    '''

    t = Tree(Newick_string)

    ts = TreeStyle()
    ts.min_leaf_separation = 60
    ts.rotation = -90

    if (output_format == 1):
        t.show(tree_style=ts)
    elif (output_format == 0):
        t.render('tree1.PNG', tree_style=ts, w=400)
    else:
        print('Неверный аргумент tree_show: output_format!')
def draw_raw_tree(filename: str) -> None:
    """Draws a raw tree from ete3 representation
    stored in a file

    Parameters
    ----------
    filename : str
        a name of the file

    Returns
    -------
    None
    """

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

    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 #4
0
def traitTreeMinimal(traits, mapper):
    ### Take dict of traits and [R,G,B]-returning function
    ### Draw a tree with the continuous trait painted on via a colormapping function
    def rgb2hex(r, g, b):
        hex = "#{:02x}{:02x}{:02x}".format(r, g, b)
        return hex

    ts = TreeStyle()
    ts.show_leaf_name = False
    ts.rotation = 270
    ts.complete_branch_lines_when_necessary = False
    #ts.optimal_scale_level = "full"
    ts.scale = 800

    # default NodeStyle
    nstyle = NodeStyle()
    nstyle["size"] = 0
    nstyle["hz_line_color"] = "grey"
    nstyle["vt_line_color"] = "grey"
    nstyle["hz_line_width"] = 3
    nstyle["vt_line_width"] = 3

    for n in tree.traverse():
        chroma = rgb2hex(*[
            int(val) for val in mapper(traits[n.ND], gamma=0.8, scaleMax=255)
        ])  # setup for wl2RGB
        nf = CircleFace(radius=10, color='none', style='circle', label=None)
        n.set_style(nstyle)
        n.add_face(nf, column=0, position='branch-top')

    outFile = args.output + "/test_trees/cont_trait.pdf"
    tree.render(outFile, tree_style=ts)
    print >> sys.stderr, outFile
Exemple #5
0
def make_tree(t):
    ts = TreeStyle()

    ## make the tree in to a cladogram
    most_distant_leaf, tree_length = t.get_farthest_leaf()
    current_dist = 0
    for postorder, node in t.iter_prepostorder():
        if postorder:
            current_dist -= node.dist
        else:
            if node.is_leaf():
                node.dist += tree_length - (current_dist + node.dist)
            elif node.up:  # node is internal
                current_dist += node.dist

    ## Rotate and color the lables
    def rotation_layout(node):
        if node.is_leaf():
            if node.name == 'X':
                F = TextFace(node.name, tight_text=True, fgcolor='Blue')
                F.rotation = 90
                add_face_to_node(F, node, column=0, position="branch-right")
            elif node.name == 'Y':
                F = TextFace(node.name, tight_text=True, fgcolor='Red')
                F.rotation = 90
                add_face_to_node(F, node, column=0, position="branch-right")
            elif node.name == 'A':
                F = TextFace("")
                add_face_to_node(F, node, column=0, position="branch-right")
            else:
                F = TextFace(node.name, tight_text=True, fgcolor='Green')
                F.rotation = 90
                add_face_to_node(F, node, column=0, position="branch-right")

    ## Format the tree image
    nstyle = NodeStyle()
    nstyle["hz_line_type"] = 0
    nstyle["vt_line_color"] = "#ffffff"
    nstyle["hz_line_color"] = "#ffffff"
    nstyle["vt_line_width"] = 4
    nstyle["hz_line_width"] = 4
    nstyle["size"] = 0

    for n in t.traverse():
        n.set_style(nstyle)

    ## Set background
    t.img_style["bgcolor"] = "#2e3440"

    ## Tree 'shape'

    ts.min_leaf_separation = 20
    ts.show_leaf_name = False
    ts.layout_fn = rotation_layout
    ts.rotation = -90
    ts.show_scale = False

    #t.show(tree_style=ts)

    t.render(f"{t.name}.svg", tree_style=ts, dpi=900)
Exemple #6
0
    def ete_draw(self, fname=None):
        """ Draws the tree and saves it to a file.  If `fname` is None,
            show the tree instead of saving it.

            Args:
                fname: filename to save to (default=None)
        """
        if Cfg.USE_ETE3:

            def layout(node):
                faces.add_face_to_node(AttrFace("name"),
                                       node,
                                       column=0,
                                       position="branch-right")

            ts = TreeStyle()
            ts.show_leaf_name = False
            ts.layout_fn = layout
            ts.rotation = 90

            tree = EteTree(self.ete_str(), format=8)

            if fname:
                tree.render(fname, tree_style=ts)
            else:
                tree.show(tree_style=ts)
        else:
            # TODO maybe throw an error?
            pass
Exemple #7
0
def plot_marker_tree(tree, marker, resize_nodes=False, save=True):
    supplementary_data = pd.read_csv('../Suppl.Table2.CODEX_paper_MRLdatasetexpression.csv')
    supplementary_data.rename(columns={'X.X': 'X', 'Y.Y': 'Y', 'Z.Z': 'Z'}, inplace=True)
    supplementary_data['CD45_int'] = supplementary_data['CD45'].astype(int)
    ids_to_names = pd.read_csv('ClusterIDtoName.txt', sep='\t')
    cell_lines = list(ids_to_names['ID'].values)
    ids_to_names = dict(zip(ids_to_names['ID'].values, ids_to_names['Name'].values))
    # remove dirt from supplementary data 
    supplementary_annotations = pd.read_excel('../Suppl.Table2.cluster annotations and cell counts.xlsx')
    dirt = supplementary_annotations.loc[supplementary_annotations['Imaging phenotype (cell type)'] == 'dirt', 
                                         'X-shift cluster ID']
    supplementary_data = supplementary_data[~supplementary_data['Imaging phenotype cluster ID'].isin(dirt)]
    supplementary_data['sample'] = supplementary_data['sample_Xtile_Ytile'].apply(lambda x: x.split('_')[0])
    suppl_converted = convert_coordinates(supplementary_data)[['X', 'Y', 'Z', 'sample', marker]]
    
    new_tree = TreeNode(name = tree.name)
    new_tree.img_style['size'] = 1 if resize_nodes else 10
    new_tree.img_style['fgcolor'] = hls2hex(0, 0, 0)
    new_tree.img_style['shape'] = 'sphere'
    
    marker_avgs = []
    old_layer = [tree]
    new_layer = [new_tree]
    layer_num = 0
    while old_layer:
        next_old_layer, next_new_layer = [], []
        for ind, node in enumerate(old_layer):
            for child in node.children:
                next_old_layer.append(child)
                new_child = TreeNode(name = child.name)
                marker_avg = get_node_markers(child, marker, suppl_converted)
                new_child.add_features(marker_avg=marker_avg)
                marker_avgs.append(marker_avg)
                new_layer[ind].add_child(new_child)
                next_new_layer.append(new_child)
        old_layer = next_old_layer
        new_layer = next_new_layer
        layer_num += 1
        
    marker_min, marker_max = np.min(marker_avgs), np.max(marker_avgs)
    for node in new_tree.iter_descendants():
        norm_marker = (node.marker_avg - marker_min) / (marker_max - marker_min)
        node.add_features(marker_avg=norm_marker)
        node.add_features(color=hls2hex(0, norm_marker, norm_marker*0.5))
        
    for node in new_tree.iter_descendants():
        node.img_style['size'] = 1 + 10 * node.marker_avg if resize_nodes else 10
        node.img_style['fgcolor'] = node.color
        node.img_style['shape'] = 'sphere'
        
    ts = TreeStyle()
    ts.show_leaf_name = False
    ts.rotation = 90
    ts.title.add_face(TextFace(marker, fsize=20), column=0)
    save_dir = 'Marker_Trees' if resize_nodes else 'Marker_Trees_Same_Size'
        
    if save:
        new_tree.render(save_dir + '/marker_tree_{}.png'.format(marker), tree_style=ts)
    else:
        return new_tree.render('%%inline', tree_style=ts)
Exemple #8
0
 def to_diagram(self):
     t = self.program.to_tree_node()
     ts = TreeStyle()
     ts.show_leaf_name = False
     ts.show_scale = False
     ts.rotation = 90
     t.render(f"./diagrams/{FUNCTION_NAME}_{self.fitness}.png",
              tree_style=ts)
Exemple #9
0
def tree_render_minimum(tree):
    '''Set the minimum settings on a ete3 tree for rendering a GCtree.'''
    ts = TreeStyle()
    ts.show_leaf_name = False
    ts.rotation = 90
    tree.ladderize()

    return tree, ts
Exemple #10
0
def get_example_tree():
    t = Tree()
    t.populate(10)
    ts = TreeStyle()
    ts.rotation = 45
    ts.show_leaf_name = False
    ts.layout_fn = rotation_layout

    return t, ts
Exemple #11
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 plot_clustering_tree(tree, alg_name, cutting=0, tree_format='pdf'):
    '''if cutting=True, merge the n nodes at leaf nodes with the same parent.
    '''
    global n, k1
    if (cutting):
        tree_inner = tree.copy()
        cnt = 0
        delete_tree_node_list = []
        for _n in tree_inner:
            try:
                _n.category
            except AttributeError:
                _n.add_features(category=cnt)
                for i in _n.get_sisters():
                    if not (i.is_leaf()):
                        continue
                    try:
                        i.category
                    except AttributeError:
                        i.add_features(category=cnt)
                        delete_tree_node_list.append(i)
                cnt += 1
        for _n in delete_tree_node_list:
            _n.delete()
        # rename the tree node
        tree_inner = Tree(tree_inner.write(features=[]))
    else:
        tree_inner = tree

    for _n in tree_inner:
        try:
            _n.macro
            break
        except AttributeError:
            macro_index = int(_n.name) // (n * k1)
            micro_index = (int(_n.name) - macro_index * n * k1) // n
            _n.macro = macro_index
            _n.micro = micro_index
            if (len(_n.name) > 3):
                _n.name = str(_n.category)

    ts = TreeStyle()
    ts.rotation = 90
    ts.show_scale = False
    for _n in tree_inner:
        nstyle = NodeStyle()
        nstyle['fgcolor'] = color_list[int(_n.macro)]
        nstyle['shape'] = shape_list[int(_n.micro)]
        _n.set_style(nstyle)
    time_str = datetime.now().strftime('%Y-%m-%d-')
    file_name = time_str + 'tree_' + alg_name + '.' + tree_format
    tree_inner.render(os.path.join('build', file_name), tree_style=ts)
def tree2img(newick_tree, save_path):
    t = Tree(newick_tree, format=1)
    ts = TreeStyle()
    ts.show_leaf_name = False
    ts.show_branch_length = False
    ts.show_branch_support = False
    def my_layout(node):
        F = TextFace(node.name, tight_text=True)
        add_face_to_node(F, node, column=0, position="branch-right")
    ts.layout_fn = my_layout
    ts.branch_vertical_margin = 10
    ts.rotation = 90
    t.render(save_path+'png', tree_style=ts)
    t.render(save_path+'svg', tree_style=ts)
def parse_metric_tree(tree, num_layers=None, cutoff=0.5):
    # remove cluster nodes with spearman correlation less than cutoff
    parsed_tree = tree.copy(method='deepcopy')
    metric_vals = calculate_spearman_metric(parsed_tree)
    for node in parsed_tree.iter_descendants():
        metric = metric_vals[node]
        if metric > cutoff:
            node.delete(prevent_nondicotomic=False)

    del metric_vals

    ts = TreeStyle()
    ts.show_leaf_name = False
    ts.rotation = 90
    return parsed_tree.render('%%inline', tree_style=ts)
def visualize_spearman_metric(num_layers=None, save=True):
    # visualize tree where we color each node based on the value of the spearman metric
    tree.add_features(color=hls2hex(0.95, 0.95, 0.95))
    for node in tree.iter_descendants():
        node.add_features(color=hls2hex((1 + node.metric) *
                                        0.475, (1 + node.metric) *
                                        0.475, (1 + node.metric) * 0.475))

    new_tree = recreate_tree(tree, num_layers)
    ts = TreeStyle()
    ts.show_leaf_name = False
    ts.rotation = 90
    if save:
        new_tree.render('metric_tree.png', tree_style=ts)
    else:
        return new_tree.render('%%inline', tree_style=ts)
Exemple #16
0
    def mostraArvore(self,
                     ks=";"):  #passa todos as arestas para exibir a árvore
        t = Tree(ks, format=1)
        ts = TreeStyle()
        ts.show_leaf_name = False

        def my_layout(node):  #coloca o nome em cada nó
            node.name
            F = TextFace(
                node.name.replace("*", "\n"),
                tight_text=True)  #substitui onde tem estrela p quebra de linha
            add_face_to_node(F, node, column=0, position="branch-right")
            F.rotation = -90  #rotação do nome no nó

        ts.layout_fn = my_layout
        ts.rotation = 90  #exibir árvore na vertical
        t.show(tree_style=ts)  #mostra árvore
def draw_tree(tree_string):
    
    t = Tree(tree_string, format=8)
    
    def mylayout(node):
        #if node.name != 'L':
        file = 'tmp/%s.png' % node.name
        new_face = faces.ImgFace(file)
        new_face.rotable = True
        new_face.rotation = -90
        #new_face.margin_top = 50
        new_face.margin_left = 15
        faces.add_face_to_node(new_face, node, column=0 , position='branch-top')
        
    ts = TreeStyle()
    ts.rotation = 90
    ts.layout_fn = mylayout
    t.show(tree_style = ts)
    plt.clf()
Exemple #18
0
    def __init__(self, root_text):
        # Inicializa la estructura árbol
        tree = Tree()

        # Formateamos el árbol indicandole un estilo
        style = TreeStyle()
        style.show_leaf_name = True
        style.show_scale = False
        style.scale = 100
        style.branch_vertical_margin = 30
        style.rotation = 0
        style.orientation = 0
        self.style = style
        self.tree = tree

        # Le damos estilo a la raíz del árbol
        self.tree.add_face(TextFace(root_text, fsize=10, fgcolor='darkred'),
                           column=0,
                           position='branch-right')
        self.tree.set_style(NodeStyle(size=20, hz_line_width=2,
                                      fgcolor='blue'))

        # Almacenamos la raíz del árbol como nodo actual
        self.curr_node = self.tree
Exemple #19
0
def treeMaker(path_to_prokka, path_to_hmm, pwd_hmmsearch_exe, pwd_mafft_exe,
              pwd_fasttree_exe, plot_tree):

    # Tests for presence of the tmp folder and deletes it
    tmp_folder = 'get_species_tree_wd'
    if os.path.exists(tmp_folder):
        os.system('rm -r ' + tmp_folder)
    os.mkdir(tmp_folder)

    # List all prokka dirs in the target folder
    prokka_files = [
        i for i in os.listdir(path_to_prokka)
        if os.path.isdir(path_to_prokka + '/' + i)
    ]
    print('Detected %i input genomes' % len(prokka_files))

    # Running hmmsearch on each file
    print('Running hmmsearch...')
    for f in prokka_files:
        # call hmmsearch
        #os.system('hmmsearch -o /dev/null --domtblout %s/%s_hmmout.tbl %s %s/%s/%s.faa' % (tmp_folder, f, path_to_hmm, path_to_prokka, f, f))
        os.system(
            '%s -o /dev/null --domtblout %s/%s_hmmout.tbl %s %s/%s/%s.faa' %
            (pwd_hmmsearch_exe, tmp_folder, f, path_to_hmm, path_to_prokka, f,
             f))

        # Reading the protein file in a dictionary
        proteinSequence = {}
        for seq_record in SeqIO.parse('%s/%s/%s.faa' % (path_to_prokka, f, f),
                                      'fasta'):
            proteinSequence[seq_record.id] = str(seq_record.seq)

        # Reading the hmmersearch table/extracting the protein part found beu hmmsearch out of the protein/Writing each protein sequence that was extracted to a fasta file (one for each hmm in phylo.hmm
        hmm_id = ''
        hmm_name = ''
        hmm_pos1 = 0
        hmm_pos2 = 0
        hmm_score = 0

        with open(tmp_folder + '/' + f.replace('prokka/', '') + '_hmmout.tbl',
                  'r') as tbl:
            for line in tbl:
                if line[0] == "#": continue
                line = re.sub('\s+', ' ', line)
                splitLine = line.split(' ')

                if (hmm_id == ''):
                    hmm_id = splitLine[4]
                    hmm_name = splitLine[0]
                    hmm_pos1 = int(splitLine[17]) - 1
                    hmm_pos2 = int(splitLine[18])
                    hmm_score = float(splitLine[13])
                elif (hmm_id == splitLine[4]):
                    if (float(splitLine[13]) > hmm_score):
                        hmm_name = splitLine[0]
                        hmm_pos1 = int(splitLine[17]) - 1
                        hmm_pos2 = int(splitLine[18])
                        hmm_score = float(splitLine[13])
                else:
                    file_out = open(tmp_folder + '/' + hmm_id + '.fasta', 'a+')
                    file_out.write('>' + f + '\n')
                    if hmm_name != '':
                        seq = str(proteinSequence[hmm_name][hmm_pos1:hmm_pos2])
                    file_out.write(str(seq) + '\n')
                    file_out.close()
                    hmm_id = splitLine[4]
                    hmm_name = splitLine[0]
                    hmm_pos1 = int(splitLine[17]) - 1
                    hmm_pos2 = int(splitLine[18])
                    hmm_score = float(splitLine[13])

            else:
                file_out = open(tmp_folder + '/' + hmm_id + '.fasta', 'a+')
                file_out.write('>' + f + '\n')
                if hmm_name != '':
                    seq = str(proteinSequence[hmm_name][hmm_pos1:hmm_pos2])
                file_out.write(str(seq) + '\n')
                file_out.close()

    # Call mafft to align all single fasta files with hmms
    files = os.listdir(tmp_folder)
    fastaFiles = [i for i in files if i.endswith('.fasta')]
    print('Running mafft...')
    for f in fastaFiles:
        fastaFile1 = '%s/%s' % (tmp_folder, f)
        fastaFile2 = fastaFile1.replace('.fasta', '_aligned.fasta')
        os.system(pwd_mafft_exe + ' --quiet --maxiterate 1000 --globalpair ' +
                  fastaFile1 + ' > ' + fastaFile2 + ' ; rm ' + fastaFile1)

    # concatenating the single alignments
    # create the dictionary
    print('Concatenating alignments...')
    concatAlignment = {}
    for element in prokka_files:
        concatAlignment[element] = ''

    # Reading all single alignment files and append them to the concatenated alignment
    files = os.listdir(tmp_folder)
    fastaFiles = [i for i in files if i.endswith('.fasta')]
    for f in fastaFiles:
        fastaFile = tmp_folder + '/' + f
        proteinSequence = {}
        alignmentLength = 0
        for seq_record_2 in SeqIO.parse(fastaFile, 'fasta'):
            proteinName = seq_record_2.id
            proteinSequence[proteinName] = str(seq_record_2.seq)
            alignmentLength = len(proteinSequence[proteinName])

        for element in prokka_files:
            if element in proteinSequence.keys():
                concatAlignment[element] += proteinSequence[element]
            else:
                concatAlignment[element] += '-' * alignmentLength

    # writing alignment to file
    file_out = open('./species_tree.aln', 'w')
    for element in prokka_files:
        file_out.write('>' + element + '\n' + concatAlignment[element] + '\n')
    file_out.close()

    # calling fasttree for tree calculation
    print('Running fasttree...')
    os.system('%s -quiet species_tree.aln > species_tree.newick' %
              pwd_fasttree_exe)

    # Decomment the two following lines if tree is rooted but should be unrooted
    #phyloTree = dendropy.Tree.get(path='phylogenticTree.phy', schema='newick', rooting='force-unrooted')
    #dendropy.Tree.write_to_path(phyloTree, 'phylogenticTree_unrooted.phy', 'newick')

    # plot species tree
    if plot_tree == 1:
        print('Plot species tree')

        tree = Tree('species_tree.newick', format=1)
        # set tree parameters
        ts = TreeStyle()
        ts.mode = "r"  # tree model: 'r' for rectangular, 'c' for circular
        ts.show_leaf_name = 0
        # set tree title text parameters
        ts.title.add_face(TextFace('Species_Tree',
                                   fsize=8,
                                   fgcolor='black',
                                   ftype='Arial',
                                   tight_text=False),
                          column=0)  # tree title text setting
        # set layout parameters
        ts.rotation = 0  # from 0 to 360
        ts.show_scale = False
        ts.margin_top = 10  # top tree image margin
        ts.margin_bottom = 10  # bottom tree image margin
        ts.margin_left = 10  # left tree image margin
        ts.margin_right = 10  # right tree image margin
        ts.show_border = False  # set tree image border
        ts.branch_vertical_margin = 3  # 3 pixels between adjancent branches

        # set tree node style
        for each_node in tree.traverse():
            # leaf node parameters
            if each_node.is_leaf():
                ns = NodeStyle()
                ns["shape"] = "circle"  # dot shape: circle, square or sphere
                ns["size"] = 0  # dot size
                ns['hz_line_width'] = 0.5  # branch line width
                ns['vt_line_width'] = 0.5  # branch line width
                ns['hz_line_type'] = 0  # branch line type: 0 for solid, 1 for dashed, 2 for dotted
                ns['vt_line_type'] = 0  # branch line type
                ns["fgcolor"] = "blue"  # the dot setting
                each_node.add_face(TextFace(each_node.name,
                                            fsize=5,
                                            fgcolor='black',
                                            tight_text=False,
                                            bold=False),
                                   column=0,
                                   position='branch-right'
                                   )  # leaf node the node name text setting

                each_node.set_style(ns)

            # non-leaf node parameters
            else:
                nlns = NodeStyle()
                nlns["size"] = 0  # dot size
                # nlns["rotation"] = 45
                each_node.add_face(
                    TextFace(each_node.name,
                             fsize=3,
                             fgcolor='black',
                             tight_text=False,
                             bold=False),
                    column=5,
                    position='branch-top')  # non-leaf node name text setting)

                each_node.set_style(nlns)

        tree.render('species_tree' + '.png', w=900, units="px",
                    tree_style=ts)  # set figures size

    if plot_tree == 0:
        print('The built species tree was exported to species_tree.newick')
    else:
        print(
            'The built species tree was exported to species_tree.newick and species_tree.png'
        )
Exemple #20
0
            keyIndex += 1

    return mappedCols


## ETE3 TREE-VIZ FUNCTIONS ##

# basic tree style
tree_style = TreeStyle()
tree_style.show_leaf_name = False
tree_style.show_branch_length = False
tree_style.draw_guiding_lines = True
tree_style.complete_branch_lines_when_necessary = True

# make tree grow upward
tree_style.rotation = 270
# and make it appear ultrametric (which it is!)
tree_style.optimal_scale_level = "full"

# internal node style
nstyle = NodeStyle()
nstyle["fgcolor"] = "black"
nstyle["size"] = 0

# terminal node style
nstyle_L = NodeStyle()
nstyle["fgcolor"] = "black"
nstyle["size"] = 0


### Draw a tree with nodes color-coded and labeled by trait value
def simulate(args):
    '''
    Simulation subprogram. Can simulate in two modes.
    a) Neutral mode. A Galton–Watson process, with mutation probabilities according to a user defined motif model e.g. S5F.
    b) Selection mode. Using the same mutation process as in a), but in selection mode the poisson progeny distribution's lambda parameter
    is dynamically adjusted accordring to the hamming distance to a list of target sequences. The closer a sequence gets to one of the targets
    the higher fitness and the closer lambda will approach 2, vice versa when the sequence is far away lambda approaches 0.
    '''
    if args.random_seed is not None:
        numpy.random.seed(args.random_seed)
        random.seed(args.random_seed)
    mutation_model = MutationModel(args.mutability, args.substitution)
    if args.lambda0 is None:
        args.lambda0 = [max([1, int(.01 * len(args.sequence))])]
    if args.random_seq is not None:
        from Bio import SeqIO
        records = list(SeqIO.parse(args.random_seq, "fasta"))
        random.shuffle(records)
        args.sequence = str(records[0].seq).upper()
    else:
        args.sequence = args.sequence.upper()
    if args.sequence2 is not None:
        if len(args.lambda0
               ) == 1:  # Use the same mutation rate on both sequences
            args.lambda0 = [args.lambda0[0], args.lambda0[0]]
        elif len(args.lambda0) != 2:
            raise Exception(
                'Only one or two lambda0 can be defined for a two sequence simulation.'
            )

        # Extract the bounds between sequence 1 and 2:
        pair_bounds = ((0, len(args.sequence)),
                       (len(args.sequence),
                        len(args.sequence) + len(args.sequence2)))
        # Merge the two seqeunces to simplify future dealing with the pair:
        args.sequence += args.sequence2.upper()
    else:
        pair_bounds = None
    if args.selection:
        assert (
            args.B_total >= args.f_full
        )  # the fully activating fraction on BA must be possible to reach within B_total
        # Find the total amount of A necessary for sustaining the inputted carrying capacity:
        print((args.carry_cap, args.B_total, args.f_full, args.mature_affy))
        A_total = selection_utils.find_A_total(args.carry_cap, args.B_total,
                                               args.f_full, args.mature_affy,
                                               args.U)
        # Calculate the parameters for the logistic function:
        Lp = selection_utils.find_Lp(args.f_full, args.U)
        selection_params = [
            args.stop_dist, args.mature_affy, args.naive_affy,
            args.target_dist, args.target_count, args.skip_update, A_total,
            args.B_total, Lp, args.k, args.outbase
        ]
    else:
        selection_params = None

    trials = 1000
    # This loop makes us resimulate if size too small, or backmutation:
    for trial in range(trials):
        try:
            tree = mutation_model.simulate(args.sequence,
                                           pair_bounds=pair_bounds,
                                           lambda_=args.lambda_,
                                           lambda0=args.lambda0,
                                           n=args.n,
                                           N=args.N,
                                           T=args.T,
                                           verbose=args.verbose,
                                           selection_params=selection_params)
            if args.selection:
                collapsed_tree = CollapsedTree(tree=tree,
                                               name='GCsim selection',
                                               collapse_syn=False,
                                               allow_repeats=True)
            else:
                collapsed_tree = CollapsedTree(
                    tree=tree, name='GCsim neutral'
                )  # <-- This will fail if backmutations
            tree.ladderize()
            uniques = sum(node.frequency > 0
                          for node in collapsed_tree.tree.traverse())
            if uniques < 2:
                raise RuntimeError(
                    'collapsed tree contains {} sampled sequences'.format(
                        uniques))
            break
        except RuntimeError as e:
            print('{}, trying again'.format(e))
        else:
            raise
    if trial == trials - 1:
        raise RuntimeError('{} attempts exceeded'.format(trials))

    # In the case of a sequence pair print them to separate files:
    if args.sequence2 is not None:
        fh1 = open(args.outbase + '_seq1.fasta', 'w')
        fh2 = open(args.outbase + '_seq2.fasta', 'w')
        fh1.write('>naive\n')
        fh1.write(args.sequence[pair_bounds[0][0]:pair_bounds[0][1]] + '\n')
        fh2.write('>naive\n')
        fh2.write(args.sequence[pair_bounds[1][0]:pair_bounds[1][1]] + '\n')
        for leaf in tree.iter_leaves():
            if leaf.frequency != 0:
                fh1.write('>' + leaf.name + '\n')
                fh1.write(leaf.sequence[pair_bounds[0][0]:pair_bounds[0][1]] +
                          '\n')
                fh2.write('>' + leaf.name + '\n')
                fh2.write(leaf.sequence[pair_bounds[1][0]:pair_bounds[1][1]] +
                          '\n')
    else:
        with open(args.outbase + '.fasta', 'w') as f:
            f.write('>naive\n')
            f.write(args.sequence + '\n')
            for leaf in tree.iter_leaves():
                if leaf.frequency != 0:
                    f.write('>' + leaf.name + '\n')
                    f.write(leaf.sequence + '\n')

    # Some observable simulation stats to write:
    frequency, distance_from_naive, degree = zip(
        *[(node.frequency, hamming_distance(node.sequence, args.sequence),
           sum(
               hamming_distance(node.sequence, node2.sequence) == 1
               for node2 in collapsed_tree.tree.traverse()
               if node2.frequency and node2 is not node))
          for node in collapsed_tree.tree.traverse() if node.frequency])
    stats = pd.DataFrame({
        'genotype abundance': frequency,
        'Hamming distance to root genotype': distance_from_naive,
        'Hamming neighbor genotypes': degree
    })
    stats.to_csv(args.outbase + '_stats.tsv', sep='\t', index=False)

    print('{} simulated observed sequences'.format(
        sum(leaf.frequency for leaf in collapsed_tree.tree.traverse())))

    # Render the full lineage tree:
    ts = TreeStyle()
    ts.rotation = 90
    ts.show_leaf_name = False
    ts.show_scale = False

    colors = {}
    palette = SVG_COLORS
    palette -= set(['black', 'white', 'gray'])
    palette = cycle(list(palette))  # <-- Circular iterator

    # Either plot by DNA sequence or amino acid sequence:
    if args.plotAA and args.selection:
        colors[tree.AAseq] = 'gray'
    else:
        colors[tree.sequence] = 'gray'

    for n in tree.traverse():
        nstyle = NodeStyle()
        nstyle["size"] = 10
        if args.plotAA:
            if n.AAseq not in colors:
                colors[n.AAseq] = next(palette)
            nstyle['fgcolor'] = colors[n.AAseq]
        else:
            if n.sequence not in colors:
                colors[n.sequence] = next(palette)
            nstyle['fgcolor'] = colors[n.sequence]
        n.set_style(nstyle)

    # Render and pickle lineage tree:
    tree.render(args.outbase + '_lineage_tree.svg', tree_style=ts)
    with open(args.outbase + '_lineage_tree.p', 'wb') as f:
        pickle.dump(tree, f)

    # Render collapsed tree,
    # create an id-wise colormap
    # NOTE: node.name can be a set
    if args.plotAA and args.selection:
        colormap = {
            node.name: colors[node.AAseq]
            for node in collapsed_tree.tree.traverse()
        }
    else:
        colormap = {
            node.name: colors[node.sequence]
            for node in collapsed_tree.tree.traverse()
        }
    collapsed_tree.write(args.outbase + '_collapsed_tree.p')
    collapsed_tree.render(args.outbase + '_collapsed_tree.svg',
                          idlabel=args.idlabel,
                          colormap=colormap)
    # Print colormap to file:
    with open(args.outbase + '_collapsed_tree_colormap.tsv', 'w') as f:
        for name, color in colormap.items():
            f.write((name if isinstance(name, str) else ','.join(name)) +
                    '\t' + color + '\n')
    with open(args.outbase + '_collapsed_tree_colormap.p', 'wb') as f:
        pickle.dump(colormap, f)

    if args.selection:
        # Define a list a suitable colors that are easy to distinguish:
        palette = [
            'crimson', 'purple', 'hotpink', 'limegreen', 'darkorange',
            'darkkhaki', 'brown', 'lightsalmon', 'darkgreen', 'darkseagreen',
            'darkslateblue', 'teal', 'olive', 'wheat', 'magenta',
            'lightsteelblue', 'plum', 'gold'
        ]
        palette = cycle(list(palette))  # <-- circular iterator
        colors = {
            i: next(palette)
            for i in range(int(len(args.sequence) // 3))
        }
        # The minimum distance to the target is colored:
        colormap = {
            node.name: colors[node.target_dist]
            for node in collapsed_tree.tree.traverse()
        }
        collapsed_tree.write(args.outbase + '_collapsed_runstat_color_tree.p')
        collapsed_tree.render(args.outbase +
                              '_collapsed_runstat_color_tree.svg',
                              idlabel=args.idlabel,
                              colormap=colormap)
        # Write a file with the selection run stats. These are also plotted:
        with open(args.outbase + '_selection_runstats.p', 'rb') as fh:
            runstats = pickle.load(fh)
            selection_utils.plot_runstats(runstats, args.outbase, colors)
Exemple #22
0
def plot_tree(tree, tree_title, tree_output):
    # set tree parameters
    ts = TreeStyle()
    ts.mode = "r"  # tree model: 'r' for rectangular, 'c' for circular
    ts.show_leaf_name = 0
    # set tree title text parameters
    ts.title.add_face(TextFace(tree_title,
                               fsize=8,
                               fgcolor='black',
                               ftype='Arial',
                               tight_text=False),
                      column=0)  # tree title text setting
    # set layout parameters
    ts.rotation = 0  # from 0 to 360
    ts.show_scale = False
    ts.margin_top = 10  # top tree image margin
    ts.margin_bottom = 10  # bottom tree image margin
    ts.margin_left = 10  # left tree image margin
    ts.margin_right = 10  # right tree image margin
    ts.show_border = False  # set tree image border
    ts.branch_vertical_margin = 3  # 3 pixels between adjancent branches

    # set tree node style
    for each_node in tree.traverse():
        # leaf node parameters
        if each_node.is_leaf():
            ns = NodeStyle()
            ns["shape"] = "circle"  # dot shape: circle, square or sphere
            ns["size"] = 0  # dot size
            ns['hz_line_width'] = 0.5  # branch line width
            ns['vt_line_width'] = 0.5  # branch line width
            ns['hz_line_type'] = 0  # branch line type: 0 for solid, 1 for dashed, 2 for dotted
            ns['vt_line_type'] = 0  # branch line type
            ns["fgcolor"] = "blue"  # the dot setting
            each_node.add_face(TextFace(each_node.name,
                                        fsize=5,
                                        fgcolor='black',
                                        tight_text=False,
                                        bold=False),
                               column=0,
                               position='branch-right'
                               )  # leaf node the node name text setting

            each_node.set_style(ns)

        # non-leaf node parameters
        else:
            nlns = NodeStyle()
            nlns["size"] = 0  # dot size
            #nlns["rotation"] = 45
            each_node.add_face(
                TextFace(each_node.name,
                         fsize=3,
                         fgcolor='black',
                         tight_text=False,
                         bold=False),
                column=5,
                position='branch-top')  # non-leaf node name text setting)

            each_node.set_style(nlns)

    tree.render(tree_output, w=900, units="px",
                tree_style=ts)  # set figures size
Exemple #23
0
def matriline_tree(id, db):
    offspring = id
    central_ind = db.get_elephant(id = id)[1]
    #Start upwards to the oldest existing maternal ancestor
    direct_mothers = []
    mother = int
    while mother is not None:
        mother = db.get_mother(id=offspring)
        direct_mothers.append(mother)
        offspring = mother

        if direct_mothers[-1] is None:
            direct_mothers.pop()
    #Find the oldest known female in the line
    if direct_mothers != []:
        oldest_mother = direct_mothers.pop()
    else:
        oldest_mother = id
    #Go back down. The criterion to stop is that no female of generation 'n'
    #has any offspring.

    mothers = [oldest_mother]
    generation_n = [1]
    oldest_mother_num = db.get_elephant(id = oldest_mother)[1]
    newick="('"+str(oldest_mother_num)+"_\u2640')"
    branch_length = [[oldest_mother_num,2]]

    while generation_n.__len__() != 0:
        generation_n = []

        for m in mothers:
            m_num = db.get_elephant(id = m)[1]
            m_birth = db.get_elephant(id = m)[5]
            o = db.get_offsprings(id = m)
            if o is not None:
                taxon = []

                for i in o:
                    generation_n.append(i)
                    info = db.get_elephant(id = i)
                    num = info[1]
                    sex = info[4]
                    birth = info[5]
                    age_of_mother_at_birth = round((birth - m_birth).days / 365.25)
                    branch_length.append([num,age_of_mother_at_birth])
                    if sex == 'F':
                        u = '\u2640'
                    elif sex == 'M':
                        u = '\u2642'
                    else:
                        u = '?'
                    taxon.append(str(num)+'_'+u)

                #Could be refined so that branch length equals age of mother at childbirth
                newick = newick.replace(("'"+str(m_num)+"_\u2640'"), (str(taxon).replace('[','(').replace(']',')').replace(' ','')+str(m_num)+'_\u2640'))
        mothers = generation_n
    newick = newick.replace("'","")+';'

    #Now formatting for the actual plotting in ete3:
    t = Tree(newick , format=8)
    # print(t.get_ascii(attributes=['name'], show_internal=True))
    ts = TreeStyle()
    ts.show_leaf_name = False
    ts.rotation = 90
    ts.show_scale = False
    ts.min_leaf_separation = 50
    def my_layout(node):
         F = TextFace(node.name, tight_text=True)
         F.fsize=6
         F.margin_left=5
         F.margin_right=5
         F.margin_top=0
         F.margin_bottom=15
         F.rotation=-90
         add_face_to_node(F, node, column=0, position="branch-right")
    ts.layout_fn = my_layout
    ts.margin_left=10
    ts.margin_right=10
    ts.margin_top=10
    ts.margin_bottom=10

    i = 0

    for n in t.traverse():
        if i == 0:
            n.delete()
            n.img_style["size"] = 0.
            n.img_style["vt_line_width"] = 1
            n.img_style["hz_line_width"] = 1
            i += 1
        else:
            if str(n.name[:-2]) == str(central_ind):
                n.img_style["size"] = 10
                n.img_style["vt_line_width"] = 1
                n.img_style["hz_line_width"] = 1
                n.img_style["shape"] = "circle"
                n.img_style["fgcolor"] = "#A30B37"
                n.dist = int(branch_length[i-1][1])
            else:
                n.img_style["size"] = 0.
                n.img_style["vt_line_width"] = 1
                n.img_style["hz_line_width"] = 1
                n.dist = int(branch_length[i-1][1])
            i += 1
    t.render('tree.png', w=600, units= 'px', tree_style=ts)

    taxa = []
    for n in t.traverse():
        taxa.append(n.name)
    return(t.write(format=1),taxa)
Exemple #24
0
    def plot_hierarchy_ete3(hierarchy_df,
                            clusters,
                            n_groups=2,
                            colors=None,
                            linewidth=2,
                            show_cells=False,
                            leaf_scale=1.,
                            file_path=None):
        """
        Parameters
        ----------
        hierarchy_df
        clusters
        n_groups : int, default=2
            number of groups to color
        colors : list of colors understood by ete3
            (RGB hex code or SVG color name)
        linewidth : float, default=2
        show_cells : bool, default=False
            whether to have cells or clusters as leaves.
            If False, leaf node size is proportional to number of cells in
            cluster
        leaf_scale : float, default=0.2
            global scale of leaf node sizes
        file_path : str
            if given, tree will be rendered as pdf
        Returns
        -------
        t : formatted ete3.Tree object
        ts : ete3.TreeStyle object
        """
        newick_string = hierarchy_to_newick(hierarchy_df,
                                            clusters,
                                            cell_leaves=show_cells)
        t = Tree(newick_string, format=1)

        cellstate_names, cellstate_sizes = np.unique(clusters,
                                                     return_counts=True)
        size_dict = dict(zip(cellstate_names, cellstate_sizes))
        all_leaf_names = np.array([f'C{c}' for c in cellstate_names])
        h_clusters_cellstates = clusters_from_hierarchy(
            hierarchy_df, cluster_init=cellstate_names, steps=-n_groups + 1)
        cluster_names = np.unique(h_clusters_cellstates)

        if colors is None:
            colors = plt.cm.hsv(np.linspace(0, 1, n_groups + 1))[:-1]
        color_map = {
            cn: matplotlib.colors.to_hex(cl)
            for cn, cl in zip(cluster_names, colors)
        }

        ts = TreeStyle()
        ts.show_leaf_name = False
        ts.scale = 3e-5
        ts.rotation = 90

        base_color = 'black'
        base_style = NodeStyle()
        base_style['vt_line_width'] = linewidth
        base_style['hz_line_width'] = linewidth
        base_style['size'] = 0
        base_style["vt_line_color"] = base_color
        base_style["hz_line_color"] = base_color

        t.set_style(base_style)
        for n in t.traverse():
            n.set_style(base_style)

        # color subbranches of tree in their respective colors
        for cn in cluster_names:
            color = color_map[cn]
            style = NodeStyle(**base_style)
            style["vt_line_color"] = color
            style["hz_line_color"] = color
            style['fgcolor'] = color

            leaf_names = all_leaf_names[(h_clusters_cellstates == cn)]
            if len(leaf_names) == 1:
                node = t.search_nodes(name=leaf_names[0])[0]
                leaf_style = NodeStyle(**style)
                if not show_cells:
                    cellstate_id = int(node.name[1:])
                    leaf_style['size'] = np.sqrt(
                        size_dict[cellstate_id]) * leaf_scale
                node.set_style(leaf_style)
            else:
                ancestor = t.get_common_ancestor([str(l) for l in leaf_names])
                ancestor.set_style(style)

                for node in ancestor.iter_descendants():
                    if node.is_leaf():
                        leaf_style = NodeStyle(**style)
                        if not show_cells:
                            cellstate_id = int(node.name[1:])
                            leaf_style['size'] = np.sqrt(
                                size_dict[cellstate_id]) * leaf_scale
                        node.set_style(leaf_style)
                    else:
                        node.set_style(style)
        if file_path:
            t.render(file_path, tree_style=ts)

        return t, ts
circular_style.show_branch_length = True
circular_style.show_branch_support = True
t.render("mytree.png", tree_style=circular_style)


nstyle = NodeStyle()
nstyle["hz_line_width"] = 3
nstyle["vt_line_width"] = 3

# Applies the same static style to all nodes in the tree. Note that,
# if "nstyle" is modified, changes will affect to all nodes
for n in t.traverse():
   n.set_style(nstyle)



ts = TreeStyle()
ts.branch_vertical_margin = 10
ts.show_leaf_name = True
ts.rotation = 90
ts.scale=100
t.render("tree_test100.png",tree_style=ts)

ts.scale=1000
t.render("tree_test1000.png",tree_style=ts)
## compare to

#t = Tree( '("[a,b]",c);' )
#t.show()

# []
Exemple #26
0
    def render(self,
               outfile,
               idlabel=False,
               isolabel=False,
               colormap=None,
               chain_split=None):
        '''Render to image file, filetype inferred from suffix, svg for color images'''
        def my_layout(node):
            circle_color = 'lightgray' if colormap is None or node.name not in colormap else colormap[
                node.name]
            text_color = 'black'
            if isinstance(circle_color, str):
                if isolabel and hasattr(node, 'isotype'):
                    nl = ''.join(
                        sorted(set([ISO_SHORT[iss] for iss in node.isotype]),
                               key=lambda x: ISO_TYPE_charORDER[x]))
                else:
                    nl = str(node.frequency)
                C = CircleFace(radius=max(3, 10 * scipy.sqrt(node.frequency)),
                               color=circle_color,
                               label={
                                   'text': nl,
                                   'color': text_color
                               } if node.frequency > 0 else None)
                C.rotation = -90
                C.hz_align = 1
                faces.add_face_to_node(C, node, 0)
            else:
                P = PieChartFace(
                    [100 * x / node.frequency for x in circle_color.values()],
                    2 * 10 * scipy.sqrt(node.frequency),
                    2 * 10 * scipy.sqrt(node.frequency),
                    colors=[(color if color != 'None' else 'lightgray')
                            for color in list(circle_color.keys())],
                    line_color=None)
                T = TextFace(' '.join(
                    [str(x) for x in list(circle_color.values())]),
                             tight_text=True)
                T.hz_align = 1
                T.rotation = -90
                faces.add_face_to_node(P, node, 0, position='branch-right')
                faces.add_face_to_node(T, node, 1, position='branch-right')
            if idlabel:
                T = TextFace(node.name, tight_text=True, fsize=6)
                T.rotation = -90
                T.hz_align = 1
                faces.add_face_to_node(
                    T,
                    node,
                    1 if isinstance(circle_color, str) else 2,
                    position='branch-right')
            elif isolabel and hasattr(node, 'isotype') and False:
                iso_name = ''.join(
                    sorted(set([ISO_SHORT[iss] for iss in node.isotype]),
                           key=lambda x: ISO_TYPE_charORDER[x]))
                #T = TextFace(iso_name, tight_text=True, fsize=6)
                #T.rotation = -90
                #T.hz_align = 1
                #faces.add_face_to_node(T, node, 1 if isinstance(circle_color, str) else 2, position='branch-right')
                C = CircleFace(radius=max(3, 10 * scipy.sqrt(node.frequency)),
                               color=circle_color,
                               label={
                                   'text': iso_name,
                                   'color': text_color
                               } if node.frequency > 0 else None)
                C.rotation = -90
                C.hz_align = 1
                faces.add_face_to_node(C, node, 0)

        for node in self.tree.traverse():
            nstyle = NodeStyle()
            nstyle['size'] = 0
            if node.up is not None:
                if set(node.sequence.upper()) == set(
                        'ACGT'):  # Don't know what this do, try and delete
                    aa = translate(node.sequence)
                    aa_parent = translate(node.up.sequence)
                    nonsyn = hamming_distance(aa, aa_parent)
                    if '*' in aa:
                        nstyle['bgcolor'] = 'red'
                    if nonsyn > 0:
                        nstyle['hz_line_color'] = 'black'
                        nstyle['hz_line_width'] = nonsyn
                    else:
                        nstyle['hz_line_type'] = 1
            node.set_style(nstyle)

        ts = TreeStyle()
        ts.show_leaf_name = False
        ts.rotation = 90
        ts.draw_aligned_faces_as_table = False
        ts.allow_face_overlap = True
        ts.layout_fn = my_layout
        ts.show_scale = False
        self.tree.render(outfile, tree_style=ts)
        # If we labelled seqs, let's also write the alignment out so we have the sequences (including of internal nodes):
        if idlabel:
            aln = MultipleSeqAlignment([])
            for node in self.tree.traverse():
                aln.append(
                    SeqRecord(Seq(str(node.sequence), generic_dna),
                              id=node.name,
                              description='abundance={}'.format(
                                  node.frequency)))
            AlignIO.write(aln,
                          open(os.path.splitext(outfile)[0] + '.fasta', 'w'),
                          'fasta')
Exemple #27
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 #28
0
root = Tree()
node_cur = root

'''#######################
 Tree Style Begin
'''
ts = TreeStyle()
ts.title.add_face(TextFace("Tree example", fsize=8), column=0)
ts.scale = 50
ts.mode = 'r'

# left or right
ts.orientation = 1

ts.rotation = 270
ts.show_leaf_name = False
ts.show_branch_length = True
#ts.show_branch_length = True
'''
 Tree Style End
#######################'''




'''#######################
 Node Style Begin
'''
ns_root = NodeStyle()
ns_root["size"] = 10
Exemple #29
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 #30
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 plot_clustering_tree(tree, alg_name):
    ts = TreeStyle()
    ts.rotation = 90
    ts.show_scale = False
    time_str = datetime.now().strftime('%Y-%m-%d-')    
    tree.render(os.path.join('build', time_str + alg_name + '.pdf'), tree_style=ts)
Exemple #32
0
def testTreesMinimal(scenarios, traits, mapper):
    def rgb2hex(r, g, b):
        hex = "#{:02x}{:02x}{:02x}".format(r, g, b)
        return hex

    ### Draw test trees. This is a modified version of the test routine in pcoc_num_tree.py, stuffed in a for loop
    for cutoff in sorted(scenarios.keys()):
        tree = init_tree(args.tree)
        # not mucking with additive trees yet; ultrametrize the tree and normalize to length 1
        tree.convert_to_ultrametric(tree_length=1)

        # read scenario into a dict
        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:])

        ts = TreeStyle()
        # ts.allow_face_overlap = True
        ts.show_leaf_name = False
        ts.rotation = 270
        ts.complete_branch_lines_when_necessary = False
        # ts.optimal_scale_level = "full"
        ts.scale = 800

        for n in tree.traverse():

            # default NodeStyle
            nstyle = NodeStyle()
            nstyle["size"] = 0
            nstyle["hz_line_color"] = "none"
            nstyle["vt_line_color"] = "none"
            nstyle["hz_line_width"] = 3
            nstyle["vt_line_width"] = 3

            # colored faces
            chroma = rgb2hex(*[
                int(val)
                for val in mapper(traits[n.ND], gamma=0.8, scaleMax=255)
            ])  # setup for wl2RGB
            nf = CircleFace(radius=10,
                            color=chroma,
                            style='circle',
                            label=None)

            # scenario-dependent features
            if manual_mode_nodes:
                # if transition node
                if n.ND in manual_mode_nodes["T"]:
                    #nstyle["hz_line_color"] = "orange"
                    nf.inner_border.width = 4
                    nf.inner_border.color = 'red'
                # if convergent node
                elif n.ND in manual_mode_nodes["C"]:
                    #nstyle["hz_line_color"] = "violet"
                    nf.inner_border.width = 4
                    nf.inner_border.color = 'white'
                # if ancestral
                else:
                    nstyle["hz_line_color"] = "none"

                n.set_style(nstyle)
                n.add_face(nf, column=0, position='branch-top')

        # limiting number of digits
        outFile = args.output + "/test_trees/" + str(cutoff).replace(
            '.', '_')[:np.min([5, len(str(cutoff))])] + ".pdf"
        tree.render(outFile, tree_style=ts)
        print >> sys.stderr, outFile
Exemple #33
0
def build_tree(population, det_lim=1, log=False):
    '''Builds an ete3 Tree object based on the clone phylogeny in the population
        A detection limit can be set which will filter out clones that fall below this limit. The limit is
            one by default, so that only alive clones are taken into account.
        A log-scale can be set which will be used to calculate the node sizes as the log10 of the clone size'''

    def tree_layout(node):
        '''Tree layout function to define the layout of each node within the tree'''
        hex_color = '#%02X%02X%02X' %(node.rgb_color)
        node.img_style["fgcolor"] = hex_color  # set color of node
        node.img_style["size"] = node.weight   # set size of node


    start_clone = population.start_clone
    t = Tree(name=start_clone.ID, dist=0)   # set start clone as root of tree
    if log == True:
        size = 10*np.log10(start_clone.get_family_size())
    else:
        size = start_clone.get_family_size()
    t.add_features(weight=size, rgb_color=start_clone.rgb_color)


    def subtree(clone):
        '''Helper function to generate the subtree for each subclone
            Recursively called to include all subclones situated under given clone'''
        # calculate branch distance as difference between clone and parent birthdays
        distance = clone.birthday - clone.parent.birthday
        s = Tree(name=clone.ID, dist=distance)          # set clone as root of subtree
        if log == True:
            size = 10*np.log10(clone.get_family_size())
        else:
            size = clone.get_family_size()
        s.add_features(weight=size, rgb_color=clone.rgb_color)

        # create copy of subclones list and filter (this avoids the original subclones list to be filtered)
        sub_filtered = clone.subclones[:]
        if det_lim > 0:
            sub_filtered = list(filter(lambda subclone: subclone.get_family_size() >= det_lim, sub_filtered))

        for sub in sub_filtered:
            st = subtree(sub)  # call subtree function recursively for each subclone
            s.add_child(st)
        return s


    # create copy of subclones list and filter (this avoids the original subclones list to be filtered)
    filtered = start_clone.subclones[:]
    if det_lim > 0:
        filtered = list(filter(lambda clone: clone.get_family_size() >= det_lim, filtered))

    for subclone in filtered:
        s = subtree(subclone)
        t.add_child(s)

    # Define TreeStyle
    ts = TreeStyle()
    ts.show_leaf_name = False
    ts.show_branch_length = False
    ts.show_branch_support = False
    ts.rotation = 90  # rotate the tree to get a horizontal one
    ts.layout_fn = tree_layout

    return t, ts
Exemple #34
0
def plot_species_tree(tree_newick, tree_type, gene_name, tree_file_name,
                      name_list, tree_image_folder):
    # set tree parameters
    tree = Tree(tree_newick, format=2)
    ts = TreeStyle()
    ts.mode = "r"  # tree model: 'r' for rectangular, 'c' for circular
    ts.show_leaf_name = False
    tree_title = tree_type + ' (' + gene_name + ')'  # define tree title
    # set tree title text parameters
    ts.title.add_face(TextFace(tree_title,
                               fsize=8,
                               fgcolor='black',
                               ftype='Arial',
                               tight_text=False),
                      column=0)  # tree title text setting
    # set layout parameters
    ts.rotation = 0  # from 0 to 360
    ts.show_scale = False
    ts.margin_top = 10  # top tree image margin
    ts.margin_bottom = 10  # bottom tree image margin
    ts.margin_left = 10  # left tree image margin
    ts.margin_right = 10  # right tree image margin
    ts.show_border = False  # set tree image border
    ts.branch_vertical_margin = 3  # 3 pixels between adjancent branches

    # set tree node style
    for each_node in tree.traverse():
        # leaf node parameters
        if each_node.is_leaf():
            ns = NodeStyle()
            ns['shape'] = 'circle'  # dot shape: circle, square or sphere
            ns['size'] = 0  # dot size
            ns['hz_line_width'] = 0.5  # branch line width
            ns['vt_line_width'] = 0.5  # branch line width
            ns['hz_line_type'] = 0  # branch line type: 0 for solid, 1 for dashed, 2 for dotted
            ns['vt_line_type'] = 0  # branch line type
            if each_node.name in name_list:
                ns['fgcolor'] = 'red'  # the dot setting
                each_node.add_face(
                    TextFace(each_node.name,
                             fsize=8,
                             fgcolor='red',
                             tight_text=False,
                             bold=False),
                    column=0,
                    position='branch-right')  # the node name text setting
                each_node.set_style(ns)
            else:
                ns['fgcolor'] = 'blue'  # the dot setting
                each_node.add_face(
                    TextFace(each_node.name,
                             fsize=8,
                             fgcolor='black',
                             tight_text=False,
                             bold=False),
                    column=0,
                    position='branch-right')  # the node name text setting
                each_node.set_style(ns)

        # non-leaf node parameters
        else:
            nlns = NodeStyle()
            nlns['size'] = 0  # dot size
            each_node.add_face(
                TextFace(each_node.name,
                         fsize=4,
                         fgcolor='black',
                         tight_text=False,
                         bold=False),
                column=5,
                position='branch-top')  # non-leaf node name text setting)
            each_node.set_style(nlns)
    # set figures size
    tree.render('%s/%s.png' % (tree_image_folder, tree_file_name),
                w=900,
                units='px',
                tree_style=ts)
Exemple #35
0
        self.fitness = f
        if self.fitness is None:
            self.fitness = fitness(self.program)

    def copy(self):
        return Individual(program=self.program.copy(),
                          max_depth=self.max_depth,
                          f=self.fitness)

    def to_diagram(self):
        t = self.program.to_tree_node()
        ts = TreeStyle()
        ts.show_leaf_name = False
        ts.show_scale = False
        ts.rotation = 90
        t.render(f"./diagrams/{FUNCTION_NAME}_{self.fitness}.png",
                 tree_style=ts)


if __name__ == "__main__":
    i = Individual(max_depth=4)
    print(i.program.to_list())
    t = i.program.to_tree_node()
    print(f"depth: {i.program.get_max_depth()}")
    ts = TreeStyle()
    ts.show_leaf_name = False
    ts.show_scale = False
    ts.rotation = 90
    t.render("example.png", tree_style=ts)
    t.show(tree_style=ts)