def render_tree(tree, context_file): print('rendering tree...') print(tree) ts = TreeStyle() ts.tree_width = 30 if not args.compressed == True: tree.render(context_file[0].replace('fna', '_tree_annotated.pdf'), tree_style=ts) else: print(context_file[0].replace('.centroids', '_tree_compressed.pdf')) tree.render(context_file[0].replace('.centroids', '_tree_compressed.pdf'), tree_style=ts) print('tree rendered!')
(t & item[:item.index(':')]).add_face(seqFace, 0, "aligned") return t def get_example_tree_2(): # Create a random tree and add to each leaf a random set of motifs # from the original set t= Tree(nwTree) for item in nwTree.replace('(','').replace(')', '').replace(';', '').replace(',','\t').split('\t'): seqFace2 = SeqMotifFace(seq, motifs=motifDict_2[item[:item.index(':')]], seq_format="-", gap_format="blank") (t & item[:item.index(':')]).add_face(seqFace2, 0, "aligned") return t if __name__ == '__main__': t = get_example_tree() ts = TreeStyle() ts.tree_width = 300 ts.show_branch_support = True if args.tree_order: t.render(args.out_prefix+"_flankgenes_1.svg",tree_style=ts) else: t.show(tree_style=ts) t.render(args.out_prefix+"_flankgenes_1.svg",tree_style=ts) if __name__ == '__main__': t = get_example_tree_2() ts = TreeStyle() ts.tree_width = 300 ts.show_branch_support = True if args.tree_order: t.render(args.out_prefix+"_flankgenes_2.svg", tree_style=ts) else:
def plot_phylo(nw_tree, out_name, parenthesis_classif=True, show_support=False, radial_mode=False, root=False): from ete3 import Tree, AttrFace, TreeStyle, NodeStyle, TextFace import orthogroup2phylogeny_best_refseq_uniprot_hity ete2_tree = Tree(nw_tree, format=0) if root: R = ete2_tree.get_midpoint_outgroup() # and set it as tree outgroup ete2_tree.set_outgroup(R) ete2_tree.set_outgroup('Bacillus subtilis') ete2_tree.ladderize() if parenthesis_classif: print('parenthesis_classif!') name2classif = {} for lf in ete2_tree.iter_leaves(): print(lf) try: classif = lf.name.split('_')[-2][0:-1] print('classif', classif) #lf.name = lf.name.split('(')[0] name2classif[lf.name] = classif except: pass classif_list = list(set(name2classif.values())) classif2col = dict( zip( classif_list, orthogroup2phylogeny_best_refseq_uniprot_hity. get_spaced_colors(len(classif_list)))) for lf in ete2_tree.iter_leaves(): #try: if parenthesis_classif: try: col = classif2col[name2classif[lf.name]] except: col = 'black' else: col = 'black' #print col #lf.name = '%s|%s-%s' % (lf.name, accession2name_and_phylum[lf.name][0],accession2name_and_phylum[lf.name][1]) if radial_mode: ff = AttrFace("name", fsize=12, fstyle='italic') else: ff = AttrFace("name", fsize=12, fstyle='italic') #ff.background.color = 'red' ff.fgcolor = col lf.add_face(ff, column=0) if not show_support: print('support') for n in ete2_tree.traverse(): print(n.support) nstyle = NodeStyle() if float(n.support) < 1: nstyle["fgcolor"] = "red" nstyle["size"] = 4 n.set_style(nstyle) else: nstyle["fgcolor"] = "red" nstyle["size"] = 0 n.set_style(nstyle) else: for n in ete2_tree.traverse(): nstyle = NodeStyle() nstyle["fgcolor"] = "red" nstyle["size"] = 0 n.set_style(nstyle) #nameFace = AttrFace(lf.name, fsize=30, fgcolor=phylum2col[accession2name_and_phylum[lf.name][1]]) #faces.add_face_to_node(nameFace, lf, 0, position="branch-right") # #nameFace.border.width = 1 ''' except: col = 'red' print col lf.name = '%s| %s' % (lf.name, locus2organism[lf.name]) ff = AttrFace("name", fsize=12) #ff.background.color = 'red' ff.fgcolor = col lf.add_face(ff, column=0) ''' #n = TextFace(lf.name, fgcolor = "black", fsize = 12, fstyle = 'italic') #lf.add_face(n, 0) ''' for n in ete2_tree.traverse(): nstyle = NodeStyle() if n.support < 90: nstyle["fgcolor"] = "black" nstyle["size"] = 4 n.set_style(nstyle) else: nstyle["fgcolor"] = "red" nstyle["size"] = 0 n.set_style(nstyle) ''' ts = TreeStyle() ts.show_leaf_name = False #ts.scale=2000 #ts.scale=20000 ts.show_branch_support = show_support if radial_mode: ts.mode = "c" ts.arc_start = -90 ts.arc_span = 360 ts.tree_width = 370 ts.complete_branch_lines_when_necessary = True ete2_tree.render(out_name, tree_style=ts, w=900)
def get_example_tree(File): adres=os.getcwd() file_out_supliment = open(adres+"/out_spliment/"+File, 'w') node_file = open(adres+"/node/"+File, 'w') # Create a random tree and add to each leaf a random set of motifs # from the original set #t = Tree("( (A, B, C, D, E, F, G), H, I);") #Считываем все домены domain_all_legend={} file_all_domen=os.listdir(adres+"/for_pic/1_tree_nwk/") file_all_domen.remove(".DS_Store") file_all_domen.sort() i=0 for file_domain in file_all_domen: file_open_domain = open(adres+"/for_pic/3_domain/"+file_domain, 'r') for line in file_open_domain: line_=line.split("\t") try: if not (line_[2] in domain_all_legend): domain_all_legend.setdefault(line_[2],dic_domain_pic_pic[i]) i+=1 if i>len(dic_domain_pic_pic): i=0 except: a=0 mem="" file_open = open(adres+"/for_pic/1_tree_nwk/"+File, 'r') for line in file_open: mem=mem+line tt = Tree(mem, format=0) style = NodeStyle() style["fgcolor"] = "#000000" style["size"] = 0 style["vt_line_color"] = "#000000" style["hz_line_color"] = "#000000" style["vt_line_width"] = 4 style["hz_line_width"] = 4 style["vt_line_type"] = 8 # 0 solid, 1 dashed, 2 dotted style["hz_line_type"] = 8 for node in tt.traverse("levelorder"): node.img_style = style if (len(node.name))>1: node_file.write(node.name+"\n") children1=node.children for element in children1: element.img_style = style for node in tt.traverse("preorder"): node.img_style = style children1=node.children for element in children1: element.img_style = style node_file.close #вывести дерево с цветами #print (tt.get_ascii(attributes=["name", "color"], show_internal=False)) #поиск предка ancestor1="" i=0 for element in ancestor_grop: if i==0: for node in tt.traverse("postorder"): if i==0: node_name=str(node.name) if (node_name.startswith(element)) and not((node_name.startswith("PPE"))): ancestor1=str(node.name) i=1 break else: break else: break if not (ancestor1==""): tt.set_outgroup(ancestor1) #tt.render(adres+"/out/"+File[:-3]+"_2.png", tree_style=circular_style) print(str(ancestor1)+" - предок") file_out_supliment.write(str(ancestor1)+"\t"+" - предполагаемый корень"+"\n") else: print("Не нашел предка") file_out_supliment.write("\n\n\n Выявленные клады\n") #добавляем цвета к кладам for leaf in tt: i=0 node_name=str(leaf.name) for clad in all_clad: collor=collor_list[i] i+=1 for element in clad: if (node_name.startswith(element)): leaf.add_features(color=collor) #print(leaf) #print(tt) #забираем монофилитические цвета #print (tt.get_ascii(attributes=["name", "color"], show_internal=False)) ii=-1 for clad in all_clad: ii+=1 collor=collor_list[ii] for monophyletic_tree in tt.get_monophyletic(values=[collor], target_attr="color"): i=[] name_node_mono_color=[] for leaf in monophyletic_tree: i.append(leaf) name_node_mono_color.append(leaf.name) if len(i)>1: n1 = tt.get_common_ancestor(i) nst1 = NodeStyle() nst1["bgcolor"] = collor nst1["fgcolor"] = "#000000" nst1["size"] = 0 nst1["vt_line_color"] = "#000000" nst1["hz_line_color"] = "#000000" nst1["vt_line_width"] = 4 nst1["hz_line_width"] = 4 nst1["vt_line_type"] = 8 # 0 solid, 1 dashed, 2 dotted nst1["hz_line_type"] = 8 n1.set_style(nst1) for element in name_node_mono_color: file_out_supliment.write(str(element)+"\t"+" - "+collor+"\n") file_out_supliment.write("\n") file_out_supliment.write("\n\n\n Легенда доменного состава\n") #добавляем разметку по доменам dic_seq={} dic_domain={} dic_domain_pic={} i=0 list_legend_domain3=[] for node in tt.traverse("postorder"): #длины белков fasta_sequences=SeqIO.parse(open(adres+"/for_pic/2_MSA/"+File), "fasta") for element in fasta_sequences: if str(element.id)==str(node.name): dic_seq.setdefault(str(node.name),str(element.seq)) #доменный состав a=[] file_domain = open(adres+"/for_pic/3_domain/"+File, 'r') for line in file_domain: line_=line.split("\t") if line_[0]==str(node.name): if not (line_[2] in list_legend_domain3): list_legend_domain3.append(line_[2]) if not (line_[2] in dic_domain_pic): dic_domain_pic.setdefault(line_[2],dic_domain_pic_pic[i]) i+=1 #print(dic_domain_pic[line_[2]]) #print(i) a1=[int(line_[3]),int(line_[4]), "()", None, 15, "black", domain_all_legend[line_[2]], "arial|9|black|"+line_[2]] a.append(a1) dic_domain.setdefault(str(node.name),a) file_out_supliment.write(line_[2]+"\t"+domain_all_legend[line_[2]]+"\n") else: a1=[int(line_[3]),int(line_[4]), "()", None, 15, "black", domain_all_legend[line_[2]], "arial|9|black|"+line_[2]] a.append(a1) dic_domain.setdefault(str(node.name),a) for element in dic_domain: #print(str(element)+" "+ str(dic_domain[element])) try: seqFace = SeqMotifFace(seq=dic_seq[element], motifs=dic_domain[element], seq_format="line") (tt & element).add_face(seqFace, 0, "aligned") except: seqFace = SeqMotifFace(seq=dic_seq[element], seq_format="line", gapcolor="red") (tt & element).add_face(seqFace, 0, "aligned") print("except") #Рисуем легенду circular_style = TreeStyle() circular_style.show_leaf_name = False circular_style.show_branch_length = True circular_style.show_branch_support = True circular_style.scale = 75 circular_style.tree_width = 50 file_domain.close file_domain = open(adres+"/for_pic/3_domain/"+File, 'r') list_legend_domain={} list_legend_domain2=[] #считали список доменов i=0 for line in file_domain: line_=line.split("\t") try: if not(line_[2] in list_legend_domain2): #print(line_[2]) list_legend_domain2.append(line_[2]) list_legend_domain.setdefault("a"+str(i),line_[2]) i+=1 except: print("не понял что это за домен") i=0 #считываем легенду доменов file_domain_legend2={} file_domain_legend = open(adres+"/domain_legend.txt", 'r') for line in file_domain_legend: line_=line.split("\t") aaa=line_[1].replace(" ","_") aaa=aaa.replace("(","_") aaa=aaa.replace(")","_") aaa=aaa.replace(",","_") aaa=aaa.replace(":","_") aaa=aaa.replace(".","_") file_domain_legend2.setdefault(line_[0],aaa.replace("\n","")) #N = AttrFace("name", fsize=12) #faces.add_face_to_node(N, node, 1, position="branch-right") #рисуем домены ww="" for element in file_domain_legend2: ww=ww+","+file_domain_legend2[element] ww="("+ww[1:]+");" tree_domen_all=Tree(ww) for element in file_domain_legend2: try: element2=domain_all_legend[element] a1=[10,90, "()", None, 15, "black", domain_all_legend[element], "arial|9|black|"+element] i+=1 a=[] a.append(a1) seqFace = SeqMotifFace(seq=seq_seq, motifs=a, seq_format="line") #node_node="a"+str(i) node_node=file_domain_legend2[element] try: (tree_domen_all & node_node).add_face(seqFace, 0, "aligned") except: q=1 print("не нашел узел") except: q=1 circular_style.layout_fn = layout tree_domen_all.render(adres+"/out_legend_all.png", tree_style=circular_style) file_domain_out = open(adres+"/123123123.txt", 'w') w="" for element in list_legend_domain3: w=w+","+file_domain_legend2[element] w="("+w[1:]+");" tree_domen=Tree(w) for element in list_legend_domain3: file_domain_out.write(element+"\n") a1=[10,90, "()", None, 15, "black", domain_all_legend[element], "arial|9|black|"+element] i+=1 a=[] a.append(a1) try: seqFace = SeqMotifFace(seq=seq_seq, motifs=a, seq_format="line") #node_node="a"+str(i) node_node=file_domain_legend2[element] (tree_domen & node_node).add_face(seqFace, 0, "aligned") except: #print("Закончились узлы легенды") k=0 circular_style.layout_fn = layout tree_domen.render(adres+"/out_legend/"+File[:-4]+".png", tree_style=circular_style) #удаленние части узлов for node in tt.traverse("postorder"): try: seqFace = SeqMotifFace(seq=dic_seq[str(node.name)], motifs=dic_domain[str(node.name)], seq_format="line") (tt & node.name).add_face(seqFace, 0, "aligned") a=0 if len(node.name)<2: a=1 for element_save in save_node: if (node.name).startswith(element_save): a=1 for element_dell in dell_node: if (node.name).startswith(element_dell): a=0 if a==0: node.delete() except: if len(node.name)>0: seqFace = SeqMotifFace(seq=dic_seq[str(node.name)], seq_format="line", gapcolor="red") (tt & node.name).add_face(seqFace, 0, "aligned") node.delete() d0=0 #удаленние части узлов ЗАВЕРШЕНО #особые точки node_color=[] file_node_color = open(adres+"/for_pic/4_color_node/out_list_gene2.txt", 'r') for line in file_node_color: node_color.append(line.replace("\n","")) for node in tt.traverse("postorder"): if node.name in node_color: style = NodeStyle() style["fgcolor"] = "Red" style["size"] = 9 style["vt_line_color"] = "#000000" style["hz_line_color"] = "#000000" style["vt_line_width"] = 4 style["hz_line_width"] = 4 style["vt_line_type"] = 8 # 0 solid, 1 dashed, 2 dotted style["hz_line_type"] = 8 node.set_style(style) file_out_supliment.close #забираем монофилитические цвета #print (tt.get_ascii(attributes=["name", "color"], show_internal=False)) ii=-1 for clad in all_clad: ii+=1 collor=collor_list[ii] for monophyletic_tree in tt.get_monophyletic(values=[collor], target_attr="color"): i=[] name_node_mono_color=[] for leaf in monophyletic_tree: i.append(leaf) name_node_mono_color.append(leaf.name) if len(i)>1: n1 = tt.get_common_ancestor(i) nst1 = NodeStyle() nst1["bgcolor"] = collor nst1["fgcolor"] = "#000000" nst1["size"] = 0 nst1["vt_line_color"] = "#000000" nst1["hz_line_color"] = "#000000" nst1["vt_line_width"] = 4 nst1["hz_line_width"] = 4 nst1["vt_line_type"] = 8 # 0 solid, 1 dashed, 2 dotted nst1["hz_line_type"] = 8 n1.set_style(nst1) for element in name_node_mono_color: file_out_supliment.write(str(element)+"\t"+" - "+collor+"\n") file_out_supliment.write("\n") return tt
if __name__ == '__main__': adres=os.getcwd() file_all=os.listdir(adres+"/for_pic/1_tree_nwk/") for File in file_all: if not(File.startswith(".")): print(File) t = get_example_tree(File) #выбор стиля circular_style = TreeStyle() circular_style.show_leaf_name = False circular_style.show_branch_length = True circular_style.show_branch_support = True circular_style.scale = 75 circular_style.tree_width = 50 #circular_style.rotation = 90 #circular_style.extra_branch_line_type=(0) #circular_style.guiding_lines_type= (0) #circular_style.title.add_face(TextFace(File, fsize=25), column=0) circular_style.layout_fn = layout t.render(adres+"/out/"+File[:-4]+".png", tree_style=circular_style) circular_style.mode = "r" # draw tree in circular mode circular_style.extra_branch_line_type=(2) circular_style.guiding_lines_type= (2) circular_style.guiding_lines_color =("red") for n in t.traverse(): nstyle = NodeStyle() nstyle["fgcolor"] = "red" nstyle["size"] = 15 n.set_style(nstyle)
N.margin_left = 20 N.margin_right = 20 faces.add_face_to_node(N, node, column=0) t = sys.argv[1] alg = sys.argv[2] predic_table = sys.argv[3] out_img_name = sys.argv[4] #bilaterian_desc = ncbi.get_descendant_taxa('Bilateria', collapse_subspecies=True) #print type(bilaterian_desc) tree_upp = PhyloTree(newick=t, alignment=alg, alg_format="fasta") R = tree_upp.get_midpoint_outgroup() tree_upp.set_outgroup(R) predict_name = {} for line in open(predic_table): if line.rstrip() and not line.startswith("#"): prot_name = line.split("\t")[0] pred_name = line.split("\t")[5] predict_name[prot_name] = pred_name ts = TreeStyle() ts.show_leaf_name = False ts.tree_width = 2000 ts.layout_fn = layout tree_upp.render(out_img_name, tree_style=ts, h=200000, dpi=300, units="px")
def make_tree_figure(tree, palette, outfile, edit_d, wgd, outgroups, usedict=False, outformat="png", moved=False, coutgr=False): """ Creates and saves an image for a tree object. Args: tree (ete3.Tree): input tree palette (list): pre-defined list of colors to use outfile (str): name for the output image edit_d (dict): dictionary to store/load colors wgd (str): restrict coloring to specified wgd usedict (bool, optional): should dictionary be used to load colors outformat (str, optional): output format for image png (default), svg or pdf moved (bool, optional): color rearranged non-wgd species leaves Returns: dict: colors to leaf names mapping """ #create a treestyle that we'll customize tstyle = TreeStyle() tstyle.show_leaf_name = True corrected_wgd_nodes = get_corrected_wgd_nodes(tree, wgd, outgroups) if not corrected_wgd_nodes and not usedict: sys.stderr.write( f"No corrected subtree for wgd {wgd}, no image created.\n") return edit_d leaves = {i.name for i in tree.get_leaves()} if usedict and not leaves.intersection(set(edit_d.keys())): sys.stderr.write( f"No corrected subtree for wgd {wgd}, no image created.\n") return edit_d for node in tree.traverse(): if not node.is_leaf(): is_corrected_wgd = node in corrected_wgd_nodes #color duplication, speciation and dubious nodes with convention colors color_internal_node(node, is_corrected_wgd) #color edited leaves else: ignore = False if not coutgr and node.S in outgroups: ignore = True color_leaves(node, palette, edit_d, wgd, usedict=usedict, moved=moved, ignore=ignore) #color root node color_internal_node(tree) #hide default leaf name since we added custom ones tstyle.show_leaf_name = False #set width tstyle.tree_width = 200 #save image out = outfile + "." + outformat tree.render(out, dpi=80, tree_style=tstyle) sys.stderr.write(f"{out} created !!\n") return edit_d
def run(args): if args.text_mode: from ete3 import Tree for tindex, tfile in enumerate(args.src_tree_iterator): #print tfile if args.raxml: nw = re.sub(":(\d+\.\d+)\[(\d+)\]", ":\\1[&&NHX:support=\\2]", open(tfile).read()) t = Tree(nw) else: t = Tree(tfile) print( t.get_ascii(show_internal=args.show_internal_names, attributes=args.show_attributes)) return import random import re import colorsys from collections import defaultdict from ete3 import (Tree, PhyloTree, TextFace, RectFace, faces, TreeStyle, add_face_to_node, random_color) global FACES if args.face: FACES = parse_faces(args.face) else: FACES = [] # VISUALIZATION ts = TreeStyle() ts.mode = args.mode ts.show_leaf_name = True ts.tree_width = args.tree_width for f in FACES: if f["value"] == "@name": ts.show_leaf_name = False break if args.as_ncbi: ts.show_leaf_name = False FACES.extend( parse_faces([ 'value:@sci_name, size:10, fstyle:italic', 'value:@taxid, color:grey, size:6, format:" - %s"', 'value:@sci_name, color:steelblue, size:7, pos:b-top, nodetype:internal', 'value:@rank, color:indianred, size:6, pos:b-bottom, nodetype:internal', ])) if args.alg: FACES.extend( parse_faces([ 'value:@sequence, size:10, pos:aligned, ftype:%s' % args.alg_type ])) if args.heatmap: FACES.extend( parse_faces(['value:@name, size:10, pos:aligned, ftype:heatmap'])) if args.bubbles: for bubble in args.bubbles: FACES.extend( parse_faces([ 'value:@%s, pos:float, ftype:bubble, opacity:0.4' % bubble, ])) ts.branch_vertical_margin = args.branch_separation if args.show_support: ts.show_branch_support = True if args.show_branch_length: ts.show_branch_length = True if args.force_topology: ts.force_topology = True ts.layout_fn = lambda x: None for tindex, tfile in enumerate(args.src_tree_iterator): #print tfile if args.raxml: nw = re.sub(":(\d+\.\d+)\[(\d+)\]", ":\\1[&&NHX:support=\\2]", open(tfile).read()) t = PhyloTree(nw) else: t = PhyloTree(tfile) if args.alg: t.link_to_alignment(args.alg, alg_format=args.alg_format) if args.heatmap: DEFAULT_COLOR_SATURATION = 0.3 BASE_LIGHTNESS = 0.7 def gradient_color(value, max_value, saturation=0.5, hue=0.1): def rgb2hex(rgb): return '#%02x%02x%02x' % rgb def hls2hex(h, l, s): return rgb2hex( tuple([ int(x * 255) for x in colorsys.hls_to_rgb(h, l, s) ])) lightness = 1 - (value * BASE_LIGHTNESS) / max_value return hls2hex(hue, lightness, DEFAULT_COLOR_SATURATION) heatmap_data = {} max_value, min_value = None, None for line in open(args.heatmap): if line.startswith('#COLNAMES'): pass elif line.startswith('#') or not line.strip(): pass else: fields = line.split('\t') name = fields[0].strip() values = [float(x) if x else None for x in fields[1:]] maxv = max(values) minv = min(values) if max_value is None or maxv > max_value: max_value = maxv if min_value is None or minv < min_value: min_value = minv heatmap_data[name] = values heatmap_center_value = 0 heatmap_color_center = "white" heatmap_color_up = 0.3 heatmap_color_down = 0.7 heatmap_color_missing = "black" heatmap_max_value = abs(heatmap_center_value - max_value) heatmap_min_value = abs(heatmap_center_value - min_value) if heatmap_center_value <= min_value: heatmap_max_value = heatmap_min_value + heatmap_max_value else: heatmap_max_value = max(heatmap_min_value, heatmap_max_value) # scale the tree if not args.height: args.height = None if not args.width: args.width = None f2color = {} f2last_seed = {} for node in t.traverse(): node.img_style['size'] = 0 if len(node.children) == 1: node.img_style['size'] = 2 node.img_style['shape'] = "square" node.img_style['fgcolor'] = "steelblue" ftype_pos = defaultdict(int) for findex, f in enumerate(FACES): if (f['nodetype'] == 'any' or (f['nodetype'] == 'leaf' and node.is_leaf()) or (f['nodetype'] == 'internal' and not node.is_leaf())): # if node passes face filters if node_matcher(node, f["filters"]): if f["value"].startswith("@"): fvalue = getattr(node, f["value"][1:], None) else: fvalue = f["value"] # if node's attribute has content, generate face if fvalue is not None: fsize = f["size"] fbgcolor = f["bgcolor"] fcolor = f['color'] if fcolor: # Parse color options auto_m = re.search("auto\(([^)]*)\)", fcolor) if auto_m: target_attr = auto_m.groups()[0].strip() if not target_attr: color_keyattr = f["value"] else: color_keyattr = target_attr color_keyattr = color_keyattr.lstrip('@') color_bin = getattr( node, color_keyattr, None) last_seed = f2last_seed.setdefault( color_keyattr, random.random()) seed = last_seed + 0.10 + random.uniform( 0.1, 0.2) f2last_seed[color_keyattr] = seed fcolor = f2color.setdefault( color_bin, random_color(h=seed)) if fbgcolor: # Parse color options auto_m = re.search("auto\(([^)]*)\)", fbgcolor) if auto_m: target_attr = auto_m.groups()[0].strip() if not target_attr: color_keyattr = f["value"] else: color_keyattr = target_attr color_keyattr = color_keyattr.lstrip('@') color_bin = getattr( node, color_keyattr, None) last_seed = f2last_seed.setdefault( color_keyattr, random.random()) seed = last_seed + 0.10 + random.uniform( 0.1, 0.2) f2last_seed[color_keyattr] = seed fbgcolor = f2color.setdefault( color_bin, random_color(h=seed)) if f["ftype"] == "text": if f.get("format", None): fvalue = f["format"] % fvalue F = TextFace(fvalue, fsize=fsize, fgcolor=fcolor or "black", fstyle=f.get('fstyle', None)) elif f["ftype"] == "fullseq": F = faces.SeqMotifFace(seq=fvalue, seq_format="seq", seqtail_format="seq", height=fsize) elif f["ftype"] == "compactseq": F = faces.SeqMotifFace( seq=fvalue, seq_format="compactseq", seqtail_format="compactseq", height=fsize) elif f["ftype"] == "blockseq": F = faces.SeqMotifFace( seq=fvalue, seq_format="blockseq", seqtail_format="blockseq", height=fsize, fgcolor=fcolor or "slategrey", bgcolor=fbgcolor or "slategrey", scale_factor=1.0) fbgcolor = None elif f["ftype"] == "bubble": try: v = float(fvalue) except ValueError: rad = fsize else: rad = fsize * v F = faces.CircleFace(radius=rad, style="sphere", color=fcolor or "steelblue") elif f["ftype"] == "heatmap": if not f['column']: col = ftype_pos[f["pos"]] else: col = f["column"] for i, value in enumerate( heatmap_data.get(node.name, [])): ftype_pos[f["pos"]] += 1 if value is None: color = heatmap_color_missing elif value > heatmap_center_value: color = gradient_color( abs(heatmap_center_value - value), heatmap_max_value, hue=heatmap_color_up) elif value < heatmap_center_value: color = gradient_color( abs(heatmap_center_value - value), heatmap_max_value, hue=heatmap_color_down) else: color = heatmap_color_center node.add_face(RectFace( 20, 20, color, color), position="aligned", column=col + i) # Add header # for i, name in enumerate(header): # nameF = TextFace(name, fsize=7) # nameF.rotation = -90 # tree_style.aligned_header.add_face(nameF, column=i) F = None elif f["ftype"] == "profile": # internal profiles? F = None elif f["ftype"] == "barchart": F = None elif f["ftype"] == "piechart": F = None # Add the Face if F: F.opacity = f['opacity'] or 1.0 # Set face general attributes if fbgcolor: F.background.color = fbgcolor if not f['column']: col = ftype_pos[f["pos"]] ftype_pos[f["pos"]] += 1 else: col = f["column"] node.add_face(F, column=col, position=f["pos"]) if args.image: t.render("t%d.%s" % (tindex, args.image), tree_style=ts, w=args.width, h=args.height, units=args.size_units) else: t.show(None, tree_style=ts)
def run(args): if args.text_mode: from ete3 import Tree for tindex, tfile in enumerate(args.src_tree_iterator): #print tfile if args.raxml: nw = re.sub(":(\d+\.\d+)\[(\d+)\]", ":\\1[&&NHX:support=\\2]", open(tfile).read()) t = Tree(nw) else: t = Tree(tfile) print(t.get_ascii(show_internal=args.show_internal_names, attributes=args.show_attributes)) return import random import re import colorsys from collections import defaultdict from ete3 import (Tree, PhyloTree, TextFace, RectFace, faces, TreeStyle, add_face_to_node, random_color) global FACES if args.face: FACES = parse_faces(args.face) else: FACES = [] # VISUALIZATION ts = TreeStyle() ts.mode = args.mode ts.show_leaf_name = True ts.tree_width = args.tree_width for f in FACES: if f["value"] == "@name": ts.show_leaf_name = False break if args.as_ncbi: ts.show_leaf_name = False FACES.extend(parse_faces( ['value:@sci_name, size:10, fstyle:italic', 'value:@taxid, color:grey, size:6, format:" - %s"', 'value:@sci_name, color:steelblue, size:7, pos:b-top, nodetype:internal', 'value:@rank, color:indianred, size:6, pos:b-bottom, nodetype:internal', ])) if args.alg: FACES.extend(parse_faces( ['value:@sequence, size:10, pos:aligned, ftype:%s' %args.alg_type] )) if args.heatmap: FACES.extend(parse_faces( ['value:@name, size:10, pos:aligned, ftype:heatmap'] )) if args.bubbles: for bubble in args.bubbles: FACES.extend(parse_faces( ['value:@%s, pos:float, ftype:bubble, opacity:0.4' %bubble, ])) ts.branch_vertical_margin = args.branch_separation if args.show_support: ts.show_branch_support = True if args.show_branch_length: ts.show_branch_length = True if args.force_topology: ts.force_topology = True ts.layout_fn = lambda x: None for tindex, tfile in enumerate(args.src_tree_iterator): #print tfile if args.raxml: nw = re.sub(":(\d+\.\d+)\[(\d+)\]", ":\\1[&&NHX:support=\\2]", open(tfile).read()) t = PhyloTree(nw) else: t = PhyloTree(tfile) if args.alg: t.link_to_alignment(args.alg, alg_format=args.alg_format) if args.heatmap: DEFAULT_COLOR_SATURATION = 0.3 BASE_LIGHTNESS = 0.7 def gradient_color(value, max_value, saturation=0.5, hue=0.1): def rgb2hex(rgb): return '#%02x%02x%02x' % rgb def hls2hex(h, l, s): return rgb2hex( tuple([int(x*255) for x in colorsys.hls_to_rgb(h, l, s)])) lightness = 1 - (value * BASE_LIGHTNESS) / max_value return hls2hex(hue, lightness, DEFAULT_COLOR_SATURATION) heatmap_data = {} max_value, min_value = None, None for line in open(args.heatmap): if line.startswith('#COLNAMES'): pass elif line.startswith('#') or not line.strip(): pass else: fields = line.split('\t') name = fields[0].strip() values = [float(x) if x else None for x in fields[1:]] maxv = max(values) minv = min(values) if max_value is None or maxv > max_value: max_value = maxv if min_value is None or minv < min_value: min_value = minv heatmap_data[name] = values heatmap_center_value = 0 heatmap_color_center = "white" heatmap_color_up = 0.3 heatmap_color_down = 0.7 heatmap_color_missing = "black" heatmap_max_value = abs(heatmap_center_value - max_value) heatmap_min_value = abs(heatmap_center_value - min_value) if heatmap_center_value <= min_value: heatmap_max_value = heatmap_min_value + heatmap_max_value else: heatmap_max_value = max(heatmap_min_value, heatmap_max_value) # scale the tree if not args.height: args.height = None if not args.width: args.width = None f2color = {} f2last_seed = {} for node in t.traverse(): node.img_style['size'] = 0 if len(node.children) == 1: node.img_style['size'] = 2 node.img_style['shape'] = "square" node.img_style['fgcolor'] = "steelblue" ftype_pos = defaultdict(int) for findex, f in enumerate(FACES): if (f['nodetype'] == 'any' or (f['nodetype'] == 'leaf' and node.is_leaf()) or (f['nodetype'] == 'internal' and not node.is_leaf())): # if node passes face filters if node_matcher(node, f["filters"]): if f["value"].startswith("@"): fvalue = getattr(node, f["value"][1:], None) else: fvalue = f["value"] # if node's attribute has content, generate face if fvalue is not None: fsize = f["size"] fbgcolor = f["bgcolor"] fcolor = f['color'] if fcolor: # Parse color options auto_m = re.search("auto\(([^)]*)\)", fcolor) if auto_m: target_attr = auto_m.groups()[0].strip() if not target_attr : color_keyattr = f["value"] else: color_keyattr = target_attr color_keyattr = color_keyattr.lstrip('@') color_bin = getattr(node, color_keyattr, None) last_seed = f2last_seed.setdefault(color_keyattr, random.random()) seed = last_seed + 0.10 + random.uniform(0.1, 0.2) f2last_seed[color_keyattr] = seed fcolor = f2color.setdefault(color_bin, random_color(h=seed)) if fbgcolor: # Parse color options auto_m = re.search("auto\(([^)]*)\)", fbgcolor) if auto_m: target_attr = auto_m.groups()[0].strip() if not target_attr : color_keyattr = f["value"] else: color_keyattr = target_attr color_keyattr = color_keyattr.lstrip('@') color_bin = getattr(node, color_keyattr, None) last_seed = f2last_seed.setdefault(color_keyattr, random.random()) seed = last_seed + 0.10 + random.uniform(0.1, 0.2) f2last_seed[color_keyattr] = seed fbgcolor = f2color.setdefault(color_bin, random_color(h=seed)) if f["ftype"] == "text": if f.get("format", None): fvalue = f["format"] % fvalue F = TextFace(fvalue, fsize = fsize, fgcolor = fcolor or "black", fstyle = f.get('fstyle', None)) elif f["ftype"] == "fullseq": F = faces.SeqMotifFace(seq=fvalue, seq_format="seq", seqtail_format="seq", height=fsize) elif f["ftype"] == "compactseq": F = faces.SeqMotifFace(seq=fvalue, seq_format="compactseq", seqtail_format="compactseq", height=fsize) elif f["ftype"] == "blockseq": F = faces.SeqMotifFace(seq=fvalue, seq_format="blockseq", seqtail_format="blockseq", height=fsize, fgcolor=fcolor or "slategrey", bgcolor=fbgcolor or "slategrey", scale_factor = 1.0) fbgcolor = None elif f["ftype"] == "bubble": try: v = float(fvalue) except ValueError: rad = fsize else: rad = fsize * v F = faces.CircleFace(radius=rad, style="sphere", color=fcolor or "steelblue") elif f["ftype"] == "heatmap": if not f['column']: col = ftype_pos[f["pos"]] else: col = f["column"] for i, value in enumerate(heatmap_data.get(node.name, [])): ftype_pos[f["pos"]] += 1 if value is None: color = heatmap_color_missing elif value > heatmap_center_value: color = gradient_color(abs(heatmap_center_value - value), heatmap_max_value, hue=heatmap_color_up) elif value < heatmap_center_value: color = gradient_color(abs(heatmap_center_value - value), heatmap_max_value, hue=heatmap_color_down) else: color = heatmap_color_center node.add_face(RectFace(20, 20, color, color), position="aligned", column=col + i) # Add header # for i, name in enumerate(header): # nameF = TextFace(name, fsize=7) # nameF.rotation = -90 # tree_style.aligned_header.add_face(nameF, column=i) F = None elif f["ftype"] == "profile": # internal profiles? F = None elif f["ftype"] == "barchart": F = None elif f["ftype"] == "piechart": F = None # Add the Face if F: F.opacity = f['opacity'] or 1.0 # Set face general attributes if fbgcolor: F.background.color = fbgcolor if not f['column']: col = ftype_pos[f["pos"]] ftype_pos[f["pos"]] += 1 else: col = f["column"] node.add_face(F, column=col, position=f["pos"]) if args.image: t.render("t%d.%s" %(tindex, args.image), tree_style=ts, w=args.width, h=args.height, units=args.size_units) else: t.show(None, tree_style=ts)
(t & "C").add_face(seqFace, 0, "aligned") seqFace = SeqMotifFace(seq, seq_format="()") (t & "D").add_face(seqFace, 0, "aligned") seqFace = SeqMotifFace(seq, motifs=simple_motifs, seq_format="-") (t & "E").add_face(seqFace, 0, "aligned") seqFace = SeqMotifFace(seq=None, motifs=simple_motifs, gap_format="blank") (t & "F").add_face(seqFace, 0, "aligned") seqFace = SeqMotifFace(seq, motifs=mixed_motifs, seq_format="-") (t & "G").add_face(seqFace, 0, "aligned") seqFace = SeqMotifFace(seq=None, motifs=box_motifs, gap_format="line") (t & "H").add_face(seqFace, 0, "aligned") seqFace = SeqMotifFace(seq[30:60], seq_format="seq") (t & "I").add_face(seqFace, 0, "aligned") return t if __name__ == '__main__': t = get_example_tree() ts = TreeStyle() ts.tree_width = 50 #t.show(tree_style=ts) t.render("seq_motif_faces.png", tree_style=ts)