def tree_style_with_data(self, data={}, order=None, force_topology=False): """ newick: text or file render_in: default %%inline for notebooks data: {leaf -> col -> value} """ ts = TreeStyle() if data: if not order: # order = list(data.keys()) first = data.keys() first = list(first)[0] order = data[first].keys() ts.show_leaf_name = True ts.draw_guiding_lines = True ts.force_topology = force_topology for i, x in enumerate(order): tf = TextFace(x) tf.margin_left = 5 ts.aligned_header.add_face(tf, column=i) if data: for leaf in self.tree.get_leaves(): for i, col in enumerate(order): tf = TextFace(data[leaf.name][col]) tf.margin_left = 5 leaf.add_face(tf, column=i, position="aligned") return 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 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
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)
from ete3 import TreeStyle from ete3 import EvolTree from ete3 import faces tree = EvolTree("data/S_example/measuring_S_tree.nw") tree.link_to_alignment('data/S_example/alignment_S_measuring_evol.fasta') print(tree) print('\n Running free-ratio model with calculation of ancestral sequences...') tree.run_model('fb_anc') #tree.link_to_evol_model('/tmp/ete3-codeml/fb_anc/out', 'fb_anc') I = TreeStyle() I.force_topology = False I.draw_aligned_faces_as_table = True I.draw_guiding_lines = True I.guiding_lines_type = 2 I.guiding_lines_color = "#CCCCCC" for n in sorted(tree.get_descendants() + [tree], key=lambda x: x.node_id): if n.is_leaf(): continue anc_face = faces.SequenceFace(n.sequence, 'aa', fsize=10, bg_colors={}) I.aligned_foot.add_face(anc_face, 1) I.aligned_foot.add_face( faces.TextFace('node_id: #%d ' % (n.node_id), fsize=8), 0) print('display result of bs_anc model, with ancestral amino acid sequences.') tree.show(tree_style=I) print('\nThe End.')
def scan_internals_pearR(tree, size, threshold, sources="none", simpson_threhold=0.4): global t #sources is defaulted to be "none" import math, seaborn import numpy as np from scipy.stats import pearsonr, spearmanr R_list = [] R2_list = [] S_index_list = [] tree_path = os.path.join(filepath, tree) t = Tree(tree_path, format=0) internals_dict = {} internal_nodes = [] avoid_sources = ["Unknown"] # sources to be omitted i = 0 path_trees = 'time_signal_trees' if not os.path.exists(path_trees): os.mkdir(path_trees) for node in t.traverse(): if len(node) >= size: internal_nodes.append(node) dist_list = [] year_list = [] if sources != "none": source_list = [] node.add_features(nodetype='internal') conf = node.support for leaf in node: #may change with different label format ###time internal_dist = node.get_distance(leaf) year_list.append(leaf.name.split('_')[1]) dist_list.append(internal_dist) ###end of time ###sources if sources != "none": z = leaf.name s = z.split("_")[4] if s not in avoid_sources: source_list.append(s) ####end of sources len_leaves = len(year_list) x_years = np.asarray(year_list).astype(np.int) y_dists = np.asarray(dist_list) R, P = spearmanr(x_years, y_dists) Rpear, Ppear = pearsonr(x_years, y_dists) ###for sources if sources != "none": source_names, source_fre = Uniq(source_list) s_index = simpson(source_fre) S_index_list.append(s_index) ###end of sources if math.isnan(R) != True: if R * R >= threshold: i += 1 nodetree = str(i) + '_R2_' + str(round(R * R, 2)) + '.tree' node.write(outfile=filepath + '/' + path_trees + '/' + nodetree, format=0) nt = Tree(filepath + '/' + path_trees + '/' + nodetree) leaves = [leaf.name.replace("'", "") for leaf in nt] leaves_num = len(leaves) leave_first = leaves[0].split('_')[0] leavesfile = open( filepath + '/' + path_trees + '/' + nodetree + '.' + str(leaves_num) + '.' + leave_first + '.leaves.txt', 'w') leavesfile.write("\n".join(leaves)) internals_dict[node] = R, P node.add_features(Rsize=int(R * R * 50)) R2_text = TextFace('R2=' + str(round(R * R, 2))) #node.add_face(R2_text,column=0,position='branch-top') leaves_text = TextFace('Leaves=' + str(len_leaves)) #node.add_face(leaves_text,column=0,position='branch-bottom') R2_list.append(R * R) for leaf in node: leaf.add_features(showname=True) elif Rpear * Rpear >= threshold: i += 1 nodetree = str(i) + '_R2_' + str(round(Rpear * Rpear, 2)) + '.tree' node.write(outfile=filepath + '/' + path_trees + '/' + nodetree, format=0) nt = Tree(filepath + '/' + path_trees + '/' + nodetree) leaves = [leaf.name.replace("'", "") for leaf in nt] leaves_num = len(leaves) leave_first = leaves[0].split('_')[0] leavesfile = open( filepath + '/' + path_trees + '/' + nodetree + '.' + str(leaves_num) + '.' + leave_first + '.leaves.txt', 'w') leavesfile.write("\n".join(leaves)) internals_dict[node] = Rpear, Ppear node.add_features(Rpearsize=int(Rpear * Rpear * 50)) R2_text = TextFace('R2=' + str(round(Rpear * Rpear, 2))) #node.add_face(R2_text,column=0,position='branch-top') leaves_text = TextFace('Leaves=' + str(len_leaves)) #node.add_face(leaves_text,column=0,position='branch-bottom') R2_list.append(Rpear * Rpear) for leaf in node: leaf.add_features(showname=True) else: internals_dict[node] = R, P R2_list.append(R * R) ###for sources if sources != "none": if s_index <= simpson_threhold: #more clonal, low diversity nstyle["hz_line_color"] = "blue" node.set_style(nstyle) source_text = TextFace('S=' + str(round(s_index, 2)), fgcolor="blue", fsize=15) node.add_face(source_text, column=1, position='branch-bottom') else: nstyle["hz_line_color"] = "green" node.set_style(nstyle) source_text = TextFace('S=' + str(round(s_index, 2)), fgcolor="green", fsize=15) node.add_face(source_text, column=1, position='branch-bottom') ###end of sources ###for time ## seaborn.set(style="white", palette="muted", color_codes=True) ## sns_plot=seaborn.distplot(np.array(R2_list),rug=True) ## fig = sns_plot.get_figure() ## fig.savefig(os.path.join(filepath, tree.rsplit('.')[0]+"_R2_distribution.png")) ## sns_plot.clear() ###end of time ###for source if sources != "none": seaborn.set(style="white", palette="muted", color_codes=True) sns_plot2 = seaborn.distplot(np.array(S_index_list), rug=True) fig2 = sns_plot2.get_figure() fig2.savefig(filepath + tree.rsplit('.')[0] + "_simpson_index_distribution.png") sns_plot2.clear() ###end of source ns = NodeStyle() ns["vt_line_width"] = 2 ns["hz_line_width"] = 2 ns["size"] = 0 for node in t.traverse(): node.set_style(ns) ts = TreeStyle() ts.layout_fn = layout ts.mode = "c" ts.scale = 180 ts.show_leaf_name = False ts.force_topology = True ts.allow_face_overlap = True #ts.branch_vertical_margin=2 #t.render(filepath+tree.rsplit('.')[0]+"_time_signals.png",dpi=300,tree_style=ts) outpath = os.path.join(filepath, tree.rsplit('.')[0] + "_time_signals.pdf") t.render(outpath, tree_style=ts)
def create_circle(self, filename, title, name2color=None, name2class_dic=None, class2color_dic=None, vector=None, ignore_branch_length=True): plt.clf() axis_font = {'size': '3'} plt.rc('xtick', labelsize=0.1) plt.rc('ytick', labelsize=0.1) plt.rc({'font.size': 0.1}) # legend creation if name2class_dic and class2color_dic: leg = [] for cls, color in class2color_dic.items(): leg.append(mpatches.Patch(color=color, label=cls)) t = Tree(self.nwk) # iterate over tree leaves only for l in t.iter_leaves(): ns = NodeStyle() if name2color: ns["bgcolor"] = name2color[ l.name] if l.name in name2color else 'white' elif name2class_dic and class2color_dic: ns["bgcolor"] = class2color_dic[name2class_dic[ l.name]] if l.name in name2class_dic else 'white' # Gray dashed branch lines #ns["hz_line_type"] = 1 #ns["hz_line_color"] = "#cccccc" # l.img_style = ns F = TextFace(l.name) F.ftype = 'Times' #if vector: # if l.name in vector: l.add_features(profile=[random.random() for x in range(10)]) #vector[l.name]) l.add_features(deviation=[0 for x in range(10) ]) #len(vector[l.name]))]) l.add_face(ProfileFace(max_v=1, min_v=0.0, center_v=0.5, width=200, height=40, style='heatmap', colorscheme=5), column=0, position='aligned') # Create an empty TreeStyle ts = TreeStyle() # Set our custom layout function ts.layout_fn = VisualizeCircularTree.layout # Draw a tree ts.mode = "c" # We will add node names manually ts.show_leaf_name = False # Show branch data ts.show_branch_length = True ts.show_branch_support = True ts.force_topology = ignore_branch_length ts.title.add_face(TextFace(title, fsize=20, ftype='Times'), column=15) # legend creation if name2class_dic and class2color_dic: for k, (cls, col) in enumerate(class2color_dic.items()): x = RectFace(8, 8, 'black', col) #x.opacity=0.5 ts.legend.add_face(x, column=8) ts.legend.add_face(TextFace(' ' + cls + ' ', fsize=9, ftype='Times'), column=9) t.render(filename + '.pdf', tree_style=ts, dpi=5000)
SAMPLE_LANG_PAIRS = None DATA_PATH = {"northeuralex": "data/northeuralex-cldf-20210111-fix-pd.tsv", "ielex": "data/ielex-4-26-2016.csv"} DATA_URL = {"northeuralex": "http://www.sfs.uni-tuebingen.de/~jdellert/northeuralex/0.9/northeuralex-0.9-forms.tsv", "ielex": "TEST"} CLTS_PATH = "v1.4.1.tar.gz" CLTS_URL = "https://github.com/cldf-clts/clts/archive/v1.4.1.tar.gz" # Define tree style ETE_TREE_STYLE = TreeStyle() ETE_TREE_STYLE.show_scale = False ETE_TREE_STYLE.show_leaf_name = False ETE_TREE_STYLE.force_topology = False ETE_TREE_STYLE.show_border = False ETE_TREE_STYLE.margin_top = ETE_TREE_STYLE.margin_bottom = ETE_TREE_STYLE.margin_right = ETE_TREE_STYLE.margin_left = 5 ETE_NODE_STYLE = NodeStyle() ETE_NODE_STYLE["size"] = 0 # remove balls from leaves config = { "n_hidden": N_HIDDEN, "n_layers_encoder": N_LAYERS_ENCODER, "n_layers_decoder": N_LAYERS_DECODER, "dropout": DROPOUT, "bidirectional_encoder": BIDIRECTIONAL_ENCODER, "bidirectional_decoder": BIDIRECTIONAL_DECODER, "encoder_all_steps": ENCODER_ALL_STEPS, "batch_size": BATCH_SIZE,
from ete3 import EvolTree from ete3 import faces tree = EvolTree ("data/S_example/measuring_S_tree.nw") tree.link_to_alignment ('data/S_example/alignment_S_measuring_evol.fasta') print tree print '\n Running free-ratio model with calculation of ancestral sequences...' tree.run_model ('fb_anc') #tree.link_to_evol_model('/tmp/ete3-codeml/fb_anc/out', 'fb_anc') I = TreeStyle() I.force_topology = False I.draw_aligned_faces_as_table = True I.draw_guiding_lines = True I.guiding_lines_type = 2 I.guiding_lines_color = "#CCCCCC" for n in sorted (tree.get_descendants()+[tree], key=lambda x: x.node_id): if n.is_leaf(): continue anc_face = faces.SequenceFace (n.sequence, 'aa', fsize=10, bg_colors={}) I.aligned_foot.add_face(anc_face, 1) I.aligned_foot.add_face(faces.TextFace('node_id: #%d '%(n.node_id), fsize=8), 0) print 'display result of bs_anc model, with ancestral amino acid sequences.' tree.show(tree_style=I) print '\nThe End.'
name_face = AttrFace("name", fsize=10, ftype="Roboto", fgcolor='#191919') name_face.margin_right = 10 name_face.margin_left = 10 # Adds the name face to the image at the preferred position faces.add_face_to_node(name_face, node, column=0, position="branch-right") t = Tree(nodes2['ROOT'].newick() + ';', format=8) ts = TreeStyle() ts.mode = "c" ts.arc_start = 0 ts.arc_span = 360 ts.force_topology = True ts.show_scale = False ts.branch_vertical_margin = 2 ts.root_opening_factor = 0 # Do not add leaf trees automatically ts.show_leaf_name = False # Use my custom layout ts.layout_fn = my_layout nstyle = NodeStyle() nstyle["size"] = 0 for n in t.traverse(): n.set_style(nstyle) c = t & "artifact.n.01" cn = NodeStyle()
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)
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 curr_best = 0.00 best = [] #"best" here means worth looking into, although it is going to include some real shitty trees
def create_circle(self, filename, title, ignore_branch_length=True): plt.clf() axis_font = {'size': '29'} plt.rc('xtick', labelsize=0.1) plt.rc('ytick', labelsize=0.1) plt.rc({'font.size': 0.2}) plt.rc('text', usetex=True) # legend creation if self.motif2struct and self.struct2color_dic: leg = [] for cls, color in self.struct2color_dic.items(): leg.append(mpatches.Patch(color=color, label=str(cls))) t = Tree(self.nwk) node_to_keep = [] for l in t.iter_leaves(): if len(l.name) > 1: node_to_keep.append(l.name) t.prune(tuple(node_to_keep)) # iterate over tree leaves only for l in t.iter_leaves(): ns = NodeStyle() if self.motif2struct and self.struct2color_dic: ns["bgcolor"] = self.struct2color_dic[self.motif2struct[ l. name]] if l.name in self.motif2struct and self.motif2struct[ l.name] in self.struct2color_dic else 'white' # Gray dashed branch lines #ns["hz_line_type"] = 1 #ns["hz_line_color"] = "#cccccc" # l.img_style = ns if self.propVec: if l.name in self.propVec: l.add_features(profile=self.propVec[l.name]) l.add_features(deviation=[ 0 for x in range(len(self.propVec[l.name])) ]) l.add_face(ProfileFace(max_v=1, min_v=-1, center_v=0, width=200, height=40, style='heatmap', colorscheme=2), column=3, position='aligned') l.name = " " + l.name + " " # Create an empty TreeStyle ts = TreeStyle() # Set our custom layout function ts.layout_fn = VisualizeTreeOfMotifs.layout # Draw a tree ts.mode = "c" # We will add node names manually ts.show_leaf_name = False # Show branch data ts.show_branch_length = False ts.show_branch_support = False ts.force_topology = ignore_branch_length ts.title.add_face(TextFace(title, fsize=20, ftype='Times'), column=15) # legend creation if self.motif2struct and self.struct2color_dic: for k, (cls, col) in enumerate(self.struct2color_dic.items()): x = RectFace(15, 15, 'black', col) #x.opacity=0.5 ts.legend.add_face(x, column=8) ts.legend.add_face(TextFace(' ' + str(cls) + ' ', fsize=30, ftype='Times'), column=9) ts.legend.add_face(TextFace('--- Properties vector order ↓', fsize=30, ftype='Times'), column=10) for y in [ 'Mean molecular weight of amino acids', 'Mean flexibility of amino acids', 'Mean DIWV instability index of sequence', 'Mean surface accessibility of amino acids', 'Mean KD hydrophobicity', 'Mean hydrophilicity of amino acids' ]: x = RectFace(5, 5, 'black', 'black') #x.opacity=0.5 ts.legend.add_face(x, column=11) ts.legend.add_face(TextFace(' ' + y + ' ', fsize=25, ftype='Times'), column=12) t.render(filename + '.pdf', tree_style=ts, dpi=5000)
def uploaded_secuence(request): path = BASE_DIR + '/secuences/secuence.fasta' handler = SequenceHandler() handler.validate_sequences(path) upload_id = calendar.timegm(time.gmtime()) if not handler.has_errors: for fasta in handler.dic_data: coordenadas = convertDirectionToCoordinates(fasta['loc']) fasta_to_insert = Secuence() fasta_to_insert.address = fasta['loc'] fasta_to_insert.date = fasta['date'] fasta_to_insert.latitud = coordenadas[0] fasta_to_insert.longitud = coordenadas[1] fasta_to_insert.bio_id = fasta['gb'] fasta_to_insert.content = fasta['seq'] fasta_to_insert.length = len(fasta['seq']) fasta_to_insert.upload_id = upload_id fasta_to_insert.source = fasta['source'] fasta_to_insert.save() handler.clean_data() if not handler.is_aligned: if platform.system() == 'Linux': handler.lnx_alignment(path) handler.lnx_build_tree() else: handler.win_alignment(path) handler.win_build_tree() else: # la secuencia esta alineada handler.make_file_aln_for_iqtree() if platform.system() == 'Linux': handler.lnx_build_tree() else: handler.win_build_tree() messages.success(request, f"El archivo se ha subido correctamente") tree_file = BASE_DIR + "/secuences/secuence.fasta_aln.fasta.treefile" aln_path = BASE_DIR + "/secuences/secuence.fasta_aln.fasta" ts = TreeStyle() ts.force_topology = True ts.show_branch_support = True ts.show_leaf_name = False ts.branch_vertical_margin = 10 t = PhyloTree(tree_file) t.link_to_alignment(aln_path) img_name = "TpFinalBioApp/static/TpFinalBioApp/img/output/myTree" + "_" + str( upload_id) + ".svg" t.render(img_name, tree_style=ts) print(t) if platform.system() != 'Linux': os.remove(BASE_DIR + "/secuences/secuence.fasta_aln.fasta.model.gz") return redirect('Map', upload_id) else: messages.error(request, f"El archivo no es correcto. " + handler.error_message) return redirect('Home')
def drawtree(sequence_dictionary): # LOAD TCS EVALUATION FILE all_evaluations = list(SeqIO.parse(EVALUATIONFILE, "fasta")) dict_of_evaluations = {} for seq_record in all_evaluations: dict_of_evaluations[seq_record.id] = seq_record.seq print(seq_record.id + " : " + seq_record.seq) # LOAD NEWICK FILE TO CHECK FOR REMOVED TAXA AND REMOVE THEM FROM THE DICTIONARY with open(SPECIES_TREE, 'r') as newick_file: newick_string = newick_file.read() for key in list(sequence_dictionary): if key in newick_string: print(key + " ok!") else: sequence_dictionary.pop(key, None) # LOAD FASTA SEQUENCES all_sequences = list(SeqIO.parse(FASTA_ALIGNED_TRIMMED, "fasta")) dict_of_sequences = {} for seq_record in all_sequences: # Only load fasta sequence if it was not removed during tree assembly if seq_record.id in newick_string: dict_of_sequences[seq_record.id] = seq_record.seq print(seq_record.id + " : " + seq_record.seq) # AMINO ACID COLORING amino_acid_fgcolor_dict = { 'A': 'Black', 'C': 'Black', 'D': 'Black', 'E': 'Black', 'F': 'Black', 'G': 'Black', 'H': 'Black', 'I': 'Black', 'K': 'Black', 'L': 'Black', 'M': 'Black', 'N': 'Black', 'P': 'Black', 'Q': 'Black', 'R': 'Black', 'S': 'Black', 'T': 'Black', 'V': 'Black', 'W': 'Black', 'Y': 'Black', '-': 'Black' } # AMINO ACID BACKGROUND COLORING amino_acid_bgcolor_dict = { 'A': 'White', 'C': 'White', 'D': 'White', 'E': 'White', 'F': 'White', 'G': 'White', 'H': 'White', 'I': 'White', 'K': 'White', 'L': 'White', 'M': 'White', 'N': 'White', 'P': 'White', 'Q': 'White', 'R': 'White', 'S': 'White', 'T': 'White', 'V': 'White', 'W': 'White', 'Y': 'White', '-': 'White' } outgroup_name = 'XP_022098898.1' print("Loading tree file " + SPECIES_TREE) t = Tree(SPECIES_TREE) ts = TreeStyle() ts.show_leaf_name = False # Zoom in x-axis direction ts.scale = 40 # This makes all branches the same length!!!!!!! ts.force_topology = True #Tree.render(t, "final_tree_decoded.svg") t.set_outgroup(t & outgroup_name) ts.show_branch_support = False ts.show_branch_length = False ts.draw_guiding_lines = True ts.branch_vertical_margin = 10 # 10 pixels between adjacent branches print(t) # Define node styles for different animal classes # Mammals mammalia = NodeStyle() mammalia["bgcolor"] = "Chocolate" # Reptiles reptilia = NodeStyle() reptilia["bgcolor"] = "Olive" # Cartilaginous fish chondrichthyes = NodeStyle() chondrichthyes["bgcolor"] = "SteelBlue" # Ray-fenned fish actinopterygii = NodeStyle() actinopterygii["bgcolor"] = "CornflowerBlue" # Lobe-finned fish sarcopterygii = NodeStyle() sarcopterygii["bgcolor"] = "DarkCyan" # Birds aves = NodeStyle() aves["bgcolor"] = "DarkSalmon" # Amphibia amphibia = NodeStyle() amphibia["bgcolor"] = "DarkSeaGreen" # Myxini myxini = NodeStyle() myxini["bgcolor"] = "LightBlue" general_leaf_style = NodeStyle() # size of the blue ball general_leaf_style["size"] = 15 # Draws nodes as small red spheres of diameter equal to 10 pixels nstyle = NodeStyle() nstyle["shape"] = "sphere" nstyle["size"] = 15 nstyle["fgcolor"] = "darkred" # Gray dashed branch lines #nstyle["hz_line_type"] = 1 #nstyle["hz_line_color"] = "#cccccc" # Applies the same static style to all nodes in the tree if they are not leaves. # Note that if "nstyle" is modified, changes will affect to all nodes # Apply a separate style to all leaf nodes for node in t.traverse(): if node.is_leaf(): print("Setting leaf style for node " + node.name) animal_class_name = sequence_dictionary[node.name][3] print(animal_class_name) if animal_class_name == 'Mammalia': node.set_style(mammalia) elif animal_class_name == 'Reptilia': node.set_style(reptilia) elif animal_class_name == 'Chondrichthyes': node.set_style(chondrichthyes) elif animal_class_name == 'Actinopterygii': node.set_style(actinopterygii) elif animal_class_name == 'Sarcopterygii': node.set_style(sarcopterygii) elif animal_class_name == 'Aves': node.set_style(aves) elif animal_class_name == 'Amphibia': node.set_style(amphibia) elif animal_class_name == 'Myxini': node.set_style(myxini) else: node.set_style(nstyle) # Set general leaf attributes node.set_style(general_leaf_style) else: node.set_style(nstyle) # ADD IMAGES #for key, value in dict_of_images.items(): # imgFace = ImgFace(IMG_PATH+value, height = 40) # (t & key).add_face(imgFace, 0, "aligned") # imgFace.margin_right = 10 # imgFace.hzalign = 2 # ADD TEXT for key, value in sequence_dictionary.items(): if key == outgroup_name: print(key, value[0], value[1], value[2], value[3]) textFace = TextFace(value[1] + " (" + value[2] + ", " + key + ") ", fsize=16) (t & key).add_face(textFace, 2, "aligned") textFace.margin_left = 10 print(key, value[0], value[1], value[2], value[3]) textFace = TextFace(" ", fsize=16) (t & key).add_face(textFace, 2, "aligned") textFace.margin_left = 10 print(key, value[0], value[1], value[2], value[3]) textFace = TextFace("Consensus score", fsize=16) (t & key).add_face(textFace, 2, "aligned") textFace.margin_left = 10 else: print(key, value[0], value[1], value[2], value[3]) textFace = TextFace(value[1] + " (" + value[2] + ", " + key + ") ", fsize=16) (t & key).add_face(textFace, 2, "aligned") textFace.margin_left = 10 # ADD DUMMY TEXT for key, value in sequence_dictionary.items(): textFace3 = TextFace(" ", fsize=16) (t & key).add_face(textFace3, 0, "aligned") # ADD SVG IMAGES for key, value in sequence_dictionary.items(): svgFace = SVGFace(IMG_PATH + value[0], height=40) (t & key).add_face(svgFace, 1, "aligned") svgFace.margin_right = 10 svgFace.margin_left = 10 svgFace.hzalign = 2 animal_class_name = value[3] if animal_class_name == 'Mammalia': svgFace.background.color = "Chocolate" elif animal_class_name == 'Reptilia': svgFace.background.color = "Olive" elif animal_class_name == 'Chondrichthyes': svgFace.background.color = "SteelBlue" elif animal_class_name == 'Actinopterygii': svgFace.background.color = "CornflowerBlue" elif animal_class_name == 'Sarcopterygii': svgFace.background.color = "DarkCyan" elif animal_class_name == 'Aves': svgFace.background.color = "DarkSalmon" elif animal_class_name == 'Amphibia': svgFace.background.color = "DarkSeaGreen" elif animal_class_name == 'Myxini': svgFace.background.color = "LightBlue" else: svgFace.background.color = "White" color_dict = { '-': "White", '0': "#FF6666", '1': "#EE7777", '2': "#DD8888", '3': "#CC9999", '4': "#BBAAAA", '5': "#AABBBB", '6': "#99CCCC", '7': "#88DDDD", '8': "#77EEEE", '9': "#66FFFF" } # ADD SEQUENCES AS TEXT (ADDING MORE THAN ONE SEQUENCE DOES NOT WORK) for key, value in dict_of_sequences.items(): if key == outgroup_name: for char in range(0, len(value)): textFace2 = TextFace(value[char], fsize=16) (t & key).add_face(textFace2, char + 3, "aligned") textFace2.background.color = color_dict[ dict_of_evaluations[key][char]] # This is for the consensus coloring, print a space instead of the sequence charactger of the outgroup sequence textFace4 = TextFace(' ', fsize=16) (t & key).add_face(textFace4, char + 3, "aligned") textFace4.background.color = "White" textFace5 = TextFace(' ', fsize=16) (t & key).add_face(textFace5, char + 3, "aligned") textFace5.background.color = color_dict[ dict_of_evaluations['cons'][char]] textFace6 = TextFace(' ', fsize=16) (t & key).add_face(textFace6, char + 3, "aligned") textFace6.background.color = "White" # margins have the same color as the consensus color # These do not work!!!! #textFace4.margin_top = 10 #textFace4.margin_bottom = 10 else: for char in range(0, len(value)): #print(str(char) + " of " + str(len(value))) textFace2 = TextFace(value[char], fsize=16) (t & key).add_face(textFace2, char + 3, "aligned") #print('key: '+key) #print(dict_of_evaluations[key]) #print(dict_of_evaluations[key][char]) textFace2.background.color = color_dict[ dict_of_evaluations[key][char]] # ROTATING SOME NODES CAN BE DONE HERE: # MOVE ACTINOPTERYGII NEXT TO THE OTHER FISH # Actinopterygii, e.g. Spotted gar - XP_006632034.2 # Sarcopterygii, e.g. Coelacant - XP_006006690.1 # Mammals, e.g. Rat - NP_446105.1 # Birds, e.g. Chicken - XP_420532.3 #n1 = t.get_common_ancestor("XP_420532.3", "NP_446105.1") # spotted gar and coelacant #n1 = t.get_common_ancestor("XP_006632034.2", "XP_006006690.1") #n1.swap_children() # Atlantic salmon and coelacant #n2 = t.get_common_ancestor("NP_001167218.1", "XP_006006690.1") #n2.swap_children() # Tibet frog and coelacanttroglodytes #n2 = t.get_common_ancestor("XP_018419054.1", "XP_006006690.1") #n2.swap_children() # Xenopus and coelacant #n2 = t.get_common_ancestor("XP_002933363.1", "XP_006006690.1") #n2.swap_children() # alligator and penguin #n2 = t.get_common_ancestor("XP_006276984.1", "XP_009329004.1") #n2.swap_children() # hagfish and human n2 = t.get_common_ancestor("ENSEBUT00000000354.1", "NP_005420.1") n2.swap_children() # zebrafish and human n2 = t.get_common_ancestor("NP_991297.1", "NP_005420.1") n2.swap_children() # Tibet frog and human n2 = t.get_common_ancestor("XP_018419054.1", "NP_005420.1") n2.swap_children() # gekko and penguin n2 = t.get_common_ancestor("XP_015283812.1", "XP_009329004.1") n2.swap_children() # turtle and penguin n2 = t.get_common_ancestor("XP_005304228.1", "XP_009329004.1") n2.swap_children() # Opossum and human n2 = t.get_common_ancestor("XP_007496150.2", "NP_005420.1") n2.swap_children() # Dog and human n2 = t.get_common_ancestor("XP_540047.2", "NP_005420.1") n2.swap_children() # Mouse and human n2 = t.get_common_ancestor("NP_033532.1", "NP_005420.1") n2.swap_children() # Chimp and human n2 = t.get_common_ancestor("XP_526740.1", "NP_005420.1") n2.swap_children() # Add description to treefile # # Add fasta description line of outgroup sequence description_text = "Outgroup sequence: " + outgroup_name + "starfish VEGF-C\n" # Bootstrap analysis description_text += "Bootstrap: approximate Likelihood-Ratio Test\n" # Alignment methods description_text += "Alignment algorithm: m_coffee using" + "clustalw2, t_coffee, muscle, mafft, pcma, probcons" description_text += "\n" #ts.title.add_face(TextFace(description_text, fsize=12), column=0) t.render(SVG_TREEFILE, tree_style=ts, units="mm", h=240)
def build_colorful_tree(newick, filename=""): """ Note that these will fail if we dont have all the pre-reqs and it is not triival to get them all. This stuff is NOT general purpose. """ from ete3 import Tree, TreeStyle, CircleFace, TextFace tree = Tree(newick) #setup colors and treestyle ts = TreeStyle() ts.show_leaf_name = True ts.mode = "c" ts.arc_start = -180 # 0 degrees = 3 o'clock ts.force_topology = True ts.arc_span = 360 face = CircleFace(30, "MediumSeaGreen") face.margin_top = 1000 ts.legend.add_face(face, column=0) face = TextFace("Normal B-cell", fsize=64) face.margin_right = 100 face.margin_top = 1000 ts.legend.add_face(face, column=1) ts.legend.add_face(CircleFace(30, "SeaGreen"), column=0) face = TextFace("Normal B CD19pcell", fsize=64) face.margin_right = 100 ts.legend.add_face(face, column=1) ts.legend.add_face(CircleFace(30, "ForestGreen"), column=0) face = TextFace("Normal B CD19pCD27pcell", fsize=64) face.margin_right = 100 ts.legend.add_face(face, column=1) ts.legend.add_face(CircleFace(30, "Green"), column=0) face = TextFace("Normal B CD19pCD27mcell", fsize=64) face.margin_right = 100 ts.legend.add_face(face, column=1) ts.legend.add_face(CircleFace(30, "RoyalBlue"), column=0) face = TextFace("CLL all-batches", fsize=64) face.margin_right = 100 ts.legend.add_face(face, column=1) #draw tree from ete3 import NodeStyle styles = {} styles["normal_B"] = NodeStyle(bgcolor="MediumSeaGreen", hz_line_color="Black", vt_line_color="Black") styles["NormalBCD19pcell"] = NodeStyle(bgcolor="SeaGreen", hz_line_color="Black", vt_line_color="Black") styles["NormalBCD19pCD27pcell"] = NodeStyle(bgcolor="ForestGreen", hz_line_color="Black", vt_line_color="Black") styles["NormalBCD19pCD27mcell"] = NodeStyle(bgcolor="Green", hz_line_color="Black", vt_line_color="Black") styles["CLL"] = NodeStyle(bgcolor="RoyalBlue", hz_line_color="Black", vt_line_color="Black") for node in tree.traverse("postorder"): #print node.set_style() if len(node.get_leaf_names()) == 1: name = node.get_leaf_names()[0] if "normal_B" in name: node.set_style(styles["normal_B"]) elif "NormalBCD19pcell" in name: node.set_style(styles["NormalBCD19pcell"]) elif "NormalBCD19pCD27pcell" in name: node.set_style(styles["NormalBCD19pCD27pcell"]) elif "NormalBCD19pCD27mcell" in name: node.set_style(styles["NormalBCD19pCD27mcell"]) else: node.set_style(styles["CLL"]) #lol tree.render(filename, w=10, dpi=600, units='in', 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)