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 custom_treestyle(): ts = TreeStyle() ts.layout_fn = custom_layout ts.show_leaf_name = False ts.branch_vertical_margin = 0 ts.min_leaf_separation = 0 return ts
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 get_example_tree(): t = Tree() ts = TreeStyle() ts.layout_fn = layout ts.mode = "c" ts.show_leaf_name = True ts.min_leaf_separation = 15 t.populate(100) return t, ts
def set_default_TreeStyle(tree, draw_nodes): ts = TreeStyle() ts.mode = "c" ts.arc_start = -180 ts.arc_span = 180 ts.root_opening_factor = 1 ts.show_branch_length = False ts.show_branch_support = True ts.force_topology = False ts.show_leaf_name = False ts.min_leaf_separation = 10 ts.root_opening_factor = 1 ts.complete_branch_lines_when_necessary = True return ts, tree
def get_tree_shape(newick, graph, lower_threshold, higher_threshold): t = Tree(newick, format=8) for n in t.traverse(): nstyle = NodeStyle() nstyle["fgcolor"] = "yellow" name = newick_to_name(n.name) if name != '': if graph.nodes[name]["val"] > higher_threshold: nstyle["fgcolor"] = "green" elif graph.nodes[name]["val"] < lower_threshold: nstyle["fgcolor"] = "red" nstyle["size"] = 5 n.set_style(nstyle) ts = TreeStyle() ts.show_leaf_name = True ts.show_branch_length = False ts.min_leaf_separation = 0.5 ts.mode = "c" ts.root_opening_factor = 0.75 return t, ts
def set_default_TreeStyle(tree): ts = TreeStyle() ts.mode = "c" ts.root_opening_factor = 1 ts.show_branch_length = True ts.show_branch_support = True ts.force_topology = True ts.show_leaf_name = False ts.min_leaf_separation = 10 ts.root_opening_factor = 1 ts.complete_branch_lines_when_necessary = True ns = NodeStyle() ns["size"] = 6 ns["fgcolor"] = "Black" ns["hz_line_width"] = 8 ns["vt_line_width"] = 8 for node in tree.traverse("postorder"): # if not node.is_leaf(): node.set_style(ns) tree.set_style(ts) return ts, tree
annotated_tree = annotate_tips_prot (nj_tree, target_taxa, info_table) else: annotated_tree = annotate_tips(nj_tree, target_taxa, '{}.best.taxids'.format(blastout)) with open("{}_rscuTree_annot.csv".format(prefix),'w') as f: for l in [ [x.name, x.annotation] for x in annotated_tree.iter_leaves()]: try: l.insert(1,taxlvl_decisions.loc[l[0]].item()) except: l.insert(1,'unclassified') l = [i.strip() for i in l] f.write("{}\n".format( ','.join(l) )) circ = TreeStyle() circ.scale=500 circ.min_leaf_separation=1 circ.mode="c" circ.force_topology=True circ.show_leaf_name = True #annotated_tree.show(tree_style=circ) #sys.exit() ## Print the tree to extended Newick string and draw picture to PDF #annotated_tree.render(prefix+"_rscu_nj_annotated.pdf", tree_style=ts) #annotated_tree.write(features = [], format = 0, outfile = prefix+"_rscu_nj_annotated.tre") #logger.info("The taxon-annotated RSCU tree has been written to "+os.getcwd()+"/"+prefix+"_rscu_nj_annotated.tre") #logger.info("A picture of the taxon-annotated RSCU tree has been written to "+os.getcwd()+"/"+prefix+"_rscu_nj_annotated.pdf") #%% Find the best clade to use for training ClaMS
def generateFigure(PF, sample, rank, input_file, output_base_name, file_type, plot_l1, scaling, output_dpi): # Make the ETE3 tree try: tree = ncbi.get_topology(PF.get_all_tax_ids(sample), rank_limit=rank) except: logging.getLogger('Tampa').critical("Input format not compatible.") exit(1) ts = TreeStyle() ts.layout_fn = PF.layout ts.mode = "c" ts.show_leaf_name = False ts.show_branch_length = False ts.show_branch_support = False ts.min_leaf_separation = 10 ts.arc_span = 360 #ts.legend.add_face(CircleFace(100, "#1b9e77", label="Predicted"), column=0) #ts.legend.add_face(CircleFace(100, '#d95f02', label="True"), column=1) # add white space to move the legend closer ts.legend.add_face(CircleFace(65, "#FFFFFF"), column=2) ts.legend.add_face(CircleFace(65, "#FFFFFF"), column=1) ts.legend.add_face(CircleFace(65, "#FFFFFF"), column=0) ts.legend.add_face(CircleFace(65, "#FFFFFF"), column=2) ts.legend.add_face(CircleFace(65, "#FFFFFF"), column=1) ts.legend.add_face(CircleFace(65, "#FFFFFF"), column=0) # add the legend legend_fs = 50 C1 = CircleFace(100, "#1b9e77") C1.hz_align = True ts.legend.add_face(C1, column=0) T1 = TextFace("Predicted", fsize=legend_fs) T1.hz_align = True ts.legend.add_face(T1, column=0) if len(PF.ground_truth_dict) > 0: C2 = CircleFace(100, "#d95f02") C2.hz_align = True ts.legend.add_face(C2, column=1) T2 = TextFace("True", fsize=legend_fs) T2.hz_align = True ts.legend.add_face(T2, column=1) T3 = TextFace(f"Tool: {os.path.basename(input_file).split('.')[0]}", fsize=legend_fs) T3.hz_align = True ts.legend.add_face(T3, column=0) ts.allow_face_overlap = False # this lets me mess a bit with font size and face size without the interaction of the two ts.min_leaf_separation = 10 tree_output_file = f"{output_base_name}_tree_{rank}_{sample}.{file_type}" tree.render(tree_output_file, h=5.2, w=5, tree_style=ts, units="in", dpi=output_dpi) if plot_l1: # if you asked for L1 too, then plot that true_abundance_at_rank = [] predicted_abundance_at_rank = [] for node in tree.get_leaves(): if node.rank == rank: tax_id = str(node.taxid) if tax_id in PF.ground_truth_tax_id_to_percentage: true_abundance_at_rank.append(PF.ground_truth_tax_id_to_percentage[str(node.taxid)] / 100.) else: true_abundance_at_rank.append(0) if tax_id in PF.profile_tax_id_to_percentage: predicted_abundance_at_rank.append(PF.profile_tax_id_to_percentage[str(node.taxid)] / 100.) else: predicted_abundance_at_rank.append(0) data = np.zeros((len(true_abundance_at_rank), 2)) data[:, 0] = np.array(true_abundance_at_rank) data[:, 1] = np.array(predicted_abundance_at_rank) df = pd.DataFrame(data, columns=['True', 'Predicted']) # g = seaborn.FacetGrid(df, height=6) ax = seaborn.scatterplot(x='True', y='Predicted', data=df, color='b', s=55) eps = 1 ax.set_aspect('equal') max_val = np.max(data) + eps ax.set_xlim(-.5, max_val) ax.set_ylim(-.5, max_val) ax.set_xbound(-.5, max_val) ax.set_ybound(-.5, max_val) #plt.figure(figsize=(6,6)) plt.plot(np.linspace(0, max_val, 100), np.linspace(0, max_val, 100), color='k') for (x, y) in zip(true_abundance_at_rank, predicted_abundance_at_rank): if x > y: ax.vlines(x, y, x, colors='r') if y > x: ax.vlines(x, x, y, colors='r') plt.title(f"Tool: {os.path.basename(input_file).split('.')[0]}") plt.tight_layout() l1_out_file = f"{output_base_name}_L1_{rank}.{file_type}" plt.savefig(l1_out_file, dpi=output_dpi)
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)
noisy_tree.write(format=1, features=["ND","T","C","Cz"],outfile="%s/annotated_tree_est.nhx"%(self.reptree),format_root_node=True) else: noisy_tree.write(format=1, features=["ND","T","C"],outfile="%s/annotated_tree_est.nhx"%(self.reptree),format_root_node=True) self.tree_fn_est = self.reptree + "/noisy_root_tree.nhx" self.treeconv_fn_est = self.reptree + "/noisy_root_tree_conv.nhx" self.annotated_tree_fn_est = "%s/annotated_tree_est.nhx" %(self.reptree) return # Basic tree style tree_style = TreeStyle() tree_style.show_leaf_name = True tree_style.show_branch_length = True tree_style.min_leaf_separation = 4 tree_style.branch_vertical_margin = 2 nstyle_T = NodeStyle() nstyle_T["fgcolor"] = "orange" #nstyle_T["shape"] = "square" nstyle_T["size"] = 5 nstyle_T["vt_line_color"] = "orange" nstyle_T["hz_line_color"] = "orange" nstyle_T["vt_line_width"] = 2 nstyle_T["hz_line_width"] = 2 nstyle_C = NodeStyle() nstyle_C["fgcolor"] = "orange" nstyle_C["size"] = 5
min = float(root_info.split("age_range={")[1].split("_")[0]) max = float(root_info.split("age_range={")[1].split("_")[1].split("}")[0]) ciMin = float(root_info.split("age_quant_5_95={")[1].split("_")[0]) ciMax = float( root_info.split("age_quant_5_95={")[1].split("_")[1].split("}")[0]) id = float(root_info.split("id=")[1].split(":")[0]) t.add_features(support=1.0, age_median=median, age_mean=mean, age_sd=sd, age_range="{" + str(min) + "_" + str(max) + "}", age_quant_5_95="{" + str(ciMin) + "_" + str(ciMax) + "}", id=id) ts = TreeStyle() ts.min_leaf_separation = 0 ts.show_scale = False ts.show_leaf_name = False ts.scale = scale #0.3 #0.1# 0.3 # 10 pixels per branch length unit nstyle = NodeStyle() nstyle["size"] = 0.0001 for n in t.traverse(): n.set_style(nstyle) for leaf in t: leaf.add_face(AttrFace("name", fstyle="italic"), column=0, position='branch-right') #This first rendering is used to get _nid attributes for each node coord = t.render(outputfile + ".png", tree_style=ts, w=widthImage, units="mm")
def plotSingleTree(var, ranges): print("Plotting tree for trait %s (ranges: %s)" % (var, ranges)) assert (type(ranges) == type(())) ts = TreeStyle() ts.show_branch_length = False ts.show_leaf_name = False ts.scale = 130 # scale for branch length #ts.rotation = 90 ts.rotation = 0 ts.min_leaf_separation = 250 tree = majorGroupsTree.copy() taxidsToKeep = set( df[df['ExplanatoryVar'] == var]['TaxGroup'].values) def nodeLayoutFunc(node): taxid = int(node.name) if taxid in taxidsToKeep: taxGroupName = ncbiTaxa.get_taxid_translator( [taxid] )[taxid] # There has to be an easier way to look up names... row = None rangeRows = None print(len(ranges)) if (len(ranges) == 1): row = df[(df['ExplanatoryVar'] == var) & (df['TaxGroup'] == taxid) & (df['Range'] == ranges[0])] assert (len(row) == len(ranges)) elif len(ranges) > 1: row = df[(df['ExplanatoryVar'] == var) & (df['TaxGroup'] == taxid) & (df['Range'] == 0)] assert (len(row) == 1) rangeRows = df[(df['ExplanatoryVar'] == var) & (df['TaxGroup'] == taxid) & (df['Range'].isin(set(ranges)))] else: assert (False) overallPval = float(row['Pvalue'].values[0]) name = TextFace("%s" % taxGroupName, fsize=baseFontSize * 2.5) name.tight_text = True name.margin_left = 20 name.margin_right = 0 name.margin_top = 40 name.margin_bottom = 12 faces.add_face_to_node(name, node, column=0) #print(rangeRows) # For each range to be included in this plot, add a bar for rangeId in ranges: #print("rangeId = %s" % (rangeId)) rowForThisRange = None if len(ranges) == 1: rowForThisRange = row else: rowForThisRange = rangeRows[rangeRows['Range'] == rangeId] assert (len(rowForThisRange) == 1) # Extract p-value and "effect-size" (signed R^2) effectSize = float( rowForThisRange['EffectSize'].values[0]) pval = float(rowForThisRange['Pvalue'].values[0]) # Set bar-graph color and significance markers barColor = "" significanceMarker = "" if (pval < significanceLevel): significanceMarker = " %s" % unichr(0x2731) if effectSize < 0: barColor = "#1133ff" else: barColor = "#ff3311" else: # not significant if effectSize < 0: barColor = "#b0b0f0" else: barColor = "#ccb090" # Add the minus sign if needed signChar = "" if effectSize < 0: signChar = unichr( 0x2212 ) # minus sign (more legible than a hypen...) v = RectFace(width=abs(effectSize) * barScale, height=baseFontSize * 3.5, fgcolor=barColor, bgcolor=barColor, label={ "text": "%s%.2g %s" % (signChar, abs(effectSize), significanceMarker), "fontsize": baseFontSize * 1.8, "color": "black" }) #v.rotation = -90 v.margin_top = 1 v.margin_left = 30 v.margin_right = 8 v.margin_bottom = 12 faces.add_face_to_node(v, node, column=0) details = TextFace( "N=%d" % row['NumSpecies'], fsize=baseFontSize * 1.5) #, fsize=baseFontSize) #, fstyle="italic") details.background.color = "#dfdfdf" details.margin_left = 6 details.margin_right = 20 #details.margin_top=5 #details.margin_bottom=0 faces.add_face_to_node(details, node, column=1) nstyle = NodeStyle() nstyle["size"] = 0 node.set_style(nstyle) ts.layout_fn = nodeLayoutFunc # Annotate tree nodes nodesToKeep = [] for node in tree.traverse(): if int(node.name) in taxidsToKeep: nodesToKeep.append(node) tree.prune(nodesToKeep) rangesStr = "" if len(ranges) == 1: rangesStr = str(ranges[0]) else: rangesStr = "_".join(map(str, ranges)) tree.render('regressionByTaxgroup_%s_range_%s.pdf' % (var, rangesStr), tree_style=ts, units="mm") tree.render('regressionByTaxgroup_%s_range_%s.svg' % (var, rangesStr), tree_style=ts, units="mm")
except IOError: print ("Unknown file: ", treefile) sys.exit() lines = "" for l in f: lines = lines+l f.close() t = Tree(lines, format=1 ) #"((HalmarSJ:59,(BdeexoJS:7,(BdebacW:6,(Bdebacst:4,Bdebac:4)64:2)65:1)66:52)853:1,((((SorcelSoe7:5,SorcelSo:5)87:11,HalochDS:16)97:1,(((((MyxxanDK:8,MyxfulHW:8)86:2,(MyxstiDS:9,Myxful12:9)85:1)96:1,CorcorDS:11)103:1,Arcgep:12)106:3,(AnaspFw:13,(Anadeh2Ca8:2,(Anadeh2C:1,AnaspK:1)61:1)62:11)63:2)109:2)112:41,(((PelcarDS:31,Geosub:31)81:1,((PelproDS:22,GeolovSZ:22)79:8,((Geopic:24,((GeosulPC:3,GeosulKN:3)82:20,GeometGS:23)94:1)101:5,((GeouraRf:27,GeodalFR:27)78:1,(GeospM1:18,(GeospM2:14,GeobemBe:14)77:4)80:10)93:1)104:1)107:2)110:25,(((SynaciSB:54,DestieDS:54)75:1,((((DesoleHx:35,(DestolTo:34,DesautHR:34)70:1)72:1,DesalkAK:36)89:14,((((DessulDS:37,DespsyLS:37)73:5,DesproDS:42)90:1,DesalkAH:43)98:6,((DesretDS:44,DesbacDS:44)71:4,((((Desvulstn6:26,((Desvulst:21,DesvulRC:21)76:4,DesvulDP:25)92:1)100:12,((LawintPH:19,LawintN3:19)84:14,Desdessu:33)95:5)102:1,DesalaG2:39)105:8,(DesmagRS:46,(Desafrst:45,(DessalDS:41,(DesdesND:40,DesaesAs:40)69:1)74:4)91:1)99:1)108:1)111:1)113:1)114:3,(SynfumMP:52,(DesbaaDS:51,DesaceDS:51)68:1)88:1)115:2)116:1,(HipmarDS:20,DesaceA6:20)67:36)117:1)118:1)119:2);", format=1 ) ts = TreeStyle() ts.min_leaf_separation= 0 #ts.scale = 88 nstyle = NodeStyle() nstyle["size"] = 0.0001 for n in t.traverse(): n.set_style(nstyle) #t.render("tree.png", tree_style=ts) coord = t.render(outputfile+".png", tree_style=ts, w=183, units="mm") #coord = t.render("tree.png") #print(coord) # Map between node name and node id
t = Tree(s, format=1) return t a1 = Binary_Leaf("a1", 0.4) a2 = Binary_Leaf("a2", 0.3) a3 = Binary_Leaf("a3", 0.2) a4 = Binary_Leaf("a4", 0.1) List = [a1, a2, a3, a4] Leaves = Leaf_List(List) tree = Huffman(Leaves) ts = TreeStyle() ts.show_scale = False ts.min_leaf_separation = 30 tree.render('Basic_Huffman.png', tree_style=ts) List2 = [] for l1 in List: for l2 in List: a = Binary_Leaf(l1.name + l2.name, l1.probability * l2.probability) List2.append(a) Leaves = Leaf_List(List2) tree = Huffman(Leaves) ts2 = TreeStyle() ts2.show_scale = False ts2.min_leaf_separation = 30
def make_tree_ali_detect_combi(g_tree, ali_nf, Out, hist_up="", x_values=[], hp=[], dict_benchmark={}, reorder=False, det_tool=False, title=""): reptree = g_tree.reptree cz_nodes = g_tree.cz_nodes ### Tree ## Tree style phylotree_style = TreeStyle() phylotree_style.show_leaf_name = False phylotree_style.show_branch_length = False phylotree_style.draw_guiding_lines = True phylotree_style.min_leaf_separation = 1 ## For noisy tree cz_nodes_s = {} if cz_nodes: cols = [ "#008000", "#800080", "#007D80", "#9CA1A2", "#A52A2A", "#ED8585", "#FF8EAD", "#8EB1FF", "#FFE4A1", "#ADA1FF" ] col_i = 0 for Cz in cz_nodes.keys(): cz_nodes_s[Cz] = NodeStyle() cz_nodes_s[Cz]["fgcolor"] = cols[col_i] cz_nodes_s[Cz]["size"] = 5 cz_nodes_s[Cz]["hz_line_width"] = 2 cz_nodes_s[Cz]["vt_line_width"] = 2 cz_nodes_s[Cz]["vt_line_color"] = cols[col_i] cz_nodes_s[Cz]["hz_line_color"] = cols[col_i] col_i += 1 sim_root_ND = g_tree.outgroup_ND def my_layout(node): ## Sequence name F = TextFace(node.name, tight_text=True) add_face_to_node(F, node, column=0, position="aligned") ## Sequence motif if node.is_leaf(): motifs_n = [] box_color = "black" opacity = 1 if node.T == "True" or node.C == "True": motifs_n.append([ 0, len(node.sequence), "[]", 10, 12, box_color, box_color, None ]) motifs_n.append( [0, len(node.sequence), "seq", 10, 10, None, None, None]) seq_face = SeqMotifFace(seq=node.sequence, seqtype='aa', seq_format='seq', fgcolor=box_color, motifs=motifs_n) seq_face.overlaping_motif_opacity = opacity add_face_to_node(seq_face, node, column=1, position='aligned') ## Nodes style if det_tool and node.T == "True": node.set_style(nstyle_T_sim) add_t(node) elif det_tool and node.C == "True": node.set_style(nstyle_C_sim) elif det_tool: node.set_style(nstyle) #if not det_tool no background elif node.T == "True" and not int( node.ND) in g_tree.conv_events.nodesWithTransitions_est: node.set_style(nstyle_T_sim) add_t(node) elif node.T == "True" and int( node.ND) in g_tree.conv_events.nodesWithTransitions_est: node.set_style(nstyle_T_sim_est) add_t(node) elif int(node.ND) in g_tree.conv_events.nodesWithTransitions_est: node.set_style(nstyle_T_est) elif node.C == "True" and not int( node.ND) in g_tree.conv_events.nodesWithConvergentModel_est: node.set_style(nstyle_C_sim) elif node.C == "True" and int( node.ND) in g_tree.conv_events.nodesWithConvergentModel_est: node.set_style(nstyle_C_sim_est) elif int(node.ND) in g_tree.conv_events.nodesWithConvergentModel_est: node.set_style(nstyle_C_est) elif cz_nodes_s and node.Cz != "False": node.set_style(cz_nodes_s[int(node.Cz)]) if int(node.ND) == int(cz_nodes[int(node.Cz)][0]): add_t(node) else: node.set_style(nstyle) if int(node.ND) == sim_root_ND and not det_tool: add_sim_root(node) phylotree_style.layout_fn = my_layout # Get tree dimensions tree_nf = g_tree.annotated_tree_fn_est logger.debug("tree_nf: %s", tree_nf) t = PhyloTree(tree_nf) t.link_to_alignment(ali_nf) t.render(Out) tree_face = TreeFace(t, phylotree_style) tree_face.update_items() tree_h = tree_face._height() tree_w = tree_face._width() ### X axes: if not x_values: # Complete representation x_values_up = [ x + 1 for x in range(0, len(dict_benchmark.values()[0])) ] inter = 5 else: # Filtered representation x_values_up = x_values inter = 1 ### Histogram up if hist_up in ["PCOC", "PC", "OC", "Topological", "Identical"]: header_hist_value_up = 'Posterior probability (' + hist_up.upper( ) + ' model)' hist_value_up = dict_benchmark[hist_up] # Define emphased lines hlines = [0.8, 0.9, 0.99] hlines_col = ['#EFDB00', 'orange', 'red'] # Type of representation kind = 'stick' # bar/curve/stick y_values_up = hist_value_up hist = SequencePlotFace_mod(y_values_up, hlines=hlines, hlines_col=hlines_col, kind=kind, header=header_hist_value_up, height=40, col_width=10, ylim=[0, 1]) hist.hp = hp hist.x_values = x_values_up hist.x_inter_values = inter hist.set_sticks_color() if reorder: # draw colored boxes hist.put_colored_boxes = (True, tree_h + 40) phylotree_style.aligned_header.add_face(hist, 1) ### Rect all model: sequencescorebox = SequenceScoreFace(dict_benchmark, col_width=10) sequencescorebox.hp = hp sequencescorebox.x_values = x_values_up sequencescorebox.x_inter_values = inter if not hist_up in ["PCOC", "PC", "OC", "Topological", "Identical"]: sequencescorebox.x_axis = True phylotree_style.aligned_header.add_face(sequencescorebox, 1) if title: phylotree_style.title.add_face(TextFace(title), column=0) tree_nf = reptree + "/annotated_tree.nhx" logger.debug("tree_nf: %s", tree_nf) res = t.render(Out, tree_style=phylotree_style) del t return (res)
def bub_tree(tree, fasta, outfile1, root, types, c_dict, show, size, colours, field1, field2, scale, multiplier, dna): """ :param tree: tree object from ete :param fasta: the fasta file used to make the tree :param outfile1: outfile suffix :param root: sequence name to use as root :param types: tree type: circular (c) or rectangle (r) :param c_dict: dictionary mapping colour to time point (from col_map) :param show: show the tree in a gui (y/n) :param size: scale the terminal nodes by frequency information (y/n) :param colours: if using a matched fasta file, colour the sequence by charge/IUPAC :param field1: the field that contains the size/frequency value :param field2: the field that contains the size/frequency value :param scale: how much to scale the x axis :param multiplier :param dna true/false, is sequence a DNA sequence? :param t_list list of time points :return: None, outputs svg/pdf image of the tree """ if multiplier is None: mult = 500 else: mult = multiplier if dna: dna_prot = 'dna' bg_c = { 'A': 'green', 'C': 'blue', 'G': 'black', 'T': 'red', '-': 'grey', 'X': 'white' } fg_c = { 'A': 'black', 'C': 'black', 'G': 'black', 'T': 'black', '-': 'black', 'X': 'white' } else: dna_prot = 'aa' bg_c = { 'K': '#145AFF', 'R': '#145AFF', 'H': '#8282D2', 'E': '#E60A0A', 'D': '#E60A0A', 'N': '#00DCDC', 'Q': '#00DCDC', 'S': '#FA9600', 'T': '#FA9600', 'L': '#0F820F', 'I': '#0F820F', 'V': '#0F820F', 'Y': '#3232AA', 'F': '#3232AA', 'W': '#B45AB4', 'C': '#E6E600', 'M': '#E6E600', 'A': '#C8C8C8', 'G': '#EBEBEB', 'P': '#DC9682', '-': 'grey', 'X': 'white' } fg_c = { 'K': 'black', 'R': 'black', 'H': 'black', 'E': 'black', 'D': 'black', 'N': 'black', 'Q': 'black', 'S': 'black', 'T': 'black', 'L': 'black', 'I': 'black', 'V': 'black', 'Y': 'black', 'F': 'black', 'W': 'black', 'C': 'black', 'M': 'black', 'A': 'black', 'G': 'black', 'P': 'black', '-': 'grey', 'X': 'white' } if colours == 3: bg_c = None fg_c = None # outfile3 = str(outfile1.replace(".svg", ".nwk")) tstyle = TreeStyle() tstyle.force_topology = False tstyle.mode = types tstyle.scale = scale tstyle.min_leaf_separation = 0 tstyle.optimal_scale_level = 'full' # 'mid' # tstyle.complete_branch_lines_when_necessary = False if types == 'c': tstyle.root_opening_factor = 0.25 tstyle.draw_guiding_lines = False tstyle.guiding_lines_color = 'slateblue' tstyle.show_leaf_name = False tstyle.allow_face_overlap = True tstyle.show_branch_length = False tstyle.show_branch_support = False TreeNode(format=0, support=True) # tnode = TreeNode() if root is not None: tree.set_outgroup(root) # else: # r = tnode.get_midpoint_outgroup() # print("r", r) # tree.set_outgroup(r) time_col = [] for node in tree.traverse(): # node.ladderize() if node.is_leaf() is True: try: name = node.name.split("_") time = name[field2] kind = name[3] # print(name) except: time = 'zero' name = node.name print("Incorrect name format for ", node.name) if size is True: try: s = 20 + float(name[field1]) * mult except: s = 20 print("No frequency information for ", node.name) else: s = 20 colour = c_dict[time] time_col.append((time, colour)) nstyle = NodeStyle() nstyle["fgcolor"] = colour nstyle["size"] = s nstyle["hz_line_width"] = 10 nstyle["vt_line_width"] = 10 nstyle["hz_line_color"] = colour nstyle["vt_line_color"] = 'black' nstyle["hz_line_type"] = 0 nstyle["vt_line_type"] = 0 node.set_style(nstyle) if root is not None and node.name == root: # place holder in case you want to do something with the root leaf print('root is ', node.name) # nstyle["shape"] = "square" # nstyle["fgcolor"] = "black" # nstyle["size"] = s # nstyle["shape"] = "circle" # node.set_style(nstyle) else: nstyle["shape"] = "circle" node.set_style(nstyle) if fasta is not None: seq = fasta[str(node.name)] seqFace = SequenceFace(seq, seqtype=dna_prot, fsize=10, fg_colors=fg_c, bg_colors=bg_c, codon=None, col_w=40, alt_col_w=3, special_col=None, interactive=True) # seqFace = SeqMotifFace(seq=seq, motifs=None, seqtype=dna_prot, gap_format=' ', seq_format='()', scale_factor=20, # height=20, width=50, fgcolor='white', bgcolor='grey', gapcolor='white', ) # seqFace = SeqMotifFace(seq, seq_format="seq", fgcolor=fg_c, bgcolor=bg_c) #interactive=True (tree & node.name).add_face(seqFace, 0, "aligned") else: nstyle = NodeStyle() nstyle["size"] = 0.1 nstyle["hz_line_width"] = 10 nstyle["vt_line_width"] = 10 node.set_style(nstyle) continue tree.ladderize() # tnode.ladderize() legendkey = sorted(set(time_col)) legendkey = [(tp, col) for tp, col in legendkey] # legendkey.insert(0, ('Root', 'black')) legendkey.append(('', 'white')) for tm, clr in legendkey: tstyle.legend.add_face(faces.CircleFace(30, clr), column=0) tstyle.legend.add_face(faces.TextFace('\t' + tm, ftype='Arial', fsize=60, fgcolor='black', tight_text=True), column=1) if show is True: tree.show(tree_style=tstyle) tree.render(outfile1, dpi=600, tree_style=tstyle)
def matriline_tree(id, db, as_list=False): offspring = id e = db.get_elephant(id=id) if e: central_ind = e[1] else: return(None) # Start upwards to the oldest existing maternal ancestor direct_mothers = [] mother = str 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]] ############################ # Exporation in list form if as_list is True: # at each generation, we will make two objects: an unstructured list giving all individuals, # and a structured list keeping track of paths # We make a first pass to create the unstructured list: tree_list_unstructured = [oldest_mother_num] g = 0 generation_n = [0] while generation_n.__len__() != 0: generation_n = [] # these_off = None if type(tree_list_unstructured[g]) is list: for i in tree_list_unstructured[g]: these_off = db.get_offsprings(num=i) if these_off: for o in these_off: generation_n.append(o) else: these_off = db.get_offsprings(num=tree_list_unstructured[g]) if these_off: for o in these_off: generation_n.append(o) g += 1 tree_list_unstructured.append(generation_n) if tree_list_unstructured[-1] == []: tree_list_unstructured.pop() # Now the genealogy is explored, we go through it and structure it: tree_list_structured = [oldest_mother_num] for generation in tree_list_unstructured: next_generation = [] these_off = None if type(generation) is not list: these_off = db.get_offsprings(num=generation) if these_off: next_generation = these_off else: next_generation = [] elif type(generation) is list and generation != []: for g in generation: these_off = db.get_offsprings(num=g) if these_off: next_generation.append(these_off) else: next_generation.append([]) if not all(x==[] for x in next_generation): tree_list_structured.append(next_generation) return([tree_list_structured, tree_list_unstructured]) ############################ # Exploration in Newick form 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] if not num: num = info[3] 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) 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)