def drawParamTree(tree, params, *args, **kargs): tree = tree.copy() kargs.setdefault("legendScale", True) kargs.setdefault("xscale", 100) kargs.setdefault("yscale", 20) kargs.setdefault("minlen", 0) kargs.setdefault("maxlen", util.INF) if "labels" not in kargs: kargs["labels"] = {} for name in tree.nodes: if not tree.nodes[name].isLeaf(): kargs["labels"][name] = str(name) # set branch lengths to means for name in tree.nodes: tree.nodes[name].dist = params[name][0] # draw basic tree tmargin = 10 lmargin = 10 canvas = treesvg.drawTree(tree, autoclose=False, tmargin=tmargin, lmargin=lmargin, *args, **kargs) # draw variance coords = treelib.layout_tree(tree, kargs["xscale"], kargs["yscale"], kargs["minlen"], kargs["maxlen"]) canvas.beginTransform(("translate", lmargin, tmargin)) canvas.beginStyle("stroke-width: 3") for name, node in tree.nodes.iteritems(): if node == tree.root: continue x, y = coords[node] if node.parent: parentx = coords[node.parent][0] else: parentx = 0 varline = params[name][1] * (x - parentx) / params[name][0] canvas.line(x, y, max(parentx, x - varline), y, ) canvas.endStyle() canvas.endTransform() canvas.endSvg()
def show_smc(smc, mut=None, show_labels=False, branch_click=None, use_names=False): """ """ def draw_labels(tree, layout): return group(* [text_clip(names[leaf.name], layout[leaf][0] - .4, layout[leaf][1], layout[leaf][0] + .4, layout[leaf][1] - 1e4, 4, 20, "top", "center") for leaf in tree.leaves()]) def branch_hotspot(node, parent, x, y, y2): def func(): branch_click(node, parent) return hotspot("click", x-.5, y, x+.5, y2, func) def print_branch(node, parent): print "node", node.name def trans_camera(win, x, y): v = win.get_visible() win.set_visible(v[0]+x, v[1]+y, v[2]+x, v[3]+y, "exact") def on_scroll_window(win): region = win.get_visible() print region def on_resize_window(win): region = win.get_visible() print region branch_color = (1, 1, 1) spr_color = (1, 0, 0, .5) recomb_color = (1, 0, 0) # create window win = summon.Window() win.set_binding(input_key("]"), lambda : trans_camera(win, treewidth, 0)) win.set_binding(input_key("["), lambda : trans_camera(win, -treewidth, 0)) win.add_view_change_listener(lambda : on_scroll_window(win)) #win.remove_resize_listener(lambda : on_resize_window(win)) treex = 0 step = 2 names = [] seq_range = [0, 0] treewidth = 10 tree = None layout = None for item in smc: if item["tag"] == "NAMES": names = item["names"] if not use_names: names = map(str, range(len(names))) treewidth = len(names) elif item["tag"] == "RANGE": seq_range = [item["start"], item["end"]] elif item["tag"] == "TREE": tree = item["tree"] layout = treelib.layout_tree(tree, xscale=1, yscale=1) treelib.layout_tree_vertical(layout, leaves=0) #map_layout(layout, yfunc=minlog) region_text = text_clip("%d-%d" % (item["start"], item["end"]), treewidth*.05, 0, treewidth*.95, -max(l[1] for l in layout.values()), 4, 20, "center", "top") g = win.add_group( translate(treex, 0, color(1,1,1), sumtree.draw_tree(tree, layout, vertical=True), (draw_labels(tree, layout) if show_labels else group()), zoom_clamp(translate(0, -20, region_text), axis=(treewidth, 0), miny=1.0, maxy=1.0) )) clicking = group() g.append(clicking) elif item["tag"] == "SPR": rx, ry = layout[tree[item["recomb_node"]]] ry = item["recomb_time"] cx, cy = layout[tree[item["coal_node"]]] cy = item["coal_time"] g.append( group( lines(color(*spr_color), rx, ry, cx, cy), mark_tree(tree, layout, item["recomb_node"], time=item["recomb_time"], col=recomb_color))) treex += treewidth + step ''' tree_track = iter(tree_track) if mut: mut = util.PushIter(mut) block, tree = tree_track.next() if branch_click is True: branch_click = print_branch win = summon.Window() treex = 0 step = 2 treewidth = len(list(tree.leaves())) + step def trans_camera(win, x, y): v = win.get_visible() win.set_visible(v[0]+x, v[1]+y, v[2]+x, v[3]+y, "exact") win.set_binding(input_key("]"), lambda : trans_camera(win, treewidth, 0)) win.set_binding(input_key("["), lambda : trans_camera(win, -treewidth, 0)) for block, tree in chain([(block, tree)], tree_track): pos = block[0] print pos layout = treelib.layout_tree(tree, xscale=1, yscale=1) treelib.layout_tree_vertical(layout, leaves=0) g = win.add_group( translate(treex, 0, color(1,1,1), sumtree.draw_tree(tree, layout, vertical=True), (draw_labels(tree, layout) if show_labels else group()), text_clip( "%d-%d" % (block[0], block[1]), treewidth*.05, 0, treewidth*.95, -max(l[1] for l in layout.values()), 4, 20, "center", "top"))) clicking = group() g.append(clicking) # hotspots if branch_click: for node in tree: if node.parent: x, y = layout[node] x2, y2 = layout[node.parent] clicking.append(branch_hotspot(node, node.parent, x, y, y2)) #win.add_group(clicking) # draw mut if mut: for mpos, age, chroms in mut: if block[0] < mpos < block[1]: node = arglib.split_to_tree_branch(tree, chroms) parent = node.parent if node and parent: t = random.uniform(layout[node][1], layout[parent][1]) nx, ny = layout[node] win.add_group(draw_mark(treex + nx, t, col=(0,0,1))) elif mpos > block[1]: mut.push((mpos, age, chroms)) break treex += treewidth ''' win.home("exact") return win
def show_tree_track(tree_track, mut=None, show_labels=False, use_blocks=False, branch_click=None): """ tree_track = [((start, end), tree), ...] """ def draw_labels(tree, layout): return group(* [text_clip(leaf.name, layout[leaf][0], layout[leaf][1], 1, layout[leaf][1] + 1e4, 4, 20, "middle", "left") for leaf in tree.leaves()]) def branch_hotspot(node, parent, x, y, y2): def func(): branch_click(node, parent) return hotspot("click", x-.5, y, x+.5, y2, func) def print_branch(node, parent): print "node", node.name tree_track = iter(tree_track) if mut: mut = util.PushIter(mut) block, tree = tree_track.next() if branch_click is True: branch_click = print_branch win = summon.Window() treex = 0 step = 2 treewidth = len(list(tree.leaves())) + step def trans_camera(win, x, y): v = win.get_visible() win.set_visible(v[0]+x, v[1]+y, v[2]+x, v[3]+y, "exact") win.set_binding(input_key("]"), lambda : trans_camera(win, treewidth, 0)) win.set_binding(input_key("["), lambda : trans_camera(win, -treewidth, 0)) for block, tree in chain([(block, tree)], tree_track): pos = block[0] print pos layout = treelib.layout_tree(tree, xscale=1, yscale=1) treelib.layout_tree_vertical(layout, leaves=0) g = win.add_group( translate(treex, 0, color(1,1,1), sumtree.draw_tree(tree, layout, vertical=True), (draw_labels(tree, layout) if show_labels else group()), text_clip( "%d-%d" % (block[0], block[1]), treewidth*.05, 0, treewidth*.95, -max(l[1] for l in layout.values()), 4, 20, "center", "top"))) clicking = group() g.append(clicking) # hotspots if branch_click: for node in tree: if node.parent: x, y = layout[node] x2, y2 = layout[node.parent] clicking.append(branch_hotspot(node, node.parent, x, y, y2)) #win.add_group(clicking) # draw mut if mut: for mpos, age, chroms in mut: if block[0] < mpos < block[1]: node = arglib.split_to_tree_branch(tree, chroms) parent = node.parent if node and parent: t = random.uniform(layout[node][1], layout[parent][1]) nx, ny = layout[node] win.add_group(draw_mark(treex + nx, t, col=(0,0,1))) elif mpos > block[1]: mut.push((mpos, age, chroms)) break treex += treewidth #win.set_visible(* win.get_root().get_bounding() + ("exact",)) win.home("exact") return win
def show_smc(smc, mut=None, show_labels=False, branch_click=None, use_names=False): """ """ def draw_labels(tree, layout): return group(*[ text_clip(names[leaf.name], layout[leaf][0] - .4, layout[leaf][1], layout[leaf][0] + .4, layout[leaf][1] - 1e4, 4, 20, "top", "center") for leaf in tree.leaves() ]) def branch_hotspot(node, parent, x, y, y2): def func(): branch_click(node, parent) return hotspot("click", x - .5, y, x + .5, y2, func) def print_branch(node, parent): print "node", node.name def trans_camera(win, x, y): v = win.get_visible() win.set_visible(v[0] + x, v[1] + y, v[2] + x, v[3] + y, "exact") def on_scroll_window(win): region = win.get_visible() print region def on_resize_window(win): region = win.get_visible() print region branch_color = (1, 1, 1) spr_color = (1, 0, 0, .5) recomb_color = (1, 0, 0) # create window win = summon.Window() win.set_binding(input_key("]"), lambda: trans_camera(win, treewidth, 0)) win.set_binding(input_key("["), lambda: trans_camera(win, -treewidth, 0)) win.add_view_change_listener(lambda: on_scroll_window(win)) #win.remove_resize_listener(lambda : on_resize_window(win)) treex = 0 step = 2 names = [] seq_range = [0, 0] treewidth = 10 tree = None layout = None for item in smc: if item["tag"] == "NAMES": names = item["names"] if not use_names: names = map(str, range(len(names))) treewidth = len(names) elif item["tag"] == "RANGE": seq_range = [item["start"], item["end"]] elif item["tag"] == "TREE": tree = item["tree"] layout = treelib.layout_tree(tree, xscale=1, yscale=1) treelib.layout_tree_vertical(layout, leaves=0) #map_layout(layout, yfunc=minlog) region_text = text_clip("%d-%d" % (item["start"], item["end"]), treewidth * .05, 0, treewidth * .95, -max(l[1] for l in layout.values()), 4, 20, "center", "top") g = win.add_group( translate( treex, 0, color(1, 1, 1), sumtree.draw_tree(tree, layout, vertical=True), (draw_labels(tree, layout) if show_labels else group()), zoom_clamp(translate(0, -20, region_text), axis=(treewidth, 0), miny=1.0, maxy=1.0))) clicking = group() g.append(clicking) elif item["tag"] == "SPR": rx, ry = layout[tree[item["recomb_node"]]] ry = item["recomb_time"] cx, cy = layout[tree[item["coal_node"]]] cy = item["coal_time"] g.append( group( lines(color(*spr_color), rx, ry, cx, cy), mark_tree(tree, layout, item["recomb_node"], time=item["recomb_time"], col=recomb_color))) treex += treewidth + step ''' tree_track = iter(tree_track) if mut: mut = util.PushIter(mut) block, tree = tree_track.next() if branch_click is True: branch_click = print_branch win = summon.Window() treex = 0 step = 2 treewidth = len(list(tree.leaves())) + step def trans_camera(win, x, y): v = win.get_visible() win.set_visible(v[0]+x, v[1]+y, v[2]+x, v[3]+y, "exact") win.set_binding(input_key("]"), lambda : trans_camera(win, treewidth, 0)) win.set_binding(input_key("["), lambda : trans_camera(win, -treewidth, 0)) for block, tree in chain([(block, tree)], tree_track): pos = block[0] print pos layout = treelib.layout_tree(tree, xscale=1, yscale=1) treelib.layout_tree_vertical(layout, leaves=0) g = win.add_group( translate(treex, 0, color(1,1,1), sumtree.draw_tree(tree, layout, vertical=True), (draw_labels(tree, layout) if show_labels else group()), text_clip( "%d-%d" % (block[0], block[1]), treewidth*.05, 0, treewidth*.95, -max(l[1] for l in layout.values()), 4, 20, "center", "top"))) clicking = group() g.append(clicking) # hotspots if branch_click: for node in tree: if node.parent: x, y = layout[node] x2, y2 = layout[node.parent] clicking.append(branch_hotspot(node, node.parent, x, y, y2)) #win.add_group(clicking) # draw mut if mut: for mpos, age, chroms in mut: if block[0] < mpos < block[1]: node = arglib.split_to_tree_branch(tree, chroms) parent = node.parent if node and parent: t = random.uniform(layout[node][1], layout[parent][1]) nx, ny = layout[node] win.add_group(draw_mark(treex + nx, t, col=(0,0,1))) elif mpos > block[1]: mut.push((mpos, age, chroms)) break treex += treewidth ''' win.home("exact") return win
def show_tree_track(tree_track, mut=None, show_labels=False, use_blocks=False, branch_click=None): """ tree_track = [((start, end), tree), ...] """ def draw_labels(tree, layout): return group(*[ text_clip(leaf.name, layout[leaf][0], layout[leaf][1], 1, layout[leaf][1] + 1e4, 4, 20, "middle", "left") for leaf in tree.leaves() ]) def branch_hotspot(node, parent, x, y, y2): def func(): branch_click(node, parent) return hotspot("click", x - .5, y, x + .5, y2, func) def print_branch(node, parent): print "node", node.name tree_track = iter(tree_track) if mut: mut = util.PushIter(mut) block, tree = tree_track.next() if branch_click is True: branch_click = print_branch win = summon.Window() treex = 0 step = 2 treewidth = len(list(tree.leaves())) + step def trans_camera(win, x, y): v = win.get_visible() win.set_visible(v[0] + x, v[1] + y, v[2] + x, v[3] + y, "exact") win.set_binding(input_key("]"), lambda: trans_camera(win, treewidth, 0)) win.set_binding(input_key("["), lambda: trans_camera(win, -treewidth, 0)) for block, tree in chain([(block, tree)], tree_track): pos = block[0] print pos layout = treelib.layout_tree(tree, xscale=1, yscale=1) treelib.layout_tree_vertical(layout, leaves=0) g = win.add_group( translate( treex, 0, color(1, 1, 1), sumtree.draw_tree(tree, layout, vertical=True), (draw_labels(tree, layout) if show_labels else group()), text_clip("%d-%d" % (block[0], block[1]), treewidth * .05, 0, treewidth * .95, -max(l[1] for l in layout.values()), 4, 20, "center", "top"))) clicking = group() g.append(clicking) # hotspots if branch_click: for node in tree: if node.parent: x, y = layout[node] x2, y2 = layout[node.parent] clicking.append(branch_hotspot(node, node.parent, x, y, y2)) #win.add_group(clicking) # draw mut if mut: for mpos, age, chroms in mut: if block[0] < mpos < block[1]: node = arglib.split_to_tree_branch(tree, chroms) parent = node.parent if node and parent: t = random.uniform(layout[node][1], layout[parent][1]) nx, ny = layout[node] win.add_group(draw_mark(treex + nx, t, col=(0, 0, 1))) elif mpos > block[1]: mut.push((mpos, age, chroms)) break treex += treewidth #win.set_visible(* win.get_root().get_bounding() + ("exact",)) win.home("exact") return win
def draw_tree(tree, labels={}, xscale=100, yscale=20, canvas=None, leafPadding=10, leafFunc=lambda x: str(x.name), labelOffset=None, fontSize=10, labelSize=None, minlen=1, maxlen=util.INF, filename=sys.stdout, rmargin=150, lmargin=10, tmargin=0, bmargin=None, colormap=None, stree=None, layout=None, gene2species=None, lossColor=(0, 0, 1), dupColor=(1, 0, 0), eventSize=4, legendScale=False, autoclose=None, extendRoot=True, labelLeaves=True, drawHoriz=True, nodeSize=0): # set defaults fontRatio = 8. / 11. if labelSize == None: labelSize = .7 * fontSize if labelOffset == None: labelOffset = -1 if bmargin == None: bmargin = yscale if sum(x.dist for x in tree.nodes.values()) == 0: legendScale = False minlen = xscale if colormap == None: for node in tree: node.color = (0, 0, 0) else: colormap(tree) if stree and gene2species: recon = phylo.reconcile(tree, stree, gene2species) events = phylo.label_events(tree, recon) losses = phylo.find_loss(tree, stree, recon) else: events = None losses = None if len(labels) > 0 or (stree and gene2species): drawHoriz = True # layout tree if layout is None: coords = treelib.layout_tree(tree, xscale, yscale, minlen, maxlen) else: coords = layout xcoords, ycoords = zip(*coords.values()) maxwidth = max(xcoords) maxheight = max(ycoords) + labelOffset # initialize canvas if canvas == None: canvas = svg.Svg(util.open_stream(filename, "w")) width = int(rmargin + maxwidth + lmargin) height = int(tmargin + maxheight + bmargin) canvas.beginSvg(width, height) if autoclose == None: autoclose = True else: if autoclose == None: autoclose = False # draw tree def walk(node): x, y = coords[node] if node.parent: parentx, parenty = coords[node.parent] else: if extendRoot: parentx, parenty = 0, y else: parentx, parenty = x, y # e.g. no branch # draw branch if drawHoriz: canvas.line(parentx, y, x, y, color=node.color) else: canvas.line(parentx, parenty, x, y, color=node.color) # draw branch labels if node.name in labels: branchlen = x - parentx lines = str(labels[node.name]).split("\n") labelwidth = max(map(len, lines)) labellen = min(labelwidth * fontRatio * fontSize, max(int(branchlen - 1), 0)) for i, line in enumerate(lines): canvas.text( line, parentx + (branchlen - labellen) / 2., y + labelOffset + (-len(lines) + 1 + i) * (labelSize + 1), labelSize) # draw nodes if nodeSize > 0: canvas.circle(x, y, nodeSize, strokeColor=svg.null, fillColor=node.color) # draw leaf labels or recur if node.is_leaf(): if labelLeaves: canvas.text(leafFunc(node), x + leafPadding, y + fontSize / 2., fontSize, fillColor=node.color) else: if drawHoriz: # draw vertical part of branch top = coords[node.children[0]][1] bot = coords[node.children[-1]][1] canvas.line(x, top, x, bot, color=node.color) # draw children for child in node.children: walk(child) canvas.beginTransform(("translate", lmargin, tmargin)) walk(tree.root) if stree and gene2species: draw_events(canvas, tree, coords, events, losses, lossColor=lossColor, dupColor=dupColor, size=eventSize) canvas.endTransform() # draw legend if legendScale: if legendScale == True: # automatically choose a scale length = maxwidth / float(xscale) order = math.floor(math.log10(length)) length = 10**order drawScale(lmargin, tmargin + maxheight + bmargin - fontSize, length, xscale, fontSize, canvas=canvas) if autoclose: canvas.endSvg() return canvas
def draw_tree(tree, labels={}, xscale=100, yscale=20, canvas=None, leafPadding=10, leafFunc=lambda x: str(x.name), labelOffset=None, fontSize=10, labelSize=None, minlen=1, maxlen=util.INF, filename=sys.stdout, rmargin=150, lmargin=10, tmargin=0, bmargin=None, colormap=None, stree=None, layout=None, gene2species=None, lossColor=(0, 0, 1), dupColor=(1, 0, 0), eventSize=4, legendScale=False, autoclose=None, extendRoot=True, labelLeaves=True, drawHoriz=True, nodeSize=0): # set defaults fontRatio = 8. / 11. if labelSize == None: labelSize = .7 * fontSize if labelOffset == None: labelOffset = -1 if bmargin == None: bmargin = yscale if sum(x.dist for x in tree.nodes.values()) == 0: legendScale = False minlen = xscale if colormap == None: for node in tree: node.color = (0, 0, 0) else: colormap(tree) if stree and gene2species: recon = phylo.reconcile(tree, stree, gene2species) events = phylo.label_events(tree, recon) losses = phylo.find_loss(tree, stree, recon) else: events = None losses = None if len(labels) > 0 or (stree and gene2species): drawHoriz = True # layout tree if layout is None: coords = treelib.layout_tree(tree, xscale, yscale, minlen, maxlen) else: coords = layout xcoords, ycoords = zip(* coords.values()) maxwidth = max(xcoords) maxheight = max(ycoords) + labelOffset # initialize canvas if canvas == None: canvas = svg.Svg(util.open_stream(filename, "w")) width = int(rmargin + maxwidth + lmargin) height = int(tmargin + maxheight + bmargin) canvas.beginSvg(width, height) if autoclose == None: autoclose = True else: if autoclose == None: autoclose = False # draw tree def walk(node): x, y = coords[node] if node.parent: parentx, parenty = coords[node.parent] else: if extendRoot: parentx, parenty = 0, y else: parentx, parenty = x, y # e.g. no branch # draw branch if drawHoriz: canvas.line(parentx, y, x, y, color=node.color) else: canvas.line(parentx, parenty, x, y, color=node.color) # draw branch labels if node.name in labels: branchlen = x - parentx lines = str(labels[node.name]).split("\n") labelwidth = max(map(len, lines)) labellen = min(labelwidth * fontRatio * fontSize, max(int(branchlen-1), 0)) for i, line in enumerate(lines): canvas.text(line, parentx + (branchlen - labellen)/2., y + labelOffset +(-len(lines)+1+i)*(labelSize+1), labelSize) # draw nodes if nodeSize > 0: canvas.circle(x, y, nodeSize, strokeColor=svg.null, fillColor=node.color) # draw leaf labels or recur if node.is_leaf(): if labelLeaves: canvas.text(leafFunc(node), x + leafPadding, y+fontSize/2., fontSize, fillColor=node.color) else: if drawHoriz: # draw vertical part of branch top = coords[node.children[0]][1] bot = coords[node.children[-1]][1] canvas.line(x, top, x, bot, color=node.color) # draw children for child in node.children: walk(child) canvas.beginTransform(("translate", lmargin, tmargin)) walk(tree.root) if stree and gene2species: draw_events(canvas, tree, coords, events, losses, lossColor=lossColor, dupColor=dupColor, size=eventSize) canvas.endTransform() # draw legend if legendScale: if legendScale == True: # automatically choose a scale length = maxwidth / float(xscale) order = math.floor(math.log10(length)) length = 10 ** order drawScale(lmargin, tmargin + maxheight + bmargin - fontSize, length, xscale, fontSize, canvas=canvas) if autoclose: canvas.endSvg() return canvas
def draw_tree(tree, brecon, stree, xscale=100, yscale=100, leaf_padding=10, label_size=None, label_offset=None, font_size=12, stree_font_size=20, canvas=None, autoclose=True, rmargin=10, lmargin=10, tmargin=0, bmargin=0, tree_color=(0, 0, 0), tree_trans_color=(0, 0, 0), stree_color=(.4, .4, 1), snode_color=(.2, .2, .7), dup_color=(1, 0, 0), dup_color_border=(.5, 0, 0), trans_color=(0, 1, 0), trans_color_border=(0, .5, 0), event_size=10, snames=None, rootlen=None, stree_width=.8, filename="tree.svg" ): # set defaults font_ratio = 8. / 11. if label_size is None: label_size = .7 * font_size #if label_offset is None: # label_offset = -1 if sum(x.dist for x in tree.nodes.values()) == 0: legend_scale = False minlen = xscale if snames is None: snames = dict((x, x) for x in stree.leaf_names()) # layout stree slayout = treelib.layout_tree(stree, xscale, yscale) if rootlen is None: rootlen = .1 * max(l[0] for l in slayout.values()) # setup slayout x, y = slayout[stree.root] slayout[None] = (x - rootlen, y) for node, (x, y) in slayout.items(): slayout[node] = (x + rootlen, y - .5 * yscale) # layout tree ylists = defaultdict(lambda: []) yorders = {} # layout speciations and genes (y) for node in tree.preorder(): snode, event = brecon[node][-1] if event == "spec" or event == "gene": yorders[node] = len(ylists[snode]) ylists[snode].append(node) # layout dups and transfers (y) for node in tree.postorder(): snode, event = brecon[node][-1] if event != "spec" and event != "gene": v = [yorders[child] for child in node.children if brecon[child][-1][0] == snode] if len(v) == 0: yorders[node] = 0 else: yorders[node] = stats.mean(v) # layout node (x) xorders = {} xmax = defaultdict(lambda: 0) for node in tree.postorder(): snode, event = brecon[node][-1] if event == "spec" or event == "gene": xorders[node] = 0 else: v = [xorders[child] for child in node.children if brecon[child][-1][0] == snode] if len(v) == 0: xorders[node] = 1 else: xorders[node] = max(v) + 1 xmax[snode] = max(xmax[snode], xorders[node]) # setup layout layout = {None: slayout[brecon[tree.root][-1][0].parent]} for node in tree: snode = brecon[node][-1][0] nx, ny = slayout[snode] px, py = slayout[snode.parent] # calc x frac = (xorders[node]) / float(xmax[snode] + 1) deltax = nx - px x = nx - frac * deltax # calc y deltay = ny - py slope = deltay / float(deltax) deltax2 = x - px deltay2 = slope * deltax2 offset = py + deltay2 frac = (yorders[node] + 1) / float(max(len(ylists[snode]), 1) + 1) y = offset + (frac - .5) * stree_width * yscale layout[node] = (x, y) if y > max(l[1] for l in slayout.values()) + 50: print nx, ny print px, py print offset, frac print ylists[snode], yorders[node] print brecon[node] print node, snode, layout[node] # layout label sizes max_label_size = max(len(x.name) for x in tree.leaves()) * font_ratio * font_size max_slabel_size = max(len(x.name) for x in stree.leaves()) * font_ratio * stree_font_size ''' if colormap == None: for node in tree: node.color = (0, 0, 0) else: colormap(tree) if stree and gene2species: recon = phylo.reconcile(tree, stree, gene2species) events = phylo.label_events(tree, recon) losses = phylo.find_loss(tree, stree, recon) else: events = None losses = None # layout tree if layout is None: coords = treelib.layout_tree(tree, xscale, yscale, minlen, maxlen) else: coords = layout ''' xcoords, ycoords = zip(* slayout.values()) maxwidth = max(xcoords) + max_label_size + max_slabel_size maxheight = max(ycoords) + .5 * yscale # initialize canvas if canvas is None: canvas = svg.Svg(util.open_stream(filename, "w")) width = int(rmargin + maxwidth + lmargin) height = int(tmargin + maxheight + bmargin) canvas.beginSvg(width, height) canvas.beginStyle("font-family: \"Sans\";") if autoclose == None: autoclose = True else: if autoclose == None: autoclose = False canvas.beginTransform(("translate", lmargin, tmargin)) draw_stree(canvas, stree, slayout, yscale=yscale, stree_width=stree_width, stree_color=stree_color, snode_color=snode_color) # draw stree leaves for node in stree: x, y = slayout[node] if node.is_leaf(): canvas.text(snames[node.name], x + leaf_padding + max_label_size, y+stree_font_size/2., stree_font_size, fillColor=snode_color) # draw tree for node in tree: x, y = layout[node] px, py = layout[node.parent] trans = False if node.parent: snode = brecon[node][-1][0] psnode = brecon[node.parent][-1][0] while snode: if psnode == snode: break snode = snode.parent else: trans = True if not trans: canvas.line(x, y, px, py, color=tree_color) else: arch = 20 x2 = (x*.5 + px*.5) - arch y2 = (y*.5 + py*.5) x3 = (x*.5 + px*.5) - arch y3 = (y*.5 + py*.5) canvas.write("<path d='M%f %f C%f %f %f %f %f %f' %s />\n " % (x, y, x2, y2, x3, y3, px, py, " style='stroke-dasharray: 4, 2' " + svg.colorFields(tree_trans_color, (0,0,0,0)))) # draw events for node in tree: snode, event = brecon[node][-1] x, y = layout[node] o = event_size / 2.0 if event == "dup": canvas.rect(x - o, y - o, event_size, event_size, fillColor=dup_color, strokeColor=dup_color_border) elif event == "trans": canvas.rect(x - o, y - o, event_size, event_size, fillColor=trans_color, strokeColor=trans_color_border) # draw tree leaves for node in tree: x, y = layout[node] if node.is_leaf(): canvas.text(node.name, x + leaf_padding, y+font_size/2., font_size, fillColor=(0, 0, 0)) canvas.endTransform() if autoclose: canvas.endStyle() canvas.endSvg() return canvas
def draw_tree(tree, stree, extra, xscale=100, yscale=100, leaf_padding=10, label_size=None, label_offset=None, font_size=12, stree_font_size=20, canvas=None, autoclose=True, rmargin=10, lmargin=10, tmargin=0, bmargin=0, stree_color=(.4, .4, 1), snode_color=(.2, .2, .7), event_size=10, rootlen=None, stree_width=.8, filename=sys.stdout, labels=None, slabels=None): recon = extra["species_map"] loci = extra["locus_map"] order = extra["order"] # setup color map all_loci = sorted(set(loci.values())) num_loci = len(all_loci) colormap = util.rainbow_color_map(low=0, high=num_loci - 1) locus_color = {} for ndx, locus in enumerate(all_loci): locus_color[locus] = colormap.get(ndx) # set defaults font_ratio = 8. / 11. if label_size is None: label_size = .7 * font_size #if label_offset is None: # label_offset = -1 if sum(x.dist for x in tree.nodes.values()) == 0: legend_scale = False minlen = xscale snames = dict((x, x) for x in stree.leaf_names()) if labels is None: labels = {} if slabels is None: slabels = {} # layout stree slayout = treelib.layout_tree(stree, xscale, yscale) if rootlen is None: rootlen = .1 * max(l[0] for l in slayout.values()) # setup slayout x, y = slayout[stree.root] slayout[None] = (x - rootlen, y) for node, (x, y) in slayout.items(): slayout[node] = (x + rootlen, y - .5 * yscale) # layout tree ylists = defaultdict(lambda: []) yorders = {} # layout speciations and genes (y) events = phylo.label_events(tree, recon) for node in tree.preorder(): snode = recon[node] event = events[node] if event == "spec" or event == "gene": yorders[node] = len(ylists[snode]) ylists[snode].append(node) # layout internal nodes (y) for node in tree.postorder(): snode = recon[node] event = events[node] if event != "spec" and event != "gene": v = [yorders[child] for child in node.children] yorders[node] = stats.mean(v) # layout node (x) xorders = {} xmax = defaultdict(lambda: 0) for node in tree.postorder(): snode = recon[node] event = events[node] if event == "spec" or event == "gene": xorders[node] = 0 else: v = [xorders[child] for child in node.children] xorders[node] = max(v) + 1 xmax[snode] = max(xmax[snode], xorders[node]) ## # initial order ## xpreorders = {} ## for node in tree.postorder(): ## snode = recon[node] ## event = events[node] ## if event == "spec" or event == "gene": ## xpreorders[node] = 0 ## else: ## v = [xpreorders[child] for child in node.children] ## xpreorders[node] = max(v) + 1 #### print node.name, xpreorders[node] ## # hack-ish approach : shift x until order is satisfied ## def shift(node, x): ## xpreorders[node] += x ## for child in node.children: ## if events[child] != "spec": ## shift(child, x) ## satisfied = False ## while not satisfied: ## satisfied = True ## for snode, d in order.iteritems(): ## for plocus, lst in d.iteritems(): ## # test each pair ## for m, node1 in enumerate(lst): ## x1 = xpreorders[node1] ## for node2 in lst[m+1:]: ## x2 = xpreorders[node2] #### print node1, node2, x1, x2 ## if x2 < x1: ## # violation - shift all descendants in the sbranch ## satisfied = False #### print 'violation', node1, node2, x1, x2, x1-x2+1 ## shift(node2, x1-x2+1) ## break ## # finally, "normalize" xorders ## xorders = {} ## xmax = defaultdict(lambda: 0) ## for node in tree.postorder(): ## snode = recon[node] ## xorders[node] = xpreorders[node] ## xmax[snode] = max(xmax[snode], xorders[node]) #### print node.name, xpreorders[node] # setup layout layout = {None: slayout[None]} for node in tree: snode = recon[node] nx, ny = slayout[snode] px, py = slayout[snode.parent] # calc x frac = (xorders[node]) / float(xmax[snode] + 1) deltax = nx - px x = nx - frac * deltax # calc y deltay = ny - py slope = deltay / float(deltax) deltax2 = x - px deltay2 = slope * deltax2 offset = py + deltay2 frac = (yorders[node] + 1) / float(max(len(ylists[snode]), 1) + 1) y = offset + (frac - .5) * stree_width * yscale layout[node] = (x, y) ## if y > max(l[1] for l in slayout.values()) + 50: ## print nx, ny ## print px, py ## print offset, frac ## print ylists[snode], yorders[node] ## print node, snode, layout[node] # layout label sizes max_label_size = max(len(x.name) for x in tree.leaves()) * font_ratio * font_size max_slabel_size = max( len(x.name) for x in stree.leaves()) * font_ratio * stree_font_size xcoords, ycoords = zip(*slayout.values()) maxwidth = max(xcoords) + max_label_size + max_slabel_size maxheight = max(ycoords) + .5 * yscale # initialize canvas if canvas is None: canvas = svg.Svg(util.open_stream(filename, "w")) width = int(rmargin + maxwidth + lmargin) height = int(tmargin + maxheight + bmargin) canvas.beginSvg(width, height) canvas.beginStyle("font-family: \"Sans\";") if autoclose == None: autoclose = True else: if autoclose == None: autoclose = False canvas.beginTransform(("translate", lmargin, tmargin)) draw_stree(canvas, stree, slayout, yscale=yscale, stree_width=stree_width, stree_color=stree_color, snode_color=snode_color, slabels=slabels) # draw stree leaves for node in stree: x, y = slayout[node] if node.is_leaf(): canvas.text(snames[node.name], x + leaf_padding + max_label_size, y + stree_font_size / 2., stree_font_size, fillColor=snode_color) # draw tree for node in tree: x, y = layout[node] px, py = layout[node.parent] if node.parent: color = locus_color[loci[node.parent]] else: color = locus_color[loci[tree.root]] canvas.line(x, y, px, py, color=color) # draw tree names for node in tree: x, y = layout[node] px, py = layout[node.parent] if node.is_leaf(): canvas.text(node.name, x + leaf_padding, y + font_size / 2., font_size, fillColor=(0, 0, 0)) if node.name in labels: canvas.text(labels[node.name], x, y, label_size, fillColor=(0, 0, 0)) # draw events for node in tree: if node.parent: locus = loci[node] plocus = loci[node.parent] if locus != plocus: color = locus_color[locus] x, y = layout[node] o = event_size / 2.0 canvas.rect(x - o, y - o, event_size, event_size, fillColor=color, strokeColor=color) canvas.endTransform() if autoclose: canvas.endStyle() canvas.endSvg() return canvas
def draw_tree(tree, brecon, stree, xscale=100, yscale=100, leaf_padding=10, label_size=None, label_offset=None, font_size=12, stree_font_size=20, canvas=None, autoclose=True, rmargin=10, lmargin=10, tmargin=0, bmargin=0, tree_color=(0, 0, 0), tree_trans_color=(0, 0, 0), stree_color=(.4, .4, 1), snode_color=(.2, .2, .7), dup_color=(1, 0, 0), dup_color_border=(.5, 0, 0), trans_color=(0, 1, 0), trans_color_border=(0, .5, 0), event_size=10, snames=None, rootlen=None, stree_width=.8, filename="tree.svg"): # set defaults font_ratio = 8. / 11. if label_size is None: label_size = .7 * font_size #if label_offset is None: # label_offset = -1 if sum(x.dist for x in tree.nodes.values()) == 0: legend_scale = False minlen = xscale if snames is None: snames = dict((x, x) for x in stree.leaf_names()) # layout stree slayout = treelib.layout_tree(stree, xscale, yscale) if rootlen is None: rootlen = .1 * max(l[0] for l in slayout.values()) # setup slayout x, y = slayout[stree.root] slayout[None] = (x - rootlen, y) for node, (x, y) in slayout.items(): slayout[node] = (x + rootlen, y - .5 * yscale) # layout tree ylists = defaultdict(lambda: []) yorders = {} # layout speciations and genes (y) for node in tree.preorder(): snode, event = brecon[node][-1] if event == "spec" or event == "gene": yorders[node] = len(ylists[snode]) ylists[snode].append(node) # layout dups and transfers (y) for node in tree.postorder(): snode, event = brecon[node][-1] if event != "spec" and event != "gene": v = [ yorders[child] for child in node.children if brecon[child][-1][0] == snode ] if len(v) == 0: yorders[node] = 0 else: yorders[node] = stats.mean(v) # layout node (x) xorders = {} xmax = defaultdict(lambda: 0) for node in tree.postorder(): snode, event = brecon[node][-1] if event == "spec" or event == "gene": xorders[node] = 0 else: v = [ xorders[child] for child in node.children if brecon[child][-1][0] == snode ] if len(v) == 0: xorders[node] = 1 else: xorders[node] = max(v) + 1 xmax[snode] = max(xmax[snode], xorders[node]) # setup layout layout = {None: slayout[brecon[tree.root][-1][0].parent]} for node in tree: snode = brecon[node][-1][0] nx, ny = slayout[snode] px, py = slayout[snode.parent] # calc x frac = (xorders[node]) / float(xmax[snode] + 1) deltax = nx - px x = nx - frac * deltax # calc y deltay = ny - py slope = deltay / float(deltax) deltax2 = x - px deltay2 = slope * deltax2 offset = py + deltay2 frac = (yorders[node] + 1) / float(max(len(ylists[snode]), 1) + 1) y = offset + (frac - .5) * stree_width * yscale layout[node] = (x, y) if y > max(l[1] for l in slayout.values()) + 50: print nx, ny print px, py print offset, frac print ylists[snode], yorders[node] print brecon[node] print node, snode, layout[node] # layout label sizes max_label_size = max(len(x.name) for x in tree.leaves()) * font_ratio * font_size max_slabel_size = max( len(x.name) for x in stree.leaves()) * font_ratio * stree_font_size ''' if colormap == None: for node in tree: node.color = (0, 0, 0) else: colormap(tree) if stree and gene2species: recon = phylo.reconcile(tree, stree, gene2species) events = phylo.label_events(tree, recon) losses = phylo.find_loss(tree, stree, recon) else: events = None losses = None # layout tree if layout is None: coords = treelib.layout_tree(tree, xscale, yscale, minlen, maxlen) else: coords = layout ''' xcoords, ycoords = zip(*slayout.values()) maxwidth = max(xcoords) + max_label_size + max_slabel_size maxheight = max(ycoords) + .5 * yscale # initialize canvas if canvas is None: canvas = svg.Svg(util.open_stream(filename, "w")) width = int(rmargin + maxwidth + lmargin) height = int(tmargin + maxheight + bmargin) canvas.beginSvg(width, height) canvas.beginStyle("font-family: \"Sans\";") if autoclose == None: autoclose = True else: if autoclose == None: autoclose = False canvas.beginTransform(("translate", lmargin, tmargin)) draw_stree(canvas, stree, slayout, yscale=yscale, stree_width=stree_width, stree_color=stree_color, snode_color=snode_color) # draw stree leaves for node in stree: x, y = slayout[node] if node.is_leaf(): canvas.text(snames[node.name], x + leaf_padding + max_label_size, y + stree_font_size / 2., stree_font_size, fillColor=snode_color) # draw tree for node in tree: x, y = layout[node] px, py = layout[node.parent] trans = False if node.parent: snode = brecon[node][-1][0] psnode = brecon[node.parent][-1][0] while snode: if psnode == snode: break snode = snode.parent else: trans = True if not trans: canvas.line(x, y, px, py, color=tree_color) else: arch = 20 x2 = (x * .5 + px * .5) - arch y2 = (y * .5 + py * .5) x3 = (x * .5 + px * .5) - arch y3 = (y * .5 + py * .5) canvas.write("<path d='M%f %f C%f %f %f %f %f %f' %s />\n " % (x, y, x2, y2, x3, y3, px, py, " style='stroke-dasharray: 4, 2' " + svg.colorFields(tree_trans_color, (0, 0, 0, 0)))) # draw events for node in tree: snode, event = brecon[node][-1] x, y = layout[node] o = event_size / 2.0 if event == "dup": canvas.rect(x - o, y - o, event_size, event_size, fillColor=dup_color, strokeColor=dup_color_border) elif event == "trans": canvas.rect(x - o, y - o, event_size, event_size, fillColor=trans_color, strokeColor=trans_color_border) # draw tree leaves for node in tree: x, y = layout[node] if node.is_leaf(): canvas.text(node.name, x + leaf_padding, y + font_size / 2., font_size, fillColor=(0, 0, 0)) canvas.endTransform() if autoclose: canvas.endStyle() canvas.endSvg() return canvas