예제 #1
0
 def __init__(self,
              ax,
              x,
              y1,
              y2,
              y3,
              width=.015,
              fc="k",
              fill=False,
              zorder=2):
     """
     Chromosome with centromeres at y2 position
     """
     pts = []
     r = width * .5
     pts += plot_cap((x, y1 - r), np.radians(range(180)), r)
     pts += [[x - r, y1 - r], [x - r, y2 + r]]
     pts += plot_cap((x, y2 + r), np.radians(range(180, 360)), r)
     pts += [[x + r, y2 + r], [x + r, y1 - r]]
     ax.add_patch(Polygon(pts, fc=fc, fill=fill, zorder=zorder))
     pts = []
     pts += plot_cap((x, y2 - r), np.radians(range(180)), r)
     pts += [[x - r, y2 - r], [x - r, y3 + r]]
     pts += plot_cap((x, y3 + r), np.radians(range(180, 360)), r)
     pts += [[x + r, y3 + r], [x + r, y2 - r]]
     ax.add_patch(Polygon(pts, fc=fc, fill=fill, zorder=zorder))
     ax.add_patch(
         CirclePolygon((x, y2),
                       radius=r * .5,
                       fc="k",
                       ec="k",
                       zorder=zorder))
예제 #2
0
    def __init__(self, ax, x1, x2, y, height, gradient=True, tip=.0025, \
                 color="k", **kwargs):

        super(GeneGlyph, self).__init__(ax)
        # Figure out the polygon vertices first
        orientation = 1 if x1 < x2 else -1
        level = 10
        # Frame
        p1 = (x1, y - height * .5)
        p2 = (x2 - orientation * tip, y - height * .5)
        p3 = (x2, y)
        p4 = (x2 - orientation * tip, y + height * .5)
        p5 = (x1, y + .5 * height)
        self.append(Polygon([p1, p2, p3, p4, p5], ec=color, **kwargs))

        if gradient:
            zz = kwargs.get("zorder", 1)
            zz += 1
            # Patch (apply white mask)
            for cascade in np.arange(0, .5, .5 / level):
                p1 = (x1, y - height * cascade)
                p2 = (x2 - orientation * tip, y - height * cascade)
                p3 = (x2, y)
                p4 = (x2 - orientation * tip, y + height * cascade)
                p5 = (x1, y + height * cascade)
                self.append(Polygon([p1, p2, p3, p4, p5], fc='w', \
                        lw=0, alpha=.2, zorder=zz))

        self.add_patches()
예제 #3
0
    def __init__(self, ax, x1, x2, y, height=.015, ec="k", patch=None,
                 patchcolor='lightgrey', lw=1, fc=None,
                 zorder=2, roundrect=False):
        """
        Horizontal version of the Chromosome glyph above.
        """
        x1, x2 = sorted((x1, x2))
        super(HorizontalChromosome, self).__init__(ax)
        pts, r = self.get_pts(x1, x2, y, height)
        if roundrect:
            RoundRect(ax, (x1, y - height * .5), x2 - x1, height, fill=False,
                      lw=lw, ec=ec, zorder=zorder + 1)
        else:
            self.append(Polygon(pts, fill=False, lw=lw, ec=ec, zorder=zorder))

        if fc:
            pts, r = self.get_pts(x1, x2, y, height / 2)
            if roundrect:
                RoundRect(ax, (x1, y - height / 4), x2 - x1, height / 2, fc=fc,
                          lw=0, zorder=zorder)
            else:
                self.append(Polygon(pts, fc=fc, lw=0, zorder=zorder))
        if patch:
            rr = r * .9  # Shrink a bit for the patches
            for i in xrange(0, len(patch), 2):
                if i + 1 > len(patch) - 1:
                    continue
                p1, p2 = patch[i], patch[i + 1]
                self.append(Rectangle((p1, y - rr), p2 - p1, 2 * rr, lw=0,
                             fc=patchcolor))

        self.add_patches()
예제 #4
0
파일: glyph.py 프로젝트: sajjadasaf/jcvi
    def __init__(self,
                 ax,
                 x1,
                 x2,
                 y,
                 height,
                 gradient=True,
                 tip=0.0025,
                 color="k",
                 shadow=False,
                 **kwargs):

        super(GeneGlyph, self).__init__(ax)
        # Figure out the polygon vertices first
        orientation = 1 if x1 < x2 else -1
        level = 10
        tip = min(tip, abs(x1 - x2))
        # Frame
        p1 = (x1, y - height * 0.5)
        p2 = (x2 - orientation * tip, y - height * 0.5)
        p3 = (x2, y)
        p4 = (x2 - orientation * tip, y + height * 0.5)
        p5 = (x1, y + 0.5 * height)
        if "fc" not in kwargs:
            kwargs["fc"] = color
        if "ec" not in kwargs:
            kwargs["ec"] = color
        P = Polygon([p1, p2, p3, p4, p5], **kwargs)
        self.append(P)

        if gradient:
            zz = kwargs.get("zorder", 1)
            zz += 1
            # Patch (apply white mask)
            for cascade in np.arange(0, 0.5, 0.5 / level):
                p1 = (x1, y - height * cascade)
                p2 = (x2 - orientation * tip, y - height * cascade)
                p3 = (x2, y)
                p4 = (x2 - orientation * tip, y + height * cascade)
                p5 = (x1, y + height * cascade)
                self.append(
                    Polygon([p1, p2, p3, p4, p5],
                            fc="w",
                            lw=0,
                            alpha=0.2,
                            zorder=zz))

        if shadow:
            import matplotlib.patheffects as pe

            P.set_path_effects([pe.withSimplePatchShadow((1, -1), alpha=0.4)])

        self.add_patches()
예제 #5
0
    def __init__(self,
                 ax,
                 x,
                 y1,
                 y2,
                 width=.015,
                 ec="k",
                 patch=None,
                 lw=1,
                 fc="k",
                 zorder=2):
        """
        Chromosome with positions given in (x, y1) => (x, y2)

        The chromosome can also be patched, e.g. to show scaffold composition in
        alternating shades. Use a list of starting locations to segment.
        """
        y1, y2 = sorted((y1, y2))
        super(Chromosome, self).__init__(ax)
        pts, r = self.get_pts(x, y1, y2, width)
        self.append(Polygon(pts, fill=False, lw=lw, ec=ec, zorder=zorder))
        if patch:
            rr = r * .9  # Shrink a bit for the patches
            for i in xrange(0, len(patch), 2):
                if i + 1 > len(patch) - 1:
                    continue
                p1, p2 = patch[i], patch[i + 1]
                self.append(
                    Rectangle((x - rr, p1),
                              2 * rr,
                              p2 - p1,
                              lw=0,
                              fc="lightgrey"))

        self.add_patches()
예제 #6
0
    def __init__(self, ax, xy, width, height, shrink=.1, label=None, **kwargs):

        shrink *= height
        x, y = xy
        pts = []
        # plot the four rounded cap one by one
        pts += plot_cap((x + width - shrink, y + height - shrink),
                        np.radians(range(0, 90)), shrink)
        pts += [[x + width - shrink, y + height], [x + shrink, y + height]]
        pts += plot_cap((x + shrink, y + height - shrink),
                        np.radians(range(90, 180)), shrink)
        pts += [[x, y + height - shrink], [x, y + shrink]]
        pts += plot_cap((x + shrink, y + shrink), np.radians(range(180, 270)),
                        shrink)
        pts += [[x + shrink, y], [x + width - shrink, y]]
        pts += plot_cap((x + width - shrink, y + shrink),
                        np.radians(range(270, 360)), shrink)
        pts += [[x + width, y + shrink], [x + width, y + height - shrink]]
        p1 = Polygon(pts, **kwargs)
        ax.add_patch(p1)
        # add a white transparency ellipse filter
        if label:
            ax.text(x + width / 2,
                    y + height / 2,
                    label,
                    size=10,
                    ha="center",
                    va="center",
                    color="w")
예제 #7
0
파일: chromosome.py 프로젝트: zjwang6/jcvi
def draw_cytoband(ax,
                  chrom,
                  filename=datafile("hg38.band.txt"),
                  ymid=0.5,
                  width=0.99,
                  height=0.11):
    import pandas as pd

    bands = pd.read_csv(filename, sep="\t")
    chrombands = bands[bands["#chrom"] == chrom]
    data = []
    for i, (chr, start, end, name, gie) in chrombands.iterrows():
        data.append((chr, start, end, name, gie))
    chromsize = max(x[2] for x in data)
    scale = width * 1.0 / chromsize
    xstart, ystart = (1 - width) / 2, ymid - height / 2
    bp_to_pos = lambda x: xstart + x * scale
    in_acen = False
    for chr, start, end, name, gie in data:
        color, alpha = get_color(gie)
        bplen = end - start
        if "acen" in gie:
            if in_acen:
                xys = [
                    (bp_to_pos(start), ymid),
                    (bp_to_pos(end), ystart),
                    (bp_to_pos(end), ystart + height),
                ]
            else:
                xys = [
                    (bp_to_pos(start), ystart),
                    (bp_to_pos(start), ystart + height),
                    (bp_to_pos(end), ymid),
                ]
            p = Polygon(xys, closed=True, ec="k", fc=color, alpha=alpha)
            in_acen = True
        else:
            p = Rectangle(
                (bp_to_pos(start), ystart),
                bplen * scale,
                height,
                ec="k",
                fc=color,
                alpha=alpha,
            )
        # print bp_to_pos(end)
        ax.add_patch(p)
        ax.text(
            bp_to_pos((start + end) / 2),
            ymid + height * 0.8,
            name,
            rotation=40,
            color="lightslategray",
        )

    ax.text(0.5, ystart - height, chrom, size=16, ha="center", va="center")

    ax.set_xlim(0, 1)
    ax.set_ylim(0, 1)
    ax.set_axis_off()
예제 #8
0
def plot_diagram(ax, x, y, label="S", title="syntenic", gradient=True):
    """
    Part of the diagrams that are re-used. (x, y) marks the center of the
    diagram. Label determines the modification to the "S" graph.
    """
    trackgap = 0.06
    tracklen = 0.12
    xa, xb = x - tracklen, x + tracklen
    ya, yb = y + trackgap, y - trackgap
    hsps = (((60, 150), (50, 130)), ((190, 225), (200, 240)), ((330, 280), (360, 310)))

    for yy in (ya, yb):
        ax.plot((xa, xb), (yy, yy), "-", color="gray", lw=2, zorder=1)

    ytip = 0.015
    mrange = 400
    m = lambda t: xa + t * 1.0 / mrange * tracklen * 2

    for i, ((a, b), (c, d)) in enumerate(hsps):
        fb = False
        if label == "FB" and i == 1:
            c, d = 270, 280
            fb = True
        if label == "G" and i == 0:
            c, d = 120, 65

        a, b, c, d = [m(t) for t in (a, b, c, d)]
        color = "g" if i == 1 else "r"
        GeneGlyph(ax, a, b, ya, 2 * ytip, fc=color, gradient=gradient, zorder=10)

        if i == 1 and label in ("F", "G", "FN"):
            pass
        else:
            if fb:
                GeneGlyph(
                    ax, c, d, yb, 2 * ytip, fc="w", tip=0, gradient=gradient, zorder=10
                )
            else:
                GeneGlyph(ax, c, d, yb, 2 * ytip, fc="r", gradient=gradient, zorder=10)

        r = Polygon(
            ((a, ya - ytip), (c, yb + ytip), (d, yb + ytip), (b, ya - ytip)),
            fc="r",
            alpha=0.2,
        )

        if i == 1 and label not in ("S", "FB"):
            pass
        elif i == 0 and label == "G":
            pass
        else:
            ax.add_patch(r)

    if label == "FN":
        ax.text(x + 0.005, yb, "NNNNN", ha="center", size=7)

    title = "{0}: {1}".format(label, title)
    ax.text(x, ya + 5 * ytip, title, size=8, ha="center")
예제 #9
0
파일: glyph.py 프로젝트: fw1121/jcvi
    def __init__(self, ax, x1, x2, y, height, gradient=True, tip=.0025, \
                 color="k", shadow=False, **kwargs):

        super(GeneGlyph, self).__init__(ax)
        # Figure out the polygon vertices first
        orientation = 1 if x1 < x2 else -1
        level = 10
        tip = min(tip, abs(x1 - x2))
        # Frame
        p1 = (x1, y - height * .5)
        p2 = (x2 - orientation * tip, y - height * .5)
        p3 = (x2, y)
        p4 = (x2 - orientation * tip, y + height * .5)
        p5 = (x1, y + .5*height)
        if "fc" not in kwargs:
            kwargs["fc"] = color
        if "ec" not in kwargs:
            kwargs["ec"] = color
        P = Polygon([p1, p2, p3, p4, p5], **kwargs)
        self.append(P)

        if gradient:
            zz = kwargs.get("zorder", 1)
            zz += 1
            # Patch (apply white mask)
            for cascade in np.arange(0, .5, .5 / level):
                p1 = (x1, y - height * cascade)
                p2 = (x2 - orientation * tip, y - height * cascade)
                p3 = (x2, y)
                p4 = (x2 - orientation * tip, y + height * cascade)
                p5 = (x1, y + height * cascade)
                self.append(Polygon([p1, p2, p3, p4, p5], fc='w', \
                        lw=0, alpha=.2, zorder=zz))

        if shadow:
            import matplotlib.patheffects as pe
            P.set_path_effects([pe.withSimplePatchShadow((1, -1), \
                                alpha=.4, patch_alpha=1)])

        self.add_patches()
예제 #10
0
    def __init__(self, ax, x1, x2, y, height, tip=.0025, **kwargs):
        # Figure out the polygon vertices first
        orientation = 1 if x1 < x2 else -1
        level = 10
        # Frame
        p1 = (x1, y - height * .5)
        p2 = (x2 - orientation * tip, y - height * .5)
        p3 = (x2, y)
        p4 = (x2 - orientation * tip, y + height * .5)
        p5 = (x1, y + .5 * height)
        ax.add_patch(Polygon([p1, p2, p3, p4, p5], ec='k', **kwargs))

        zz = kwargs.get("zorder", 1)
        zz += 1
        # Patch (apply white mask)
        for cascade in np.arange(0, .5, .5 / level):
            p1 = (x1, y - height * cascade)
            p2 = (x2 - orientation * tip, y - height * cascade)
            p3 = (x2, y)
            p4 = (x2 - orientation * tip, y + height * cascade)
            p5 = (x1, y + height * cascade)
            ax.add_patch(Polygon([p1, p2, p3, p4, p5], fc='w', \
                    lw=0, alpha=.2, zorder=zz))
예제 #11
0
 def __init__(self,
              ax,
              x1,
              x2,
              y,
              height=.015,
              fc="k",
              fill=False,
              zorder=2):
     """
     Chromosome with positions given in (x1, y) => (x2, y)
     """
     pts = []
     r = height * .5
     pts += plot_cap((x1, y), np.radians(range(90, 270)), r)
     pts += [[x1, y - r], [x2, y - r]]
     pts += plot_cap((x2, y), np.radians(range(270, 450)), r)
     pts += [[x2, y + r], [x1, y + r]]
     ax.add_patch(Polygon(pts, fc=fc, fill=fill, zorder=zorder))
예제 #12
0
 def __init__(self,
              ax,
              x,
              y1,
              y2,
              width=.015,
              fc="k",
              fill=False,
              zorder=2):
     """
     Chromosome with positions given in (x, y1) => (x, y2)
     """
     pts = []
     r = width * .5
     pts += plot_cap((x, y1 - r), np.radians(range(180)), r)
     pts += [[x - r, y1 - r], [x - r, y2 + r]]
     pts += plot_cap((x, y2 + r), np.radians(range(180, 360)), r)
     pts += [[x + r, y2 + r], [x + r, y1 - r]]
     ax.add_patch(Polygon(pts, fc=fc, fill=fill, zorder=zorder))
예제 #13
0
파일: bites.py 프로젝트: zjwang6/jcvi
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)