def draw(self, file, colors, color_internal_nodes=True, legend_labels=(), show_branch_support=True, show_scale=True, legend_scale=1, mode="c", neighbours=None, neighbours_block=None): max_color = len(colors) used_colors = set() for node in self.tree.traverse(): if not (color_internal_nodes or node.is_leaf()): continue color = colors[min(node.color, max_color - 1)] node.img_style['bgcolor'] = color used_colors.add(color) ts = TreeStyle() ts.mode = mode ts.scale = self.scale # Disable the default tip names config ts.show_leaf_name = False ts.show_branch_support = show_branch_support # ts.branch_vertical_margin = 20 ts.show_scale = show_scale cur_max_color = max(v.color for v in self.tree.traverse()) current_colors = colors[0:cur_max_color + 1] for i, (label, color_) in enumerate(zip(legend_labels, current_colors)): if color_ not in used_colors: continue rf = RectFace(20 * legend_scale, 16 * legend_scale, color_, color_) rf.inner_border.width = 1 rf.margin_right = 14 rf.margin_left = 14 tf = TextFace(label, fsize=26 * legend_scale) tf.margin_right = 14 ts.legend.add_face(rf, column=0) ts.legend.add_face(tf, column=1) if neighbours: old_tree = self.tree.copy() self.draw_neighbours(neighbours, neighbours_block) self.tree.render(file, w=1000, tree_style=ts) if neighbours: self.tree = old_tree
def get_tree_style(): ts = TreeStyle() ts.show_leaf_name = False # True ts.layout_fn = layout ts.rotation = 90 ts.branch_vertical_margin = 10 ts.show_scale = False # ts.mode = "c" ts.scale = 50 ts.title.add_face(TextFace(" ", fsize=20), column=0) # for n in t.traverse(): # nstyle = NodeStyle() # nstyle["fgcolor"] = "red" # nstyle["size"] = 15 # n.set_style(nstyle) # ts.show_leaf_name = True ts.legend.add_face(TextFace(" "), column=0) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(RectFace(20, 20, NO_SUPPORT_COLOR, NO_SUPPORT_COLOR), column=0) ts.legend.add_face(TextFace(" Topic with no support (u(t)=0)"), column=1) ts.legend.add_face(TextFace(" "), column=0) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(RectFace(20, 20, "#90ee90", "#90ee90"), column=0) ts.legend.add_face(TextFace(" Topic with minor support 0<u(t)<=0.4"), column=1) ts.legend.add_face(TextFace(" "), column=0) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(RectFace(20, 20, "green", "green"), column=0) ts.legend.add_face( TextFace(u" Topic with medium support 0.4<u(t)<=0.6 "), column=1) ts.legend.add_face(TextFace(" "), column=0) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(RectFace(20, 20, "#004000", "#004000"), column=0) ts.legend.add_face(TextFace(" Topic with high support u(t)>0.6"), column=1) ts.legend.add_face(TextFace(" "), column=0) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(CircleFace(10, "red"), column=0) ts.legend.add_face(TextFace(" Gap"), column=1) ts.legend.add_face(TextFace(" "), column=0) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(RectFace(40, 40, "#004000", "#004000"), column=0) # green # ts.legend.add_face(CircleFace(15, "green"), column=1) ts.legend.add_face(TextFace(" Head subject or offshoot"), column=1) ts.legend_position = 4 # ts.title.add_face(TextFace(" ", fsize=20), column=0) return ts
def render_tree(tree, mode, cluster, colourDict, width, position): duplicates = ["'EBOV|EMLab-RT|KG12||GIN|Boke|?|MinION_LQ05|2015-05-27'", "'EBOV|EMLab-RT|KG45||GIN|Boke|?|MinION_LQ10|2015-06-09'", "'EBOV|EMLab-RT|KG90||GIN|Boke|?|MinION_LQ05|2015-06-19'", "'EBOV|EMLab-RT|KG91||GIN|Boke|?|MinION_LQ05|2015-06-20'"] print('Running %s: %s cluster' %(mode, cluster)) if mode == 'small': #delete unwanted leaves keep_leaves = [] b = ["'" + clusters[cluster][0] + "'", "'" + clusters[cluster][1] + "'"] for a in tree.get_common_ancestor(b).get_leaves(): keep_leaves.append(a.name) delete_leaves = [leaf for leaf in tree.get_leaf_names() if leaf not in keep_leaves] #if cluster == 'Boke': # delete_leaves.extend(duplicates) print('Keeping %s leaves' %len(keep_leaves)) for leaf in delete_leaves: if tree.search_nodes(name=leaf)[0]: n = tree.search_nodes(name=leaf)[0] #if leaf in duplicates: # n.delete(preserve_branch_length=True) #else: n.delete() #print 'Removed %s' %(n.get_leaf_names()[0]) tree.ladderize() tree.write(outfile=sys.argv[1] + '_' + cluster + '.nwk') for n in tree.get_leaves(): display_name = n.get_leaf_names()[0][1:-1] country = metadata[display_name]['country'] instrument = metadata[display_name]['instrument'] #if cluster == 'Boke': if mode == 'big': n.add_face(MyTextFace(metadata[display_name]['short_id'], ftype="Helvetica", fsize=size[mode]), column=0, position="aligned") n.add_face(MyTextFace(metadata[display_name]['prefec'], ftype="Helvetica", fsize=size[mode]), column=1, position="aligned") n.add_face(MyTextFace(metadata[display_name]['date'], ftype="Helvetica", fsize=size[mode]), column=2, position="aligned") if country == 'GUI' or country == 'GIN': if instrument == 'MinION': C = CircleFace(radius=size[mode]/2, color=colourDict[metadata[display_name]['prefec']]) else: C = CircleFace(radius=size[mode]/2, color='#F1F1F1') elif country == 'SLE': if instrument == 'MinION': C = RectFace(width=size[mode], height=size[mode], bgcolor=colourDict[metadata[display_name]['prefec']], fgcolor='#FFFFFF') else: C = RectFace(width=size[mode], height=size[mode], bgcolor='#D3D3D3', fgcolor='#FFFFFF') elif country == 'LIB' or country == 'LBR': if instrument == 'MinION': C = RectFace(triangle=True, width=size[mode], height=size[mode], bgcolor=colourDict[metadata[display_name]['prefec']], fgcolor='#FFFFFF') else: C = RectFace(triangle=True, width=size[mode], height=size[mode], bgcolor='#939393', fgcolor='#FFFFFF') n.add_face(C, column=1, position=position) tree.render(file_name=sys.argv[1] + '_' + cluster + '.pdf', tree_style=ts, w=width)
def layout(node): if node.is_leaf(): N = AttrFace("sci_name", fsize=30) faces.add_face_to_node(N, node, 0, position="branch-right") circle = RectFace(100, 100, "black", "black") faces.add_face_to_node(circle, position="aligned", column=0, node=node) if "coli" in node.sci_name: circle = RectFace(100, 100, "red", "red") faces.add_face_to_node(circle, position="aligned", column=1, node=node) if "Salm" in node.sci_name: circle = RectFace(100, 100, "blue", "blue") faces.add_face_to_node(circle, position="aligned", column=2, node=node)
def get_example_tree(): # Performs a tree reconciliation analysis gene_tree_nw = '((Dme_001,Dme_002),(((Cfa_001,Mms_001),((Hsa_001,Ptr_001),Mmu_001)),(Ptr_002,(Hsa_002,Mmu_002))));' t = PhyloTree(gene_tree_nw) ts = TreeStyle() # disable default PhyloTree Layout ts.layout_fn = lambda x: True t.link_to_alignment(alg) node2content = t.get_cached_content() for node in t.traverse(): node.img_style["size"] = 0 if not node.is_leaf(): leaves = node2content[node] # get columns with different aa subseqs, relevant_columns = mutation_columns([lf.sequence for lf in leaves]) for seq in subseqs: f = SeqMotifFace(seq, seq_format="seq", width=10, height=8) f.margin_top = 2 f.margin_right = 6 node.add_face(f, column=0, position="branch-bottom") for j, col in enumerate(relevant_columns): col_f = RectFace(10, 10, fgcolor=None, bgcolor=None, label={"text":str(col), "fonttype":"Courier", "color":"black", "fontsize":6}) node.add_face(col_f, column=j, position="branch-top") col_f.margin_bottom = 2 else: f = SeqMotifFace(node.sequence, seq_format="seq", width=6) node.add_face(f, column=0, position="aligned") alg_length = len(lf.sequence) ts.draw_aligned_faces_as_table = False for colnum in xrange(alg_length): col_f = RectFace(10, 10, fgcolor=None, bgcolor=None, label={"text":str(colnum), "fonttype":"Courier", "color":"black", "fontsize":6}) ts.aligned_header.add_face(col_f, column=colnum) return t, ts
def layout(node): if node.is_leaf(): if node.name=="A": node.color="Blue" node.attr2="Green" elif node.name=="B": node.color="Red" node.attr2="Orange" else: node.color="Grey" node.attr2="Yellow" faces.add_face_to_node( CircleFace(radius=5, color=node.color), node, column=1) faces.add_face_to_node( RectFace(width=10, height=10, fgcolor=node.attr2, bgcolor=node.attr2), node, column=2)
def draw_tree(pstrains, names=False, subset=None): evol = {x.rstrip() for x in open('input/evolution_experiment.txt')} tree = get_tree('input/tree.nwk') strains = {x.name for x in tree.traverse() if x.name != ''} if subset is None: subset = strains evol_tree = {x.name for x in tree.traverse() if x.name in evol} commensals = {} for x in strains: if pstrains[x] == 'Commensal strain': commensals[x] = colors.cnames['blue'] elif pstrains[x] == 'Pathogenic strain': commensals[x] = colors.cnames['red'] else: commensals[x] = colors.cnames['white'] ref = NodeStyle() ref['fgcolor'] = sns.xkcd_rgb['light red'] inner = NodeStyle() inner['size'] = 0 for n in tree.traverse(): if not n.is_leaf(): n.set_style(inner) continue if n.name not in subset: continue if not names: r = RectFace(10, 3, commensals[n.name], commensals[n.name]) n.add_face(r, 0, position="aligned") ev = NodeStyle() ev["fgcolor"] = "black" ev['size'] = 3 n.set_style(ev) circular_style = TreeStyle() circular_style.mode = "c" if not names: circular_style.scale = 1300 else: circular_style.scale = 7300 circular_style.show_leaf_name = names return tree, circular_style
def visualize_tree(ete_tree_obj, genotypes={}, metadata={}, cansnp_supported_nodes={}): """ Function for visualization of cannonical snp supported clades Parameters ---------- ete_tree_obj cansnp_supported_nodes Returns ------- """ # Basic tree style ts = TreeStyle() ts.show_leaf_name = True # Draws nodes as small red spheres of diameter equal to 10 pixels for n in ete_tree_obj.traverse(): nstyle = NodeStyle() nstyle["shape"] = "sphere" nstyle["fgcolor"] = "darkred" if n.name in cansnp_supported_nodes: print("Found") #nstyle["fgcolor"] = "blue" #nstyle["size"] = cansnp_supported_nodes[n.name]['size'] #nstyle["bgcolor"] =cansnp_supported_nodes[n.name]['bgcolor'] face = RectFace(width=100, height=100, fgcolor='red', bgcolor='green') n.add_face(face, column=1) n.set_style(nstyle) ete_tree_obj.show(tree_style=ts)
def setup_heatmap(tree, tree_style, header, center_value=0, nameMap={}, nameLabel='', color_up=0.7, color_down=0.2, color_center="white"): DEFAULT_COLOR_SATURATION = 0.5 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(map(lambda x: int(x * 255), colorsys.hls_to_rgb(h, l, s)))) lightness = 1 - (value * BASE_LIGHTNESS) / max_value return hls2hex(hue, lightness, DEFAULT_COLOR_SATURATION) # Calculate max gradient value from the ClusterTree matrix maxv = abs(center_value - tree.arraytable._matrix_max) minv = abs(center_value - tree.arraytable._matrix_min) if center_value <= tree.arraytable._matrix_min: MAX_VALUE = minv + maxv else: MAX_VALUE = max(maxv, minv) # Add heatmap colors to tree cols_add_before_heat = 0 if nameMap: cols_add_before_heat = 1 for lf in tree: if nameMap: longNameFace = faces.TextFace(nameMap.get(lf.name, lf.name)) lf.add_face(longNameFace, column=0, position="aligned") for i, value in enumerate(getattr(lf, "profile", [])): if value > center_value: color = gradient_color(abs(center_value - value), MAX_VALUE, hue=color_up) elif value < center_value: color = gradient_color(abs(center_value - value), MAX_VALUE, hue=color_down) else: color = center_value #color = "LightGreen" lf.add_face(RectFace(25, 25, "white", color), position="aligned", column=i + cols_add_before_heat) # Uncomment to add numeric values to the matrix #lf.add_face(TextFace("%0.2f "%value, fsize=5), position="aligned", column=i) lf.add_face(nameFace, column=i + cols_add_before_heat + 1, position="aligned") if nameMap and nameLabel: nameF = TextFace(nameLabel, fsize=10) #nameF.rotation = -90 tree_style.aligned_header.add_face(nameF, column=0) # Add header for i, name in enumerate(header): nameF = TextFace(name, fsize=10) nameF.rotation = -90 tree_style.aligned_header.add_face(nameF, column=i + cols_add_before_heat)
def draw_tree(tree, conf, outfile): try: from ete3 import (add_face_to_node, AttrFace, TextFace, TreeStyle, RectFace, CircleFace, SequenceFace, random_color, SeqMotifFace) except ImportError as e: print(e) return def ly_basic(node): if node.is_leaf(): node.img_style['size'] = 0 else: node.img_style['size'] = 0 node.img_style['shape'] = 'square' if len(MIXED_RES) > 1 and hasattr(node, "tree_seqtype"): if node.tree_seqtype == "nt": node.img_style["bgcolor"] = "#CFE6CA" ntF = TextFace("nt", fsize=6, fgcolor='#444', ftype='Helvetica') add_face_to_node(ntF, node, 10, position="branch-bottom") if len(NPR_TREES) > 1 and hasattr(node, "tree_type"): node.img_style['size'] = 4 node.img_style['fgcolor'] = "steelblue" node.img_style['hz_line_width'] = 1 node.img_style['vt_line_width'] = 1 def ly_leaf_names(node): if node.is_leaf(): spF = TextFace(node.species, fsize=10, fgcolor='#444444', fstyle='italic', ftype='Helvetica') add_face_to_node(spF, node, column=0, position='branch-right') if hasattr(node, 'genename'): geneF = TextFace(" (%s)" % node.genename, fsize=8, fgcolor='#777777', ftype='Helvetica') add_face_to_node(geneF, node, column=1, position='branch-right') def ly_supports(node): if not node.is_leaf() and node.up: supFace = TextFace("%0.2g" % (node.support), fsize=7, fgcolor='indianred') add_face_to_node(supFace, node, column=0, position='branch-top') def ly_tax_labels(node): if node.is_leaf(): c = LABEL_START_COL largest = 0 for tname in TRACKED_CLADES: if hasattr(node, "named_lineage") and tname in node.named_lineage: linF = TextFace(tname, fsize=10, fgcolor='white') linF.margin_left = 3 linF.margin_right = 2 linF.background.color = lin2color[tname] add_face_to_node(linF, node, c, position='aligned') c += 1 for n in range(c, len(TRACKED_CLADES)): add_face_to_node(TextFace('', fsize=10, fgcolor='slategrey'), node, c, position='aligned') c += 1 def ly_full_alg(node): pass def ly_block_alg(node): if node.is_leaf(): if 'sequence' in node.features: seqFace = SeqMotifFace(node.sequence, []) # [10, 100, "[]", None, 10, "black", "rgradient:blue", "arial|8|white|domain Name"], motifs = [] last_lt = None for c, lt in enumerate(node.sequence): if lt != '-': if last_lt is None: last_lt = c if c + 1 == len(node.sequence): start, end = last_lt, c motifs.append([ start, end, "()", 0, 12, "slategrey", "slategrey", None ]) last_lt = None elif lt == '-': if last_lt is not None: start, end = last_lt, c - 1 motifs.append([ start, end, "()", 0, 12, "grey", "slategrey", None ]) last_lt = None seqFace = SeqMotifFace(node.sequence, motifs, intermotif_format="line", seqtail_format="line", scale_factor=ALG_SCALE) add_face_to_node(seqFace, node, ALG_START_COL, aligned=True) TRACKED_CLADES = [ "Eukaryota", "Viridiplantae", "Fungi", "Alveolata", "Metazoa", "Stramenopiles", "Rhodophyta", "Amoebozoa", "Crypthophyta", "Bacteria", "Alphaproteobacteria", "Betaproteobacteria", "Cyanobacteria", "Gammaproteobacteria", ] # ["Opisthokonta", "Apicomplexa"] colors = random_color(num=len(TRACKED_CLADES), s=0.45) lin2color = dict([(ln, colors[i]) for i, ln in enumerate(TRACKED_CLADES)]) NAME_FACE = AttrFace('name', fsize=10, fgcolor='#444444') LABEL_START_COL = 10 ALG_START_COL = 40 ts = TreeStyle() ts.draw_aligned_faces_as_table = False ts.draw_guiding_lines = False ts.show_leaf_name = False ts.show_branch_support = False ts.scale = 160 ts.layout_fn = [ly_basic, ly_leaf_names, ly_supports, ly_tax_labels] MIXED_RES = set() MAX_SEQ_LEN = 0 NPR_TREES = [] for n in tree.traverse(): if hasattr(n, "tree_seqtype"): MIXED_RES.add(n.tree_seqtype) if hasattr(n, "tree_type"): NPR_TREES.append(n.tree_type) seq = getattr(n, "sequence", "") MAX_SEQ_LEN = max(len(seq), MAX_SEQ_LEN) if MAX_SEQ_LEN: ALG_SCALE = min(1, 1000. / MAX_SEQ_LEN) ts.layout_fn.append(ly_block_alg) if len(NPR_TREES) > 1: rF = RectFace(4, 4, "steelblue", "steelblue") rF.margin_right = 10 rF.margin_left = 10 ts.legend.add_face(rF, 0) ts.legend.add_face(TextFace(" NPR node"), 1) ts.legend_position = 3 if len(MIXED_RES) > 1: rF = RectFace(20, 20, "#CFE6CA", "#CFE6CA") rF.margin_right = 10 rF.margin_left = 10 ts.legend.add_face(rF, 0) ts.legend.add_face(TextFace(" Nucleotide based alignment"), 1) ts.legend_position = 3 try: tree.set_species_naming_function(spname) annotate_tree_with_ncbi(tree) a = tree.search_nodes(species='Dictyostelium discoideum')[0] b = tree.search_nodes(species='Chondrus crispus')[0] #out = tree.get_common_ancestor([a, b]) #out = tree.search_nodes(species='Haemophilus parahaemolyticus')[0].up tree.set_outgroup(out) tree.swap_children() except Exception: pass tree.render(outfile, tree_style=ts, w=170, units='mm', dpi=150) tree.render(outfile + '.svg', tree_style=ts, w=170, units='mm', dpi=150) tree.render(outfile + '.pdf', tree_style=ts, w=170, units='mm', dpi=150)
def plot(self, placement, togjson, outdir, cfg): """ plot a plcement in the tree show all pplacer placements and the LCA and HCA node as well as the inferred lineage """ from ete3 import NodeStyle, TreeStyle from ete3 import CircleFace, TextFace, RectFace logging.debug("Plotting trees now") # with no X display this needs to be set os.environ["QT_QPA_PLATFORM"] = "offscreen" info = self.loadInfo(togjson) def defaultNodeStyle(): return NodeStyle() nodeStyles = defaultdict(defaultNodeStyle) no = 0 for LCAp, HPAp in zip(placement["LCA"], placement["HPA"]): plotpath = os.path.join(outdir, f"tree_{no}.png") # make shallow copy t = self.t LCA = LCAp["node"] HPA = HPAp["node"] # define basic tree style ts = TreeStyle() # hide leave names ts.show_leaf_name = False ts.root_opening_factor = 1 # circular tree ts.mode = "c" ts.rotation = 210 ts.arc_start = 0 # 0 degrees = 3 o'clock ts.arc_span = 350 highlightsize = 80 nodesize = 10 # define styles for special nodes # at the moment hard coded, but could be accesible for the user # LCA style LCAstyle = NodeStyle() LCAstyle["fgcolor"] = "#33a02c" LCAstyle["bgcolor"] = "#b2df8a" LCAstyle["size"] = highlightsize # HPA style HPAstyle = NodeStyle() HPAstyle["fgcolor"] = "#1f78b4" HPAstyle["bgcolor"] = "#a6cee3" HPAstyle["size"] = highlightsize # default node defaultStyle = NodeStyle() defaultStyle["fgcolor"] = "gray" defaultStyle["size"] = nodesize # add legend ts.legend_position = 1 ts.legend.add_face(CircleFace(40, LCAstyle["fgcolor"]), column=1) ts.legend.add_face(TextFace(f"LCA", fsize=50), column=2) ts.legend.add_face(CircleFace(40, HPAstyle["fgcolor"]), column=1) ts.legend.add_face(TextFace(f"HPA", fsize=50), column=2) i = 1 ts.legend.add_face(TextFace(f"p = {i}", fsize=50), column=1) while i > 0: temp_face = RectFace(60, 10, fgcolor=p_to_color(i), bgcolor=p_to_color(i)) temp_face.margin_top = -4 ts.legend.add_face(temp_face, column=1) i -= 0.01 ts.legend.add_face(TextFace(f"p = {cfg['minPlacementLikelyhood']}", fsize=50), column=1) # add highlights for each placed protein for n in t.traverse(): if n.name.startswith("PTHR"): # set color based on posterior prob: x = (info[n.name]["post_prob"] - cfg["minPlacementLikelyhood"]) / ( 1 - cfg["minPlacementLikelyhood"]) # orange to purple gradient from 0 to 1 posterior propability he = p_to_color(x) nodeStyles[he]["bgcolor"] = he # define back color of locations n.set_style(nodeStyles[he]) elif n.name == LCA: n.set_style(LCAstyle) elif n.name == HPA: n.set_style(HPAstyle) else: n.set_style(defaultStyle) # plot to disk _ = t.render(plotpath, w=320, units="mm", tree_style=ts) no = no + 1
def heatmap_view(tree, orthologous_groups, save_dir): """Generates a heatmap of regulation states in all species.""" light_tree = copy.deepcopy(tree) # Tree copy for the light heatmap # Heat map settings rect_face_fgcolor = 'black' locus_tag_len = max( len(gene.locus_tag) + 5 for ortho_grp in orthologous_groups for gene in ortho_grp.genes) rect_face_width = locus_tag_len * 8 light_rect_face_width = 20 rect_face_height = 20 rotation = 90 # Sort orthologous groups by the number of regulated genes in each group orthologous_groups = filter_and_sort_orthologous_grps(orthologous_groups) # For each species and its gene in each orthologous group, draw a rectangle for node, light_node in zip(tree.get_leaves(), light_tree.get_leaves()): for i, orthologous_grp in enumerate(orthologous_groups, start=1): #get all orthologs in group matching_genes = [g for g in orthologous_grp.genes \ if g.genome.strain_name == node.name] #if there is ortholog if len(matching_genes) > 0: # Get the first ortholog from the genome in the group #this is the one with higher probability of regulation. #so this probability will be displayed for the group gene = matching_genes[0] p_regulation = gene.operon.regulation_probability p_notregulation = 1.0 - p_regulation p_absence = 0 # No ortholog from this genome else: gene = None p_regulation = 0 p_notregulation = 0 p_absence = 1 # Color of the rectangle is based on probabilities rect_face_bgcolor = rgb2hex(p_notregulation, p_regulation, p_absence) rect_face_text = ('%s [%d]' % (gene.locus_tag, gene.operon.operon_id) if gene else '') rect_face_label = { 'text': rect_face_text, 'font': 'Courier', 'fontsize': 8, 'color': 'black' } # Create the rectangle rect_face = RectFace(rect_face_width, rect_face_height, rect_face_fgcolor, rect_face_bgcolor, label=rect_face_label) light_rect_face = RectFace(light_rect_face_width, rect_face_height, rect_face_fgcolor, rect_face_bgcolor, label='') rect_face.rotation = -rotation light_rect_face.rotation = -rotation # Add the rectangle to the corresponding column node.add_face(rect_face, column=i, position='aligned') light_node.add_face(light_rect_face, column=i, position='aligned') ts = TreeStyle() # Add orthologous group descriptions descriptions = ['-'.join([grp.description, \ str([item['ID'] for item in grp.COGs]) if len(grp.COGs)>0 else '', \ str([item['ID'] for item in grp.NOGs]) if len(grp.NOGs)>0 else '', \ str([item['ID'] for item in grp.PFAMs])] if len(grp.PFAMs)>0 else '')\ for grp in orthologous_groups] max_description_len = max(map(len, descriptions)) descriptions = [ '[%d]' % i + description + ' ' * (max_description_len - len(description)) for i, description in enumerate(descriptions, start=1) ] for i, description in enumerate(descriptions, start=1): text_face = TextFace(description, ftype='Courier') text_face.hz_align = 1 text_face.vt_align = 1 text_face.rotation = -rotation ts.aligned_header.add_face(text_face, column=i) # Rotate the generated heatmap. ts.margin_left = 10 ts.margin_top = 20 ts.rotation = rotation ts.show_scale = False # For some reason, it can't render to PDF in color tree.render(os.path.join(save_dir, 'heatmap.svg'), tree_style=ts) light_tree.render(os.path.join(save_dir, 'heatmap_light.svg'), tree_style=ts)
def draw_tree(the_tree, colour, back_color, label, out_file, the_scale, extend, bootstrap, group_file, grid_options, the_table, pres_abs, circular): t = Tree(the_tree, quoted_node_names=True) # t.ladderize() font_size = 8 font_type = 'Heveltica' font_gap = 3 font_buffer = 10 o = t.get_midpoint_outgroup() t.set_outgroup(o) the_leaves = [] for leaves in t.iter_leaves(): the_leaves.append(leaves) groups = {} num = 0 # set cutoff value for clades as 1/20th of the distance between the furthest two branches # assign nodes to groups last_node = None ca_list = [] if not group_file is None: style = NodeStyle() style['size'] = 0 style["vt_line_color"] = '#000000' style["hz_line_color"] = '#000000' style["vt_line_width"] = 1 style["hz_line_width"] = 1 for n in t.traverse(): n.set_style(style) with open(group_file) as f: group_dict = {} for line in f: group_dict[line.split()[0]] = line.split()[1] for node in the_leaves: i = node.name for j in group_dict: if j in i: if group_dict[j] in groups: groups[group_dict[j]].append(i) else: groups[group_dict[j]] = [i] coloured_nodes = [] for i in groups: the_col = i style = NodeStyle() style['size'] = 0 style["vt_line_color"] = the_col style["hz_line_color"] = the_col style["vt_line_width"] = 2 style["hz_line_width"] = 2 if len(groups[i]) == 1: ca = t.search_nodes(name=groups[i][0])[0] ca.set_style(style) coloured_nodes.append(ca) else: ca = t.get_common_ancestor(groups[i]) ca.set_style(style) coloured_nodes.append(ca) tocolor = [] for j in ca.children: tocolor.append(j) while len(tocolor) > 0: x = tocolor.pop(0) coloured_nodes.append(x) x.set_style(style) for j in x.children: tocolor.append(j) ca_list.append((ca, the_col)) if back_color: # for each common ancestor node get it's closest common ancestor neighbour and find the common ancestor of those two nodes # colour the common ancestor then add it to the group - continue until only the root node is left while len(ca_list) > 1: distance = float('inf') for i, col1 in ca_list: for j, col2 in ca_list: if not i is j: parent = t.get_common_ancestor(i, j) getit = True the_dist = t.get_distance(i, j) if the_dist <= distance: distance = the_dist the_i = i the_j = j the_i_col = col1 the_j_col = col2 ca_list.remove((the_i, the_i_col)) ca_list.remove((the_j, the_j_col)) rgb1 = strtorgb(the_i_col) rgb2 = strtorgb(the_j_col) rgb3 = ((rgb1[0] + rgb2[0]) / 2, (rgb1[1] + rgb2[1]) / 2, (rgb1[2] + rgb2[2]) / 2) new_col = colorstr(rgb3) new_node = t.get_common_ancestor(the_i, the_j) the_col = new_col style = NodeStyle() style['size'] = 0 style["vt_line_color"] = the_col style["hz_line_color"] = the_col style["vt_line_width"] = 2 style["hz_line_width"] = 2 new_node.set_style(style) coloured_nodes.append(new_node) ca_list.append((new_node, new_col)) for j in new_node.children: tocolor.append(j) while len(tocolor) > 0: x = tocolor.pop(0) if not x in coloured_nodes: coloured_nodes.append(x) x.set_style(style) for j in x.children: tocolor.append(j) elif colour: distances = [] for node1 in the_leaves: for node2 in the_leaves: if node1 != node2: distances.append(t.get_distance(node1, node2)) distances.sort() clade_cutoff = distances[len(distances) / 4] for node in the_leaves: i = node.name if not last_node is None: if t.get_distance(node, last_node) <= clade_cutoff: groups[group_num].append(i) else: groups[num] = [num, i] group_num = num num += 1 else: groups[num] = [num, i] group_num = num num += 1 last_node = node for i in groups: num = groups[i][0] h = num * 360 / len(groups) the_col = hsl_to_str(h, 0.5, 0.5) style = NodeStyle() style['size'] = 0 style["vt_line_color"] = the_col style["hz_line_color"] = the_col style["vt_line_width"] = 2 style["hz_line_width"] = 2 if len(groups[i]) == 2: ca = t.search_nodes(name=groups[i][1])[0] ca.set_style(style) else: ca = t.get_common_ancestor(groups[i][1:]) ca.set_style(style) tocolor = [] for j in ca.children: tocolor.append(j) while len(tocolor) > 0: x = tocolor.pop(0) x.set_style(style) for j in x.children: tocolor.append(j) ca_list.append((ca, h)) # for each common ancestor node get it's closest common ancestor neighbour and find the common ancestor of those two nodes # colour the common ancestor then add it to the group - continue until only the root node is left while len(ca_list) > 1: distance = float('inf') got_one = False for i, col1 in ca_list: for j, col2 in ca_list: if not i is j: parent = t.get_common_ancestor(i, j) getit = True for children in parent.children: if children != i and children != j: getit = False break if getit: the_dist = t.get_distance(i, j) if the_dist <= distance: distance = the_dist the_i = i the_j = j the_i_col = col1 the_j_col = col2 got_one = True if not got_one: break ca_list.remove((the_i, the_i_col)) ca_list.remove((the_j, the_j_col)) new_col = (the_i_col + the_j_col) / 2 new_node = t.get_common_ancestor(the_i, the_j) the_col = hsl_to_str(new_col, 0.5, 0.3) style = NodeStyle() style['size'] = 0 style["vt_line_color"] = the_col style["hz_line_color"] = the_col style["vt_line_width"] = 2 style["hz_line_width"] = 2 new_node.set_style(style) ca_list.append((new_node, new_col)) # if you just want a black tree else: style = NodeStyle() style['size'] = 0 style["vt_line_color"] = '#000000' style["hz_line_color"] = '#000000' style["vt_line_width"] = 1 style["hz_line_width"] = 1 for n in t.traverse(): n.set_style(style) color_list = [(240, 163, 255), (0, 117, 220), (153, 63, 0), (76, 0, 92), (25, 25, 25), (0, 92, 49), (43, 206, 72), (255, 204, 153), (128, 128, 128), (148, 255, 181), (143, 124, 0), (157, 204, 0), (194, 0, 136), (0, 51, 128), (255, 164, 5), (255, 168, 187), (66, 102, 0), (255, 0, 16), (94, 241, 242), (0, 153, 143), (224, 255, 102), (116, 10, 255), (153, 0, 0), (255, 255, 128), (255, 255, 0), (255, 80, 5), (0, 0, 0), (50, 50, 50)] up_to_colour = {} ts = TreeStyle() column_list = [] width_dict = {} if not grid_options is None: colour_dict = {} type_dict = {} min_val_dict = {} max_val_dict = {} leaf_name_dict = {} header_count = 0 the_columns = {} if grid_options == 'auto': with open(the_table) as f: headers = f.readline().rstrip().split('\t')[1:] for i in headers: the_columns[i] = [i] type_dict[i] = 'colour' colour_dict[i] = {'empty': '#FFFFFF'} width_dict[i] = 20 up_to_colour[i] = 0 column_list.append(i) else: with open(grid_options) as g: for line in g: if line.startswith('H'): name, type, width = line.rstrip().split('\t')[1:] if name in the_columns: the_columns[name].append(name + '_' + str(header_count)) else: the_columns[name] = [ name + '_' + str(header_count) ] width = int(width) name = name + '_' + str(header_count) header_count += 1 colour_dict[name] = {'empty': '#FFFFFF'} type_dict[name] = type width_dict[name] = width column_list.append(name) up_to_colour[name] = 0 min_val_dict[name] = float('inf') max_val_dict[name] = 0 elif line.startswith('C'): c_name, c_col = line.rstrip().split('\t')[1:] if not c_col.startswith('#'): c_col = colorstr(map(int, c_col.split(','))) colour_dict[name][c_name] = c_col val_dict = {} with open(the_table) as f: headers = f.readline().rstrip().split('\t')[1:] column_no = {} for num, i in enumerate(headers): if i in the_columns: column_no[num] = i for line in f: name = line.split('\t')[0] leaf_name = None for n in t.traverse(): if n.is_leaf(): if name.split('.')[0] in n.name: leaf_name = n.name if leaf_name is None: continue else: leaf_name_dict[leaf_name] = name vals = line.rstrip().split('\t')[1:] if name in val_dict: sys.exit('Duplicate entry found in table.') else: val_dict[name] = {} for num, val in enumerate(vals): if num in column_no and val != '': for q in the_columns[column_no[num]]: column_name = q if type_dict[column_name] == 'colour': val_dict[name][column_name] = val if not val in colour_dict[column_name]: colour_dict[column_name][val] = colorstr( color_list[up_to_colour[column_name] % len(color_list)]) up_to_colour[column_name] += 1 elif type_dict[column_name] == 'text': val_dict[name][column_name] = val elif type_dict[column_name] == 'colour_scale_date': year, month, day = val.split('-') year, month, day = int(year), int(month), int( day) the_val = datetime.datetime( year, month, day, 0, 0, 0) - datetime.datetime( 1970, 1, 1, 0, 0, 0) val_dict[name][ column_name] = the_val.total_seconds() if the_val.total_seconds( ) < min_val_dict[column_name]: min_val_dict[ column_name] = the_val.total_seconds() if the_val.total_seconds( ) > max_val_dict[column_name]: max_val_dict[ column_name] = the_val.total_seconds() elif type_dict[column_name] == 'colour_scale': the_val = float(val) val_dict[name][column_name] = the_val if the_val < min_val_dict[column_name]: min_val_dict[column_name] = the_val if the_val > max_val_dict[column_name]: max_val_dict[column_name] = the_val else: sys.exit('Unknown column type') if not out_file is None: new_desc = open(out_file + '.new_desc', 'w') else: new_desc = open('viridis.new_desc', 'w') ts.legend_position = 3 leg_column = 0 for num, i in enumerate(column_list): nameF = TextFace(font_gap * ' ' + i.rsplit('_', 1)[0] + ' ' * font_buffer, fsize=font_size, ftype=font_type, tight_text=True) nameF.rotation = -90 ts.aligned_header.add_face(nameF, column=num + 1) new_desc.write('H\t' + i.rsplit('_', 1)[0] + '\t' + type_dict[i] + '\t' + str(width_dict[i]) + '\n') x = num * 200 if type_dict[i] == 'colour': ts.legend.add_face(TextFace( font_gap * ' ' + i.rsplit('_', 1)[0] + ' ' * font_buffer, fsize=font_size, ftype=font_type, tight_text=True), column=leg_column + 1) ts.legend.add_face(RectFace(width_dict[i], 20, '#FFFFFF', '#FFFFFF'), column=leg_column) for num2, j in enumerate(colour_dict[i]): new_desc.write('C\t' + j + '\t' + colour_dict[i][j] + '\n') ts.legend.add_face(TextFace(font_gap * ' ' + j + ' ' * font_buffer, fsize=font_size, ftype=font_type, tight_text=True), column=leg_column + 1) ts.legend.add_face(RectFace(width_dict[i], 20, colour_dict[i][j], colour_dict[i][j]), column=leg_column) leg_column += 2 elif type_dict[i] == 'colour_scale': ts.legend.add_face(TextFace( font_gap * ' ' + i.rsplit('_', 1)[0] + ' ' * font_buffer, fsize=font_size, ftype=font_type, tight_text=True), column=leg_column + 1) ts.legend.add_face(RectFace(width_dict[i], 20, '#FFFFFF', '#FFFFFF'), column=leg_column) for num2 in range(11): y = num2 * 20 + 30 val = (max_val_dict[i] - min_val_dict[i]) * num2 / 10.0 h = val / (max_val_dict[i] - min_val_dict[i]) * 270 s = 0.5 l = 0.5 colour = hsl_to_str(h, s, l) ts.legend.add_face(TextFace(font_gap * ' ' + str(val) + ' ' * font_buffer, fsize=font_size, ftype=font_type, tight_text=True), column=leg_column + 1) ts.legend.add_face(RectFace(width_dict[i], 20, colour, colour), column=leg_column) leg_column += 2 elif type_dict[i] == 'colour_scale_date': ts.legend.add_face(TextFace( font_gap * ' ' + i.rsplit('_', 1)[0] + ' ' * font_buffer, fsize=font_size, ftype=font_type, tight_text=True), column=leg_column + 1) ts.legend.add_face(RectFace(width_dict[i], 20, '#FFFFFF', '#FFFFFF'), column=leg_column) for num2 in range(11): y = num2 * 20 + 30 val = (max_val_dict[i] - min_val_dict[i]) * num2 / 10.0 h = val / (max_val_dict[i] - min_val_dict[i]) * 360 s = 0.5 l = 0.5 colour = hsl_to_str(h, s, l) days = str(int(val / 60 / 60 / 24)) + ' days' ts.legend.add_face(TextFace(font_gap * ' ' + days + ' ' * font_buffer, fsize=font_size, ftype=font_type, tight_text=True), column=leg_column + 1) ts.legend.add_face(RectFace(width_dict[i], 20, colour, colour), column=leg_column) leg_column += 2 for n in t.traverse(): if n.is_leaf(): name = leaf_name_dict[n.name] if i in val_dict[name]: val = val_dict[name][i] else: val = 'empty' if type_dict[i] == 'colour': n.add_face(RectFace(width_dict[i], 20, colour_dict[i][val], colour_dict[i][val]), column=num + 1, position="aligned") elif type_dict[i] == 'colour_scale' or type_dict[ i] == 'colour_scale_date': if val == 'empty': colour = '#FFFFFF' else: h = (val - min_val_dict[i]) / ( max_val_dict[i] - min_val_dict[i]) * 360 s = 0.5 l = 0.5 colour = hsl_to_str(h, s, l) n.add_face(RectFace(width_dict[i], 20, colour, colour), column=num + 1, position="aligned") elif type_dict[i] == 'text': n.add_face(TextFace(font_gap * ' ' + val + ' ' * font_buffer, fsize=font_size, ftype=font_type, tight_text=True), column=num + 1, position="aligned") if not pres_abs is None: starting_col = len(column_list) + 1 subprocess.Popen('makeblastdb -out tempdb -dbtype prot -in ' + pres_abs[0], shell=True).wait() folder = pres_abs[1] len_dict = {} gene_list = [] ts.legend.add_face(TextFace(font_gap * ' ' + 'Gene present/absent' + ' ' * font_buffer, fsize=font_size, ftype=font_type, tight_text=True), column=starting_col + 1) ts.legend.add_face(RectFace(20, 20, '#FFFFFF', '#FFFFFF'), column=starting_col) ts.legend.add_face(TextFace(font_gap * ' ' + 'Gene present/absent' + ' ' * font_buffer, fsize=font_size, ftype=font_type, tight_text=True), column=starting_col + 1) ts.legend.add_face(RectFace(20, 20, "#5ba965", "#5ba965"), column=starting_col) ts.legend.add_face(TextFace(font_gap * ' ' + 'Gene present/absent' + ' ' * font_buffer, fsize=font_size, ftype=font_type, tight_text=True), column=starting_col + 1) ts.legend.add_face(RectFace(20, 20, "#cb5b4c", "#cb5b4c"), column=starting_col) with open(pres_abs[0]) as f: for line in f: if line.startswith('>'): name = line.split()[0][1:] gene_list.append(name) len_dict[name] = 0 nameF = TextFace(font_gap * ' ' + name + ' ' * font_buffer, fsize=font_size, ftype=font_type, tight_text=True) nameF.rotation = -90 ts.aligned_header.add_face(nameF, column=starting_col + len(gene_list) - 1) else: len_dict[name] += len(line.rstrip()) min_length = 0.9 min_ident = 90 for n in t.iter_leaves(): the_name = n.name if the_name[0] == '"' and the_name[-1] == '"': the_name = the_name[1:-1] if the_name.endswith('.ref'): the_name = the_name[:-4] if not os.path.exists(folder + '/' + the_name): for q in os.listdir(folder): if q.startswith(the_name): the_name = q if not os.path.exists(the_name + '.blast'): subprocess.Popen( 'blastx -query ' + folder + '/' + the_name + ' -db tempdb -outfmt 6 -num_threads 24 -out ' + the_name + '.blast', shell=True).wait() gotit = set() with open(the_name + '.blast') as b: for line in b: query, subject, ident, length = line.split()[:4] ident = float(ident) length = int(length) if ident >= min_ident and length >= min_length * len_dict[ subject]: gotit.add(subject) for num, i in enumerate(gene_list): if i in gotit: colour = "#5ba965" else: colour = "#cb5b4c" n.add_face(RectFace(20, 20, colour, colour), column=num + starting_col, position="aligned") # for num, i in enumerate(gene_list): # x = (starting_col + num) * 200 # svg.writeString(i, x+50, 20, 12) # y = 30 # svg.drawOutRect(x + 50, y, 12, 12, strtorgb('#5ba965'), strtorgb('#5ba965'), lt=0) # svg.writeString('present', x + 70, y + 12, 12) # y = 50 # svg.drawOutRect(x + 50, y, 12, 12, strtorgb('#cb5b4c'), strtorgb('#cb5b4c'), lt=0) # svg.writeString('absent', x + 70, y + 12, 12) # Set these to False if you don't want bootstrap/distance values ts.show_branch_length = label ts.show_branch_support = bootstrap ts.show_leaf_name = False for node in t.traverse(): if node.is_leaf(): node.add_face(AttrFace("name", fsize=font_size, ftype=font_type, tight_text=True, fgcolor='black'), column=0, position="aligned") ts.margin_left = 20 ts.margin_right = 100 ts.margin_top = 20 ts.margin_bottom = 20 if extend: ts.draw_guiding_lines = True ts.scale = the_scale if not circular is None: ts.mode = "c" ts.arc_start = 0 ts.arc_span = 360 if out_file is None: t.show(tree_style=ts) else: t.render(out_file, w=210, units='mm', 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)
big_tree.ladderize() ts = TreeStyle() ts.show_leaf_name = False #ts.show_branch_support = True ts.scale = 100000 if mode == 'small': ts.scale = 750000 #add legend for each in list(colourDict.keys()): ts.legend.add_face(CircleFace(radius=size[mode]/2, color=colourDict[each]), column=0) ts.legend.add_face(TextFace(each, ftype="Helvetica", fsize=size[mode]), column=1) ts.legend.add_face(CircleFace(radius=size[mode]/2, color='#F1F1F1'), column=0) ts.legend.add_face(TextFace('Guinea', ftype="Helvetica", fsize=size[mode]), column=1) ts.legend.add_face(RectFace(width=size[mode], height=size[mode], bgcolor='#D3D3D3', fgcolor='#FFFFFF'), column=0) ts.legend.add_face(TextFace('Sierra Leone', ftype="Helvetica", fsize=size[mode]), column=1) ts.legend.add_face(RectFace(triangle=True, width=size[mode], height=size[mode], bgcolor='#939393', fgcolor='#FFFFFF'), column=0) ts.legend.add_face(TextFace('Liberia', ftype="Helvetica", fsize=size[mode]), column=1) #reset nodes ns = NodeStyle() ns['size'] = 0 ns['hz_line_width'] = 2 ns['vt_line_width'] = 2 if mode =='big': ns['hz_line_width'] = 0 ns['vt_line_width'] = 0 for n in big_tree.traverse(): n.set_style(ns)
def format( tree , genedict , detection , includenames , filename , speciescolors = None): print 'final output...' red = Color('red') blue = Color('blue') colorvec = list(red.range_to(blue, len(genedict.keys()))) colormap = {} columnmap = {} for i,ref in enumerate(genedict): if ref not in detection: columnmap[ref] = 3 if 'hybrid' in ref.lower(): columnmap[ref] = 0 if 'eff' in ref.lower(): columnmap[ref] = 1 if 'hap' in ref.lower(): columnmap[ref] = 2 colormap[ref] = colorvec[i].hex for i,ref in enumerate(detection): columnmap[ref] = 3 + i colormap[ref] = colorvec[i].hex print columnmap print colormap circledict = {} for n in t.traverse(): nst = NodeStyle() nst["size"] = 0 nst["fgcolor"] = 'black' nst["hz_line_width"] = 4 nst["vt_line_width"]= 4 nst.show_name = False if n.is_leaf(): if speciescolors != None and n.name in speciescolors: nst["bgcolor"] = colors[n.name] nst.show_name = True n.add_face( AttrFace(attr = 'name', ftype='Helvetica', fgcolor='black', fsize =18 ,fstyle = 'normal' ), column =0 ) refs = json.loads(n.refs) for ref in genedict: if ref in refs and ref in detection: n.add_face( CircleFace ( 10 , colormap[ref]), column = 2 + columnmap[ref] ) n.img_style = nst if ref in refs and ref not in detection: n.add_face( RectFace ( 20 , 20 , colormap[ref], colormap[ref] ), column = 2 + columnmap[ref] ) n.img_style = nst if ref not in refs and ref not in detection: n.add_face( RectFace ( 20 , 20 , colormap[ref], 'white' ), column = 2 + columnmap[ref] ) n.img_style = nst ###color by species if n.name in speciescolors: nst['bgcolor'] = speciescolors[n.name] else: if n.name.strip() in includenames: n.add_face( AttrFace(attr = 'name', ftype='Helvetica', fgcolor='black', fsize =20 ,fstyle = 'normal' ), column =0 ) nst.size = 2 n.img_style = nst else: nst.size = 0 n.img_style = nst ts = TreeStyle() for i,ref in enumerate(colormap.keys()): if 'ubi' not in ref: ts.title.add_face(TextFace(ref, fsize=12), column=0) ts.title.add_face( RectFace(10 , 10 , colormap[ref] , colormap[ref]), column = 1) ts.show_leaf_name=False """ts.mode = "c" ts.arc_start = 270 ts.arc_span = 359 ts.root_opening_factor = 1 """ ts.scale = 190 t.show(tree_style = ts) t.render(filename + ".png", tree_style = ts) t.render( filename +".svg" , tree_style = ts)
if "coli" in node.sci_name: circle = RectFace(100, 100, "red", "red") faces.add_face_to_node(circle, position="aligned", column=1, node=node) if "Salm" in node.sci_name: circle = RectFace(100, 100, "blue", "blue") faces.add_face_to_node(circle, position="aligned", column=2, node=node) ts = TreeStyle() ts.branch_vertical_margin = 10 ts.allow_face_overlap = False ts.show_scale = False ts.show_leaf_name = False ts.layout_fn = layout ts.mode = "c" ts.root_opening_factor = .25 ts.optimal_scale_level = "full" ts.force_topology = True for i, j in enumerate(lineage_colors.keys()): ts.legend.add_face(RectFace(10000, 300, lineage_colors[j], lineage_colors[j]), column=i) ts.legend.add_face(TextFace(j, fsize=600), column=i) tree.show(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)
def traitTestTrees(scenarios, traits, mapper, outDir, treePath, floatSwitch=0): # styles for convergent and transition nodes styleConv = NodeStyle() styleConv["fgcolor"] = "black" styleConv["size"] = 0 styleConv["hz_line_width"] = branchWidth styleConv["vt_line_width"] = branchWidth styleConv["hz_line_color"] = "orange" styleConv["vt_line_color"] = "orange" styleTran = NodeStyle() styleTran["fgcolor"] = "black" styleTran["size"] = 0 styleTran["hz_line_width"] = branchWidth styleTran["vt_line_width"] = branchWidth styleTran["vt_line_color"] = "orange" # face object indicating a transition block = RectFace(4, 20, "blue", "blue") block.margin_right = 2 def rgb2hex(r, g, b): hex = "#{:02x}{:02x}{:02x}".format(r, g, b) return hex # loop thru trees for cutoff in sorted(scenarios.keys()): tree = init_tree(treePath) #tree.convert_to_ultrametric(tree_length=1) # parse scenario manual_mode_nodes = {"T": [], "C": []} p_events = scenarios[cutoff].strip().split("/") for e in p_events: l_e = map(int, e.split(",")) manual_mode_nodes["T"].append(l_e[0]) manual_mode_nodes["C"].extend(l_e[1:]) # loop thru nodes for n in tree.traverse(): #outline for the circle node #ol = CircleFace(11, color = "black")# #n.add_face(ol, column=1, position="float-behind") #float-behind # draw circle face with mapped color nd = CircleFace( 14, color=rgb2hex(*[int(val) for val in mapper(traits[n.ND])])) nd.background.color = None nd.border.width = None if manual_mode_nodes: if n.ND in manual_mode_nodes["T"]: n.set_style(styleTran) n.add_face(block, column=0, position="float") elif n.ND in manual_mode_nodes["C"]: n.set_style(styleConv) else: n.set_style(nstyle) else: nd.background.color = "white" n.add_face(nd, column=2, position="float") # float # this is necessary for some reason to keep the tree from collapsing n.add_face(TextFace(" "), column=2, position="branch-bottom") n.img_style["size"] = 0 outFile = str(round(cutoff, floatSwitch)).replace('.', '_') + ".pdf" # prepend path to filename outFile = outDir + '/' + outFile tree.render(outFile, h=6, units="in", tree_style=tree_style) print >> sys.stderr, outFile
def draw_tree(variant_dict, profile_dict, the_tree, ref_name): major_alleles, minor_alleles = profile_dict t = Tree(the_tree, quoted_node_names=True) font_size = 8 font_type = 'Heveltica' font_gap = 3 font_buffer = 10 ts = TreeStyle() position_list = None allele_count = {} max_major = 0 max_minor = 0 max_combo = 0 max_major_minor = 0 for n in t.iter_leaves(): the_name = n.name if the_name == ref_name: t.set_outgroup(n) if position_list is None: position_list = list(variant_dict[the_name]) position_list.sort() for num, i in enumerate(position_list): nameF = TextFace(font_gap * ' ' + str(i) + ' ' * font_buffer, fsize=font_size, ftype=font_type, tight_text=True) nameF.rotation = -90 ts.aligned_header.add_face(nameF, column=num) minor_allele, major_allele, missing = 0, 0, 0 for num, i in enumerate(position_list): if i in major_alleles and variant_dict[the_name][ i] in major_alleles[i]: s, l = 0.0, 0.1 major_allele += 1 elif i in minor_alleles and variant_dict[the_name][ i] in minor_alleles[i]: s, l = 0.0, 0.5 minor_allele += 1 else: s, l = 0.0, 0.9 missing += 1 if variant_dict[the_name][i] == 'a': colour = colorstr(hsl_to_rgb(0, s, l)) #colour = "#65dad0" elif variant_dict[the_name][i] == 't': colour = colorstr(hsl_to_rgb(140, s, l)) #colour = "#daa3dc" elif variant_dict[the_name][i] == 'c': colour = colorstr(hsl_to_rgb(220, s, l)) #colour = "#9bd686" elif variant_dict[the_name][i] == 'g': colour = colorstr(hsl_to_rgb(300, s, l)) #colour = "#e1b86f" else: colour = "#ffffff" #colour = colorstr(hsl_to_rgb(h, s, l)) n.add_face(RectFace(20, 20, colour, colour), column=num, position="aligned") allele_count[the_name] = (major_allele, minor_allele, missing) if major_allele > max_major: max_major = major_allele if minor_allele + major_allele >= max_combo: max_combo = minor_allele + major_allele if minor_allele >= max_minor: max_minor = minor_allele if major_allele > max_major_minor: max_major_minor = major_allele nst1 = NodeStyle() nst1["bgcolor"] = "LightSteelBlue" nst2 = NodeStyle() nst2["bgcolor"] = "Moccasin" with open(args.out_text, 'w') as o: for n in t.iter_leaves(): the_name = n.name major_allele, minor_allele, missing = allele_count[the_name] if major_allele == max_major: o.write("max_major\t%s\t%d\t%d\t%d\n" % (the_name, major_allele, minor_allele, missing)) n.img_style["bgcolor"] = "#cb6a49" elif minor_allele == max_minor and major_allele == max_major_minor: o.write("max_minor\t%s\t%d\t%d\t%d\n" % (the_name, major_allele, minor_allele, missing)) n.img_style["bgcolor"] = "#7aa457" elif minor_allele + major_allele == max_combo: o.write("max_combo\t%s\t%d\t%d\t%d\n" % (the_name, major_allele, minor_allele, missing)) n.img_style["bgcolor"] = "#a46cb7" n.add_face(TextFace('%d/%d/%d' % (major_allele, minor_allele, missing), fsize=font_size, ftype=font_type, tight_text=True), column=len(position_list), position="aligned") ts.legend.add_face(TextFace('A', fsize=font_size, ftype=font_type, tight_text=True), column=0) s = 0.5 ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(0, s, 0.3)), colorstr(hsl_to_rgb(0, s, 0.3))), column=1) ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(0, s, 0.5)), colorstr(hsl_to_rgb(0, s, 0.5))), column=2) ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(0, s, 0.8)), colorstr(hsl_to_rgb(0, s, 0.8))), column=3) ts.legend.add_face(TextFace('T', fsize=font_size, ftype=font_type, tight_text=True), column=0) ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(140, s, 0.3)), colorstr(hsl_to_rgb(140, s, 0.3))), column=1) ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(140, s, 0.5)), colorstr(hsl_to_rgb(140, s, 0.5))), column=2) ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(140, s, 0.8)), colorstr(hsl_to_rgb(140, s, 0.8))), column=3) ts.legend.add_face(TextFace('C', fsize=font_size, ftype=font_type, tight_text=True), column=0) ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(220, s, 0.3)), colorstr(hsl_to_rgb(220, s, 0.3))), column=1) ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(220, s, 0.5)), colorstr(hsl_to_rgb(220, s, 0.5))), column=2) ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(220, s, 0.8)), colorstr(hsl_to_rgb(220, s, 0.8))), column=3) ts.legend.add_face(TextFace('G', fsize=font_size, ftype=font_type, tight_text=True), column=0) ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(300, s, 0.3)), colorstr(hsl_to_rgb(300, s, 0.3))), column=1) ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(300, s, 0.5)), colorstr(hsl_to_rgb(300, s, 0.5))), column=2) ts.legend.add_face(RectFace(20, 20, colorstr(hsl_to_rgb(300, s, 0.8)), colorstr(hsl_to_rgb(300, s, 0.8))), column=3) ts.legend.add_face(TextFace('-', fsize=font_size, ftype=font_type, tight_text=True), column=0) ts.legend.add_face(RectFace(20, 20, "#cccccc", "#cccccc"), column=1) t.render(args.out_file, w=210, units='mm', tree_style=ts)
for output_string, mode, layout_fn in zip( [ "tree_symbols", "tree_symbols", "tree_arrows", ], ["c", "r", "r"], [botstrap_lower_right, botstrap_lower_right, botstrap_symbols]): stars_style = TreeStyle() stars_style.layout_fn = layout_fn stars_style.orientation = tree_orientation stars_style.mode = mode for subtype in subtype_color_dict: stars_style.legend.add_face(RectFace(10, 10, subtype_color_dict[subtype], subtype_color_dict[subtype]), column=0) stars_style.legend.add_face(TextFace( subtype, fgcolor=subtype_color_dict[subtype], bold=True), column=1) stars_style.legend_position = 2 ref_tree.render(file_name="plots/{}_{}_{}.pdf".format( plot_prefix, output_string, mode), tree_style=stars_style) print("Done.") # dataframe for bootstrap values plotting shared_edge_df = pd.DataFrame(shared_edge_support_values) # "top-right" of scatter plot high_support_df = shared_edge_df[
def draw_tree(tree, conf, outfile): try: from ete3 import (add_face_to_node, AttrFace, TextFace, TreeStyle, RectFace, CircleFace, SequenceFace, random_color, SeqMotifFace) except ImportError as e: print(e) return def ly_basic(node): if node.is_leaf(): node.img_style['size'] = 0 else: node.img_style['size'] = 0 node.img_style['shape'] = 'square' if len(MIXED_RES) > 1 and hasattr(node, "tree_seqtype"): if node.tree_seqtype == "nt": node.img_style["bgcolor"] = "#CFE6CA" ntF = TextFace("nt", fsize=6, fgcolor='#444', ftype='Helvetica') add_face_to_node(ntF, node, 10, position="branch-bottom") if len(NPR_TREES) > 1 and hasattr(node, "tree_type"): node.img_style['size'] = 4 node.img_style['fgcolor'] = "steelblue" node.img_style['hz_line_width'] = 1 node.img_style['vt_line_width'] = 1 def ly_leaf_names(node): if node.is_leaf(): spF = TextFace(node.species, fsize=10, fgcolor='#444444', fstyle='italic', ftype='Helvetica') add_face_to_node(spF, node, column=0, position='branch-right') if hasattr(node, 'genename'): geneF = TextFace(" (%s)" %node.genename, fsize=8, fgcolor='#777777', ftype='Helvetica') add_face_to_node(geneF, node, column=1, position='branch-right') def ly_supports(node): if not node.is_leaf() and node.up: supFace = TextFace("%0.2g" %(node.support), fsize=7, fgcolor='indianred') add_face_to_node(supFace, node, column=0, position='branch-top') def ly_tax_labels(node): if node.is_leaf(): c = LABEL_START_COL largest = 0 for tname in TRACKED_CLADES: if hasattr(node, "named_lineage") and tname in node.named_lineage: linF = TextFace(tname, fsize=10, fgcolor='white') linF.margin_left = 3 linF.margin_right = 2 linF.background.color = lin2color[tname] add_face_to_node(linF, node, c, position='aligned') c += 1 for n in range(c, len(TRACKED_CLADES)): add_face_to_node(TextFace('', fsize=10, fgcolor='slategrey'), node, c, position='aligned') c+=1 def ly_full_alg(node): pass def ly_block_alg(node): if node.is_leaf(): if 'sequence' in node.features: seqFace = SeqMotifFace(node.sequence, []) # [10, 100, "[]", None, 10, "black", "rgradient:blue", "arial|8|white|domain Name"], motifs = [] last_lt = None for c, lt in enumerate(node.sequence): if lt != '-': if last_lt is None: last_lt = c if c+1 == len(node.sequence): start, end = last_lt, c motifs.append([start, end, "()", 0, 12, "slategrey", "slategrey", None]) last_lt = None elif lt == '-': if last_lt is not None: start, end = last_lt, c-1 motifs.append([start, end, "()", 0, 12, "grey", "slategrey", None]) last_lt = None seqFace = SeqMotifFace(node.sequence, motifs, intermotif_format="line", seqtail_format="line", scale_factor=ALG_SCALE) add_face_to_node(seqFace, node, ALG_START_COL, aligned=True) TRACKED_CLADES = ["Eukaryota", "Viridiplantae", "Fungi", "Alveolata", "Metazoa", "Stramenopiles", "Rhodophyta", "Amoebozoa", "Crypthophyta", "Bacteria", "Alphaproteobacteria", "Betaproteobacteria", "Cyanobacteria", "Gammaproteobacteria",] # ["Opisthokonta", "Apicomplexa"] colors = random_color(num=len(TRACKED_CLADES), s=0.45) lin2color = dict([(ln, colors[i]) for i, ln in enumerate(TRACKED_CLADES)]) NAME_FACE = AttrFace('name', fsize=10, fgcolor='#444444') LABEL_START_COL = 10 ALG_START_COL = 40 ts = TreeStyle() ts.draw_aligned_faces_as_table = False ts.draw_guiding_lines = False ts.show_leaf_name = False ts.show_branch_support = False ts.scale = 160 ts.layout_fn = [ly_basic, ly_leaf_names, ly_supports, ly_tax_labels] MIXED_RES = set() MAX_SEQ_LEN = 0 NPR_TREES = [] for n in tree.traverse(): if hasattr(n, "tree_seqtype"): MIXED_RES.add(n.tree_seqtype) if hasattr(n, "tree_type"): NPR_TREES.append(n.tree_type) seq = getattr(n, "sequence", "") MAX_SEQ_LEN = max(len(seq), MAX_SEQ_LEN) if MAX_SEQ_LEN: ALG_SCALE = min(1, 1000./MAX_SEQ_LEN) ts.layout_fn.append(ly_block_alg) if len(NPR_TREES) > 1: rF = RectFace(4, 4, "steelblue", "steelblue") rF.margin_right = 10 rF.margin_left = 10 ts.legend.add_face(rF, 0) ts.legend.add_face(TextFace(" NPR node"), 1) ts.legend_position = 3 if len(MIXED_RES) > 1: rF = RectFace(20, 20, "#CFE6CA", "#CFE6CA") rF.margin_right = 10 rF.margin_left = 10 ts.legend.add_face(rF, 0) ts.legend.add_face(TextFace(" Nucleotide based alignment"), 1) ts.legend_position = 3 try: tree.set_species_naming_function(spname) annotate_tree_with_ncbi(tree) a = tree.search_nodes(species='Dictyostelium discoideum')[0] b = tree.search_nodes(species='Chondrus crispus')[0] #out = tree.get_common_ancestor([a, b]) #out = tree.search_nodes(species='Haemophilus parahaemolyticus')[0].up tree.set_outgroup(out) tree.swap_children() except Exception: pass tree.render(outfile, tree_style=ts, w=170, units='mm', dpi=150) tree.render(outfile+'.svg', tree_style=ts, w=170, units='mm', dpi=150) tree.render(outfile+'.pdf', tree_style=ts, w=170, units='mm', dpi=150)
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)
columnmap[fasta] = i colormap[fasta] = colorvec[i].hex annotated = [] print speciescolors for fasta in genedict: for leaf in t.get_leaves(): nst = NodeStyle() nst["size"] = 0 nst["fgcolor"] = 'black' nst["hz_line_width"] = 2 nst["vt_line_width"]= 2 nst.show_name = True if leaf.name.split('/')[0] in genedict[fasta]: if 'HH' not in fasta and 'LOMETS' not in fasta: leaf.add_face( RectFace ( 10 , 10 , colormap[fasta], colormap[fasta] ), column = columnmap[fasta] ) if leaf not in annotated: try: face = leaf.add_face( TextFace ( text = genedict[fasta][leaf.name.split('/')[0]][2]) , column = 10 ) annotated.append(leaf) except: print genedict[fasta][leaf.name.split('/')[0]] if colorSepcies == True: lineage = genedict[fasta][leaf.name.split('/')[0]][3].split(';') + [genedict[fasta][leaf.name.split('/')[0]][2]] + genedict[fasta][leaf.name.split('/')[0]][2].split() for taxa in lineage[-1:]: if taxa in speciescolors: print taxa print speciescolors[taxa] nst['bgcolor'] = speciescolors[taxa]
def draw_lifting_tree_inline(filename: str) -> None: ts = TreeStyle() ts.show_leaf_name = False ts.layout_fn = layout_lift ts.rotation = 90 ts.branch_vertical_margin = 10 ts.show_scale = False ts.scale = 50 ts.title.add_face(TextFace(" ", fsize=20), column=0) ts.legend.add_face(TextFace(" "), column=0) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(TextFace(" "), column=2) ts.legend.add_face(TextFace(" "), column=3) ts.legend.add_face(TextFace(" "), column=0) ts.legend.add_face(TextFace("Node shape and size:"), column=1) ts.legend.add_face(TextFace(" "), column=2) ts.legend.add_face(TextFace("Node color - membership value:"), column=3) ts.legend.add_face(TextFace(" "), column=0) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(TextFace(" "), column=2) ts.legend.add_face(TextFace(" "), column=3) ts.legend.add_face(PieChartFace([100], 20, 20, colors=['white'], line_color='black'), column=0) ts.legend.add_face(TextFace(" topics that relate to the cluster"), column=1) ts.legend.add_face(RectFace(30, 10, "#90ee90", "#90ee90"), column=2) ts.legend.add_face(TextFace(" topic with minor membership 0<u(t)<=0.2"), column=3) ts.legend.add_face(TextFace(" "), column=0) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(TextFace(" "), column=2) ts.legend.add_face(TextFace(" "), column=3) ts.legend.add_face(PieChartFace([100], 40, 40, colors=['white'], line_color='black'), column=0) ts.legend.add_face(TextFace(" head subject"), column=1) ts.legend.add_face(RectFace(30, 10, "green", "green"), column=2) ts.legend.add_face(TextFace(u" topic with medium membership 0.2<u(t)<=0.4 "), column=3) ts.legend.add_face(TextFace(" "), column=0) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(TextFace(" "), column=2) ts.legend.add_face(TextFace(" "), column=3) ts.legend.add_face(RectFace(20, 20, "black", "white"), column=0) ts.legend.add_face(TextFace(" topics that don't refer to cluster "), \ column=1) ts.legend.add_face(RectFace(30, 10, "#004000", "#004000"), column=2) ts.legend.add_face(TextFace(" topic with high membership u(t)>0.4"), column=3) ts.legend.add_face(TextFace(" "), column=0) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(TextFace(" "), column=2) ts.legend.add_face(TextFace(" "), column=3) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(RectFace(30, 10, "red", "red"), column=2) ts.legend.add_face(TextFace(" topic with no membership (u(t)=0)"), column=3) ts.legend_position = 3 ete3_desc = read_ete3_from_file(filename) tree = Tree(ete3_desc, format=1) # tree.show(tree_style=ts) return tree.render("%%inline",tree_style=ts)
def heatmap_view(tree, orthologous_groups, save_dir): """Generates a heatmap of regulation states in all species.""" light_tree = copy.deepcopy(tree) # Tree copy for the light heatmap # Heat map settings rect_face_fgcolor = 'black' locus_tag_len = max(len(gene.locus_tag) + 5 for ortho_grp in orthologous_groups for gene in ortho_grp.genes) rect_face_width = locus_tag_len * 8 light_rect_face_width = 20 rect_face_height = 20 rotation = 90 # Sort orthologous groups by the number of regulated genes in each group orthologous_groups = filter_and_sort_orthologous_grps(orthologous_groups) # For each species and its gene in each orthologous group, draw a rectangle for node, light_node in zip(tree.get_leaves(), light_tree.get_leaves()): for i, orthologous_grp in enumerate(orthologous_groups, start=1): #get all orthologs in group matching_genes = [g for g in orthologous_grp.genes \ if g.genome.strain_name == node.name] #if there is ortholog if len(matching_genes) > 0: # Get the first ortholog from the genome in the group #this is the one with higher probability of regulation. #so this probability will be displayed for the group gene = matching_genes[0] p_regulation = gene.operon.regulation_probability p_notregulation = 1.0 - p_regulation p_absence = 0 # No ortholog from this genome else: gene = None p_regulation = 0 p_notregulation = 0 p_absence = 1 # Color of the rectangle is based on probabilities rect_face_bgcolor = rgb2hex( p_notregulation, p_regulation, p_absence) rect_face_text = ('%s [%d]' % (gene.locus_tag, gene.operon.operon_id) if gene else '') rect_face_label = {'text': rect_face_text, 'font': 'Courier', 'fontsize': 8, 'color': 'black'} # Create the rectangle rect_face = RectFace(rect_face_width, rect_face_height, rect_face_fgcolor, rect_face_bgcolor, label=rect_face_label) light_rect_face = RectFace(light_rect_face_width, rect_face_height, rect_face_fgcolor, rect_face_bgcolor, label='') rect_face.rotation = -rotation light_rect_face.rotation = -rotation # Add the rectangle to the corresponding column node.add_face(rect_face, column=i, position='aligned') light_node.add_face(light_rect_face, column=i, position='aligned') ts = TreeStyle() # Add orthologous group descriptions descriptions = ['-'.join([grp.description, str(grp.NOGs)]) for grp in orthologous_groups] max_description_len = max(map(len, descriptions)) descriptions = [ '[%d]' % i + description + ' '*(max_description_len-len(description)) for i, description in enumerate(descriptions, start=1)] for i, description in enumerate(descriptions, start=1): text_face = TextFace(description, ftype='Courier') text_face.hz_align = 1 text_face.vt_align = 1 text_face.rotation = -rotation ts.aligned_header.add_face(text_face, column=i) # Rotate the generated heatmap. ts.margin_left = 10 ts.margin_top = 20 ts.rotation = rotation ts.show_scale = False # For some reason, it can't render to PDF in color tree.render(os.path.join(save_dir, 'heatmap.svg'), tree_style=ts) light_tree.render(os.path.join(save_dir, 'heatmap_light.svg'), tree_style=ts)
def 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)