def draw(self, roundrect=False, plot_label=True): if self.empty: return y = self.y color = self.color ax = self.ax xstart = self.xstart gap = self.gap va = self.va nseqids = len(self.seqids) tr = self.tr for i, sid in enumerate(self.seqids): size = self.sizes[sid] rsize = self.ratio * size xend = xstart + rsize hc = HorizontalChromosome(ax, xstart, xend, y, height=self.height, lw=self.lw, fc=color, roundrect=roundrect) hc.set_transform(tr) sid = sid.rsplit("_", 1)[-1] si = "".join(x for x in sid if x not in string.letters) si = str(int(si)) xx = (xstart + xend) / 2 xstart = xend + gap if nseqids > 2 * MaxSeqids and (i + 1) % 10 != 0: continue if nseqids < 5: continue pad = .02 if va == "bottom": pad = -pad TextCircle(ax, xx, y + pad, si, radius=.01, fc="w", color=color, size=10, transform=tr) xp = min(self.xstart / 2, .1) if (self.xstart + self.xend) / 2 <= .5 \ else max(1 - self.end / 2, .92) label = markup(self.label) c = color if color != "gainsboro" else "k" if plot_label: ax.text(xp, y + self.height * .6, label, ha="center", color=c, transform=tr)
def draw(self, roundrect=False, plot_label=True, plot_circles=True, pad=.03, vpad=.09): if self.empty: return y = self.y color = self.color ax = self.ax xstart = self.xstart gap = self.gap va = self.va nseqids = len(self.seqids) tr = self.tr def make_circle_name(sid): sid = sid.rsplit("_", 1)[-1] si = "".join(x for x in sid if x in string.digits) si = str(int(si)) if sid in self.rev: si += '-' return si for i, sid in enumerate(self.seqids): size = self.sizes[sid] rsize = self.ratio * size xend = xstart + rsize hc = HorizontalChromosome(ax, xstart, xend, y, height=self.height, lw=self.lw, fc=color, roundrect=roundrect) hc.set_transform(tr) si = make_circle_name(sid) xx = (xstart + xend) / 2 xstart = xend + gap step = 2 if nseqids <= 40 else 10 if nseqids >= 2 * MaxSeqids and (i + 1) % step != 0: continue if nseqids < 5: continue hpad = -pad if va == "bottom" else pad if plot_circles: TextCircle(ax, xx, y + hpad, si, radius=.01, fc="w", color=color, size=10, transform=tr) label = markup(self.label) c = color if color != "gainsboro" else "k" if plot_label: if self.label_va == "top": x, y = self.x, self.y + vpad elif self.label_va == "bottom": x, y = self.x, self.y - vpad else: # "center" x, y = self.xstart - vpad, self.y ax.text(x, y, label, ha="center", va="center", color=c, transform=tr)
def draw(self, width=0.03): HorizontalChromosome( self.ax, self.xpad, 1 - self.xpad, self.ypad - 0.05, height=width * 1.5, patch=self.apatch, lw=2, ) Chromosome( self.ax, self.xpad - 0.05, self.ypad, 1 - self.ypad, width=width, patch=self.bpatch, patchcolor=self.bpatchcolor, lw=2, ) for a, b in zip(self.a, self.b): self.sax.plot(a, b, "-", color="darkslategrey", lw=2) self.sax.set_xticklabels([]) self.sax.set_yticklabels([]) self.sax.set_xlim((1, self.amax)) self.sax.set_ylim((1, self.bmax)) normalize_axes(self.ax)
def draw(self, roundrect=False, plot_label=True): if self.empty: return y = self.y color = self.color ax = self.ax xstart = self.xstart gap = self.gap va = self.va nseqids = len(self.seqids) tr = self.tr for i, sid in enumerate(self.seqids): size = self.sizes[sid] rsize = self.ratio * size xend = xstart + rsize hc = HorizontalChromosome(ax, xstart, xend, y, height=self.height, lw=self.lw, fc=color, roundrect=roundrect) hc.set_transform(tr) sid = sid.rsplit("_", 1)[-1] si = "".join(x for x in sid if x not in string.letters) si = str(int(si)) xx = (xstart + xend) / 2 xstart = xend + gap if nseqids > 2 * MaxSeqids and (i + 1) % 10 != 0: continue if nseqids < 5: continue pad = .02 if va == "bottom": pad = - pad TextCircle(ax, xx, y + pad, si, radius=.01, fc="w", color=color, size=10, transform=tr) xp = min(self.xstart / 2, .1) if (self.xstart + self.xend) / 2 <= .5 \ else max(1 - self.xend / 2, .92) label = markup(self.label) c = color if color != "gainsboro" else "k" if plot_label: ax.text(xp, y + self.height * .6, label, ha="center", color=c, transform=tr)
def draw(self, width=.03): HorizontalChromosome(self.ax, self.xpad, 1 - self.xpad, self.ypad - width / 2, height=width * 1.5, patch=self.apatch, lw=2) for r in self.reads: r.draw(self.sax) self.sax.set_xlim((1, self.amax)) self.sax.set_ylim((-1, self.ymax)) normalize_axes(self.ax) self.sax.set_axis_off()
def lms(args): """ %prog lms ALLMAPS cartoon to illustrate LMS metric. """ from random import randint from jcvi.graphics.chromosome import HorizontalChromosome p = OptionParser(lms.__doc__) opts, args, iopts = p.set_image_options(args, figsize="6x6", dpi=300) fig = plt.figure(1, (iopts.w, iopts.h)) root = fig.add_axes([0, 0, 1, 1]) # Panel A w, h = 0.7, 0.35 ax = fig.add_axes([0.15, 0.6, w, h]) xdata = [x + randint(-3, 3) for x in range(10, 110, 10)] ydata = [x + randint(-3, 3) for x in range(10, 110, 10)] ydata[3:7] = ydata[3:7][::-1] xydata = zip(xdata, ydata) lis = xydata[:3] + [xydata[4]] + xydata[7:] lds = xydata[3:7] xlis, ylis = zip(*lis) xlds, ylds = zip(*lds) ax.plot( xlis, ylis, "r-", lw=12, alpha=0.3, solid_capstyle="round", solid_joinstyle="round", ) ax.plot( xlds, ylds, "g-", lw=12, alpha=0.3, solid_capstyle="round", solid_joinstyle="round", ) ax.plot(xdata, ydata, "k.", mec="k", mfc="w", mew=3, ms=12) HorizontalChromosome(root, 0.15, 0.15 + w, 0.57, height=0.02, lw=2) root.text(0.15 + w / 2, 0.55, "Chromosome location (bp)", ha="center", va="top") ax.text(80, 30, "LIS = 7", color="r", ha="center", va="center") ax.text(80, 20, "LDS = 4", color="g", ha="center", va="center") ax.text(80, 10, "LMS = $max$(LIS, LDS) = 7", ha="center", va="center") normalize_lms_axis(ax, xlim=110, ylim=110) # Panel B w = 0.37 p = (0, 45, 75, 110) ax = fig.add_axes([0.1, 0.12, w, h]) xdata = [x for x in range(10, 110, 10)] ydata = ydata_orig = [x for x in range(10, 110, 10)] ydata = ydata[:4] + ydata[7:] + ydata[4:7][::-1] xydata = zip(xdata, ydata) lis = xydata[:7] xlis, ylis = zip(*lis) ax.plot( xlis, ylis, "r-", lw=12, alpha=0.3, solid_capstyle="round", solid_joinstyle="round", ) ax.plot(xdata, ydata, "k.", mec="k", mfc="w", mew=3, ms=12) ax.vlines(p, 0, 110, colors="beige", lw=3) normalize_lms_axis(ax, xlim=110, ylim=110) patch = [0.1 + w * x / 110.0 for x in p] HorizontalChromosome(root, 0.1, 0.1 + w, 0.09, patch=patch, height=0.02, lw=2) scaffolds = ("a", "b", "c") for i, s in enumerate(scaffolds): xx = (patch[i] + patch[i + 1]) / 2 root.text(xx, 0.09, s, va="center", ha="center") root.text(0.1 + w / 2, 0.04, "LMS($a||b||c$) = 7", ha="center") # Panel C ax = fig.add_axes([0.6, 0.12, w, h]) patch = [0.6 + w * x / 110.0 for x in p] ydata = ydata_orig ax.plot( xdata, ydata, "r-", lw=12, alpha=0.3, solid_capstyle="round", solid_joinstyle="round", ) ax.plot(xdata, ydata, "k.", mec="k", mfc="w", mew=3, ms=12) ax.vlines(p, [0], [110], colors="beige", lw=3) normalize_lms_axis(ax, xlim=110, ylim=110) HorizontalChromosome(root, 0.6, 0.6 + w, 0.09, patch=patch, height=0.02, lw=2) scaffolds = ("a", "-c", "b") for i, s in enumerate(scaffolds): xx = (patch[i] + patch[i + 1]) / 2 root.text(xx, 0.09, s, va="center", ha="center") root.text(0.6 + w / 2, 0.04, "LMS($a||-c||b$) = 10", ha="center") labels = ((0.05, 0.95, "A"), (0.05, 0.48, "B"), (0.55, 0.48, "C")) panel_labels(root, labels) normalize_axes(root) pf = "lms" image_name = pf + "." + iopts.format savefig(image_name, dpi=iopts.dpi, iopts=iopts)
def estimategaps(args): """ %prog estimategaps JM-4 chr1 JMMale-1 Illustrate ALLMAPS gap estimation algorithm. """ p = OptionParser(estimategaps.__doc__) opts, args, iopts = p.set_image_options(args, figsize="6x6", dpi=300) if len(args) != 3: sys.exit(not p.print_help()) pf, seqid, mlg = args bedfile = pf + ".lifted.bed" agpfile = pf + ".agp" function = lambda x: x.cm cc = Map(bedfile, scaffold_info=True, function=function) agp = AGP(agpfile) g = GapEstimator(cc, agp, seqid, mlg, function=function) pp, chrsize, mlgsize = g.pp, g.chrsize, g.mlgsize spl, spld = g.spl, g.spld g.compute_all_gaps(verbose=False) fig = plt.figure(1, (iopts.w, iopts.h)) root = fig.add_axes([0, 0, 1, 1]) # Panel A xstart, ystart = 0.15, 0.65 w, h = 0.7, 0.3 t = np.linspace(0, chrsize, 1000) ax = fig.add_axes([xstart, ystart, w, h]) mx, my = zip(*g.scatter_data) rho = spearmanr(mx, my) dsg = "g" ax.vlines(pp, 0, mlgsize, colors="beige") ax.plot(mx, my, ".", color=set2[3]) ax.plot(t, spl(t), "-", color=dsg) ax.text(0.05, 0.95, mlg, va="top", transform=ax.transAxes) normalize_lms_axis(ax, xlim=chrsize, ylim=mlgsize, ylabel="Genetic distance (cM)") if rho < 0: ax.invert_yaxis() # Panel B ystart -= 0.28 h = 0.25 ax = fig.add_axes([xstart, ystart, w, h]) ax.vlines(pp, 0, mlgsize, colors="beige") ax.plot(t, spld(t), "-", lw=2, color=dsg) ax.plot(pp, spld(pp), "o", mfc="w", mec=dsg, ms=5) normalize_lms_axis( ax, xlim=chrsize, ylim=25 * 1e-6, xfactor=1e-6, xlabel="Physical position (Mb)", yfactor=1000000, ylabel="Recomb. rate\n(cM / Mb)", ) ax.xaxis.grid(False) # Panel C (specific to JMMale-1) a, b = "scaffold_1076", "scaffold_861" sizes = dict( (x.component_id, (x.object_beg, x.object_end, x.component_span, x.orientation)) for x in g.agp if not x.is_gap ) a_beg, a_end, asize, ao = sizes[a] b_beg, b_end, bsize, bo = sizes[b] gapsize = g.get_gapsize(a) total_size = asize + gapsize + bsize ratio = 0.6 / total_size y = 0.16 pad = 0.03 pb_ratio = w / chrsize # Zoom lsg = "lightslategray" root.plot((0.15 + pb_ratio * a_beg, 0.2), (ystart, ystart - 0.14), ":", color=lsg) root.plot((0.15 + pb_ratio * b_end, 0.3), (ystart, ystart - 0.08), ":", color=lsg) ends = [] for tag, size, marker, beg in zip( (a, b), (asize, bsize), (49213, 81277), (0.2, 0.2 + (asize + gapsize) * ratio) ): end = beg + size * ratio marker = beg + marker * ratio ends.append((beg, end, marker)) root.plot((marker,), (y,), "o", color=lsg) root.text((beg + end) / 2, y + pad, latex(tag), ha="center", va="center") HorizontalChromosome(root, beg, end, y, height=0.025, fc="gainsboro") begs, ends, markers = zip(*ends) fontprop = dict(color=lsg, ha="center", va="center") ypos = y + pad * 2 root.plot(markers, (ypos, ypos), "-", lw=2, color=lsg) root.text( sum(markers) / 2, ypos + pad, "Distance: 1.29cM $\Leftrightarrow$ 211,824bp (6.1 cM/Mb)", **fontprop ) ypos = y - pad xx = markers[0], ends[0] root.plot(xx, (ypos, ypos), "-", lw=2, color=lsg) root.text(sum(xx) / 2, ypos - pad, "34,115bp", **fontprop) xx = markers[1], begs[1] root.plot(xx, (ypos, ypos), "-", lw=2, color=lsg) root.text(sum(xx) / 2, ypos - pad, "81,276bp", **fontprop) root.plot((ends[0], begs[1]), (y, y), ":", lw=2, color=lsg) root.text( sum(markers) / 2, ypos - 3 * pad, r"$\textit{Estimated gap size: 96,433bp}$", color="r", ha="center", va="center", ) labels = ((0.05, 0.95, "A"), (0.05, 0.6, "B"), (0.05, 0.27, "C")) panel_labels(root, labels) normalize_axes(root) pf = "estimategaps" image_name = pf + "." + iopts.format savefig(image_name, dpi=iopts.dpi, iopts=iopts)
def deletion(args): """ %prog deletion [deletion-genes|deletion-bases] C2-deletions boleracea.bed Plot histogram for napus deletions. Can plot deletion-genes or deletion-bases. The three largest segmental deletions will be highlighted along with a drawing of the C2 chromosome. """ import math from jcvi.formats.bed import Bed from jcvi.graphics.chromosome import HorizontalChromosome from jcvi.graphics.base import kb_formatter p = OptionParser(deletion.__doc__) opts, args, iopts = p.set_image_options(args) if len(args) != 3: sys.exit(not p.print_help()) deletion_genes, deletions, bed = args dg = [int(x) for x in open(deletion_genes)] dsg, lsg = "darkslategray", "lightslategray" fig = plt.figure(1, (iopts.w, iopts.h)) root = fig.add_axes([0, 0, 1, 1]) ax = fig.add_axes([.1, .1, .8, .8]) minval = 2 if deletion_genes == "deleted-genes" else 2048 bins = np.logspace(math.log(minval, 10), math.log(max(dg), 10), 16) n, bins, histpatches = ax.hist(dg, bins=bins, \ fc=lsg, alpha=.75) ax.set_xscale('log', basex=2) if deletion_genes == "deleted-genes": ax.xaxis.set_major_formatter(mpl.ticker.FormatStrFormatter('%d')) ax.set_xlabel('No. of deleted genes in each segment') else: ax.xaxis.set_major_formatter(kb_formatter) ax.set_xlabel('No. of deleted bases in each segment') ax.yaxis.set_major_formatter(mpl.ticker.FormatStrFormatter('%d')) ax.set_ylabel('No. of segments') ax.patch.set_alpha(0.1) # Draw chromosome C2 na, nb = .45, .85 root.text((na + nb) / 2, .54, "ChrC02", ha="center") HorizontalChromosome(root, na, nb, .5, height=.025, fc=lsg, fill=True) order = Bed(bed).order fp = open(deletions) scale = lambda x: na + x * (nb - na) / 52886895 for i, row in enumerate(fp): i += 1 num, genes = row.split() genes = genes.split("|") ia, a = order[genes[0]] ib, b = order[genes[-1]] mi, mx = a.start, a.end mi, mx = scale(mi), scale(mx) root.add_patch(Rectangle((mi, .475), mx - mi, .05, fc="red", ec="red")) if i == 1: # offset between two adjacent regions for aesthetics mi -= .015 elif i == 2: mi += .015 TextCircle(root, mi, .44, str(i), fc="red") for i, mi in zip(range(1, 4), (.83, .78, .73)): TextCircle(root, mi, .2, str(i), fc="red") root.set_xlim(0, 1) root.set_ylim(0, 1) root.set_axis_off() image_name = deletion_genes + ".pdf" savefig(image_name, dpi=iopts.dpi, iopts=iopts)
def draw(self, roundrect=False, plot_label=True, pad=.03, vpad=.09): if self.empty: return y = self.y color = self.color ax = self.ax xstart = self.xstart gap = self.gap va = self.va nseqids = len(self.seqids) tr = self.tr for i, sid in enumerate(self.seqids): size = self.sizes[sid] rsize = self.ratio * size xend = xstart + rsize hc = HorizontalChromosome(ax, xstart, xend, y, height=self.height, lw=self.lw, fc=color, roundrect=roundrect) hc.set_transform(tr) sid = sid.rsplit("_", 1)[-1] si = "".join(x for x in sid if x in string.digits) si = str(int(si)) xx = (xstart + xend) / 2 xstart = xend + gap step = 2 if nseqids <= 40 else 10 if nseqids >= 2 * MaxSeqids and (i + 1) % step != 0: continue if nseqids < 5: continue hpad = -pad if va == "bottom" else pad TextCircle(ax, xx, y + hpad, si, radius=.01, fc="w", color=color, size=10, transform=tr) label = markup(self.label) c = color if color != "gainsboro" else "k" if plot_label: if self.label_va == "top": x, y = self.x, self.y + vpad va = "bottom" elif self.label_va == "bottom": x, y = self.x, self.y - vpad va = "top" else: # "center" x, y = self.xstart - vpad, self.y va = "center" ax.text(x, y, label, ha="center", va="center", color=c, transform=tr)
def plot(args): """ %prog plot input.bed seqid Plot the matchings between the reconstructed pseudomolecules and the maps. Two types of visualizations are available in one canvas: 1. Parallel axes, and matching markers are shown in connecting lines; 2. Scatter plot. """ from jcvi.graphics.base import plt, savefig, normalize_axes, \ set2, panel_labels from jcvi.graphics.chromosome import Chromosome, GeneticMap, \ HorizontalChromosome p = OptionParser(plot.__doc__) add_allmaps_plot_options(p) opts, args, iopts = p.set_image_options(args, figsize="10x6") if len(args) != 2: sys.exit(not p.print_help()) inputbed, seqid = args pf = inputbed.rsplit(".", 1)[0] bedfile = pf + ".lifted.bed" agpfile = pf + ".agp" weightsfile = opts.weightsfile links = opts.links function = get_function(opts.distance) cc = Map(bedfile, function) allseqids = cc.seqids mapnames = cc.mapnames weights = Weights(weightsfile, mapnames) assert seqid in allseqids, "{0} not in {1}".format(seqid, allseqids) s = Scaffold(seqid, cc) mlgs = [k for k, v in s.mlg_counts.items() if v >= links] mlgsizes = {} for mlg in mlgs: mm = cc.extract_mlg(mlg) mlgsize = max(function(x) for x in mm) mlgsizes[mlg] = mlgsize fig = plt.figure(1, (iopts.w, iopts.h)) root = fig.add_axes([0, 0, 1, 1]) ax1 = fig.add_axes([0, 0, .5, 1]) ax2 = fig.add_axes([.5, 0, .5, 1]) # Find the layout first ystart, ystop = .9, .1 L = Layout(mlgsizes) coords = L.coords tip = .02 marker_pos = {} # Palette colors = dict((mapname, set2[i]) for i, mapname in enumerate(mapnames)) colors = dict((mlg, colors[mlg.split("-")[0]]) for mlg in mlgs) rhos = {} # Parallel coordinates for mlg, (x, y1, y2) in coords.items(): mm = cc.extract_mlg(mlg) markers = [(m.accn, function(m)) for m in mm] # exhaustive marker list xy = [(m.pos, function(m)) for m in mm if m.seqid == seqid] mx, my = zip(*xy) rho = spearmanr(mx, my) rhos[mlg] = rho flip = rho < 0 g = GeneticMap(ax1, x, y1, y2, markers, tip=tip, flip=flip) extra = -3 * tip if x < .5 else 3 * tip ha = "right" if x < .5 else "left" mapname = mlg.split("-")[0] tlg = mlg.replace("_", ".") # Latex does not like underscore char label = "{0} (w={1})".format(tlg, weights[mapname]) ax1.text(x + extra, (y1 + y2) / 2, label, color=colors[mlg], ha=ha, va="center", rotation=90) marker_pos.update(g.marker_pos) agp = AGP(agpfile) agp = [x for x in agp if x.object == seqid] chrsize = max(x.object_end for x in agp) # Pseudomolecules in the center r = ystart - ystop ratio = r / chrsize f = lambda x: (ystart - ratio * x) patchstart = [f(x.object_beg) for x in agp if not x.is_gap] Chromosome(ax1, .5, ystart, ystop, width=2 * tip, patch=patchstart, lw=2) label = "{0} ({1})".format(seqid, human_size(chrsize, precision=0)) ax1.text(.5, ystart + tip, label, ha="center") scatter_data = defaultdict(list) # Connecting lines for b in s.markers: marker_name = b.accn if marker_name not in marker_pos: continue cx = .5 cy = f(b.pos) mx = coords[b.mlg][0] my = marker_pos[marker_name] extra = -tip if mx < cx else tip extra *= 1.25 # leave boundaries for aesthetic reasons cx += extra mx -= extra ax1.plot((cx, mx), (cy, my), "-", color=colors[b.mlg]) scatter_data[b.mlg].append((b.pos, function(b))) # Scatter plot, same data as parallel coordinates xstart, xstop = sorted((ystart, ystop)) f = lambda x: (xstart + ratio * x) pp = [x.object_beg for x in agp if not x.is_gap] patchstart = [f(x) for x in pp] HorizontalChromosome(ax2, xstart, xstop, ystop, height=2 * tip, patch=patchstart, lw=2) gap = .03 ratio = (r - gap * len(mlgs) - tip) / sum(mlgsizes.values()) tlgs = [] for mlg, mlgsize in sorted(mlgsizes.items()): height = ratio * mlgsize ystart -= height xx = .5 + xstart / 2 width = r / 2 color = colors[mlg] ax = fig.add_axes([xx, ystart, width, height]) ypos = ystart + height / 2 ystart -= gap sd = scatter_data[mlg] xx, yy = zip(*sd) ax.vlines(pp, 0, mlgsize, colors="beige") ax.plot(xx, yy, ".", color=color) rho = rhos[mlg] ax.text(.5, 1 - .4 * gap / height, r"$\rho$={0:.3f}".format(rho), ha="center", va="top", transform=ax.transAxes, color="gray") tlg = mlg.replace("_", ".") tlgs.append((tlg, ypos, color)) ax.set_xlim(0, chrsize) ax.set_ylim(0, mlgsize) ax.set_xticks([]) while height / len(ax.get_yticks()) < .03 and len( ax.get_yticks()) >= 2: ax.set_yticks(ax.get_yticks()[::2]) # Sparsify the ticks yticklabels = [int(x) for x in ax.get_yticks()] ax.set_yticklabels(yticklabels, family='Helvetica') if rho < 0: ax.invert_yaxis() for i, (tlg, ypos, color) in enumerate(tlgs): ha = "center" if len(tlgs) > 4: ha = "right" if i % 2 else "left" root.text(.5, ypos, tlg, color=color, rotation=90, ha=ha, va="center") if opts.panels: labels = ((.04, .96, 'A'), (.48, .96, 'B')) panel_labels(root, labels) normalize_axes((ax1, ax2, root)) image_name = seqid + "." + iopts.format savefig(image_name, dpi=iopts.dpi, iopts=iopts) plt.close(fig)
def composite(args): """ %prog composite fastafile chr1 Combine line plots, feature bars and alt-bars, different data types specified in options. Inputs must be BED-formatted. Three types of viz are currently supported: --lines: traditional line plots, useful for plotting feature freq --bars: show where the extent of features are --altbars: similar to bars, yet in two alternating tracks, e.g. scaffolds """ from jcvi.graphics.chromosome import HorizontalChromosome p = OptionParser(composite.__doc__) p.add_option("--lines", help="Features to plot in lineplot") p.add_option("--bars", help="Features to plot in bars") p.add_option("--altbars", help="Features to plot in alt-bars") p.add_option( "--fatten", default=False, action="store_true", help="Help visualize certain narrow features", ) p.add_option( "--mode", default="span", choices=("span", "count", "score"), help="Accumulate feature based on", ) add_window_options(p) opts, args, iopts = p.set_image_options(args, figsize="8x5") if len(args) != 2: sys.exit(not p.print_help()) fastafile, chr = args window, shift, subtract, merge = check_window_options(opts) linebeds, barbeds, altbarbeds = [], [], [] fatten = opts.fatten if opts.lines: lines = opts.lines.split(",") linebeds = get_beds(lines) if opts.bars: bars = opts.bars.split(",") barbeds = get_beds(bars) if opts.altbars: altbars = opts.altbars.split(",") altbarbeds = get_beds(altbars) linebins = get_binfiles(linebeds, fastafile, shift, mode=opts.mode, merge=merge) margin = 0.12 clen = Sizes(fastafile).mapping[chr] nbins = get_nbins(clen, shift) plt.rcParams["xtick.major.size"] = 0 plt.rcParams["ytick.major.size"] = 0 fig = plt.figure(1, (iopts.w, iopts.h)) root = fig.add_axes([0, 0, 1, 1]) root.text(0.5, 0.95, chr, ha="center", color="darkslategray") xstart, xend = margin, 1 - margin xlen = xend - xstart ratio = xlen / clen # Line plots ax = fig.add_axes([xstart, 0.6, xlen, 0.3]) lineplot(ax, linebins, nbins, chr, window, shift) # Bar plots yy = 0.5 yinterval = 0.08 xs = lambda x: xstart + ratio * x r = 0.01 fattend = 0.0025 for bb in barbeds: root.text(xend + 0.01, yy, bb.split(".")[0], va="center") HorizontalChromosome(root, xstart, xend, yy, height=0.02) bb = Bed(bb) for b in bb: start, end = xs(b.start), xs(b.end) span = end - start if fatten and span < fattend: span = fattend root.add_patch( Rectangle((start, yy - r), span, 2 * r, lw=0, fc="darkslategray")) yy -= yinterval # Alternative bar plots offset = r / 2 for bb in altbarbeds: root.text(xend + 0.01, yy, bb.split(".")[0], va="center") bb = Bed(bb) for i, b in enumerate(bb): start, end = xs(b.start), xs(b.end) span = end - start if span < 0.0001: continue offset = -offset root.add_patch( Rectangle((start, yy + offset), end - start, 0.003, lw=0, fc="darkslategray")) yy -= yinterval root.set_xlim(0, 1) root.set_ylim(0, 1) root.set_axis_off() image_name = chr + "." + iopts.format savefig(image_name, dpi=iopts.dpi, iopts=iopts)
def draw(self, roundrect=False, plot_label=True, plot_circles=True, pad=0.03, vpad=0.09): if self.empty: return y = self.y color = self.color ax = self.ax xstart = self.xstart gap = self.gap va = self.va nseqids = len(self.seqids) tr = self.tr for i, sid in enumerate(self.seqids): size = self.sizes[sid] rsize = self.ratio * size xend = xstart + rsize hc = HorizontalChromosome( ax, xstart, xend, y, height=self.height, lw=self.lw, fc=color, roundrect=roundrect, ) hc.set_transform(tr) si = make_circle_name(sid, self.rev) xx = (xstart + xend) / 2 xstart = xend + gap step = 2 if nseqids <= 40 else 10 if nseqids >= 2 * MaxSeqids and (i + 1) % step != 0: continue if nseqids < 5: continue hpad = -pad if va == "bottom" else pad if plot_circles: TextCircle( ax, xx, y + hpad, si, fc="w", color=color, size=10, transform=tr, ) label = markup(self.label) c = color if color != "gainsboro" else "k" if plot_label: if self.label_va == "top": x, y = self.x, self.y + vpad elif self.label_va == "bottom": x, y = self.x, self.y - vpad else: # "center" x, y = self.xstart - vpad / 2, self.y ax.text(x, y, label, ha="center", va="center", color=c, transform=tr)