def attribute_legend(node, authors, styles): indx1 = authors.index(node.name) author_styles = styles[indx1] text = " " counter = 0 for style in author_styles: if counter % 2 == 0: text += " \n " counter += 1 text += style + ", " text = text[:-2] text = " " + text #F = TextFace(node.name, tight_text=True, fsize=15, fgcolor="white") #add_face_to_node(F, node, column=0, position="branch-right") N = TextFace(text, fgcolor="Black", fsize=21, fstyle="bold", bold=False, tight_text=False) if not node.is_leaf(): N.rotation = 90 Nspace = TextFace(" ", fgcolor="Black", fsize=21, bold=True) node.add_face(face=Nspace, column=1) node.add_face(face=N, column=2)
def my_layout(node): #coloca o nome em cada nó node.name F = TextFace( node.name.replace("*", "\n"), tight_text=True) #substitui onde tem estrela p quebra de linha add_face_to_node(F, node, column=0, position="branch-right") F.rotation = -90 #rotação do nome no nó
def populate_legend(ts, nstyles): ts.legend_position = 4 all_files = os.listdir('.') for file in all_files: # find the legend.txt file # this is a hack, should implement a real solution eventually if 'legend.txt' in file: #j = 0 with open(file) as f: for line in f: line = line.strip() line_arr = line.split('\t') x = CircleFace(5, nstyles[line_arr[0]]['fgcolor']) ts.legend.add_face(x, column=0) ts.legend.add_face(TextFace(line_arr[0]), column=1) genome_list = '' for i in range(1, len(line_arr)): if i > 5: genome_list += '...' # too many genomes break if i == len( line_arr ) - 1: # last element shouldn't end with comma genome_list += line_arr[i][1:] else: genome_list += line_arr[i][1:] + ', ' ts.legend.add_face(TextFace(genome_list), column=2)
def layout(node): # Make node name empty for particular nodes # if node.name in ('information retrieval', 'information systems'): # node.name = '' # x = 0 # # if node.name == '3 items': # node.name = '' # Some long name war here try: print_label = int( node.e ) < 3 or node.Hd == '1' or node.Of == '1' or node.Gap == '1' or node.ForceLabel == '1' if print_label: name_split = node.name.split('|') column = 0 for line in name_split: tw = textwrap.TextWrapper(width=20) names = tw.wrap(line) for n in names: short_name = TextFace(n, tight_text=True) short_name.rotation = 270 node.add_face(short_name, column=column, position="branch-right") column += 1 # Create and apply node style nst = NodeStyle() if .4 >= float(node.u) > 0: nst["fgcolor"] = "#90ee90" elif .6 >= float(node.u) > .4: nst["fgcolor"] = "green" elif float(node.u) > .6: nst["fgcolor"] = "#004000" elif node.Gap == '1': nst["fgcolor"] = "red" else: nst["fgcolor"] = NO_SUPPORT_COLOR if node.Hd == '1' or node.Of == '1': nst["size"] = 40 nst["shape"] = 'square' else: nst["size"] = 20 nst["shape"] = 'circle' # if node.Sq == '1' and float(node.u) > 0: # nst["shape"] = 'square' node.set_style(nst) except: print(f'Exception at {node}')
def add_text_face(self, taxon2text, header_name, color_scale=False): from metagenlab_libs.colors import get_categorical_color_scale if color_scale: value2color = get_categorical_color_scale(taxon2text.values()) self._add_header(header_name) # add column for i, lf in enumerate(self.tree.iter_leaves()): if lf.name in taxon2text: n = TextFace('%s' % taxon2text[lf.name]) if color_scale: n.background.color = value2color[taxon2text[lf.name]] else: print(lf.name, "not in", taxon2text) n = TextFace('-') n.margin_top = 1 n.margin_right = 10 n.margin_left = 10 n.margin_bottom = 1 n.opacity = 1. if self.rotate: n.rotation= 270 lf.add_face(n, self.column_count, position="aligned") self.column_count += 1
def mylayout(node): # Internal Node formatting nstyle = NodeStyle() nstyle["size"] = 0 nstyle["vt_line_width"] = 2 nstyle["hz_line_width"] = 2 if node.is_leaf(): circle_face = CircleFace(10, color_dict[node.name], style='circle') faces.add_face_to_node(circle_face, node, position="branch-right", column=0) text_face = TextFace(meta_dict[node.name][0]) text_face.fgcolor = color_dict[node.name] faces.add_face_to_node(text_face, node, position="branch-right", column=1) node.set_style(nstyle) elif node.is_root(): node.dist = 0 node.set_style(nstyle) else: node.set_style(nstyle)
def render_tree(species_tree, bipart1, num_alt, png_fn, replace_taxon=None): color1 = "blue" color2 = "black" ts = TreeStyle() ts.show_leaf_name = False ts.show_scale = False nstyle = NodeStyle() nstyle["size"] = 0 ts.title.add_face( TextFace("{} bipartition in {} gene trees".format(png_fn, num_alt), fsize=15, bold=True), 0) plot_tree = species_tree for node in plot_tree.traverse(): node.set_style(nstyle) if node.name in bipart1: name_face = TextFace(node.name, fgcolor=color1) else: name_face = TextFace(node.name, fgcolor=color2) node.add_face(name_face, 0, 'branch-right') if replace_taxon: for leaf in plot_tree.get_leaves: try: leaf.name = taxon_subst[leaf.name] except KeyError: continue plot_tree.convert_to_ultrametric() plot_tree.render(png_fn, tree_style=ts, w=600)
def my_layout(node): F = TextFace(node.name, tight_text=True, penwidth=5, fsize=12) if node.name is not 'a': add_face_to_node(F, node, column=0, position="branch-right") node.set_style(ns) if node.name in families: G = TextFace(families[node.name], fstyle='italic') add_face_to_node(G, node, column=0, position="branch-right") node.set_style(ns) if node.name in dict_genera: H = TextFace(dict_genera[node.name], fstyle='italic') add_face_to_node(H, node, column=0, position="branch-right") node.set_style(ns) if node.name in dict_species: I = TextFace(dict_species[node.name], fstyle='italic') add_face_to_node(I, node, column=0, position="branch-right") node.set_style(ns) if node.name == 'sumatrana': dict_species[node.name] = '(Sumatran Torrent Frog)' # if node.is_leaf(): # node.img_style["size"] = 0 # img = ImgFace('/home/stine/Desktop/{}.jpg'.format(node.name)) # add_face_to_node(img, node, column=0, aligned=True) for n in Anura.iter_search_nodes(): if n.dist > 1: n.img_style = ns
def mylayout(node): # If node is a leaf if node.is_leaf(): # And a line profile add_face_to_node(profileFace, node, 0, aligned=True) node.img_style["size"] = 0 add_face_to_node(nameFace, node, 1, aligned=True) # If node is internal else: # If silhouette is good, creates a green bubble if node.silhouette > 0: validationFace = TextFace("Silh=%0.2f" % node.silhouette, "Verdana", 10, "#056600") node.img_style["fgcolor"] = "#056600" # Otherwise, use red bubbles else: validationFace = TextFace("Silh=%0.2f" % node.silhouette, "Verdana", 10, "#940000") node.img_style["fgcolor"] = "#940000" # Sets node size proportional to the silhouette value. node.img_style["shape"] = "sphere" if node.silhouette <= 1 and node.silhouette >= -1: node.img_style["size"] = 15 + int((abs(node.silhouette) * 10)**2) # If node is very internal, draw also a bar diagram # with the average expression of the partition add_face_to_node(validationFace, node, 0) if len(node) > 100: add_face_to_node(cbarsFace, node, 1)
def get_example_tree(tree, color_dict=None, annot_dict=None, col=None): used_colours = set() for n in tree.traverse(): if n.is_leaf(): if n.name in annot_dict: n.img_style["bgcolor"] = color_dict[annot_dict[n.name]] used_colours.add(annot_dict[n.name]) ts = TreeStyle() ts.layout_fn = layout ts.show_leaf_name = False ts.mode = "c" # ts.arc_start = -180 # 0 degrees = 3 o'clock # ts.arc_span = 180 # ts.root_opening_factor = 1 # print (used_colours) for k,v in color_dict.items(): # Check that the specific colour was actually present in the tree we're annotating if k in used_colours: ts.legend.add_face(CircleFace(100, v), column=0) ts.legend.add_face(TextFace(k, fsize=50), column=1) # Add title ts.title.add_face(TextFace("Colouring tips on " + col, fsize=100), column=0) return tree, ts
def view_by_gene(tree, orthologous_grp, save_file): # Make a copy of the tree tree = copy.deepcopy(tree) for node in tree.traverse(): percents = [ orthologous_grp.regulation_states[(node.name, s)] * 100 for s in ['1', '0', 'A'] ] stacked_bar_face = StackedBarFace(percents, width=30, height=15, colors=['green', 'red', 'blue']) stacked_bar_face.margin_left = 5 stacked_bar_face.margin_right = 5 node.add_face(stacked_bar_face, column=1) # Add locus tag if the genome has the gene from this orthologous group if node.is_leaf(): # Check if the orthologous group contains any gene of the genome gene = orthologous_grp.member_from_genome(node.name) if gene: node.add_face(TextFace(text='[%s]' % gene.locus_tag), column=2) ts = TreeStyle() ts.title.add_face(TextFace(text=orthologous_grp.description), column=1) tree.render(save_file, tree_style=ts)
def my_layout(node): style = NodeStyle() style["size"] = 0 style["vt_line_color"] = "#A0A0A0" style["hz_line_color"] = "#A0A0A0" style["vt_line_type"] = 0 # 0 solid, 1 dashed, 2 dotted style["hz_line_type"] = 0 node.set_style(style) if node.is_leaf(): name_face = AttrFace("name", fsize=8, ftype="Times") else: name_face = TextFace(node.name, fsize=18, ftype="Times") if node.node_type == Sum: for child in node.children: label = TextFace(round(child.support, 3), fsize=6) child.add_face(label, column=1, position="branch-bottom") if show_ids: node.add_face(AttrFace("id", fsize=6), column=1, position="branch-top") faces.add_face_to_node(name_face, node, column=1, position="branch-right")
def ete_labels(tree, labels, column=1, position='aligned'): from ete3 import TreeStyle, TextFace for node in tree.traverse(): if node.name in labels: lbl = labels[node.name] f2=TextFace(lbl) node.add_face(f2, column=column, position=position) f2.margin_left = 10
def to_tree_node(self): t = Tree(f"{self.function_type};", format=1) for child in self.children: t.add_child(child.to_tree_node()) tf = TextFace(f"{self.function_type}") tf.rotation = -90 t.add_face(tf, column=1, position="branch-top") return t
def my_layout(node): F = TextFace("\t" + node.name, tight_text=True, fstyle="bold", fsize=40, fgcolor="black") F.rotation = 90 add_face_to_node(F, node, column=0, position="branch-bottom")
def add_labels_n_colors_2_tree(tree_path, refseq_2_entropy, colors, feature, out): """ add entropy measurement to a tree and color it's leaves :param tree_path: a path to a tree :param refseq_2_entropy: a data base with entropy values for each refseq id :param out: output directory path to save the results :return: a tree with colors and entropy labels """ print(tree_path) str_tree = tree_2_string(tree_path) if str_tree == '': return tree = Tree(str_tree) # get all refseq ids in the tree and all corresponding entropy values all_leaves = [] for node in tree: if node.is_leaf(): all_leaves.append(node.name) #all_values = refseq_2_entropy[refseq_2_entropy['refseq_id'].isin(all_leaves)]['entropy_5'].values all_values = refseq_2_entropy[feature].values num_leaves = len(all_leaves) # create a gradient color bar #colors = linear_gradient("#DC9221", "#33C193", n=num_leaves) #mapping = value_2_color(all_values, colors['hex']) mapping = value_2_color(all_values, colors['hex']) for node in tree: if node.is_leaf(): value = refseq_2_entropy[refseq_2_entropy['refseq_id'] == node.name.split('.')[0]][feature].values[0] virus_name = refseq_2_entropy[refseq_2_entropy['refseq_id'] == node.name.split('.')[0]]['virus_name'].values[0] # change virus name node.name = virus_name c = mapping[str(value)] node.add_feature("label", value) label_face = TextFace(node.label, fgcolor=c, fsize=22) node.add_face(label_face, column=0, position='branch-right') family = os.path.basename(tree_path).split('.')[0] ts = TreeStyle() ts.mode = 'c' ts.scale = 5 # Disable the default tip names config ts.show_leaf_name = True ts.show_scale = True ts.show_branch_length = True ts.title.add_face(TextFace("{} values for {}".format(feature, family), fsize=20), column=0) # Draw Tree tree.render(os.path.join(out, '{}_{}_tree.pdf'.format(family, feature)), dpi=300, tree_style=ts)
def to_tree_node(self): t = Tree("IF;", format=1) t.add_child(self.children[1].to_tree_node()) t.add_child(self.children[0].to_tree_node()) t.add_child(self.children[2].to_tree_node()) tf = TextFace("IF") tf.rotation = -90 t.add_face(tf, column=1, position="branch-top") return t
def rotation_layout(node): if node.is_leaf(): F = TextFace(node.name, tight_text=True) F.rotation = randint(0, 360) add_face_to_node(TextFace("third" ), node, column=8, position="branch-right") add_face_to_node(TextFace("second" ), node, column=2, position="branch-right") add_face_to_node(F, node, column=0, position="branch-right") F.border.width = 1 F.inner_border.width = 1
def add_Edges(node, tree, rootNode): def calculate_thickness(child, style): thickness = (child.total_children / rootNode.total_children) * 60 if child.rank == "Superkingdom" or child.rank == "Kingdom": # just to offset MASSIVE thick lines since those two thickness = 3 # will typically contain >90% of all results if thickness < 3: # just to offset later nodes having invisible borders thickness = 3 style["vt_line_width"] = thickness style["hz_line_width"] = thickness return style #unecessary since it passes by reference, but it might be useful in future def highlight_tax(child, style): ranks = {'Name':'FireBrick', 'Species':'Crimson', 'Genus':'Chocolate', 'Family':'Gold', 'Order':'LawnGreen', 'Class':'LimeGreen', 'Phylum':'Turquoise', 'Kingdom':'SteelBlue', 'Superkingdom':'Plum'} style["bgcolor"] = ranks[child.rank] return style #unecessary since it passes by reference, but it might be useful in future for child in node.child_nodes: if child.rank is not ("Name"): # Restricting it to above Species means it won't crash rendering a tree with thousands of results newNode = Tree(name=child.node_name) # Set borders name = TextFace(child.node_name) name.border.width = 1 name.border.color = '#ffffff' # Add name, total children, and rank. newNode.add_face(name,column=0,position="branch-right") children = "[" + str(child.total_children) + "]" newNode.add_face(TextFace(children),column=0, position="branch-bottom") newNode.add_face(TextFace(child.rank),column=0, position="branch-top") # Set colour based on rank and thickness based on total number of node's children. style = NodeStyle() highlight_tax(child, style) calculate_thickness(child, style) newNode.set_style(style) # Keep iterating tree.add_child(newNode) add_Edges(child, newNode, rootNode)
def layout(self, node): try: percents = [ round(100.0 * node.f_a / node.total), round(100.0 * node.f_b / node.total), round(100.0 * node.f_c / node.total), round(100.0 * node.f_ab / node.total), round(100.0 * node.f_ac / node.total), round(100.0 * node.f_bc / node.total), round(100.0 * node.f_all / node.total), round(100.0 * node.f_none / node.total) ] except ZeroDivisionError: txt = TextFace(' ' + node.plainName, ftype='Arial', fgcolor='#000000') else: i = 0 if sum(percents) != 100: x = sorted(percents)[-1] i = percents.index(x) percents[i] += 100 - sum(percents) if self.sqrt: size = int(math.sqrt(node.total) * 5 + 1) else: size = int(math.log10(node.total) * 20 + 10) P = PieChartFace(percents, size, size, self.colors) faces.add_face_to_node(P, node, 0, position="branch-top") #fgcol = mpl_colors.rgb2hex(mpl_colormap.brg(col/10.0)) # foreground/text color depending on NAD consumer density fgcol = '#000000' if node.counter: cnt = float(sum(node.counter)) / float(node.total) txt = TextFace(' {}\n {:.2f}'.format(node.plainName, cnt), ftype='Arial', fgcolor=fgcol) elif self.count: cnt = node.total txt = TextFace(' {}\n {:d}'.format(node.plainName, cnt), ftype='Arial', fgcolor=fgcol) else: txt = TextFace(' ' + node.plainName, ftype='Arial', fgcolor=fgcol) #txt.margin_right = -30 if node.is_leaf(): faces.add_face_to_node(txt, node, 0, position="branch-right") else: faces.add_face_to_node(txt, node, 0, position="branch-bottom")
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 add_node(self, node_text, edge_text, is_max): new = self.curr_node.add_child() new.add_face(TextFace(node_text, fsize=12, fgcolor='darkred'), column=0, position='branch-right') tf = TextFace(edge_text, fsize=9, fgcolor='darkgoldenrod') tf.margin_right = 30 new.add_face(tf, column=0, position='branch-bottom') new.set_style(NodeStyle(size=14, fgcolor=('blue' if is_max else 'red'))) self.curr_node = new
def attach_counts_to_tree(tree, genome_count_per_family, species_count_per_family): ''' Attaches TextFaces to tree leaves with plastid genome counts per leaf (=family) and leaf name Params: - tree: ete3 tree with family names as leaves - genome_count_per_family: dict with key = family name, value = number of sequenced plastid genomes for that family ''' for leaf in tree.iter_leaves(): leaf.add_face(TextFace(str(leaf.name)), column=0, position="aligned") if leaf.name in genome_count_per_family: leaf.add_face(TextFace("(" + str(species_count_per_family[leaf.name]) + "/" + str(genome_count_per_family[leaf.name]) + ")"), column=1, position="aligned") else: leaf.add_face(TextFace("(" + str(species_count_per_family[leaf.name]) + "/0)"), column=1, position="aligned")
def custom_layout(node): if node.is_leaf(): aligned_name_face = TextFace(node.name, fgcolor='olive', fsize=14) add_face_to_node(aligned_name_face, node, column=2, position='aligned') name_face = TextFace(node.name, fgcolor='#333333', fsize=11) add_face_to_node(name_face, node, column=2, position='branch-right') node.img_style['size'] = 0 if (node.name in tip2info) and (node.name in image_checker): # image img_face = ImgFace(tip2info[node.name][0], is_url=True) add_face_to_node(img_face, node, column=4, position='branch-right') habitat_face = TextFace(tip2info[node.name][2], fsize=11, fgcolor='white') habitat_face.background.color = 'steelblue' habitat_face.margin_left = 3 habitat_face.margin_top = 3 habitat_face.margin_right = 3 habitat_face.margin_bottom = 3 add_face_to_node(habitat_face, node, column=3, position='aligned') else: node.img_style['size'] = 4 node.img_style['shape'] = 'square' if node.name: name_face = TextFace(node.name, fgcolor='grey', fsize=10) name_face.margin_bottom = 2 add_face_to_node(name_face, node, column=0, position='branch-top') if node.support: support_face = TextFace(node.support, fgcolor='indianred', fsize=10) add_face_to_node(support_face, node, column=0, position='branch-bottom')
def __init__(self, text, ftype="Arial", fsize=10, fgcolor="black", penwidth=0, fstyle="normal"): Face.__init__(self) TextFace.__init__(self, text, ftype, fsize, fgcolor, penwidth, fstyle, False) self.type = "item" self.item = None
def draw_tree(tree): tree_copy = tree.copy("newick-extended") tree_copy.add_feature("i", tree.i) tree_copy.add_feature("Condition", tree.Condition) for n in tree_copy.traverse(): if n.is_leaf(): n.set_style(nstyle) n.add_face(TextFace(str(n.name)), column=0, position="aligned") else: n.set_style(nstyle) nd = TextFace(str(n.i)) nd.background.color = condi_color_dic[str(n.Condition)] nd.margin_right = 2 nd.margin_top = 1 nd.margin_left = 2 nd.margin_bottom = 1 nd.border.width = 1 if add_transition: if hasattr(n, "Transition"): nd.border.color = "red" nd.border.width = 2 n.add_face(nd, column=0, position="float") n.add_face(TextFace(" "), column=0, position="branch-bottom") return tree_copy
def add_t(node): nd = TextFace("-") nd.fsize = 4 nd.background.color = "black" nd.margin_right = 0 nd.margin_top = 0 nd.margin_left = 0 nd.margin_bottom = 0 nd.border.width = 1 nd2 = TextFace(" ") nd2.fsize = 4 node.add_face(nd, column=0, position = "float") node.add_face(nd2, column=1, position = "float")
def traitTree(traits, mapper, outDir): ### Take dict of traits and [R,G,B]-returning function ### Draw a tree with the continuous trait painted on via a colormapping function def rgb2hex(r, g, b): hex = "#{:02x}{:02x}{:02x}".format(r, g, b) return hex for n in tree.traverse(): if n.is_leaf(): n.set_style(nstyle_L) n.add_face(TextFace(str(n.name)), column=0, position="aligned") else: n.set_style(nstyle) #nd = TextFace(str(n.ND)) # label with node ID nd = TextFace(str(int( traits[n.ND]))) # label with rounded continuous trait value nd.background.color = rgb2hex(*[ int(val) for val in mapper(traits[n.ND], gamma=0.8, scaleMax=255) ]) # setup for wl2RGB nd.margin_right = 2 nd.margin_top = 1 nd.margin_left = 2 nd.margin_bottom = 1 nd.border.width = 1 n.add_face(nd, column=0, position="float") n.add_face(TextFace(" "), column=0, position="branch-bottom") #outFile = args.output + "/test_trees/cont_trait.pdf" outFile = outDir + "/cont_trait.pdf" tree.render(outFile, tree_style=tree_style) print >> sys.stderr, outFile
def para_from_meta(backpropagation, node, org, table, len_dict): """for paralogs from metadata""" unique_id = org.split('..')[0] group = f"{metadata[unique_id]['Higher Taxonomy']}" paraf = TextFace(f'{metadata[unique_id]["full"]}_{len_dict[org]}@{org}', fgcolor='blue') node.name = '' node.add_face(paraf, column=0) if not backpropagation: table.write( f'{metadata[unique_id]["full"]}_{len_dict[org]}@{org}\t{group}\tp\n' ) gface = TextFace(f'[{group} {metadata[unique_id]["Lower Taxonomy"]}]') node.add_face(gface, column=1, position="aligned")
def add_branch_text(tree, tree_style, node_dict): root_node = tree & 'root' for node in tree.traverse(): if node is root_node: continue T1 = TextFace(node.name, ftype="Monaco", fsize=10) T1.hz_align = 0 node.add_face(T1, 0, 'branch-top') T2 = TextFace('%s%%' % float_trans(node_dict[node.name].profile * 100), ftype="Monaco", fsize=10) T2.hz_align = 0 node.add_face(T2, 0, 'branch-bottom') # print node_dict[node.name].size node.dist = node_dict[node.name].branch_length tree_style.scale = 1
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 add_pie_face(tree, ts, total_profile, group): for leaf_name in tree.iter_leaf_names(): node = tree & leaf_name profile_list = total_profile[node.name] if group is not None: profile_list_grouped = OrderedDict() for sample_name, profile in profile_list.iteritems(): if group[sample_name] not in profile_list_grouped: profile_list_grouped[group[sample_name]] = 0 profile_list_grouped[group[sample_name]] += profile profile_list = pd.Series(profile_list_grouped) col_num = len(profile_list) times = int(math.ceil(col_num / len(COLS_BREWER))) cols = (COLS_BREWER * times)[:col_num] summary = sum(profile_list) if not summary: print profile_list print profile_list_grouped continue percents = map(lambda s: s / summary * 100, profile_list) P = PieChartFace(percents=percents, width=50, height=50, colors=cols) node.add_face(P, 0, 'aligned') #ts.legend.add_face(TextFace(" "), 0) #ts.legend.add_face(TextFace(" "), 1) for ind, g in enumerate(profile_list.index): T = TextFace(' %s ' % g) ts.legend.add_face(T, ind*2%24) C = CircleFace(radius=10, color=cols[ind], style="circle") ts.legend.add_face(C, (ind*2+1)%24) ts.legend_position = 1
def rename_leaves(self, taxon2new_taxon, keep_original=False, add_face=True): for i, lf in enumerate(self.tree.iter_leaves()): #print(dir(lf)) #print((lf.faces[0])) #lf.faces # = None #print("Iter leaf names") #for i in lf.features: # print("i", i) if not keep_original: if lf.name in taxon2new_taxon: label = taxon2new_taxon[lf.name] else: label = 'n/a' else: if lf.name in taxon2new_taxon: label = '%s (%s)' % (taxon2new_taxon[lf.name], lf.name) else: label = 'n/a' print ("add_face", add_face) if add_face: n = TextFace(label, fgcolor = "black", fsize = 12, fstyle = 'italic') lf.add_face(n, 0) lf.name = label
def get_tree_style(): ts = TreeStyle() # ts.mode = 'c' ts.margin_top = 10 ts.margin_bottom = 10 ts.margin_left = 10 ts.margin_right = 10 ts.show_leaf_name = False ts.show_branch_length = False ts.show_branch_support = False ts.show_scale = False title = TextFace(" Tax Assignment Tree", fsize=10) title.hz_align = 2 title.vt_align = 2 ts.title.add_face(TextFace(" "), column=0) ts.title.add_face(TextFace(" "), column=0) ts.title.add_face(title, column=0) return ts
def __init__(self, *args, **kwargs): TextFace.__init__(self, *args, **kwargs) self.margin_right = 10
def custom_layout(self,node): if node.is_leaf(): aligned_name_face = TextFace(node.name, fgcolor='olive', fsize=12) aligned_name_face.margin_top = 5 aligned_name_face.margin_right = 5 aligned_name_face.margin_left = 5 aligned_name_face.margin_bottom = 5 aligned_name_face.hz_align = 0 #0 = left, 1 = center, 2 = right add_face_to_node(aligned_name_face, node, column=2, position='aligned') #name_face = TextFace(node.name, fgcolor='#333333', fsize=11) #name_face.margin_top = 3 #name_face.margin_right = 3 #name_face.margin_left = 3 #name_face.margin_bottom = 3 #add_face_to_node(name_face, node, column=2, position='branch-right') node.img_style['size'] = 0 #--------------------------------------------- #displaying extra categorical and numeric data if (node.name in self._tip2info): column_no = 3 for headerIndex, dataheader in enumerate(self._tip2headers): extra_data = self._tip2info[node.name][headerIndex] if isinstance( extra_data, ( int, float ) ): extra_face = BarChartFace([extra_data], width=100,height=25,colors=[self._tip2color[node.name][headerIndex]],labels=[dataheader],min_value=0.0,max_value=self._tip_max) else: extra_face = TextFace(extra_data, fsize=11, fgcolor='black') extra_face.background.color = self._tip2color[node.name][headerIndex] extra_face.margin_left = 5 extra_face.margin_top = 5 extra_face.margin_right = 5 extra_face.margin_bottom = 5 add_face_to_node(extra_face, node, column=column_no, position='aligned') #add_face_to_node(extra_face, node, column=column_no, aligned = True, position='branch-right') column_no += 1 else: #print "No data available" column_no = 3 for headerIndex, dataheader in enumerate(self._tip2headers): extra_face = TextFace("No data available", fsize=10, fgcolor='black') extra_face.margin_left = 5 extra_face.margin_top = 5 extra_face.margin_right = 5 extra_face.margin_bottom = 5 add_face_to_node(extra_face, node, column=column_no, position='aligned') column_no += 1 image_col_no = column_no #---------------------------------------------- if (node.name in self._img_chk_list): if self._img_data_dic[node.name] is not None: img_face = ImgFace(self._img_data_dic[node.name], is_url=True) #img_face = ImgFace(self._tip2info[node.name][0], is_url=True) #img_path = os.path.join("file:///home/tayeen/TayeenFolders/TreeViewer/WebTreeApp/newplugin_test/data/", "328653.jpg") #img_face = ImgFace(img_path, is_url=True) img_face.margin_top = 10 img_face.margin_right = 10 img_face.margin_left = 10 img_face.margin_bottom = 10 #add_face_to_node(img_face, node, column=3, position='branch-right') #add_face_to_node(img_face, node, column=3, aligned= True, position='branch-right') else: img_path = os.path.join("file://"+image_path, "ina.jpg") img_face = ImgFace(img_path, is_url=True) #add_face_to_node(img_face, node, column=5, position='branch-right') add_face_to_node(img_face, node, column=image_col_no, position='aligned') else: #node is not a leaf node.img_style['size'] = 4 node.img_style['shape'] = 'square' if node.name and self._custom_options["draw_internal"]: name_face = TextFace(node.name, fgcolor='grey', fsize=10) name_face.margin_top = 4 name_face.margin_right = 4 name_face.margin_left = 4 name_face.margin_bottom = 4 add_face_to_node(name_face, node, column=0, position='branch-top') if node.name in self._node2label: label_face = TextFace(self._node2label[node.name], fgcolor='DarkGreen', fsize=10) label_face.margin_top = 4 label_face.margin_right = 4 label_face.margin_left = 4 label_face.margin_bottom = 4 add_face_to_node(label_face, node, column=0, position="branch-top") if node.support and self._custom_options["draw_support"]: support_face = TextFace(node.support, fgcolor='indianred', fsize=10) support_face.margin_top = 4 support_face.margin_right = 4 support_face.margin_left = 4 support_face.margin_bottom = 4 add_face_to_node(support_face, node, column=0, position='branch-bottom') if hasattr(node, "hide") and int(node.hide) == 1: node.img_style["draw_descendants"]= False collapsed_face = faces.TextFace(" %s collapsed leaves." %len(node), \ fsize=10, fgcolor="#444", ftype="Arial") faces.add_face_to_node(collapsed_face, node, 0) else: node.img_style["draw_descendants"] = True # Parse node features features and conver them into styles. This must be done like this, since current ete version #does not allow modifying style outside the layout function. if hasattr(node, "bsize"): node.img_style["size"]= int(node.bsize) if hasattr(node, "shape"): node.img_style["shape"]= node.shape if hasattr(node, "bgcolor"): node.img_style["bgcolor"]= node.bgcolor if hasattr(node, "fgcolor"): node.img_style["fgcolor"]= node.fgcolor #parse all nodes features if hasattr(node, "bh_bgcolor"): node.img_style["bgcolor"]= node.bh_bgcolor if hasattr(node, "bh_size"): node.img_style["size"]= node.bh_size if hasattr(node, "lh_color"): node.img_style['hz_line_color'] = node.lh_color node.img_style["vt_line_color"] = node.lh_color if hasattr(node, "lh_width"): node.img_style['hz_line_width'] = node.lh_width node.img_style['vt_line_width'] = node.lh_width if hasattr(node, "lh_width") and hasattr(node, "lh_color"): for n in node.iter_descendants(): n.img_style['hz_line_color'] = node.lh_color n.img_style["vt_line_color"] = node.lh_color n.img_style['hz_line_width'] = node.lh_width n.img_style['vt_line_width'] = node.lh_width
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 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 __init__(self, *args, **kwargs): TextFace.__init__(self, *args, **kwargs) self.margin_right = 10 self.ftype = 'Arial'
cell_id = trackResult[r, 0] time_begin = trackResult[r, 1] time_end = trackResult[r, 2] parent_id = trackResult[r, 3] time_duration = np.abs(time_begin-time_end) # for root if parent_id == 0: # Add name to root for the first iteration root.add_feature("name", str(cell_id)) # change the branch length root.add_feature("dist", time_duration) #change node style root.set_style(ns_root) # set node name to face nameFace = TextFace(root.name) nameFace.fgcolor = "white" nameFace.fsize = 15 # nameFace.border.width = 1 nameFace.background.color = "green" node_cur.add_face(nameFace, column=1, position="branch-bottom") else: # for child #### search the parent node by parent_id node_cur = root.search_nodes(name=str(parent_id)) # there should be only one parent node if len(node_cur) == 1: #### set child with its id node_cur = node_cur[0].add_child(name=str(cell_id)) #### set duration node_cur.add_feature("dist", time_duration)