Exemple #1
0
def draw_ploidy(fig, root, blocksfile, bedfile, blockslayout):
    switchidsfile = "switch.ids"
    Synteny(
        fig,
        root,
        blocksfile,
        bedfile,
        blockslayout,
        scalebar=True,
        switch=switchidsfile,
    )

    # Legend showing the orientation of the genes
    draw_gene_legend(root, 0.2, 0.3, 0.53)

    # WGD labels
    radius = 0.025
    tau_color = "#bebada"
    alpha_color = "#bc80bd"
    label_color = "k"
    pad = 0.05
    for y in (0.74 + 1.5 * pad, 0.26 - 1.5 * pad):
        TextCircle(
            root,
            0.25,
            y,
            r"$\alpha^{O}$",
            radius=radius,
            fc=alpha_color,
            color=label_color,
            fontweight="bold",
        )
        TextCircle(
            root,
            0.75,
            y,
            r"$\alpha^{O}$",
            radius=radius,
            fc=alpha_color,
            color=label_color,
            fontweight="bold",
        )
    for y in (0.74 + 3 * pad, 0.26 - 3 * pad):
        TextCircle(root,
                   0.5,
                   y,
                   r"$\tau$",
                   radius=radius,
                   fc=tau_color,
                   color=label_color)
Exemple #2
0
def amborella(args):
    """
    %prog amborella seqids karyotype.layout mcscan.out all.bed synteny.layout

    Build a composite figure that calls graphics.karyotype and graphics.synteny.
    """
    p = OptionParser(amborella.__doc__)
    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(not p.print_help())

    seqidsfile, klayout, datafile, bedfile, slayout = args
    switch = opts.switch
    tree = opts.tree

    fig = plt.figure(1, (iopts.w, iopts.h))
    root = fig.add_axes([0, 0, 1, 1])

    Karyotype(fig, root, seqidsfile, klayout)
    Synteny(fig, root, datafile, bedfile, slayout, switch=switch, tree=tree)

    # legend showing the orientation of the genes
    draw_gene_legend(root, .5, .68, .5)

    # annotate the WGD events
    fc = 'lightslategrey'
    x = .05
    radius = .012
    TextCircle(root, x, .86, '$\gamma$', radius=radius)
    TextCircle(root, x, .95, '$\epsilon$', radius=radius)
    root.plot([x, x], [.83, .9], ":", color=fc, lw=2)
    pts = plot_cap((x, .95), np.radians(range(-70, 250)), .02)
    x, y = zip(*pts)
    root.plot(x, y, ":", color=fc, lw=2)

    root.set_xlim(0, 1)
    root.set_ylim(0, 1)
    root.set_axis_off()

    pf = "amborella"
    image_name = pf + "." + iopts.format
    savefig(image_name, dpi=iopts.dpi, iopts=iopts)
Exemple #3
0
def ploidy(args):
    """
    %prog ploidy seqids karyotype.layout mcscan.out all.bed synteny.layout

    Build a figure that calls graphics.karyotype to illustrate the high ploidy
    of WGD history of pineapple genome. The script calls both graphics.karyotype
    and graphic.synteny.
    """
    p = OptionParser(ploidy.__doc__)
    p.add_option("--switch", help="Rename the seqid with two-column file")
    opts, args, iopts = p.set_image_options(args, figsize="9x7")

    if len(args) != 5:
        sys.exit(not p.print_help())

    seqidsfile, klayout, datafile, bedfile, slayout = args

    fig = plt.figure(1, (iopts.w, iopts.h))
    root = fig.add_axes([0, 0, 1, 1])

    Karyotype(fig, root, seqidsfile, klayout)
    Synteny(fig, root, datafile, bedfile, slayout, switch=opts.switch)

    # legend showing the orientation of the genes
    draw_gene_legend(root, .27, .37, .52)

    # annotate the WGD events
    fc = 'lightslategrey'
    x = .09
    radius = .012
    TextCircle(root, x, .825, r'$\tau$', radius=radius, fc=fc)
    TextCircle(root, x, .8, r'$\sigma$', radius=radius, fc=fc)
    TextCircle(root, x, .72, r'$\rho$', radius=radius, fc=fc)
    for ypos in (.825, .8, .72):
        root.text(.12, ypos, r"$\times2$", color=fc, ha="center", va="center")
    root.plot([x, x], [.85, .775], ":", color=fc, lw=2)
    root.plot([x, x], [.75, .675], ":", color=fc, lw=2)

    labels = ((.04, .96, 'A'), (.04, .54, 'B'))
    panel_labels(root, labels)

    root.set_xlim(0, 1)
    root.set_ylim(0, 1)
    root.set_axis_off()

    pf = "pineapple-karyotype"
    image_name = pf + "." + iopts.format
    savefig(image_name, dpi=iopts.dpi, iopts=iopts)
Exemple #4
0
    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)
Exemple #5
0
def draw_wgd_xy(ax, xx, yy, wgdline):
    """Draw WGD at (xx, yy) position

    Args:
        ax (axis): Matplotlib axes
        xx (float): x position
        yy (float): y position
        wgdline (WGDInfo): WGDInfoLines that contains the styling information
    """
    TextCircle(
        ax,
        xx,
        yy,
        wgdline.name,
        fc=wgdline.color,
        radius=0.0225,
        color="k",
        fontweight="bold",
    )
Exemple #6
0
def draw_wgd(ax, y, rescale, name, wgdcache):
    """Draw WGD at (xx yy) position

    Args:
        ax (axis): Matplotlib axes
        xx (float): x position
        yy (float): y position
        wgdline (WGDInfo): WGDInfoLines that contains the styling information
    """
    if not wgdcache or name not in wgdcache:
        return
    for line in wgdcache[name]:
        TextCircle(
            ax,
            rescale(line.divergence),
            y,
            line.name,
            fc=line.color,
            radius=0.0225,
            color="k",
            fontweight="bold",
        )
Exemple #7
0
def ploidy(args):
    """
    %prog ploidy seqids layout

    Build a figure that calls graphics.karyotype to illustrate the high ploidy
    of B. napus genome.
    """
    p = OptionParser(ploidy.__doc__)
    opts, args, iopts = p.set_image_options(args, figsize="8x7")

    if len(args) != 2:
        sys.exit(not p.print_help())

    seqidsfile, klayout = args

    fig = plt.figure(1, (iopts.w, iopts.h))
    root = fig.add_axes([0, 0, 1, 1])

    Karyotype(fig, root, seqidsfile, klayout)

    fc = "darkslategrey"
    radius = .012
    ot = -.05  # use this to adjust vertical position of the left panel
    TextCircle(root, .1, .9 + ot, r'$\gamma$', radius=radius, fc=fc)
    root.text(.1, .88 + ot, r"$\times3$", ha="center", va="top", color=fc)
    TextCircle(root, .08, .79 + ot, r'$\alpha$', radius=radius, fc=fc)
    TextCircle(root, .12, .79 + ot, r'$\beta$', radius=radius, fc=fc)
    root.text(.1,
              .77 + ot,
              r"$\times3\times2\times2$",
              ha="center",
              va="top",
              color=fc)
    root.text(.1,
              .67 + ot,
              r"Brassica triplication",
              ha="center",
              va="top",
              color=fc,
              size=11)
    root.text(.1,
              .65 + ot,
              r"$\times3\times2\times2\times3$",
              ha="center",
              va="top",
              color=fc)
    root.text(.1,
              .42 + ot,
              r"Allo-tetraploidy",
              ha="center",
              va="top",
              color=fc,
              size=11)
    root.text(.1,
              .4 + ot,
              r"$\times3\times2\times2\times3\times2$",
              ha="center",
              va="top",
              color=fc)

    bb = dict(boxstyle="round,pad=.5", fc="w", ec="0.5", alpha=0.5)
    root.text(.5,
              .2 + ot, r"\noindent\textit{Brassica napus}\\"
              "(A$\mathsf{_n}$C$\mathsf{_n}$ genome)",
              ha="center",
              size=16,
              color="k",
              bbox=bb)

    root.set_xlim(0, 1)
    root.set_ylim(0, 1)
    root.set_axis_off()

    pf = "napus"
    image_name = pf + "." + iopts.format
    savefig(image_name, dpi=iopts.dpi, iopts=iopts)
Exemple #8
0
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)
Exemple #9
0
    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)
Exemple #10
0
def main():
    p = OptionParser(__doc__)
    p.add_option(
        "--groups",
        default=False,
        action="store_true",
        help="The first row contains group info",
    )
    p.add_option("--rowgroups", help="Row groupings")
    p.add_option(
        "--horizontalbar",
        default=False,
        action="store_true",
        help="Horizontal color bar [default: vertical]",
    )
    opts, args, iopts = p.set_image_options(figsize="8x8")

    if len(args) != 1:
        sys.exit(not p.print_help())

    (datafile,) = args
    pf = datafile.rsplit(".", 1)[0]
    rowgroups = opts.rowgroups

    groups, rows, cols, data = parse_csv(datafile, vmin=1, groups=opts.groups)
    cols = [x.replace("ay ", "") for x in cols]

    if rowgroups:
        fp = open(rowgroups)
        rgroups = []
        for row in fp:
            a, b = row.split()
            irows = [rows.index(x) for x in b.split(",")]
            rgroups.append((a, min(irows), max(irows)))

    plt.rcParams["axes.linewidth"] = 0

    xstart = 0.18
    fig = plt.figure(1, (iopts.w, iopts.h))
    root = fig.add_axes([0, 0, 1, 1])
    ax = fig.add_axes([xstart, 0.15, 0.7, 0.7])

    im = ax.matshow(data, cmap=iopts.cmap, norm=mpl.colors.LogNorm(vmin=1, vmax=10000))
    nrows, ncols = len(rows), len(cols)

    xinterval = 0.7 / ncols
    yinterval = 0.7 / max(nrows, ncols)

    plt.xticks(range(ncols), cols, rotation=45, size=10, ha="center")
    plt.yticks(range(nrows), rows, size=10)

    for x in ax.get_xticklines() + ax.get_yticklines():
        x.set_visible(False)

    ax.set_xlim(-0.5, ncols - 0.5)

    t = [1, 10, 100, 1000, 10000]
    pad = 0.06
    if opts.horizontalbar:
        ypos = 0.5 * (1 - nrows * yinterval) - pad
        axcolor = fig.add_axes([0.3, ypos, 0.4, 0.02])
        orientation = "horizontal"
    else:
        axcolor = fig.add_axes([0.9, 0.3, 0.02, 0.4])
        orientation = "vertical"
    fig.colorbar(im, cax=axcolor, ticks=t, orientation=orientation)

    if groups:
        groups = [(key, len(list(nn))) for key, nn in groupby(groups)]
        yy = 0.5 + 0.5 * nrows / ncols * 0.7 + 0.06
        e = 0.005
        sep = -0.5

        for k, kl in groups:
            # Separator in the array area
            sep += kl
            ax.plot([sep, sep], [-0.5, nrows - 0.5], "w-", lw=2)
            # Group labels on the top
            kl *= xinterval
            root.plot([xstart + e, xstart + kl - e], [yy, yy], "-", color="gray", lw=2)
            root.text(xstart + 0.5 * kl, yy + e, k, ha="center", color="gray")
            xstart += kl

    if rowgroups:
        from jcvi.graphics.glyph import TextCircle

        xpos = 0.04
        tip = 0.015
        assert rgroups
        ystart = 1 - 0.5 * (1 - nrows * yinterval)
        for gname, start, end in rgroups:
            start = ystart - start * yinterval
            end = ystart - (end + 1) * yinterval
            start -= tip / 3
            end += tip / 3

            # Bracket the groups
            root.plot((xpos, xpos + tip), (start, start), "k-", lw=2)
            root.plot((xpos, xpos), (start, end), "k-", lw=2)
            root.plot((xpos, xpos + tip), (end, end), "k-", lw=2)
            TextCircle(root, xpos, 0.5 * (start + end), gname)

    root.set_xlim(0, 1)
    root.set_ylim(0, 1)
    root.set_axis_off()

    image_name = pf + "." + opts.cmap + "." + iopts.format
    savefig(image_name, dpi=iopts.dpi, iopts=iopts)
Exemple #11
0
def draw_tree(
    ax,
    t,
    hpd=None,
    margin=0.1,
    rmargin=0.2,
    tip=0.01,
    treecolor="k",
    supportcolor="k",
    internal=True,
    outgroup=None,
    dashedoutgroup=False,
    reroot=True,
    gffdir=None,
    sizes=None,
    trunc_name=None,
    SH=None,
    scutoff=0,
    leafcolor="k",
    leaffont=12,
    leafinfo=None,
    wgdinfo=None,
    geoscale=False,
):
    """
    main function for drawing phylogenetic tree
    """

    if reroot:
        if outgroup:
            R = t.get_common_ancestor(*outgroup)
        else:
            # Calculate the midpoint node
            R = t.get_midpoint_outgroup()

        if R is not t:
            t.set_outgroup(R)

        # By default, the distance to outgroup and non-outgroup is the same
        # we re-adjust the distances so that the outgroups will appear
        # farthest from everything else
        if dashedoutgroup:
            a, b = t.children
            # Avoid even split
            total = a.dist + b.dist
            newR = t.get_common_ancestor(*outgroup)
            a.dist = 0.9 * total
            b.dist = total - a.dist

    farthest, max_dist = t.get_farthest_leaf()
    print("max_dist = {}".format(max_dist), file=sys.stderr)

    xstart = margin
    ystart = 2 * margin
    # scale the tree
    scale = (1 - margin - rmargin) / max_dist

    def rescale(dist):
        return xstart + scale * dist

    def rescale_divergence(divergence):
        return rescale(max_dist - divergence)

    num_leaves = len(t.get_leaf_names())
    yinterval = (1 - ystart) / num_leaves

    # get exons structures, if any
    structures = {}
    if gffdir:
        gffiles = glob("{0}/*.gff*".format(gffdir))
        setups, ratio = get_setups(gffiles, canvas=rmargin / 2, noUTR=True)
        structures = dict((a, (b, c)) for a, b, c in setups)

    if sizes:
        sizes = Sizes(sizes).mapping

    coords = {}
    i = 0
    for n in t.traverse("postorder"):
        dist = n.get_distance(t)
        xx = rescale(dist)

        if n.is_leaf():
            yy = ystart + i * yinterval
            i += 1

            if trunc_name:
                name = truncate_name(n.name, rule=trunc_name)
            else:
                name = n.name

            if leafinfo and n.name in leafinfo:
                line = leafinfo[n.name]
                lc = line.color
                sname = line.new_name
            else:
                lc = leafcolor
                sname = None
            lc = lc or "k"
            sname = sname or name.replace("_", "-")
            # if color is given as "R,G,B"
            if "," in lc:
                lc = [float(x) for x in lc.split(",")]

            ax.text(
                xx + tip,
                yy,
                markup(sname),
                va="center",
                fontstyle="italic",
                size=leaffont,
                color=lc,
            )

            gname = n.name.split("_")[0]
            if gname in structures:
                mrnabed, cdsbeds = structures[gname]
                ExonGlyph(
                    ax,
                    1 - rmargin / 2,
                    yy,
                    mrnabed,
                    cdsbeds,
                    align="right",
                    ratio=ratio,
                )
            if sizes and gname in sizes:
                size = sizes[gname]
                size = size / 3 - 1  # base pair converted to amino acid
                size = "{0}aa".format(size)
                ax.text(1 - rmargin / 2 + tip, yy, size, size=leaffont)

        else:
            linestyle = "--" if (dashedoutgroup and n is t) else "-"
            children = [coords[x] for x in n.get_children()]
            children_x, children_y = zip(*children)
            min_y, max_y = min(children_y), max(children_y)
            # plot the vertical bar
            ax.plot((xx, xx), (min_y, max_y), linestyle, color=treecolor)
            # plot the horizontal bar
            for cx, cy in children:
                ax.plot((xx, cx), (cy, cy), linestyle, color=treecolor)
            yy = sum(children_y) * 1.0 / len(children_y)
            # plot HPD if exists
            if hpd and n.name in hpd:
                a, b = hpd[n.name]
                ax.plot(
                    (rescale_divergence(a), rescale_divergence(b)),
                    (yy, yy),
                    "-",
                    color="darkslategray",
                    alpha=0.4,
                    lw=2,
                )
            support = n.support
            if support > 1:
                support = support / 100.0
            if not n.is_root() and supportcolor:
                if support > scutoff / 100.0:
                    ax.text(
                        xx,
                        yy + 0.005,
                        "{0:d}".format(int(abs(support * 100))),
                        ha="right",
                        size=leaffont,
                        color=supportcolor,
                    )
            if internal and n.name:
                TextCircle(ax, xx, yy, n.name, size=9)

        coords[n] = (xx, yy)
        # WGD info
        draw_wgd(ax, yy, rescale_divergence, n.name, wgdinfo)

    # scale bar
    if geoscale:
        draw_geoscale(ax,
                      margin=margin,
                      rmargin=rmargin,
                      yy=margin,
                      max_dist=max_dist)
    else:
        br = 0.1
        x1 = xstart + 0.1
        x2 = x1 + br * scale
        yy = margin
        ax.plot([x1, x1], [yy - tip, yy + tip], "-", color=treecolor)
        ax.plot([x2, x2], [yy - tip, yy + tip], "-", color=treecolor)
        ax.plot([x1, x2], [yy, yy], "-", color=treecolor)
        ax.text(
            (x1 + x2) / 2,
            yy - tip,
            "{0:g}".format(br),
            va="top",
            ha="center",
            size=leaffont,
            color=treecolor,
        )

    if SH is not None:
        xs = x1
        ys = (margin + yy) / 2.0
        ax.text(
            xs,
            ys,
            "SH test against ref tree: {0}".format(SH),
            ha="left",
            size=leaffont,
            color="g",
        )

    normalize_axes(ax)
Exemple #12
0
    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)
Exemple #13
0
def bites(args):
    """
    %prog bites

    Illustrate the pipeline for automated bite discovery.
    """

    p = OptionParser(__doc__)
    opts, args = p.parse_args()

    fig = plt.figure(1, (6, 6))
    root = fig.add_axes([0, 0, 1, 1])

    # HSP pairs
    hsps = (
        ((50, 150), (60, 180)),
        ((190, 250), (160, 235)),
        ((300, 360), (270, 330)),
        ((430, 470), (450, 490)),
        ((570, 620), (493, 543)),
        ((540, 555), (370, 385)),  # non-collinear hsps
    )

    titlepos = (0.9, 0.65, 0.4)
    titles = ("Compare orthologous region", "Find collinear HSPs",
              "Scan paired gaps")
    ytip = 0.01
    mrange = 650.0
    m = lambda x: x / mrange * 0.7 + 0.1
    for i, (ya, title) in enumerate(zip(titlepos, titles)):
        yb = ya - 0.1
        plt.plot((0.1, 0.8), (ya, ya), "-", color="gray", lw=2, zorder=1)
        plt.plot((0.1, 0.8), (yb, yb), "-", color="gray", lw=2, zorder=1)
        RoundLabel(root, 0.5, ya + 4 * ytip, title)
        root.text(0.9, ya, "A. thaliana", ha="center", va="center")
        root.text(0.9, yb, "B. rapa", ha="center", va="center")
        myhsps = hsps
        if i >= 1:
            myhsps = hsps[:-1]
        for (a, b), (c, d) in myhsps:
            a, b, c, d = [m(x) for x in (a, b, c, d)]
            r1 = Rectangle((a, ya - ytip),
                           b - a,
                           2 * ytip,
                           fc="r",
                           lw=0,
                           zorder=2)
            r2 = Rectangle((c, yb - ytip),
                           d - c,
                           2 * ytip,
                           fc="r",
                           lw=0,
                           zorder=2)
            r3 = Rectangle((a, ya - ytip),
                           b - a,
                           2 * ytip,
                           fill=False,
                           zorder=3)
            r4 = Rectangle((c, yb - ytip),
                           d - c,
                           2 * ytip,
                           fill=False,
                           zorder=3)
            r5 = Polygon(
                ((a, ya - ytip), (c, yb + ytip), (d, yb + ytip),
                 (b, ya - ytip)),
                fc="r",
                alpha=0.2,
            )
            rr = (r1, r2, r3, r4, r5)
            if i == 2:
                rr = rr[:-1]
            for r in rr:
                root.add_patch(r)

    # Gap pairs
    hspa, hspb = zip(*myhsps)
    gapa, gapb = [], []
    for (a, b), (c, d) in pairwise(hspa):
        gapa.append((b + 1, c - 1))
    for (a, b), (c, d) in pairwise(hspb):
        gapb.append((b + 1, c - 1))
    gaps = zip(gapa, gapb)
    tpos = titlepos[-1]

    yy = tpos - 0.05
    for i, ((a, b), (c, d)) in enumerate(gaps):
        i += 1
        a, b, c, d = [m(x) for x in (a, b, c, d)]
        xx = (a + b + c + d) / 4
        TextCircle(root, xx, yy, str(i))

    # Bites
    ystart = 0.24
    ytip = 0.05
    bites = (
        ("Bite(40=>-15)", True),
        ("Bite(50=>35)", False),
        ("Bite(70=>120)", False),
        ("Bite(100=>3)", True),
    )
    for i, (bite, selected) in enumerate(bites):
        xx = 0.15 if (i % 2 == 0) else 0.55
        yy = ystart - i / 2 * ytip
        i += 1
        TextCircle(root, xx, yy, str(i))
        color = "k" if selected else "gray"
        root.text(xx + ytip, yy, bite, size=10, color=color, va="center")

    root.set_xlim(0, 1)
    root.set_ylim(0, 1)
    root.set_axis_off()

    figname = fname() + ".pdf"
    savefig(figname, dpi=300)