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 get_default_tree_style(color_dict): ts = TreeStyle() ts.mode = "c" # ts.layout_fn = layout ts.margin_top = 50 ts.margin_bottom = 0 ts.margin_left = 50 ts.margin_right = 50 ts.show_scale = False ts.show_leaf_name = False ts.show_branch_length = False ts.show_branch_support = False for p, c in color_dict.iteritems(): ts.legend.add_face(TextFace(" ", fsize=30), column=0) ts.legend.add_face(CircleFace(10, c), column=1) ts.legend.add_face(TextFace(" %s" % p, fsize=30), column=2) legend_margin_line = 5 while legend_margin_line: ts.legend.add_face(TextFace(" "), column=0) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(TextFace(" "), column=2) legend_margin_line -= 1 ts.legend_position = 3 return ts
def get_default_tree_style(color_dict): ts = TreeStyle() ts.mode = 'c' # ts.layout_fn = layout ts.margin_top = 50 ts.margin_bottom = 0 ts.margin_left = 50 ts.margin_right = 50 ts.show_scale = False ts.show_leaf_name = False ts.show_branch_length = False ts.show_branch_support = False for p, c in color_dict.iteritems(): ts.legend.add_face(TextFace(" ", fsize=30), column=0) ts.legend.add_face(CircleFace(10, c), column=1) ts.legend.add_face(TextFace(" %s" % p, fsize=30), column=2) legend_margin_line = 5 while legend_margin_line: ts.legend.add_face(TextFace(" "), column=0) ts.legend.add_face(TextFace(" "), column=1) ts.legend.add_face(TextFace(" "), column=2) legend_margin_line -= 1 ts.legend_position = 3 return ts
def format_tree(tree, alignment, al_len_dict, edpos, codontable={}, colors=None, codon_col={}, text="C-to-U RNA editing", ic_contents=[]): """Format the rendering of tree data for alignment""" t = tree.copy() # alignment is ordered dict # flip alignment dict from gene ==> species ==> seq # to species ==> gene ==> seq specSeq = ddict(str) edposSeq = ddict(list) cur_len = 0 limits = [] for gname, specdict in alignment.items(): for node in t: # fill missing with gap specSeq[node.name] += specdict.get(node.name, al_len_dict[gname] * '-') edposSeq[node.name] += [ x + cur_len for x in edpos[gname].get(node.name, []) ] # if node.name == 'Y08501': # print(gname) # print( edposSeq[node.name]) cur_len += al_len_dict.get(gname, 0) limits.append((gname, cur_len)) for node in t: node.add_feature("sequence", specSeq[node.name]) node.add_feature('edlist', edposSeq[node.name]) ts = TreeStyle() ts.branch_vertical_margin = 15 ts.scale = 15 ts.allow_face_overlap = False ts.show_scale = False ts.show_leaf_name = False ns = NodeStyle() ns['shape'] = 'square' ns['fgcolor'] = 'black' ns['size'] = 0 def layout(node): node.img_style = ns if node.is_leaf(): faces.add_face_to_node(AttrFace( 'fullname', fsize=14, fgcolor=(MARKED_NODE_COLOR if (node.name in colors or node.fullname in colors) else 'black')), node, 0, position="aligned") if hasattr(node, "sequence") and node.sequence: seqface = SequenceFace(node.sequence, "codon", fsize=13, codontable=codontable, col_w=RES_COL_WIDTH, bg_colors=codon_col, black_out=node.edlist) faces.add_face_to_node(seqface, node, 1, position="aligned") ts.layout_fn = layout # ts.title.add_face(TextFace('(%s) - SP score : %.0f | IC = %.2f' % (codon, sum(SP_score), sum(ic_contents)), # fsize=14, fgcolor='red'), 0) # ts.aligned_header.add_face( # faces.RectFace(14, 14, 'white', 'white'), 1) # ts.aligned_foot.add_face( # faces.RectFace(14, 14, 'white', 'white'), 1) # for (cod, col) in codon_col.items(): # ts.legend.add_face(faces.RectFace(50, 25, col, col), column=0) # ts.legend.add_face(TextFace(" %s " % cod, fsize=8), column=1) ts.legend.add_face(TextFace(text, fsize=14), column=1) ts.legend_position = 1 ind = 1 prev_gend = 0 for (gname, gend) in limits: ts.aligned_foot.add_face( List90Face(list(range(0, gend - prev_gend, 3)), fsize=13, ftype='Monospace', col_w=RES_COL_WIDTH * 3), ind) ts.aligned_foot.add_face( faces.RectFace(RES_COL_WIDTH * (gend - prev_gend), 13, '#BBBBBB', '#EEEEEE'), ind) ts.aligned_foot.add_face(TextFace(gname, fsize=13), ind) ts.aligned_foot.add_face( faces.RectFace(RES_COL_WIDTH * (gend - prev_gend), 5, 'white', 'white'), ind) prev_gend += gend ind += 1 #t.dist = 0 ts.margin_left = 5 ts.margin_right = 5 ts.margin_bottom = 5 return t, ts
def main(args): if args.alignment: t = PhyloTree(args.tree, alignment=args.alignment, alg_format='fasta') else: t = PhyloTree(args.tree) if args.highlight_new: runs = read_runs(args.highlight_new) t.set_outgroup('EM_079422') t.ladderize() ts = TreeStyle() ts.show_leaf_name = False ts.show_branch_support = False ts.layout_fn = layout thick_hz_line = NodeStyle() thick_hz_line["hz_line_width"] = 8 t.set_style(thick_hz_line) #t.children[0].set_style(thick_hz_line) #t.children[1].set_style(thick_hz_line) thick_vt_line = NodeStyle() thick_vt_line["vt_line_width"] = 4 t.set_style(thick_vt_line) # header if not args.hide_annotations: ts.aligned_header.add_face(MyTextFace('Sample identifier', fstyle='Bold', fsize=8, tight_text=False), column = 1) ts.aligned_header.add_face(MyTextFace('Prefecture', fstyle='Bold', fsize=8, tight_text=False), column = 2) ts.aligned_header.add_face(MyTextFace('Sous-prefecture', fstyle='Bold', fsize=8, tight_text=False), column = 3) ts.aligned_header.add_face(MyTextFace('Village', fstyle='Bold', fsize=8, tight_text=False), column = 4) ts.aligned_header.add_face(MyTextFace('Sample received', fstyle='Bold', fsize=8, tight_text=False), column = 5) if args.positions: positions = read_positions(args.positions) alg_header = RulerFace(positions, col_width=11, height=0, # set to 0 if dont want to use values kind="stick", hlines = [0], hlines_col = ["white"], # trick to hide hz line ) ts.aligned_header.add_face(alg_header, 6) #legend if args.legend: legend = {} for s in samples.values(): legend[s['prefec']] = s['prefec__colour'] for p in sorted(legend.keys()): ts.legend.add_face(CircleFace(4, legend[p]), column=0) ts.legend.add_face(MyTextFace(p, fsize=6, tight_text=False), column=1) ts.legend_position=1 if args.circular: ts.mode = "c" ts.arc_start = -180 # 0 degrees = 3 o'clock ts.arc_span = 180 # t.show(tree_style=ts) t.render(args.output, tree_style=ts, w=1024)
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 main(): parser = argparse.ArgumentParser() parser.add_argument("-t", action="store", dest="treef", help="The tree file") parser.add_argument("-s", action="store", dest="statf", help="The statistics file") parser.add_argument("-c", action="store", default=0, type=float, dest="scaling", help="If this parameter is set " "to more than 0, " "the size of the pie charts " "correlate with the total " "number of events at a node " "(and are scaled by the factor " "given as a float).") parser.add_argument( "-e", action="store", type=str, default="all", dest="event", help= "If an event type is specified, just this event type is visualized. Per default all event types are shown on the tree.\n" "all\n" "fusions\n" "fissions\n" "termLosses\n" "termEmergences\n" "singleDomainLosses\n" "singleDomainEmergences") parser.add_argument( "-p", action="store", dest="treeshape", default="r", choices=["c", "r"], help="shape of the tree, circle (c) or tree format (r)") parser.add_argument("-o", action="store", dest="outputname") parser.add_argument( "-y", action="store", type=str, dest="NodeIDtreeName", default=None, help="Name for output file that shows a tree with all node IDs.") parser.add_argument( "-l", dest="short_legend", help= "Writes the full legend for all events in two levels for short trees", action="store_true") params = parser.parse_args() if (params.event not in ("all", "fusions", "fissions", "termLosses", "termEmergences", "singleDomainLosses", "singleDomainEmergences")): print( "Error: Please specify a valid event type. For a list of possible options use the --help parameter." ) sys.exit(1) if params.NodeIDtreeName != None: id_tree = Tree(params.treef, format=0) coun = 0 for node in id_tree.traverse('preorder'): node.add_features(ID=coun) coun += 1 # Create empty TreeStyle ts = TreeStyle() # Set custom layout function ts.layout_fn = layout_idtree # Draw tree ts.mode = params.treeshape ts.complete_branch_lines_when_necessary = True ts.extra_branch_line_type = 0 ts.extra_branch_line_color = "black" # ts.optimal_scale_level ="full" ts.branch_vertical_margin = 40 ts.scale = 100 # We will add node names manually ts.show_leaf_name = False ts.draw_guiding_lines = True if (params.NodeIDtreeName.endswith(".pdf")): pathout = params.NodeIDtreeName else: pathout = params.NodeIDtreeName + ".pdf" id_tree.render(pathout, dpi=1200, tree_style=ts) pl.close() else: tree = Tree(params.treef, format=0) # Read statistics file node_stat_dict = {} with open(params.statf, "r") as sf: for line in sf: # Stop the loop at the second part of statistics file if line.startswith( "# Number of events per domain." ) or line.startswith( "# Events per domain arrangement for last common ancestor" ): break if line[0] not in ('#', '\n'): vecline = line.strip().split() id = vecline.pop(0) stats = [int(i) for i in vecline] node_stat_dict[int(id)] = stats # determine max. number of events per node for scaling fus_max = 0 fis_max = 0 termLoss_max = 0 termGain_max = 0 singLoss_max = 0 singGain_max = 0 tot_max = 0 # Assign rearrangement events to leaves c = 0 for node in tree.traverse('preorder'): node.add_features(fusion=node_stat_dict[c][0]) if (node_stat_dict[c][0] > fus_max): fus_max = node_stat_dict[c][0] node.add_features(fission=node_stat_dict[c][1]) if (node_stat_dict[c][1] > fis_max): fis_max = node_stat_dict[c][1] node.add_features(termLoss=node_stat_dict[c][2]) if (node_stat_dict[c][2] > termLoss_max): termLoss_max = node_stat_dict[c][2] node.add_features(termGain=node_stat_dict[c][3]) if (node_stat_dict[c][3] > termGain_max): termGain_max = node_stat_dict[c][3] node.add_features(singLoss=node_stat_dict[c][4]) if (node_stat_dict[c][4] > singLoss_max): singLoss_max = node_stat_dict[c][4] node.add_features(singGain=node_stat_dict[c][5]) if (node_stat_dict[c][5] > singGain_max): singGain_max = node_stat_dict[c][5] if (sum(node_stat_dict[c]) > tot_max): tot_max = sum(node_stat_dict[c]) c += 1 global scal scal = params.scaling global eve event_options = { "all": 0, "fusions": 1, "fissions": 2, "termLosses": 3, "termEmergences": 4, "singleDomainLosses": 5, "singleDomainEmergences": 6 } eve = event_options[params.event] # Create empty TreeStyle ts = TreeStyle() # Set custom layout function ts.layout_fn = layout_gen_events # Draw tree ts.mode = params.treeshape ts.complete_branch_lines_when_necessary = True ts.extra_branch_line_type = 0 ts.extra_branch_line_color = "black" #ts.optimal_scale_level ="full" ts.branch_vertical_margin = 40 ts.scale = 100 # We will add node names manually ts.show_leaf_name = False # legend creation if (params.event == "all"): ts.legend.add_face(CircleFace(10, "DimGray"), column=0) ts.legend.add_face(TextFace(" Fusion ", fsize=16, fgcolor='DimGray'), column=1) ts.legend.add_face(CircleFace(10, "DeepPink"), column=2) ts.legend.add_face(TextFace(' Fission ', fsize=16, fgcolor='DeepPink'), column=3) ts.legend.add_face(CircleFace(10, "YellowGreen"), column=4) ts.legend.add_face(TextFace(' Terminal Loss ', fsize=16, fgcolor='YellowGreen'), column=5) if params.short_legend: ts.legend.add_face(CircleFace(10, "DarkBlue"), column=0) ts.legend.add_face(TextFace(' Terminal Emergence ', fsize=16, fgcolor='DarkBlue'), column=1) ts.legend.add_face(CircleFace(10, "Chocolate"), column=2) ts.legend.add_face(TextFace(' Single Domain Loss ', fsize=16, fgcolor='Chocolate'), column=3) ts.legend.add_face(CircleFace(10, "DeepSkyBlue"), column=4) ts.legend.add_face(TextFace(' Single Domain Emergence ', fsize=16, fgcolor='DeepSkyBlue'), column=5) else: ts.legend.add_face(CircleFace(10, "DarkBlue"), column=6) ts.legend.add_face(TextFace(' Terminal Emergence ', fsize=16, fgcolor='DarkBlue'), column=7) ts.legend.add_face(CircleFace(10, "Chocolate"), column=8) ts.legend.add_face(TextFace(' Single Domain Loss ', fsize=16, fgcolor='Chocolate'), column=9) ts.legend.add_face(CircleFace(10, "DeepSkyBlue"), column=10) ts.legend.add_face(TextFace(' Single Domain Emergence ', fsize=16, fgcolor='DeepSkyBlue'), column=11) elif (params.event == "fusions"): ts.legend.add_face(CircleFace(10, "DimGray"), column=0) ts.legend.add_face(TextFace(" Fusion ", fsize=16, fgcolor='DimGray'), column=1) elif (params.event == "fissions"): ts.legend.add_face(CircleFace(10, "DeepPink"), column=0) ts.legend.add_face(TextFace(' Fission ', fsize=16, fgcolor='DeepPink'), column=1) elif (params.event == "termLosses"): ts.legend.add_face(CircleFace(10, "YellowGreen"), column=0) ts.legend.add_face(TextFace(' Terminal Loss ', fsize=16, fgcolor='YellowGreen'), column=1) elif (params.event == "termEmergences"): ts.legend.add_face(CircleFace(10, "DarkBlue"), column=0) ts.legend.add_face(TextFace(' Terminal Emergence ', fsize=16, fgcolor='DarkBlue'), column=1) elif (params.event == "singleDomainLosses"): ts.legend.add_face(CircleFace(10, "Chocolate"), column=0) ts.legend.add_face(TextFace(' Single Domain Loss ', fsize=16, fgcolor='Chocolate'), column=1) elif (params.event == "singleDomainEmergences"): ts.legend.add_face(CircleFace(10, "DeepSkyBlue"), column=0) ts.legend.add_face(TextFace(' Single Domain Emergence ', fsize=16, fgcolor='DeepSkyBlue'), column=1) ts.legend_position = 1 ts.draw_guiding_lines = True if (params.outputname.endswith(".pdf")): pathout = params.outputname else: pathout = params.outputname + ".pdf" tree.render(pathout, dpi=1200, tree_style=ts) pl.close() sys.exit(0)
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)
STEP("Setting tree and node styles") condi_color_dic = {"0":"#E6E6FA", "1":"#ADD8E6", "2":"#90EE90"} MESSAGE("Setting node style") nstyle = NodeStyle() nstyle["fgcolor"] = "black" nstyle["size"] = 1 MESSAGE("Setting tree style") tree_style = TreeStyle() tree_style.show_leaf_name = False tree_style.show_branch_length = False tree_style.draw_guiding_lines = True tree_style.complete_branch_lines_when_necessary = True tree_style.legend_position = 1 MESSAGE("Setting legend with condition numbers and colors") for condi_i in sorted(condi_color_dic.keys()): tf = TextFace("Condition " + condi_i) tf.background.color = condi_color_dic[condi_i] tf.margin_right = 2 tf.margin_top = 1 tf.margin_left = 2 tf.margin_bottom = 1 tf.border.width = 1 tree_style.legend.add_face(tf, column=1) if add_transition: MESSAGE("Setting transition style") tf = TextFace("Transition -> x")
def export(self, output, layout_function=None, display_internal_histogram=True): """ Method to export the tree profile object as figure (available format .SVG, .PDF, .PNG). -- Some magic going there -- Args: | output (:obj:`str`): output file name. The extension of output will set the format of the figure (SVG, .PDF, .PNG) | layout_function (:obj:`function`, optional): custom layout_fn for ete3 TreeStyle. | display_internal_histogram (:obj:`Boolean`, optional): Display internal node as histogram or raw text with numbers. Defaults to True. """ from ete3 import TreeStyle, TextFace, NodeStyle, BarChartFace # maximum number of genes per node in this treeMap max_genes = max([d for d in self.treemap.traverse()], key=lambda x:x.nbr_genes).nbr_genes if self.hog is None: _color_scheme = ["#41c1c2","#bdc3c7","#f39c12","#27ae60","#e74c3c"] _label_legend = ["Genes","Retained","Duplicated","Novel","Lost"] _values_legend = [max_genes,max_genes,max_genes,max_genes,max_genes] w_legend = 50 # todo calculate base on len(_values) else: _color_scheme = ["#41c1c2", "#bdc3c7", "#f39c12", "#e74c3c"] _label_legend = ["Genes", "Retained", "Duplicated", "Lost"] _values_legend = [max_genes, max_genes, max_genes, max_genes] w_legend = 40 # todo calculate base on len(_values) def _layout(node): if self.hog is None: _label = [str(node.nbr_genes),str(node.retained),str(node.dupl),str(node.gain),str(node.lost)] else: _label = [str(node.nbr_genes), str(node.retained), str(node.dupl), str(node.lost)] def _add_face(name_feature, value_feature, cnum=1, pos="branch-right"): node.add_face(TextFace("{}: {}".format(name_feature, value_feature)), column=cnum, position=pos) def _add_faces(cNbr=1, posNbr="branch-right", cAttr=2, posAtt="branch-right"): _add_face("#genes", node.nbr_genes, cnum=cNbr, pos=posNbr) if node.retained is not None: _add_face("#Retained", node.retained, cnum=cAttr, pos=posAtt) if node.dupl is not None: _add_face("#Duplicated", node.dupl, cnum=cAttr, pos=posAtt) if node.gain is not None: _add_face("#Novel", node.gain, cnum=cAttr, pos=posAtt) if node.lost is not None: _add_face("#Lost", node.lost, cnum=cAttr, pos=posAtt) if node.is_leaf(): if display_internal_histogram: if self.hog is None: values = [node.nbr_genes,node.retained,node.dupl,node.gain,node.lost] w_plot = 50 else: values = [node.nbr_genes, node.retained, node.dupl, node.lost] w_plot = 40 node.add_face(BarChartFace(values, deviations=None, width=w_plot, height=25, colors=_color_scheme, labels=_label, min_value=0, max_value=max_genes, label_fsize=6, scale_fsize=6),column=1, position = "branch-right") else: _add_faces() else: if display_internal_histogram: if node.is_root(): node.add_face(BarChartFace([node.nbr_genes], deviations=None, width=10, height=25, colors=["#41c1c2"], labels=[str(node.nbr_genes)], min_value=0, max_value=max_genes, label_fsize=6, scale_fsize=6),column=0, position = "branch-bottom") else: if self.hog is None: values = [node.nbr_genes,node.retained,node.dupl,node.gain,node.lost] w_plot = 50 else: values = [node.nbr_genes,node.retained,node.dupl,node.lost] w_plot = 40 node.add_face(BarChartFace(values, deviations=None, width=w_plot, height=25, colors=_color_scheme, labels=_label, min_value=0, max_value=max_genes, label_fsize=6, scale_fsize=6),column=1, position = "branch-top") else: _add_faces(cNbr=0, posNbr="branch-top", cAttr=0, posAtt="branch-bottom") ts = TreeStyle() if layout_function is not None: ts.layout_fn = layout_function else: ts.layout_fn = _layout ts.legend.add_face(BarChartFace(_values_legend, deviations=None, width=w_legend, height=25, colors=_color_scheme, labels=_label_legend, min_value=0, max_value=max_genes, label_fsize=6, scale_fsize=6),column=0) ts.legend_position = 3 self.treemap.render(output,tree_style=ts)
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)
#exit() outbreak_color = "#B22222" t = Tree(t[0]) ts = TreeStyle() ts.show_leaf_name = False ts.show_branch_length = False ts.show_branch_support = True ts.scale = 2 #ts.min_leaf_separation = 3 ts.branch_vertical_margin = 12 ts.legend_position = 4 #ts.legend.add_face(CircleFace(3, "red"), column=0) mark = TextFace("Outbreak", fsize=10, fgcolor=outbreak_color) mark.margin_top = 10 mark.margin_right = 10 mark.margin_left = 5 mark.margin_bottom = 10 #ts.legend.add_face(mark, column=1) mark2 = TextFace("X", fsize=10, fgcolor="black") # Set some attributes mark2.margin_top = 0 mark2.margin_right = 1 mark2.margin_left = 1 mark2.margin_bottom = 0 mark2.opacity = 1 # from 0 to 1
"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[ (shared_edge_df[ref_bs_label] >= bootstrap_cutoff) & (shared_edge_df[tree_bs_label] >= bootstrap_cutoff)] # "bottom-right" of scatter plot ref_aln_support_df = shared_edge_df[ (shared_edge_df[ref_bs_label] >= bootstrap_cutoff) & (shared_edge_df[tree_bs_label] < bootstrap_cutoff)]
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 main(args): if args.alignment: t = PhyloTree(args.tree, alignment=args.alignment, alg_format='fasta') else: t = PhyloTree(args.tree) if args.highlight_new: runs = read_runs(args.highlight_new) t.set_outgroup('EM_079422') t.ladderize() ts = TreeStyle() ts.show_leaf_name = False ts.show_branch_support = False ts.layout_fn = layout thick_hz_line = NodeStyle() thick_hz_line["hz_line_width"] = 8 t.set_style(thick_hz_line) #t.children[0].set_style(thick_hz_line) #t.children[1].set_style(thick_hz_line) thick_vt_line = NodeStyle() thick_vt_line["vt_line_width"] = 4 t.set_style(thick_vt_line) # header if not args.hide_annotations: ts.aligned_header.add_face(MyTextFace('Sample identifier', fstyle='Bold', fsize=8, tight_text=False), column = 1) ts.aligned_header.add_face(MyTextFace('Prefecture', fstyle='Bold', fsize=8, tight_text=False), column = 2) ts.aligned_header.add_face(MyTextFace('Sous-prefecture', fstyle='Bold', fsize=8, tight_text=False), column = 3) ts.aligned_header.add_face(MyTextFace('Village', fstyle='Bold', fsize=8, tight_text=False), column = 4) ts.aligned_header.add_face(MyTextFace('Sample received', fstyle='Bold', fsize=8, tight_text=False), column = 5) if args.positions: positions = read_positions(args.positions) alg_header = RulerFace(positions, col_width=11, height=0, # set to 0 if dont want to use values kind="stick", hlines = [0], hlines_col = ["white"], # trick to hide hz line ) ts.aligned_header.add_face(alg_header, 6) #legend if args.legend: legend = {} for s in list(samples.values()): legend[s['prefec']] = s['prefec__colour'] for p in sorted(legend.keys()): ts.legend.add_face(CircleFace(4, legend[p]), column=0) ts.legend.add_face(MyTextFace(p, fsize=6, tight_text=False), column=1) ts.legend_position=1 if args.circular: ts.mode = "c" ts.arc_start = -180 # 0 degrees = 3 o'clock ts.arc_span = 180 # t.show(tree_style=ts) t.render(args.output, tree_style=ts, w=1024)
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 renderingTreeImage(self): path = os.path.join('Input', 'ProteinInput') seq_records = SeqIO.parse(path, 'fasta') for record in seq_records: self.input_protein_accession_number.append(record.id) self.input_protein_sequence.append(record.seq) with open(os.path.join('execs', 'tmp', "rooted_tree.nwk")) as nwk_tree_handle: nwk_tree = nwk_tree_handle.read() t = Tree(nwk_tree) print(t) print '\n' ts = TreeStyle() ts.title.add_face(TextFace( 'PhyloEpsilon - Protein Ortholog Finding Tool by Bryan Dighera', fsize=16, ), column=0) ts.allow_face_overlap = True ts.show_leaf_name = True ts.show_branch_support = True leaf_names = [] for leaf in t.get_leaf_names(): np_xp_pattern = re.compile('N[P]|X[P]') digits_pattern = re.compile('\d+.\d') np_xp_search_obj = re.search(np_xp_pattern, leaf) digits_search_obj = re.search(digits_pattern, leaf) np_xp_name = np_xp_search_obj.group() digits_name = digits_search_obj.group() final_accession = str(np_xp_name + '_' + digits_name) print final_accession leaf_names.append(final_accession) #print 'leaf names: ' + '%s' % leaf_names P = Protein() protein_domains, domain_colors, unrepeated_domains = P.Domains() print domain_colors #Creates a dictionary that corresponds the protein accession number to its corresponding introns for i in range(len(leaf_names)): self.accession_dict_with_introns[ self.input_protein_accession_number[i]] = self.exon_lengths[i] i = 0 print 'protein accession number: ' + '%s' % self.input_protein_accession_number print 'Accession dict: ' + '%s' % self.accession_dict_with_introns + '\n' #Iterates through the accession numbers that correspond the the order of the leaves of the phylogenetic tree to retrieve introns and build fig for accession_number in leaf_names: intron_motifs = [[0, 0, "[]", None, 12, "White", "White", None]] #Checks the accession number against the dictionary and retrieves the corresponding introns, if no introns then doesn't append any if accession_number in self.accession_dict_with_introns: print accession_number, self.accession_dict_with_introns[ accession_number] exon_list = self.accession_dict_with_introns[accession_number] print exon_list for exon_length in exon_list: if str(exon_length) != 'NONE': for location in exon_length: split_exon_location = str(location).split('-') protein_seq_exon_location = int( math.floor(int(split_exon_location[1]) / 3)) #Calculates the intron phase and then checks the phase to append appropriate color indicating phase on diagram intron_phase = (int(split_exon_location[1]) - int(split_exon_location[0])) % 3 if intron_phase == 0: intron_motifs.append([ protein_seq_exon_location - 2, protein_seq_exon_location + 2, "[]", None, 5, "Grey", "Grey", None ]) elif intron_phase == 1: intron_motifs.append([ protein_seq_exon_location - 2, protein_seq_exon_location + 2, "[]", None, 5, "Black", "Black", None ]) elif intron_phase == 2: intron_motifs.append([ protein_seq_exon_location - 2, protein_seq_exon_location + 2, "[]", None, 5, "Blue", "Blue", None ]) else: print 'NO INTRONS FOUND FOR RECORD' print str(intron_motifs) + '\n' msa_protein_seq = self.msa_aligned_protein[i].strip('-') #ete3 module that adds the introns(motifs) to the phylogenetic tree seqFace = SeqMotifFace(str(msa_protein_seq), gapcolor="black", seq_format='line', scale_factor=1, motifs=intron_motifs) (t & t.get_leaf_names()[i]).add_face(seqFace, 0, "aligned") i += 1 n = 0 # Iterates through the accession numbers that correspond to the order of the leaves of the phylogenetic tree and compare to domain dict values # TODO: Add the legend and possibly give a number to each of the domains so they can be easily identified in the legend for accession_number in leaf_names: domain_motifs = [[0, 0, "[]", None, 12, "White", "White", None]] for domain in protein_domains: if accession_number in domain: print 'leaf accession #: ' + '%s' % accession_number print 'domains accession: ' + '%s' % domain.keys()[0] print domain.values()[0] for each_domain in domain.values()[0]: try: domain_motif_color = domain_colors[each_domain[0]] start_domain_loc = int( each_domain[1].split(':')[0]) end_domain_loc = int(each_domain[1].split(':')[1]) domain_name = str(each_domain[0]) domain_motifs.append([ start_domain_loc, end_domain_loc, "<>", 20, 20, 'Black', domain_motif_color, 'arial|8|black|' ]) except ValueError: domain_motif_color = domain_colors[each_domain[0]] start_pattern = re.compile('(?<!=\W)\d+') start_pattern_search = re.search( start_pattern, str(each_domain[1].split(':')[0])) start_domain_loc = int( start_pattern_search.group()) end_pattern = re.compile('(?<!=\W)\d+') end_pattern_search = re.search( end_pattern, str(each_domain[1].split(':')[1])) end_domain_loc = int(end_pattern_search.group()) domain_motifs.append([ start_domain_loc, end_domain_loc, "<>", 20, 20, 'Black', domain_motif_color, 'arial|8|black|' ]) print domain_motifs msa_protein_seq = self.msa_aligned_protein[n].strip('-') print msa_protein_seq print len(msa_protein_seq) print '*' * 100 domainFace = SeqMotifFace(str(msa_protein_seq), gapcolor="black", seq_format='line', scale_factor=1, motifs=domain_motifs) (t & t.get_leaf_names()[n]).add_face(domainFace, 0, "aligned") n += 1 #Creating the legend print protein_domains for single_unrepeat, colors in domain_colors.iteritems(): ts.legend.add_face(TextFace(single_unrepeat), column=0) ts.legend.add_face(SeqMotifFace( "A" * 45, [[0, 80, "[]", None, 8, "Black", colors, None]]), column=1) ts.legend_position = 1 #name_of_run = nameOfRun() file_name = self.run_name t.show(tree_style=ts) t.render(os.path.join('CompletedTrees', file_name + '.pdf'), tree_style=ts)