def plot_concept_evolution( scenarios, tree, fileformat='pdf', degree=90, **keywords ): """ Plot the evolution according to the MLN method of all words for a given concept. Parameters ---------- tree : str A tree representation in Newick format. fileformat : str (default="pdf") A valid fileformat according to Matplotlib. degree : int (default=90) The degree by which the tree is drawn. 360 yields a circular tree, 180 yields a tree filling half of the space of a circle. """ # make defaults defaults = dict( figsize=(15, 15), left=0.05, top=0.95, bottom=0.05, right=0.95, colormap=mpl.cm.jet, edgewidth=5, radius=2.5, outer_radius=0.5, inner_radius=0.25, cognates='', usetex=False, latex_preamble=False, textsize=8, change=lambda x: x ** 1.75, xlim=0, ylim=0, xlimr=False, xliml=False, ylimt=False, ylimb=False, rootsize=10, legend=True, legendsize=5, legendAloc='upper right', legendBloc='lower right', markeredgewidth=2.5, wedgeedgewidth=2, gain_linestyle='dotted', loss_linestyle='solid', ax_linewidth=0, labels={}, _prefix='- ', _suffix=' -', colors={}, start=0, filename=rcParams['filename'], loss_alpha=0.1, loss_background='0.75', edges=[], hedge_color="black", hedge_width=5, hedge_linestyle='dashed', ) keywords.update(defaults) # set filename as variable for convenience filename = keywords['filename'] # XXX customize later XXX colormap = keywords['colormap'] # switch backend, depending on whether tex is used or not backend = mpl.get_backend() if keywords['usetex'] and backend != 'pgf': plt.switch_backend('pgf') elif not keywords['usetex'] and backend != 'TkAgg': plt.switch_backend('TkAgg') # check for preamble settings if keywords['latex_preamble']: mpl.rcParams['pgf.preamble'] = keywords['latex_preamble'] # make a graph graph = nx.Graph() # get the tgraph tgraph = radial_layout( tree, degree=degree, change=keywords['change'], start=keywords['start'] ) # get the taxa taxa = [n[0] for n in tgraph.nodes(data=True) if n[1]['tip']] # set the labels labels = {} for taxon in taxa: if taxon in keywords['labels']: labels[taxon] = keywords['labels'][taxon] else: labels[taxon] = taxon # get the number of paps in order to get the right colors cfunc = np.array(np.linspace(10, 256, len(scenarios)), dtype='int') if not keywords['colors']: colors = {scenarios[i][0]: mpl.colors.rgb2hex(colormap(cfunc[i])) for i in range(len(scenarios))} else: colors = keywords['colors'] # get the wedges for the paps wedges = {} linsp = np.linspace(0, 360, len(scenarios) + 1) for i, scenario in enumerate(scenarios): pap = scenario[0] theta1, theta2 = linsp[i], linsp[i + 1] wedges[pap] = (theta1, theta2) if keywords['legend']: # set the linestyle for the legend if keywords['gain_linestyle'] == 'dotted': ls = ':' elif keywords['gain_linestyle'] == 'dashed': ls = '--' legendEntriesA = [] legendTextA = [] # add stuff for the legend for pap, gls in scenarios: w = mpl.patches.Wedge( (0, 0), 1, wedges[pap][0], wedges[pap][1], facecolor=colors[pap], zorder=1, linewidth=keywords['wedgeedgewidth'], edgecolor='black' ) legendEntriesA += [w] legendTextA += [pap] # second legend explains evolution legendEntriesB = [] legendTextB = [] p = mpl.patches.Wedge( (0, 0), 1, 0, 360, facecolor='0.5', linewidth=keywords['wedgeedgewidth'], edgecolor='black', ) legendEntriesB += [p] legendTextB += ['Loss Event'] p, = plt.plot( 0, 0, ls, color='black', linewidth=keywords['wedgeedgewidth'] ) legendEntriesB += [p] legendTextB += ['Gain Event'] # overwrite stuff plt.plot(0, 0, 'o', markersize=2, zorder=2, color='white') # iterate over the paps and append states to the graph for pap, gls in scenarios: # get the graph with the model g = gls2gml( gls, tgraph, tree, filename='' ) # iterate over the graph for n, d in g.nodes(data=True): # add the node if necessary if n not in graph: graph.add_node(n) # add a pap-dictionary if it's not already there if 'pap' not in graph.node[n]: graph.node[n]['pap'] = {} # add data graph.node[n]['pap'][pap] = d['state'] # create the figure fig = plt.figure(figsize=keywords['figsize']) figsp = fig.add_subplot(111) figsp.axes.get_xaxis().set_visible(False) figsp.axes.get_yaxis().set_visible(False) for s in figsp.spines.values(): s.set_linewidth(keywords['ax_linewidth']) plt.axis('equal') xvals = [] yvals = [] # iterate over edges first for nA, nB in g.edges(): gA = g.node[nA]['graphics'] gB = g.node[nB]['graphics'] xA, yA = gA['x'], gA['y'] xB, yB = gB['x'], gB['y'] plt.plot( [xA, xB], [yA, yB], '-', color='black', linewidth=keywords['edgewidth'] ) # add horizontal edges if this option is chosen if keywords['edges']: # get the coordinates for nA, nB in keywords['edges']: gA = g.node[nA]['graphics'] gB = g.node[nB]['graphics'] xA, yA = gA['x'], gA['y'] xB, yB = gB['x'], gB['y'] plt.plot( [xA, xB], [yA, yB], '-', color=keywords['hedge_color'], linewidth=keywords["hedge_width"], linestyle=keywords['hedge_linestyle'] ) # now iterate over the nodes for n, d in graph.nodes(data=True): cpaps = d['pap'] x, y = g.node[n]['graphics']['x'], g.node[n]['graphics']['y'] # get z-value which serves as zorder attribute try: z = 6 * len(tree.getConnectingEdges('root', n)) except: z = 0 xvals += [x] yvals += [y] # plot the default marker plt.plot( x, y, 'o', markersize=keywords['rootsize'], color='black', zorder=50 ) # check for origins in cpaps if 'O' in cpaps.values(): w = mpl.patches.Wedge( (x, y), keywords['radius'] + keywords['outer_radius'], 0, 360, facecolor='white', zorder=57 + z, linewidth=keywords['markeredgewidth'], linestyle=keywords['gain_linestyle'], ) figsp.add_artist(w) # check for retentions elif 'o' in cpaps.values(): w = mpl.patches.Wedge( (x, y), keywords['radius'] + keywords['outer_radius'], 0, 360, facecolor='white', zorder=56 + z, linewidth=keywords['markeredgewidth'], linestyle='solid', ) figsp.add_artist(w) if 'L' in cpaps.values() and 'O' in cpaps.values(): w = mpl.patches.Wedge( (x, y), keywords['radius'] + keywords['outer_radius'], 0, 360, facecolor=keywords['loss_background'], zorder=58 + z, linewidth=keywords['markeredgewidth'], edgecolor='black', linestyle=keywords['loss_linestyle'] ) figsp.add_artist(w) elif "L" in cpaps.values(): w = mpl.patches.Wedge( (x, y), keywords['radius'] + keywords['outer_radius'], 0, 360, facecolor=keywords['loss_background'], zorder=59 + z, linewidth=keywords['markeredgewidth'], edgecolor='black', ) figsp.add_artist(w) # plot all wedges for pap in cpaps: theta1, theta2 = wedges[pap] color = colors[pap] # check for characteristics of this pap # if it's a loss if cpaps[pap] == 'L': w = mpl.patches.Wedge( (x, y), keywords['radius'], theta1, theta2, facecolor=color, zorder=61 + z, alpha=keywords['loss_alpha'], # 0.25, linewidth=keywords['wedgeedgewidth'], edgecolor='black', linestyle=keywords['loss_linestyle'] ) figsp.add_artist(w) elif cpaps[pap] == 'o': w = mpl.patches.Wedge( (x, y), keywords['radius'], theta1, theta2, facecolor=color, zorder=61 + z, linewidth=keywords['wedgeedgewidth'], edgecolor='black' ) figsp.add_artist(w) elif cpaps[pap] == 'O': w = mpl.patches.Wedge( (x, y), keywords['radius'], theta1, theta2, facecolor=color, zorder=61 + z, linewidth=keywords['wedgeedgewidth'], edgecolor='black', linestyle=keywords['gain_linestyle'] ) figsp.add_artist(w) # add the labels if this option is chosen if keywords['labels']: # if node is a tip if tgraph.node[n]['tip']: # get the values gf = tgraph.node[n]['graphics'] r = gf['angle'] x, y = gf['x'], gf['y'] ha = gf['s'] # modify the text if ha == 'left': text = keywords['_prefix'] + labels[n] else: text = labels[n] + keywords['_suffix'] # plot the text plt.text( x, y, text, size=keywords['textsize'], va='center', ha=ha, fontweight='bold', color='black', rotation=r, rotation_mode='anchor', zorder=z ) # set up the xlimits if not keywords['xlimr'] and not keywords['xliml']: xl, xr = 2 * [keywords['xlim']] else: xl, xr = keywords['xliml'], keywords['xlimr'] # set up the xlimits if not keywords['ylimt'] and not keywords['ylimb']: yb, yt = 2 * [keywords['ylim']] else: yb, yt = keywords['ylimb'], keywords['ylimt'] plt.xlim((min(xvals) - xl, max(xvals) + xr)) plt.ylim((min(yvals) - yb, max(yvals) + yt)) prop = mpl.font_manager.FontProperties(size=keywords['legendsize']) if keywords['legend']: legend1 = plt.legend( legendEntriesA, legendTextA, loc=keywords['legendAloc'], numpoints=1, prop=prop ) plt.legend( legendEntriesB, legendTextB, loc=keywords['legendBloc'], prop=prop ) figsp.add_artist(legend1) plt.subplots_adjust( left=keywords['left'], right=keywords['right'], top=keywords['top'], bottom=keywords['bottom'] ) plt.savefig(filename + '.' + fileformat) plt.clf() log.file_written(filename + '.' + fileformat)
def plot_gls( gls, treestring, degree=90, fileformat='pdf', **keywords ): """ Plot a gain-loss scenario for a given reference tree. """ # get kewyords defaults = dict( figsize=(15, 15), left=0.05, top=0.95, bottom=0.05, right=0.95, radius=0.5, textsize=8, edgewidth=5, linewidth=2, scale_radius=1.2, ylim=1, xlim=1, text=True, gain_color='white', loss_color='black', gain_linestyle='dotted', loss_linestyle='solid', ax_linewidth=0, filename=rcParams['filename'] ) for k in defaults: if k not in keywords: keywords[k] = defaults[k] # set filename as variabel for convenience filename = keywords['filename'] try: tree = cg.LoadTree(treestring=treestring) except: try: tree = cg.LoadTree(treestring) except: tree = treestring tgraph = radial_layout(treestring, degree=degree) graph = gls2gml( gls, tgraph, tree ) nodes = [] # assign nodes and edges for n, d in graph.nodes(data=True): g = d['graphics'] x = g['x'] y = g['y'] s = d['state'] nodes += [(x, y, s)] # now plot the stuff fig = plt.figure(figsize=keywords['figsize']) figsp = fig.add_subplot(111) figsp.axes.get_xaxis().set_visible(False) figsp.axes.get_yaxis().set_visible(False) # set the axes linewidht for s in figsp.spines.values(): s.set_linewidth(keywords['ax_linewidth']) plt.axis('equal') for nA, nB in graph.edges(): xA = graph.node[nA]['graphics']['x'] xB = graph.node[nB]['graphics']['x'] yA = graph.node[nA]['graphics']['y'] yB = graph.node[nB]['graphics']['y'] plt.plot( [xA, xB], [yA, yB], '-', color='black', linewidth=keywords['edgewidth'], zorder=1 ) # now, iterate over nodes for x, y, s in nodes: if s == 'O': w = mpl.patches.Wedge( (x, y), keywords['radius'], 0, 360, facecolor=keywords['gain_color'], linewidth=keywords['linewidth'], linestyle=keywords['gain_linestyle'] ) elif s == 'o': w = mpl.patches.Wedge( (x, y), keywords['radius'] / keywords['scale_radius'], 0, 360, facecolor=keywords['gain_color'], linewidth=keywords['linewidth'] ) elif s == 'L': w = mpl.patches.Wedge( (x, y), keywords['radius'], 0, 360, facecolor=keywords['loss_color'], linewidth=keywords['linewidth'], linestyle=keywords['loss_linestyle'] ) else: w = mpl.patches.Wedge( (x, y), keywords['radius'] / keywords['scale_radius'], 0, 360, facecolor=keywords['loss_color'], linewidth=keywords['linewidth'] ) figsp.add_artist(w) # if text is chosen as argument if keywords['text']: if s in 'Oo': t = '1' c = 'black' else: t = '0' c = 'white' plt.text( x, y, t, size=keywords['textsize'], color=c, va="center", ha="center", fontweight='bold' ) # set x and y-values xvals = [x[0] for x in nodes] yvals = [x[1] for x in nodes] plt.xlim(min(xvals) - keywords['xlim'], max(xvals) + keywords['xlim']) plt.ylim(min(yvals) - keywords['ylim'], max(yvals) + keywords['ylim']) plt.subplots_adjust( left=keywords['left'], right=keywords['right'], top=keywords['top'], bottom=keywords['bottom'] ) plt.savefig( filename + '.' + fileformat ) plt.clf() log.file_written(filename + '.' + fileformat)
def plot_tree( treestring, degree=90, fileformat='pdf', root="root", **keywords ): """ Plot a Newick tree to PDF or other graphical formats. Parameters ---------- treestring : str A string in Newick format. degree : int Determine the degree of the tree (this determines how "circular" the tree will be). fileformat : str (default="pdf") Select the fileformat to which the tree shall be written. filename : str Determine the name of the file to which the data shall be written. Defaults to a timestamp. figsize : tuple (default=(10,10)) Determine the size of the figure. """ default = dict( ax_linewidth=0, bg='black', bottom=0.05, change=lambda x: x ** 1.75, edge_list=[], figsize=(10, 10), filename=rcParams['filename'], fontweight='bold', frameon=False, ha='center', labels=[], left=0.05, linecolor='black', linewidth=5, no_labels=False, node_dict={}, nodecolor='black', nodesize=10, right=0.95, start=0, textcolor='white', textsize='10', top=0.95, usetex=False, va='center', xlim=5, xliml=False, xlimr=False, ylim=5, ylimb=False, ylimt=False, rotation_mode='anchor', latex_preamble=False, ) for k in default: if k not in keywords: keywords[k] = default[k] # set filename as variable for convenience filename = keywords['filename'] # switch backend, depending on whether tex is used or not backend = mpl.get_backend() if keywords['usetex'] and backend != 'pgf': plt.switch_backend('pgf') mpl.rcParams['text.latex.unicode'] = True elif not keywords['usetex'] and backend != 'TkAgg': plt.switch_backend('TkAgg') if keywords['latex_preamble']: mpl.rcParams['pgf.preamble'] = keywords['latex_preamble'] # get the tree-graph graph = radial_layout( treestring, degree=degree, change=keywords['change'], start=keywords['start'], root=root ) # create the figure fig = plt.figure(figsize=keywords['figsize']) figsp = fig.add_subplot(111) figsp.axes.get_xaxis().set_visible(False) figsp.axes.get_yaxis().set_visible(False) for s in figsp.spines.values(): s.set_linewidth(keywords['ax_linewidth']) # plt.axes(frameon=keywords['frameon']) plt.axis('equal') plt.xticks([]) plt.yticks([]) # get xlim and ylim xvals, yvals = [], [] # start iterating over edges for nA, nB, d in list(graph.edges(data=True)) + keywords['edge_list']: # get the coordinates xA = graph.node[nA]['graphics']['x'] yA = graph.node[nA]['graphics']['y'] xB = graph.node[nB]['graphics']['x'] yB = graph.node[nB]['graphics']['y'] if 'color' in d: plt.plot( [xA, xB], [yA, yB], '-', **d ) else: plt.plot( [xA, xB], [yA, yB], '-', color=keywords['linecolor'], linewidth=keywords['linewidth'], ) # get the nodes for n, d in graph.nodes(data=True): g = d['graphics'] x, y = g['x'], g['y'] xvals += [x] yvals += [y] # try to get information from the node-dict try: settings = {} settings.update(keywords['node_dict'][n]) except: settings = {} # overwrite the stuff in keywords for k in keywords: if k not in settings: settings[k] = keywords[k] if d['label'].startswith('edge') \ or d['label'].startswith(root) or keywords['no_labels']: plt.plot( x, y, 'o', markersize=settings['nodesize'], color=settings['nodecolor'], markeredgewidth=settings['linewidth'] ) else: try: label = keywords['labels'][d['label']] except: label = d['label'] if 'rotation' in settings: r = settings['rotation'] else: r = g['angle'] plt.text( x, y, label, # d['label'], color=settings['textcolor'], fontweight=settings['fontweight'], va=settings['va'], ha=g['s'], bbox=dict( facecolor=settings['bg'], boxstyle='square,pad=0.2', ec="none", ), size=settings['textsize'], rotation=r, # g['angle'], rotation_mode=settings['rotation_mode'] ) # set up the xlimits if not keywords['xlimr'] and not keywords['xliml']: xl, xr = 2 * [keywords['xlim']] else: xl, xr = keywords['xliml'], keywords['xlimr'] # set up the xlimits if not keywords['ylimt'] and not keywords['ylimb']: yb, yt = 2 * [keywords['ylim']] else: yb, yt = keywords['ylimb'], keywords['ylimt'] plt.xlim((min(xvals) - xl, max(xvals) + xr)) plt.ylim((min(yvals) - yb, max(yvals) + yt)) plt.subplots_adjust( left=keywords['left'], right=keywords['right'], top=keywords['top'], bottom=keywords['bottom'] ) plt.savefig(filename + '.' + fileformat) plt.clf() log.file_written(filename + '.' + fileformat)
def plot_concept_evolution(scenarios, tree, fileformat='pdf', degree=90, **keywords): """ Plot the evolution according to the MLN method of all words for a given concept. Parameters ---------- tree : str A tree representation in Newick format. fileformat : str (default="pdf") A valid fileformat according to Matplotlib. degree : int (default=90) The degree by which the tree is drawn. 360 yields a circular tree, 180 yields a tree filling half of the space of a circle. """ # make defaults defaults = dict( figsize=(15, 15), left=0.05, top=0.95, bottom=0.05, right=0.95, colormap=mpl.cm.jet, edgewidth=5, radius=2.5, outer_radius=0.5, inner_radius=0.25, cognates='', usetex=False, latex_preamble=False, textsize=8, change=lambda x: x**1.75, xlim=0, ylim=0, xlimr=False, xliml=False, ylimt=False, ylimb=False, rootsize=10, legend=True, legendsize=5, legendAloc='upper right', legendBloc='lower right', markeredgewidth=2.5, wedgeedgewidth=2, gain_linestyle='dotted', loss_linestyle='solid', ax_linewidth=0, labels={}, _prefix='- ', _suffix=' -', colors={}, start=0, filename=rcParams['filename'], loss_alpha=0.1, loss_background='0.75', edges=[], hedge_color="black", hedge_width=5, hedge_linestyle='dashed', ) keywords.update(defaults) # set filename as variable for convenience filename = keywords['filename'] # XXX customize later XXX colormap = keywords['colormap'] # switch backend, depending on whether tex is used or not backend = mpl.get_backend() if keywords['usetex'] and backend != 'pgf': plt.switch_backend('pgf') elif not keywords['usetex'] and backend != 'TkAgg': plt.switch_backend('TkAgg') # check for preamble settings if keywords['latex_preamble']: mpl.rcParams['pgf.preamble'] = keywords['latex_preamble'] # make a graph graph = nx.Graph() # get the tgraph tgraph = radial_layout(tree, degree=degree, change=keywords['change'], start=keywords['start']) # get the taxa taxa = [n[0] for n in tgraph.nodes(data=True) if n[1]['tip']] # set the labels labels = {} for taxon in taxa: if taxon in keywords['labels']: labels[taxon] = keywords['labels'][taxon] else: labels[taxon] = taxon # get the number of paps in order to get the right colors cfunc = np.array(np.linspace(10, 256, len(scenarios)), dtype='int') if not keywords['colors']: colors = { scenarios[i][0]: mpl.colors.rgb2hex(colormap(cfunc[i])) for i in range(len(scenarios)) } else: colors = keywords['colors'] # get the wedges for the paps wedges = {} linsp = np.linspace(0, 360, len(scenarios) + 1) for i, scenario in enumerate(scenarios): pap = scenario[0] theta1, theta2 = linsp[i], linsp[i + 1] wedges[pap] = (theta1, theta2) if keywords['legend']: # set the linestyle for the legend if keywords['gain_linestyle'] == 'dotted': ls = ':' elif keywords['gain_linestyle'] == 'dashed': ls = '--' legendEntriesA = [] legendTextA = [] # add stuff for the legend for pap, gls in scenarios: w = mpl.patches.Wedge((0, 0), 1, wedges[pap][0], wedges[pap][1], facecolor=colors[pap], zorder=1, linewidth=keywords['wedgeedgewidth'], edgecolor='black') legendEntriesA += [w] legendTextA += [pap] # second legend explains evolution legendEntriesB = [] legendTextB = [] p = mpl.patches.Wedge( (0, 0), 1, 0, 360, facecolor='0.5', linewidth=keywords['wedgeedgewidth'], edgecolor='black', ) legendEntriesB += [p] legendTextB += ['Loss Event'] p, = plt.plot(0, 0, ls, color='black', linewidth=keywords['wedgeedgewidth']) legendEntriesB += [p] legendTextB += ['Gain Event'] # overwrite stuff plt.plot(0, 0, 'o', markersize=2, zorder=2, color='white') # iterate over the paps and append states to the graph for pap, gls in scenarios: # get the graph with the model g = gls2gml(gls, tgraph, tree, filename='') # iterate over the graph for n, d in g.nodes(data=True): # add the node if necessary if n not in graph: graph.add_node(n) # add a pap-dictionary if it's not already there if 'pap' not in graph.node[n]: graph.node[n]['pap'] = {} # add data graph.node[n]['pap'][pap] = d['state'] # create the figure fig = plt.figure(figsize=keywords['figsize']) figsp = fig.add_subplot(111) figsp.axes.get_xaxis().set_visible(False) figsp.axes.get_yaxis().set_visible(False) for s in figsp.spines.values(): s.set_linewidth(keywords['ax_linewidth']) plt.axis('equal') xvals = [] yvals = [] # iterate over edges first for nA, nB in g.edges(): gA = g.node[nA]['graphics'] gB = g.node[nB]['graphics'] xA, yA = gA['x'], gA['y'] xB, yB = gB['x'], gB['y'] plt.plot([xA, xB], [yA, yB], '-', color='black', linewidth=keywords['edgewidth']) # add horizontal edges if this option is chosen if keywords['edges']: # get the coordinates for nA, nB in keywords['edges']: gA = g.node[nA]['graphics'] gB = g.node[nB]['graphics'] xA, yA = gA['x'], gA['y'] xB, yB = gB['x'], gB['y'] plt.plot([xA, xB], [yA, yB], '-', color=keywords['hedge_color'], linewidth=keywords["hedge_width"], linestyle=keywords['hedge_linestyle']) # now iterate over the nodes for n, d in graph.nodes(data=True): cpaps = d['pap'] x, y = g.node[n]['graphics']['x'], g.node[n]['graphics']['y'] # get z-value which serves as zorder attribute try: z = 6 * len(tree.getConnectingEdges('root', n)) except: z = 0 xvals += [x] yvals += [y] # plot the default marker plt.plot(x, y, 'o', markersize=keywords['rootsize'], color='black', zorder=50) # check for origins in cpaps if 'O' in cpaps.values(): w = mpl.patches.Wedge( (x, y), keywords['radius'] + keywords['outer_radius'], 0, 360, facecolor='white', zorder=57 + z, linewidth=keywords['markeredgewidth'], linestyle=keywords['gain_linestyle'], ) figsp.add_artist(w) # check for retentions elif 'o' in cpaps.values(): w = mpl.patches.Wedge( (x, y), keywords['radius'] + keywords['outer_radius'], 0, 360, facecolor='white', zorder=56 + z, linewidth=keywords['markeredgewidth'], linestyle='solid', ) figsp.add_artist(w) if 'L' in cpaps.values() and 'O' in cpaps.values(): w = mpl.patches.Wedge( (x, y), keywords['radius'] + keywords['outer_radius'], 0, 360, facecolor=keywords['loss_background'], zorder=58 + z, linewidth=keywords['markeredgewidth'], edgecolor='black', linestyle=keywords['loss_linestyle']) figsp.add_artist(w) elif "L" in cpaps.values(): w = mpl.patches.Wedge( (x, y), keywords['radius'] + keywords['outer_radius'], 0, 360, facecolor=keywords['loss_background'], zorder=59 + z, linewidth=keywords['markeredgewidth'], edgecolor='black', ) figsp.add_artist(w) # plot all wedges for pap in cpaps: theta1, theta2 = wedges[pap] color = colors[pap] # check for characteristics of this pap # if it's a loss if cpaps[pap] == 'L': w = mpl.patches.Wedge( (x, y), keywords['radius'], theta1, theta2, facecolor=color, zorder=61 + z, alpha=keywords['loss_alpha'], # 0.25, linewidth=keywords['wedgeedgewidth'], edgecolor='black', linestyle=keywords['loss_linestyle']) figsp.add_artist(w) elif cpaps[pap] == 'o': w = mpl.patches.Wedge((x, y), keywords['radius'], theta1, theta2, facecolor=color, zorder=61 + z, linewidth=keywords['wedgeedgewidth'], edgecolor='black') figsp.add_artist(w) elif cpaps[pap] == 'O': w = mpl.patches.Wedge((x, y), keywords['radius'], theta1, theta2, facecolor=color, zorder=61 + z, linewidth=keywords['wedgeedgewidth'], edgecolor='black', linestyle=keywords['gain_linestyle']) figsp.add_artist(w) # add the labels if this option is chosen if keywords['labels']: # if node is a tip if tgraph.node[n]['tip']: # get the values gf = tgraph.node[n]['graphics'] r = gf['angle'] x, y = gf['x'], gf['y'] ha = gf['s'] # modify the text if ha == 'left': text = keywords['_prefix'] + labels[n] else: text = labels[n] + keywords['_suffix'] # plot the text plt.text(x, y, text, size=keywords['textsize'], va='center', ha=ha, fontweight='bold', color='black', rotation=r, rotation_mode='anchor', zorder=z) # set up the xlimits if not keywords['xlimr'] and not keywords['xliml']: xl, xr = 2 * [keywords['xlim']] else: xl, xr = keywords['xliml'], keywords['xlimr'] # set up the xlimits if not keywords['ylimt'] and not keywords['ylimb']: yb, yt = 2 * [keywords['ylim']] else: yb, yt = keywords['ylimb'], keywords['ylimt'] plt.xlim((min(xvals) - xl, max(xvals) + xr)) plt.ylim((min(yvals) - yb, max(yvals) + yt)) prop = mpl.font_manager.FontProperties(size=keywords['legendsize']) if keywords['legend']: legend1 = plt.legend(legendEntriesA, legendTextA, loc=keywords['legendAloc'], numpoints=1, prop=prop) plt.legend(legendEntriesB, legendTextB, loc=keywords['legendBloc'], prop=prop) figsp.add_artist(legend1) plt.subplots_adjust(left=keywords['left'], right=keywords['right'], top=keywords['top'], bottom=keywords['bottom']) plt.savefig(filename + '.' + fileformat) plt.clf() log.file_written(filename + '.' + fileformat)
def plot_gls(gls, treestring, degree=90, fileformat='pdf', **keywords): """ Plot a gain-loss scenario for a given reference tree. """ # get kewyords defaults = dict(figsize=(15, 15), left=0.05, top=0.95, bottom=0.05, right=0.95, radius=0.5, textsize=8, edgewidth=5, linewidth=2, scale_radius=1.2, ylim=1, xlim=1, text=True, gain_color='white', loss_color='black', gain_linestyle='dotted', loss_linestyle='solid', ax_linewidth=0, filename=rcParams['filename']) for k in defaults: if k not in keywords: keywords[k] = defaults[k] # set filename as variabel for convenience filename = keywords['filename'] try: tree = cg.LoadTree(treestring=treestring) except: try: tree = cg.LoadTree(treestring) except: tree = treestring tgraph = radial_layout(treestring, degree=degree) graph = gls2gml(gls, tgraph, tree) nodes = [] # assign nodes and edges for n, d in graph.nodes(data=True): g = d['graphics'] x = g['x'] y = g['y'] s = d['state'] nodes += [(x, y, s)] # now plot the stuff fig = plt.figure(figsize=keywords['figsize']) figsp = fig.add_subplot(111) figsp.axes.get_xaxis().set_visible(False) figsp.axes.get_yaxis().set_visible(False) # set the axes linewidht for s in figsp.spines.values(): s.set_linewidth(keywords['ax_linewidth']) plt.axis('equal') for nA, nB in graph.edges(): xA = graph.node[nA]['graphics']['x'] xB = graph.node[nB]['graphics']['x'] yA = graph.node[nA]['graphics']['y'] yB = graph.node[nB]['graphics']['y'] plt.plot([xA, xB], [yA, yB], '-', color='black', linewidth=keywords['edgewidth'], zorder=1) # now, iterate over nodes for x, y, s in nodes: if s == 'O': w = mpl.patches.Wedge((x, y), keywords['radius'], 0, 360, facecolor=keywords['gain_color'], linewidth=keywords['linewidth'], linestyle=keywords['gain_linestyle']) elif s == 'o': w = mpl.patches.Wedge( (x, y), keywords['radius'] / keywords['scale_radius'], 0, 360, facecolor=keywords['gain_color'], linewidth=keywords['linewidth']) elif s == 'L': w = mpl.patches.Wedge((x, y), keywords['radius'], 0, 360, facecolor=keywords['loss_color'], linewidth=keywords['linewidth'], linestyle=keywords['loss_linestyle']) else: w = mpl.patches.Wedge( (x, y), keywords['radius'] / keywords['scale_radius'], 0, 360, facecolor=keywords['loss_color'], linewidth=keywords['linewidth']) figsp.add_artist(w) # if text is chosen as argument if keywords['text']: if s in 'Oo': t = '1' c = 'black' else: t = '0' c = 'white' plt.text(x, y, t, size=keywords['textsize'], color=c, va="center", ha="center", fontweight='bold') # set x and y-values xvals = [x[0] for x in nodes] yvals = [x[1] for x in nodes] plt.xlim(min(xvals) - keywords['xlim'], max(xvals) + keywords['xlim']) plt.ylim(min(yvals) - keywords['ylim'], max(yvals) + keywords['ylim']) plt.subplots_adjust(left=keywords['left'], right=keywords['right'], top=keywords['top'], bottom=keywords['bottom']) plt.savefig(filename + '.' + fileformat) plt.clf() log.file_written(filename + '.' + fileformat)
def plot_tree(treestring, degree=90, fileformat='pdf', root="root", **keywords): """ Plot a Newick tree to PDF or other graphical formats. Parameters ---------- treestring : str A string in Newick format. degree : int Determine the degree of the tree (this determines how "circular" the tree will be). fileformat : str (default="pdf") Select the fileformat to which the tree shall be written. filename : str Determine the name of the file to which the data shall be written. Defaults to a timestamp. figsize : tuple (default=(10,10)) Determine the size of the figure. """ default = dict( ax_linewidth=0, bg='black', bottom=0.05, change=lambda x: x**1.75, edge_list=[], figsize=(10, 10), filename=rcParams['filename'], fontweight='bold', frameon=False, ha='center', labels=[], left=0.05, linecolor='black', linewidth=5, no_labels=False, node_dict={}, nodecolor='black', nodesize=10, right=0.95, start=0, textcolor='white', textsize='10', top=0.95, usetex=False, va='center', xlim=5, xliml=False, xlimr=False, ylim=5, ylimb=False, ylimt=False, rotation_mode='anchor', latex_preamble=False, ) for k in default: if k not in keywords: keywords[k] = default[k] # set filename as variable for convenience filename = keywords['filename'] # switch backend, depending on whether tex is used or not backend = mpl.get_backend() if keywords['usetex'] and backend != 'pgf': plt.switch_backend('pgf') mpl.rcParams['text.latex.unicode'] = True elif not keywords['usetex'] and backend != 'TkAgg': plt.switch_backend('TkAgg') if keywords['latex_preamble']: mpl.rcParams['pgf.preamble'] = keywords['latex_preamble'] # get the tree-graph graph = radial_layout(treestring, degree=degree, change=keywords['change'], start=keywords['start'], root=root) # create the figure fig = plt.figure(figsize=keywords['figsize']) figsp = fig.add_subplot(111) figsp.axes.get_xaxis().set_visible(False) figsp.axes.get_yaxis().set_visible(False) for s in figsp.spines.values(): s.set_linewidth(keywords['ax_linewidth']) # plt.axes(frameon=keywords['frameon']) plt.axis('equal') plt.xticks([]) plt.yticks([]) # get xlim and ylim xvals, yvals = [], [] # start iterating over edges for nA, nB, d in list(graph.edges(data=True)) + keywords['edge_list']: # get the coordinates xA = graph.node[nA]['graphics']['x'] yA = graph.node[nA]['graphics']['y'] xB = graph.node[nB]['graphics']['x'] yB = graph.node[nB]['graphics']['y'] if 'color' in d: plt.plot([xA, xB], [yA, yB], '-', **d) else: plt.plot( [xA, xB], [yA, yB], '-', color=keywords['linecolor'], linewidth=keywords['linewidth'], ) # get the nodes for n, d in graph.nodes(data=True): g = d['graphics'] x, y = g['x'], g['y'] xvals += [x] yvals += [y] # try to get information from the node-dict try: settings = {} settings.update(keywords['node_dict'][n]) except: settings = {} # overwrite the stuff in keywords for k in keywords: if k not in settings: settings[k] = keywords[k] if d['label'].startswith('edge') \ or d['label'].startswith(root) or keywords['no_labels']: plt.plot(x, y, 'o', markersize=settings['nodesize'], color=settings['nodecolor'], markeredgewidth=settings['linewidth']) else: try: label = keywords['labels'][d['label']] except: label = d['label'] if 'rotation' in settings: r = settings['rotation'] else: r = g['angle'] plt.text( x, y, label, # d['label'], color=settings['textcolor'], fontweight=settings['fontweight'], va=settings['va'], ha=g['s'], bbox=dict( facecolor=settings['bg'], boxstyle='square,pad=0.2', ec="none", ), size=settings['textsize'], rotation=r, # g['angle'], rotation_mode=settings['rotation_mode']) # set up the xlimits if not keywords['xlimr'] and not keywords['xliml']: xl, xr = 2 * [keywords['xlim']] else: xl, xr = keywords['xliml'], keywords['xlimr'] # set up the xlimits if not keywords['ylimt'] and not keywords['ylimb']: yb, yt = 2 * [keywords['ylim']] else: yb, yt = keywords['ylimb'], keywords['ylimt'] plt.xlim((min(xvals) - xl, max(xvals) + xr)) plt.ylim((min(yvals) - yb, max(yvals) + yt)) plt.subplots_adjust(left=keywords['left'], right=keywords['right'], top=keywords['top'], bottom=keywords['bottom']) plt.savefig(filename + '.' + fileformat) plt.clf() log.file_written(filename + '.' + fileformat)