def _draw_trees(trees, nrow=1, ncol=1, rmargin=0.3, iopts=None, outdir=".", shfile=None, **kwargs): """ Draw one or multiple trees on one plot. """ from jcvi.graphics.tree import draw_tree if shfile: SHs = DictFile(shfile, delimiter="\t") ntrees = len(trees) n = nrow * ncol for x in range(int(ceil(float(ntrees) / n))): fig = plt.figure(1, (iopts.w, iopts.h)) if iopts else plt.figure(1, (5, 5)) root = fig.add_axes([0, 0, 1, 1]) xiv = 1.0 / ncol yiv = 1.0 / nrow xstart = list(np.arange(0, 1, xiv)) * nrow ystart = list(chain(*zip(*[list(np.arange(0, 1, yiv))[::-1]] * ncol))) for i in range(n * x, n * (x + 1)): if i == ntrees: break ax = fig.add_axes([xstart[i % n], ystart[i % n], xiv, yiv]) f = trees.keys()[i] tree = trees[f] try: SH = SHs[f] except: SH = None draw_tree(ax, tree, rmargin=rmargin, reroot=False, supportcolor="r", SH=SH, **kwargs) root.set_xlim(0, 1) root.set_ylim(0, 1) root.set_axis_off() format = iopts.format if iopts else "pdf" dpi = iopts.dpi if iopts else 300 if n == 1: image_name = f.rsplit(".", 1)[0] + "." + format else: image_name = "trees{0}.{1}".format(x, format) image_name = op.join(outdir, image_name) savefig(image_name, dpi=dpi, iopts=iopts) plt.clf()
def __init__(self, fig, root, datafile, bedfile, layoutfile, switch=None, tree=None, chr_label=True, pad=.04): w, h = fig.get_figwidth(), fig.get_figheight() bed = Bed(bedfile) order = bed.order bf = BlockFile(datafile) lo = Layout(layoutfile) switch = DictFile(switch, delimiter="\t") if switch else None exts = [] for i in xrange(bf.ncols): ext = bf.get_extent(i, order) exts.append(ext) maxspan = max(exts, key=lambda x: x[-1])[-1] scale = maxspan / .65 self.gg = gg = {} self.rr = [] ymids = [] vpad = .012 * w / h for i in xrange(bf.ncols): ext = exts[i] r = Region(root, ext, lo[i], bed, scale, switch, chr_label=chr_label, vpad=vpad) self.rr.append(r) # Use tid and accn to store gene positions gg.update(dict(((i, k), v) for k, v in r.gg.items())) ymids.append(r.y) for i, j in lo.edges: for ga, gb, h in bf.iter_pairs(i, j): a, b = gg[(i, ga)], gg[(j, gb)] ymid = (ymids[i] + ymids[j]) / 2 Shade(root, a, b, ymid, fc="gainsboro", lw=0, alpha=1) for ga, gb, h in bf.iter_pairs(i, j, highlight=True): a, b = gg[(i, ga)], gg[(j, gb)] ymid = (ymids[i] + ymids[j]) / 2 Shade(root, a, b, ymid, alpha=1, highlight=h, zorder=2) if tree: from jcvi.graphics.tree import draw_tree, read_trees trees = read_trees(tree) ntrees = len(trees) logging.debug("A total of {0} trees imported.".format(ntrees)) xiv = 1. / ntrees yiv = .3 xstart = 0 ystart = min(ymids) - .4 for i in xrange(ntrees): ax = fig.add_axes([xstart, ystart, xiv, yiv]) label, outgroup, tx = trees[i] draw_tree(ax, tx, outgroup=outgroup, rmargin=.4) xstart += xiv RoundLabel(ax, .5, .3, label, fill=True, fc="lavender", color="r")
def _draw_trees(trees, nrow=1, ncol=1, rmargin=.3, iopts=None, outdir=".", shfile=None, **kwargs): """ Draw one or multiple trees on one plot. """ from jcvi.graphics.tree import draw_tree if shfile: SHs = DictFile(shfile, delimiter="\t") ntrees = len(trees) n = nrow * ncol for x in xrange(int(ceil(float(ntrees)/n))): fig = plt.figure(1, (iopts.w, iopts.h)) if iopts \ else plt.figure(1, (5, 5)) root = fig.add_axes([0, 0, 1, 1]) xiv = 1. / ncol yiv = 1. / nrow xstart = list(np.arange(0, 1, xiv)) * nrow ystart = list(chain(*zip(*[list(np.arange(0, 1, yiv))[::-1]] * ncol))) for i in xrange(n*x, n*(x+1)): if i == ntrees: break ax = fig.add_axes([xstart[i%n], ystart[i%n], xiv, yiv]) f = trees.keys()[i] tree = trees[f] try: SH = SHs[f] except: SH = None draw_tree(ax, tree, rmargin=rmargin, reroot=False, \ supportcolor="r", SH=SH, **kwargs) root.set_xlim(0, 1) root.set_ylim(0, 1) root.set_axis_off() format = iopts.format if iopts else "pdf" dpi = iopts.dpi if iopts else 300 if n == 1: image_name = f.rsplit(".", 1)[0] + "." + format else: image_name = "trees{0}.{1}".format(x, format) image_name = op.join(outdir, image_name) savefig(image_name, dpi=dpi, iopts=iopts) plt.clf()
def tree(args): """ %prog tree treefile Create a tree figure. """ from jcvi.graphics.tree import parse_tree, LeafInfoFile, WGDInfoFile, draw_tree p = OptionParser(tree.__doc__) opts, args, iopts = p.set_image_options(args, figsize="10x8") (datafile, ) = args logging.debug("Load tree file `{0}`".format(datafile)) t, hpd = parse_tree(datafile) fig = plt.figure(1, (iopts.w, iopts.h)) ax1 = fig.add_axes([0, 0, 1, 1]) supportcolor = "k" margin, rmargin = 0.1, 0.2 # Left and right margin leafinfo = LeafInfoFile("leafinfo.csv").cache wgdinfo = WGDInfoFile("wgdinfo.csv").cache outgroup = "ginkgo" # Panel A draw_tree( ax1, t, hpd=hpd, margin=margin, rmargin=rmargin, supportcolor=None, internal=False, outgroup=outgroup, reroot=False, leafinfo=leafinfo, wgdinfo=wgdinfo, geoscale=True, ) normalize_axes([ax1]) image_name = "tree.pdf" savefig(image_name, dpi=iopts.dpi, iopts=iopts)
def __init__(self, fig, root, datafile, bedfile, layoutfile, switch=None, tree=None, extra_features=None, chr_label=True, loc_label=True, pad=.05, vpad=.015, scalebar=False): w, h = fig.get_figwidth(), fig.get_figheight() bed = Bed(bedfile) order = bed.order bf = BlockFile(datafile) self.layout = lo = Layout(layoutfile) switch = DictFile(switch, delimiter="\t") if switch else None if extra_features: extra_features = Bed(extra_features) exts = [] extras = [] for i in xrange(bf.ncols): ext = bf.get_extent(i, order) exts.append(ext) if extra_features: start, end, si, ei, chr, orientation, span = ext start, end = start.start, end.end # start, end coordinates ef = list(extra_features.extract(chr, start, end)) # Pruning removes minor features with < 0.1% of the region ef_pruned = [x for x in ef if x.span >= span / 1000] print >> sys.stderr, "Extracted {0} features "\ "({1} after pruning)".format(len(ef), len(ef_pruned)) extras.append(ef_pruned) maxspan = max(exts, key=lambda x: x[-1])[-1] scale = maxspan / .65 self.gg = gg = {} self.rr = [] ymids = [] #vpad = .012 * w / h for i in xrange(bf.ncols): ext = exts[i] ef = extras[i] if extras else None r = Region(root, ext, lo[i], bed, scale, switch, chr_label=chr_label, loc_label=loc_label, vpad=vpad, extra_features=ef) self.rr.append(r) # Use tid and accn to store gene positions gg.update(dict(((i, k), v) for k, v in r.gg.items())) ymids.append(r.y) for i, j in lo.edges: for ga, gb, h in bf.iter_pairs(i, j): a, b = gg[(i, ga)], gg[(j, gb)] ymid = (ymids[i] + ymids[j]) / 2 Shade(root, a, b, ymid, fc="gainsboro", lw=0, alpha=1) for ga, gb, h in bf.iter_pairs(i, j, highlight=True): a, b = gg[(i, ga)], gg[(j, gb)] ymid = (ymids[i] + ymids[j]) / 2 Shade(root, a, b, ymid, alpha=1, highlight=h, zorder=2) if scalebar: print >> sys.stderr, "Build scalebar (scale={})".format(scale) # Find the best length of the scalebar ar = [1, 2, 5] candidates = [1000 * x for x in ar] + [10000 * x for x in ar] + \ [100000 * x for x in ar] # Find the one that's close to an optimal canvas size dists = [(abs(x / scale - .12), x) for x in candidates] dist, candidate = min(dists) dist = candidate / scale x, y, yp = .2, .96, .005 a, b = x - dist / 2, x + dist / 2 lsg = "lightslategrey" root.plot([a, a], [y - yp, y + yp], "-", lw=2, color=lsg) root.plot([b, b], [y - yp, y + yp], "-", lw=2, color=lsg) root.plot([a, b], [y, y], "-", lw=2, color=lsg) root.text(x, y + .02, human_size(candidate, precision=0), ha="center", va="center") if tree: from jcvi.graphics.tree import draw_tree, read_trees trees = read_trees(tree) ntrees = len(trees) logging.debug("A total of {0} trees imported.".format(ntrees)) xiv = 1. / ntrees yiv = .3 xstart = 0 ystart = min(ymids) - .4 for i in xrange(ntrees): ax = fig.add_axes([xstart, ystart, xiv, yiv]) label, outgroup, tx = trees[i] draw_tree(ax, tx, outgroup=outgroup, rmargin=.4, leaffont=11) xstart += xiv RoundLabel(ax, .5, .3, label, fill=True, fc="lavender", color="r")
def __init__( self, fig, root, datafile, bedfile, layoutfile, switch=None, tree=None, extra_features=None, chr_label=True, loc_label=True, genelabelsize=0, pad=0.05, vpad=0.015, scalebar=False, shadestyle="curve", glyphstyle="arrow", glyphcolor: BasePalette = OrientationPalette(), ): _, h = fig.get_figwidth(), fig.get_figheight() bed = Bed(bedfile) order = bed.order bf = BlockFile(datafile) self.layout = lo = Layout(layoutfile) switch = DictFile(switch, delimiter="\t") if switch else None if extra_features: extra_features = Bed(extra_features) exts = [] extras = [] for i in range(bf.ncols): ext = bf.get_extent(i, order) exts.append(ext) if extra_features: start, end, si, ei, chr, orientation, span = ext start, end = start.start, end.end # start, end coordinates ef = list(extra_features.extract(chr, start, end)) # Pruning removes minor features with < 0.1% of the region ef_pruned = [x for x in ef if x.span >= span / 1000] print( "Extracted {0} features " "({1} after pruning)".format(len(ef), len(ef_pruned)), file=sys.stderr, ) extras.append(ef_pruned) maxspan = max(exts, key=lambda x: x[-1])[-1] scale = maxspan / 0.65 self.gg = gg = {} self.rr = [] ymids = [] glyphcolor = ( OrientationPalette() if glyphcolor == "orientation" else OrthoGroupPalette(bf.grouper()) ) for i in range(bf.ncols): ext = exts[i] ef = extras[i] if extras else None r = Region( root, ext, lo[i], bed, scale, switch, genelabelsize=genelabelsize, chr_label=chr_label, loc_label=loc_label, vpad=vpad, extra_features=ef, glyphstyle=glyphstyle, glyphcolor=glyphcolor, ) self.rr.append(r) # Use tid and accn to store gene positions gg.update(dict(((i, k), v) for k, v in r.gg.items())) ymids.append(r.y) def offset(samearc): if samearc == "above": return 2 * pad if samearc == "above2": return 4 * pad if samearc == "below": return -2 * pad if samearc == "below2": return -4 * pad for i, j, blockcolor, samearc in lo.edges: for ga, gb, h in bf.iter_pairs(i, j): a, b = gg[(i, ga)], gg[(j, gb)] if samearc is not None: ymid = ymids[i] + offset(samearc) else: ymid = (ymids[i] + ymids[j]) / 2 Shade(root, a, b, ymid, fc=blockcolor, lw=0, alpha=1, style=shadestyle) for ga, gb, h in bf.iter_pairs(i, j, highlight=True): a, b = gg[(i, ga)], gg[(j, gb)] if samearc is not None: ymid = ymids[i] + offset(samearc) else: ymid = (ymids[i] + ymids[j]) / 2 Shade( root, a, b, ymid, alpha=1, highlight=h, zorder=2, style=shadestyle ) if scalebar: print("Build scalebar (scale={})".format(scale), file=sys.stderr) # Find the best length of the scalebar ar = [1, 2, 5] candidates = ( [1000 * x for x in ar] + [10000 * x for x in ar] + [100000 * x for x in ar] ) # Find the one that's close to an optimal canvas size dists = [(abs(x / scale - 0.12), x) for x in candidates] dist, candidate = min(dists) dist = candidate / scale x, y, yp = 0.22, 0.92, 0.005 a, b = x - dist / 2, x + dist / 2 lsg = "lightslategrey" root.plot([a, a], [y - yp, y + yp], "-", lw=2, color=lsg) root.plot([b, b], [y - yp, y + yp], "-", lw=2, color=lsg) root.plot([a, b], [y, y], "-", lw=2, color=lsg) root.text( x, y + 0.02, human_size(candidate, precision=0), ha="center", va="center", ) if tree: from jcvi.graphics.tree import draw_tree, read_trees trees = read_trees(tree) ntrees = len(trees) logging.debug("A total of {0} trees imported.".format(ntrees)) xiv = 1.0 / ntrees yiv = 0.3 xstart = 0 ystart = min(ymids) - 0.4 for i in range(ntrees): ax = fig.add_axes([xstart, ystart, xiv, yiv]) label, outgroup, color, tx = trees[i] draw_tree( ax, tx, outgroup=outgroup, rmargin=0.4, leaffont=11, treecolor=color, supportcolor=color, leafcolor=color, ) xstart += xiv RoundLabel(ax, 0.5, 0.3, label, fill=True, fc="lavender", color=color)
def phylogeny(args): """ %prog phylogeny treefile ks.layout Create a composite figure with (A) tree and (B) ks. """ from jcvi.graphics.tree import parse_tree, LeafInfoFile, WGDInfoFile, draw_tree p = OptionParser(phylogeny.__doc__) opts, args, iopts = p.set_image_options(args, figsize="10x12") (datafile, layoutfile) = args logging.debug("Load tree file `{0}`".format(datafile)) t, hpd = parse_tree(datafile) fig = plt.figure(1, (iopts.w, iopts.h)) root = fig.add_axes([0, 0, 1, 1]) ax1 = fig.add_axes([0, 0.4, 1, 0.6]) ax2 = fig.add_axes([0.12, 0.065, 0.8, 0.3]) margin, rmargin = 0.1, 0.2 # Left and right margin leafinfo = LeafInfoFile("leafinfo.csv").cache wgdinfo = WGDInfoFile("wgdinfo.csv").cache outgroup = "ginkgo" # Panel A draw_tree( ax1, t, hpd=hpd, margin=margin, rmargin=rmargin, supportcolor=None, internal=False, outgroup=outgroup, reroot=False, leafinfo=leafinfo, wgdinfo=wgdinfo, geoscale=True, ) from jcvi.apps.ks import Layout, KsPlot, KsFile # Panel B ks_min = 0.0 ks_max = 3.0 bins = 60 fill = False layout = Layout(layoutfile) print(layout, file=sys.stderr) kp = KsPlot(ax2, ks_max, bins, legendp="upper right") for lo in layout: data = KsFile(lo.ksfile) data = [x.ng_ks for x in data] data = [x for x in data if ks_min <= x <= ks_max] kp.add_data( data, lo.components, label=lo.label, color=lo.color, marker=lo.marker, fill=fill, fitted=False, kde=True, ) kp.draw(filename=None) normalize_axes([root, ax1]) labels = ((0.05, 0.95, "A"), (0.05, 0.4, "B")) panel_labels(root, labels) image_name = "phylogeny.pdf" savefig(image_name, dpi=iopts.dpi, iopts=iopts)
def __init__(self, fig, root, datafile, bedfile, layoutfile, switch=None, tree=None, extra_features=None, chr_label=True, loc_label=True, pad=.04): w, h = fig.get_figwidth(), fig.get_figheight() bed = Bed(bedfile) order = bed.order bf = BlockFile(datafile) self.layout = lo = Layout(layoutfile) switch = DictFile(switch, delimiter="\t") if switch else None if extra_features: extra_features = Bed(extra_features) exts = [] extras = [] for i in xrange(bf.ncols): ext = bf.get_extent(i, order) exts.append(ext) if extra_features: start, end, si, ei, chr, orientation, span = ext start, end = start.start, end.end # start, end coordinates ef = list(extra_features.extract(chr, start, end)) # Pruning removes minor features with < 0.1% of the region ef_pruned = [x for x in ef if x.span >= span / 1000] print >> sys.stderr, "Extracted {0} features "\ "({1} after pruning)".format(len(ef), len(ef_pruned)) extras.append(ef_pruned) maxspan = max(exts, key=lambda x: x[-1])[-1] scale = maxspan / .65 self.gg = gg = {} self.rr = [] ymids = [] vpad = .012 * w / h for i in xrange(bf.ncols): ext = exts[i] ef = extras[i] if extras else None r = Region(root, ext, lo[i], bed, scale, switch, chr_label=chr_label, loc_label=loc_label, vpad=vpad, extra_features=ef) self.rr.append(r) # Use tid and accn to store gene positions gg.update(dict(((i, k), v) for k, v in r.gg.items())) ymids.append(r.y) for i, j in lo.edges: for ga, gb, h in bf.iter_pairs(i, j): a, b = gg[(i, ga)], gg[(j, gb)] ymid = (ymids[i] + ymids[j]) / 2 Shade(root, a, b, ymid, fc="gainsboro", lw=0, alpha=1) for ga, gb, h in bf.iter_pairs(i, j, highlight=True): a, b = gg[(i, ga)], gg[(j, gb)] ymid = (ymids[i] + ymids[j]) / 2 Shade(root, a, b, ymid, alpha=1, highlight=h, zorder=2) if tree: from jcvi.graphics.tree import draw_tree, read_trees trees = read_trees(tree) ntrees = len(trees) logging.debug("A total of {0} trees imported.".format(ntrees)) xiv = 1. / ntrees yiv = .3 xstart = 0 ystart = min(ymids) - .4 for i in xrange(ntrees): ax = fig.add_axes([xstart, ystart, xiv, yiv]) label, outgroup, tx = trees[i] draw_tree(ax, tx, outgroup=outgroup, rmargin=.4, leaffont=11) xstart += xiv RoundLabel(ax, .5, .3, label, fill=True, fc="lavender", color="r")
def __init__(self, fig, root, datafile, bedfile, layoutfile, switch=None, tree=None, extra_features=None, chr_label=True, pad=.04): w, h = fig.get_figwidth(), fig.get_figheight() bed = Bed(bedfile) order = bed.order bf = BlockFile(datafile) lo = Layout(layoutfile) switch = DictFile(switch, delimiter="\t") if switch else None if extra_features: extra_features = Bed(extra_features) exts = [] extras = [] for i in xrange(bf.ncols): ext = bf.get_extent(i, order) exts.append(ext) if extra_features: start, end, si, ei, chr, orientation, span = ext start, end = start.start, end.end # start, end coordinates ef = list(extra_features.extract(chr, start, end)) # Pruning removes minor features with < 0.1% of the region ef_pruned = [x for x in ef if x.span >= span / 1000] print >> sys.stderr, "Extracted {0} features "\ "({1} after pruning)".format(len(ef), len(ef_pruned)) extras.append(ef_pruned) maxspan = max(exts, key=lambda x: x[-1])[-1] scale = maxspan / .65 self.gg = gg = {} self.rr = [] ymids = [] vpad = .012 * w / h for i in xrange(bf.ncols): ext = exts[i] ef = extras[i] if extras else None r = Region(root, ext, lo[i], bed, scale, switch, chr_label=chr_label, vpad=vpad, extra_features=ef) self.rr.append(r) # Use tid and accn to store gene positions gg.update(dict(((i, k), v) for k, v in r.gg.items())) ymids.append(r.y) for i, j in lo.edges: for ga, gb, h in bf.iter_pairs(i, j): a, b = gg[(i, ga)], gg[(j, gb)] ymid = (ymids[i] + ymids[j]) / 2 Shade(root, a, b, ymid, fc="gainsboro", lw=0, alpha=1) for ga, gb, h in bf.iter_pairs(i, j, highlight=True): a, b = gg[(i, ga)], gg[(j, gb)] ymid = (ymids[i] + ymids[j]) / 2 Shade(root, a, b, ymid, alpha=1, highlight=h, zorder=2) if tree: from jcvi.graphics.tree import draw_tree, read_trees trees = read_trees(tree) ntrees = len(trees) logging.debug("A total of {0} trees imported.".format(ntrees)) xiv = 1. / ntrees yiv = .3 xstart = 0 ystart = min(ymids) - .4 for i in xrange(ntrees): ax = fig.add_axes([xstart, ystart, xiv, yiv]) label, outgroup, tx = trees[i] draw_tree(ax, tx, outgroup=outgroup, rmargin=.4) xstart += xiv RoundLabel(ax, .5, .3, label, fill=True, fc="lavender", color="r")
def waterlilyGOM(args): """ %prog mcmctree.tre table.csv Customized figure to plot phylogeny and related infographics. """ from jcvi.graphics.tree import ( LeafInfoFile, WGDInfoFile, draw_tree, parse_tree, draw_wgd_xy, ) from jcvi.graphics.table import CsvTable, draw_table p = OptionParser(waterlilyGOM.__doc__) opts, args, iopts = p.set_image_options(args, figsize="12x9") if len(args) != 2: sys.exit(not p.print_help()) (datafile, csvfile) = args outgroup = ["ginkgo"] logging.debug("Load tree file `{0}`".format(datafile)) t, hpd = parse_tree(datafile) pf = datafile.rsplit(".", 1)[0] fig = plt.figure(1, (iopts.w, iopts.h)) root = fig.add_axes([0, 0, 1, 1]) margin, rmargin = 0.15, 0.19 # Left and right margin leafinfo = LeafInfoFile("leafinfo.csv").cache wgdinfo = WGDInfoFile("wgdinfo.csv").cache groups = "Monocots,Eudicots,ANA-grade,Gymnosperms" draw_tree( root, t, hpd=hpd, margin=margin, rmargin=rmargin, supportcolor=None, internal=False, outgroup=outgroup, leafinfo=leafinfo, wgdinfo=wgdinfo, geoscale=True, groups=groups.split(","), ) # Bottom right show legends for the WGD circles pad = 0.02 ypad = 0.04 xstart = 1 - rmargin + pad ystart = 0.2 waterlily_wgdline = wgdinfo["waterlily"][0] ypos = ystart - 2 * ypad draw_wgd_xy(root, xstart, ypos, waterlily_wgdline) root.text( xstart + pad, ypos, "Nymphaealean WGD", color=waterlily_wgdline.color, va="center", ) other_wgdline = wgdinfo["banana"][0] ypos = ystart - 3 * ypad draw_wgd_xy(root, xstart, ypos, other_wgdline) root.text( xstart + pad, ypos, "Other known WGDs", color=other_wgdline.color, va="center", ) # Top left draw the comparison table csv_table = CsvTable(csvfile) draw_table( root, csv_table, extent=(0.02, 0.44, 0.55, 0.985), stripe_color="lavender", yinflation=iopts.w / iopts.h, ) normalize_axes(root) image_name = pf + "." + iopts.format savefig(image_name, dpi=iopts.dpi, iopts=iopts)
def __init__(self, fig, root, datafile, bedfile, layoutfile, switch=None, tree=None, extra_features=None, chr_label=True, loc_label=True, pad=.04, scalebar=False): w, h = fig.get_figwidth(), fig.get_figheight() bed = Bed(bedfile) order = bed.order bf = BlockFile(datafile) self.layout = lo = Layout(layoutfile) switch = DictFile(switch, delimiter="\t") if switch else None if extra_features: extra_features = Bed(extra_features) exts = [] extras = [] for i in xrange(bf.ncols): ext = bf.get_extent(i, order) exts.append(ext) if extra_features: start, end, si, ei, chr, orientation, span = ext start, end = start.start, end.end # start, end coordinates ef = list(extra_features.extract(chr, start, end)) # Pruning removes minor features with < 0.1% of the region ef_pruned = [x for x in ef if x.span >= span / 1000] print >> sys.stderr, "Extracted {0} features "\ "({1} after pruning)".format(len(ef), len(ef_pruned)) extras.append(ef_pruned) maxspan = max(exts, key=lambda x: x[-1])[-1] scale = maxspan / .65 self.gg = gg = {} self.rr = [] ymids = [] vpad = .012 * w / h for i in xrange(bf.ncols): ext = exts[i] ef = extras[i] if extras else None r = Region(root, ext, lo[i], bed, scale, switch, chr_label=chr_label, loc_label=loc_label, vpad=vpad, extra_features=ef) self.rr.append(r) # Use tid and accn to store gene positions gg.update(dict(((i, k), v) for k, v in r.gg.items())) ymids.append(r.y) for i, j in lo.edges: for ga, gb, h in bf.iter_pairs(i, j): a, b = gg[(i, ga)], gg[(j, gb)] ymid = (ymids[i] + ymids[j]) / 2 Shade(root, a, b, ymid, fc="gainsboro", lw=0, alpha=1) for ga, gb, h in bf.iter_pairs(i, j, highlight=True): a, b = gg[(i, ga)], gg[(j, gb)] ymid = (ymids[i] + ymids[j]) / 2 Shade(root, a, b, ymid, alpha=1, highlight=h, zorder=2) if scalebar: print >> sys.stderr, "Build scalebar (scale={})".format(scale) # Find the best length of the scalebar ar = [1, 2, 5] candidates = [1000 * x for x in ar] + [10000 * x for x in ar] + \ [100000 * x for x in ar] # Find the one that's close to an optimal canvas size dists = [(abs(x / scale - .12), x) for x in candidates] dist, candidate = min(dists) dist = candidate / scale x, y, yp = .2, .96, .005 a, b = x - dist / 2, x + dist / 2 lsg = "lightslategrey" root.plot([a, a], [y - yp, y + yp], "-", lw=2, color=lsg) root.plot([b, b], [y - yp, y + yp], "-", lw=2, color=lsg) root.plot([a, b], [y, y], "-", lw=2, color=lsg) root.text(x, y + .02, human_size(candidate, precision=0), ha="center", va="center") if tree: from jcvi.graphics.tree import draw_tree, read_trees trees = read_trees(tree) ntrees = len(trees) logging.debug("A total of {0} trees imported.".format(ntrees)) xiv = 1. / ntrees yiv = .3 xstart = 0 ystart = min(ymids) - .4 for i in xrange(ntrees): ax = fig.add_axes([xstart, ystart, xiv, yiv]) label, outgroup, tx = trees[i] draw_tree(ax, tx, outgroup=outgroup, rmargin=.4, leaffont=11) xstart += xiv RoundLabel(ax, .5, .3, label, fill=True, fc="lavender", color="r")
def cotton(args): """ %prog cotton seqids karyotype.layout mcscan.out all.bed synteny.layout Build a composite figure that calls graphics.karyotype and graphic.synteny. """ from jcvi.graphics.tree import draw_tree, read_trees p = OptionParser(cotton.__doc__) p.add_option("--depthfile", help="Use depth info in this file [default: %default]") p.add_option("--tree", help="Display trees on the bottom of the figure [default: %default]") p.add_option("--switch", help="Rename the seqid with two-column file [default: %default]") opts, args, iopts = p.set_image_options(args, figsize="8x7") if len(args) != 5: sys.exit(p.print_help()) seqidsfile, klayout, datafile, bedfile, slayout = args switch = opts.switch tree = opts.tree depthfile = opts.depthfile fig = plt.figure(1, (iopts.w, iopts.h)) root = fig.add_axes([0, 0, 1, 1]) kt = Karyotype(fig, root, seqidsfile, klayout) Synteny(fig, root, datafile, bedfile, slayout, switch=switch) light = "lightslategrey" # Show the dup depth along the cotton chromosomes if depthfile: ymin, ymax = .9, .95 root.text(.11, .96, "Cotton duplication level", color="gray", size=10) root.plot([.1, .95], [ymin, ymin], color="gray") root.text(.96, .9, "1x", color="gray", va="center") root.plot([.1, .95], [ymax, ymax], color="gray") root.text(.96, .95, "6x", color="gray", va="center") fp = open(depthfile) track = kt.tracks[0] # Cotton depths = [] for row in fp: a, b, depth = row.split() depth = int(depth) try: p = track.get_coords(a) depths.append((p, depth)) except KeyError: pass depths.sort(key=lambda x: (x[0], -x[1])) xx, yy = zip(*depths) yy = [ymin + .01 * (x - 1) for x in yy] root.plot(xx, yy, "-", color=light) # legend showing the orientation of the genes draw_gene_legend(root, .5, .68, .5) # Zoom xpos = .835 ytop = .9 xmin, xmax = .18, .82 ymin, ymax = ytop, .55 lc = "k" kwargs = dict(lw=3, color=lc, mec=lc, mfc="w", zorder=3) root.plot((xpos, xpos), (ymax, .63), ":o", **kwargs) root.plot((xpos, xmin), (ymax, ymin), ":o", **kwargs) root.plot((xpos, xmax), (ymax, ymin), ":o", **kwargs) RoundRect(root, (.06, .17), .92, .35, fill=False, lw=2, ec=light) # Panels root.text(.05, .95, "a", size=20, fontweight="bold") root.text(.1, .45, "b", size=20, fontweight="bold") if tree: panel3 = fig.add_axes([.65, .05, .35, .35]) trees = read_trees(tree) label, outgroup, tx = trees[0] draw_tree(panel3, tx, outgroup=outgroup, rmargin=.4, leafcolor="r") panel3.set_xlim(0, 1) panel3.set_ylim(0, 1) panel3.set_axis_off() root.set_xlim(0, 1) root.set_ylim(0, 1) root.set_axis_off() pf = "cotton" image_name = pf + "." + iopts.format savefig(image_name, dpi=iopts.dpi, iopts=iopts)