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)
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
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)
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)
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)
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
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
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)
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()
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
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' )
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)
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
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)
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() # []
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')
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)
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
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
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)
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
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
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)
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)