def traitTreeMinimal(traits, mapper): ### 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 ts = TreeStyle() ts.show_leaf_name = False ts.rotation = 270 ts.complete_branch_lines_when_necessary = False #ts.optimal_scale_level = "full" ts.scale = 800 # default NodeStyle nstyle = NodeStyle() nstyle["size"] = 0 nstyle["hz_line_color"] = "grey" nstyle["vt_line_color"] = "grey" nstyle["hz_line_width"] = 3 nstyle["vt_line_width"] = 3 for n in tree.traverse(): chroma = rgb2hex(*[ int(val) for val in mapper(traits[n.ND], gamma=0.8, scaleMax=255) ]) # setup for wl2RGB nf = CircleFace(radius=10, color='none', style='circle', label=None) n.set_style(nstyle) n.add_face(nf, column=0, position='branch-top') outFile = args.output + "/test_trees/cont_trait.pdf" tree.render(outFile, tree_style=ts) print >> sys.stderr, outFile
def set_default_TreeStyle(tree, draw_nodes): ts = TreeStyle() ts.mode = "c" ts.arc_start = -180 ts.arc_span = 180 ts.root_opening_factor = 1 ts.show_branch_length = False ts.show_branch_support = True ts.force_topology = False ts.show_leaf_name = False ts.min_leaf_separation = 10 ts.root_opening_factor = 1 ts.complete_branch_lines_when_necessary = True return ts, tree
def get_tree_style(**kwargs): style = TreeStyle() style.layout_fn = layout style.allow_face_overlap = True style.branch_vertical_margin = 5 style.complete_branch_lines_when_necessary = False style.draw_aligned_faces_as_table = False style.scale = 1500 style.scale_length = 0.05 style.show_branch_support = False style.show_leaf_name = False for key, value in kwargs.items(): if value == "True": value = True else: try: value = float(value) except ValueError: pass setattr(style, key, value) return style
def set_default_TreeStyle(tree): ts = TreeStyle() ts.mode = "c" ts.root_opening_factor = 1 ts.show_branch_length = True ts.show_branch_support = True ts.force_topology = True ts.show_leaf_name = False ts.min_leaf_separation = 10 ts.root_opening_factor = 1 ts.complete_branch_lines_when_necessary = True ns = NodeStyle() ns["size"] = 6 ns["fgcolor"] = "Black" ns["hz_line_width"] = 8 ns["vt_line_width"] = 8 for node in tree.traverse("postorder"): # if not node.is_leaf(): node.set_style(ns) tree.set_style(ts) return ts, tree
def testTreesMinimal(scenarios, traits, mapper): def rgb2hex(r, g, b): hex = "#{:02x}{:02x}{:02x}".format(r, g, b) return hex ### Draw test trees. This is a modified version of the test routine in pcoc_num_tree.py, stuffed in a for loop for cutoff in sorted(scenarios.keys()): tree = init_tree(args.tree) # not mucking with additive trees yet; ultrametrize the tree and normalize to length 1 tree.convert_to_ultrametric(tree_length=1) # read scenario into a dict manual_mode_nodes = {"T": [], "C": []} p_events = scenarios[cutoff].strip().split("/") for e in p_events: l_e = map(int, e.split(",")) manual_mode_nodes["T"].append(l_e[0]) manual_mode_nodes["C"].extend(l_e[1:]) ts = TreeStyle() # ts.allow_face_overlap = True ts.show_leaf_name = False ts.rotation = 270 ts.complete_branch_lines_when_necessary = False # ts.optimal_scale_level = "full" ts.scale = 800 for n in tree.traverse(): # default NodeStyle nstyle = NodeStyle() nstyle["size"] = 0 nstyle["hz_line_color"] = "none" nstyle["vt_line_color"] = "none" nstyle["hz_line_width"] = 3 nstyle["vt_line_width"] = 3 # colored faces chroma = rgb2hex(*[ int(val) for val in mapper(traits[n.ND], gamma=0.8, scaleMax=255) ]) # setup for wl2RGB nf = CircleFace(radius=10, color=chroma, style='circle', label=None) # scenario-dependent features if manual_mode_nodes: # if transition node if n.ND in manual_mode_nodes["T"]: #nstyle["hz_line_color"] = "orange" nf.inner_border.width = 4 nf.inner_border.color = 'red' # if convergent node elif n.ND in manual_mode_nodes["C"]: #nstyle["hz_line_color"] = "violet" nf.inner_border.width = 4 nf.inner_border.color = 'white' # if ancestral else: nstyle["hz_line_color"] = "none" n.set_style(nstyle) n.add_face(nf, column=0, position='branch-top') # limiting number of digits outFile = args.output + "/test_trees/" + str(cutoff).replace( '.', '_')[:np.min([5, len(str(cutoff))])] + ".pdf" tree.render(outFile, tree_style=ts) print >> sys.stderr, outFile
if keySeq[i] != "-": # meaning anything except gaps mappedCols[ keyIndex] = i + 1 # map the alignment column to the key column. Gotta shift the index! keyIndex += 1 return mappedCols ## ETE3 TREE-VIZ FUNCTIONS ## # basic 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 # make tree grow upward tree_style.rotation = 270 # and make it appear ultrametric (which it is!) tree_style.optimal_scale_level = "full" # internal node style nstyle = NodeStyle() nstyle["fgcolor"] = "black" nstyle["size"] = 0 # terminal node style nstyle_L = NodeStyle() nstyle["fgcolor"] = "black" nstyle["size"] = 0
def plot_phylo(nw_tree, out_name, parenthesis_classif=True, show_support=False, radial_mode=False, root=False): from ete3 import Tree, AttrFace, TreeStyle, NodeStyle, TextFace import orthogroup2phylogeny_best_refseq_uniprot_hity ete2_tree = Tree(nw_tree, format=0) if root: R = ete2_tree.get_midpoint_outgroup() # and set it as tree outgroup ete2_tree.set_outgroup(R) ete2_tree.set_outgroup('Bacillus subtilis') ete2_tree.ladderize() if parenthesis_classif: print('parenthesis_classif!') name2classif = {} for lf in ete2_tree.iter_leaves(): print(lf) try: classif = lf.name.split('_')[-2][0:-1] print('classif', classif) #lf.name = lf.name.split('(')[0] name2classif[lf.name] = classif except: pass classif_list = list(set(name2classif.values())) classif2col = dict( zip( classif_list, orthogroup2phylogeny_best_refseq_uniprot_hity. get_spaced_colors(len(classif_list)))) for lf in ete2_tree.iter_leaves(): #try: if parenthesis_classif: try: col = classif2col[name2classif[lf.name]] except: col = 'black' else: col = 'black' #print col #lf.name = '%s|%s-%s' % (lf.name, accession2name_and_phylum[lf.name][0],accession2name_and_phylum[lf.name][1]) if radial_mode: ff = AttrFace("name", fsize=12, fstyle='italic') else: ff = AttrFace("name", fsize=12, fstyle='italic') #ff.background.color = 'red' ff.fgcolor = col lf.add_face(ff, column=0) if not show_support: print('support') for n in ete2_tree.traverse(): print(n.support) nstyle = NodeStyle() if float(n.support) < 1: nstyle["fgcolor"] = "red" nstyle["size"] = 4 n.set_style(nstyle) else: nstyle["fgcolor"] = "red" nstyle["size"] = 0 n.set_style(nstyle) else: for n in ete2_tree.traverse(): nstyle = NodeStyle() nstyle["fgcolor"] = "red" nstyle["size"] = 0 n.set_style(nstyle) #nameFace = AttrFace(lf.name, fsize=30, fgcolor=phylum2col[accession2name_and_phylum[lf.name][1]]) #faces.add_face_to_node(nameFace, lf, 0, position="branch-right") # #nameFace.border.width = 1 ''' except: col = 'red' print col lf.name = '%s| %s' % (lf.name, locus2organism[lf.name]) ff = AttrFace("name", fsize=12) #ff.background.color = 'red' ff.fgcolor = col lf.add_face(ff, column=0) ''' #n = TextFace(lf.name, fgcolor = "black", fsize = 12, fstyle = 'italic') #lf.add_face(n, 0) ''' for n in ete2_tree.traverse(): nstyle = NodeStyle() if n.support < 90: nstyle["fgcolor"] = "black" nstyle["size"] = 4 n.set_style(nstyle) else: nstyle["fgcolor"] = "red" nstyle["size"] = 0 n.set_style(nstyle) ''' ts = TreeStyle() ts.show_leaf_name = False #ts.scale=2000 #ts.scale=20000 ts.show_branch_support = show_support if radial_mode: ts.mode = "c" ts.arc_start = -90 ts.arc_span = 360 ts.tree_width = 370 ts.complete_branch_lines_when_necessary = True ete2_tree.render(out_name, tree_style=ts, w=900)
tree_ete = Tree(tree_newick, format=1) node_fh = open(sys.argv[2]) color = {} size = {} value = {} node_info = node_fh.readlines() for info in node_info: info = info.rstrip('\n') infos = list(info.split('\t')) color[infos[0]] = infos[1] size[infos[0]] = infos[2] value[infos[0]] = "%.2f %%" % (float(infos[3]) * 100) tstyle = TreeStyle() tstyle.complete_branch_lines_when_necessary = False tstyle.show_leaf_name = False tstyle.scale = 1 tstyle.branch_vertical_margin = 40 tstyle.show_scale = False tree_ete.set_style(tstyle) for node in tree_ete.traverse(): if node.name != "root": name_face = TextFace(node.name) abun_face = TextFace(value[node.name]) node.add_face(name_face, column=0, position="branch-top") node.add_face(abun_face, column=0, position="branch-bottom") nstyle = NodeStyle() nstyle["fgcolor"] = color[node.name] nstyle["size"] = float(size[node.name])
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)
import matplotlib.colors as colors # only decorate a tree that has already PHYDLOG ids for asrRun in ('1','2','3'): inputGLF = os.path.join(basePath, 'analysis', 'tables', 'gainLossNormBrLen' + str(asrRun) + '.dat') outP = os.path.join(basePath, 'analysis', 'figures', 'spTree' + str(asrRun)) if asrRun == '3': analysisNumber = '3b' else: analysisNumber = asrRun spTreeF = os.path.join(basePath, 'analysis', 'iesdb', 'speciesTree' + analysisNumber + '.nhx') gl = pd.read_csv(inputGLF, sep = "\t") t = Tree(spTreeF) t.sort_descendants(attr='O') ts = TreeStyle() ts.complete_branch_lines_when_necessary = False # calculate branch colors gainL = [] # list with all rates of gain lossL = [] # list with all rates of loss gm = gl.rgain.min() gM = gl.rgain.max() lm = gl.rloss.min() lM = gl.rloss.max() #bcrg = scaleCol(gl.pgain.tolist()) # Branch Colors for Rates of Gain #bcrl = scaleCol(gl.ploss.tolist()) # Branch Colors for Rates of Loss # make a "gain" and a "loss" copy of the tree tg = t.copy() tl = t.copy() gcm = cm.ScalarMappable(norm = colors.Normalize(vmin = gm, vmax = gM), cmap = "coolwarm") lcm = cm.ScalarMappable(norm = colors.Normalize(vmin = lm, vmax = lM), cmap = "coolwarm") for node in tg.iter_descendants(): # do not include root