Beispiel #1
0
    def _render_on_subplot(self, subplot):
        """
        TESTS::

            sage: C = circle((2,pi), 2, edgecolor='black', facecolor='green', fill=True)
        """
        import matplotlib.patches as patches
        from sage.plot.misc import get_matplotlib_linestyle

        options = self.options()
        p = patches.Circle((float(self.x), float(self.y)),
                           float(self.r),
                           clip_on=options['clip'])
        if not options['clip']:
            self._bbox_extra_artists = [p]
        p.set_linewidth(float(options['thickness']))
        p.set_fill(options['fill'])
        a = float(options['alpha'])
        p.set_alpha(a)
        ec = to_mpl_color(options['edgecolor'])
        fc = to_mpl_color(options['facecolor'])
        if 'rgbcolor' in options:
            ec = fc = to_mpl_color(options['rgbcolor'])
        p.set_edgecolor(ec)
        p.set_facecolor(fc)
        p.set_linestyle(
            get_matplotlib_linestyle(options['linestyle'], return_type='long'))
        p.set_label(options['legend_label'])
        z = int(options.pop('zorder', 0))
        p.set_zorder(z)
        subplot.add_patch(p)
Beispiel #2
0
    def _render_on_subplot(self, subplot):
        """
        TESTS::

            sage: P = polygon([(0,0), (1,2), (0,1), (-1,2)])
        """
        import matplotlib.patches as patches
        options = self.options()
        p = patches.Polygon([(self.xdata[i], self.ydata[i])
                             for i in range(len(self.xdata))])
        p.set_linewidth(float(options['thickness']))
        a = float(options['alpha'])
        z = int(options.pop('zorder', 1))
        p.set_alpha(a)
        f = options.pop('fill')
        p.set_fill(f)
        c = to_mpl_color(options['rgbcolor'])
        if f:
            ec = options['edgecolor']
            if ec is None:
                p.set_color(c)
            else:
                p.set_facecolor(c)
                p.set_edgecolor(to_mpl_color(ec))
        else:
            p.set_color(c)
        p.set_label(options['legend_label'])
        p.set_zorder(z)
        subplot.add_patch(p)
Beispiel #3
0
    def _render_on_subplot(self, subplot):
        """
        Render this ellipse in a subplot.  This is the key function that
        defines how this ellipse graphics primitive is rendered in matplotlib's
        library.

        TESTS::

            sage: ellipse((0,0),3,1,pi/6,fill=True,alpha=0.3)

        ::

            sage: ellipse((3,2),1,2)
        """
        import matplotlib.patches as patches
        options = self.options()
        p = patches.Ellipse((self.x, self.y), self.r1 * 2., self.r2 * 2.,
                            self.angle / pi * 180.)
        p.set_linewidth(float(options['thickness']))
        p.set_fill(options['fill'])
        a = float(options['alpha'])
        p.set_alpha(a)
        ec = to_mpl_color(options['edgecolor'])
        fc = to_mpl_color(options['facecolor'])
        if 'rgbcolor' in options:
            ec = fc = to_mpl_color(options['rgbcolor'])
        p.set_edgecolor(ec)
        p.set_facecolor(fc)
        p.set_linestyle(options['linestyle'])
        p.set_label(options['legend_label'])
        z = int(options.pop('zorder', 0))
        p.set_zorder(z)
        subplot.add_patch(p)
Beispiel #4
0
    def _render_on_subplot(self, subplot):
        """
        TESTS::

            sage: P = polygon([(0,0), (1,2), (0,1), (-1,2)])
        """
        import matplotlib.patches as patches
        options = self.options()
        p = patches.Polygon([(self.xdata[i],self.ydata[i]) for i in xrange(len(self.xdata))])
        p.set_linewidth(float(options['thickness']))
        a = float(options['alpha'])
        z = int(options.pop('zorder', 1))
        p.set_alpha(a)
        f = options.pop('fill')
        p.set_fill(f)
        c = to_mpl_color(options['rgbcolor'])
        if f:
            ec = options['edgecolor']
            if ec is None:
                p.set_color(c)
            else:
                p.set_facecolor(c)
                p.set_edgecolor(to_mpl_color(ec))
        else:
            p.set_color(c)
        p.set_label(options['legend_label'])
        p.set_zorder(z)
        subplot.add_patch(p)
Beispiel #5
0
    def _render_on_subplot(self, subplot):
        """
        TESTS::

            sage: C = circle((2,pi), 2, edgecolor='black', facecolor='green', fill=True) 
        """
        import matplotlib.patches as patches        
        options = self.options()
        p = patches.Circle((float(self.x), float(self.y)), float(self.r), clip_on=options['clip'])
        if not options['clip']:
            self._bbox_extra_artists=[p]
        p.set_linewidth(float(options['thickness']))
        p.set_fill(options['fill'])
        a = float(options['alpha'])
        p.set_alpha(a)
        ec = to_mpl_color(options['edgecolor'])
        fc = to_mpl_color(options['facecolor'])
        if 'rgbcolor' in options: 
            ec = fc = to_mpl_color(options['rgbcolor'])
        p.set_edgecolor(ec)
        p.set_facecolor(fc)
        p.set_linestyle(options['linestyle'])
        p.set_label(options['legend_label'])
        z = int(options.pop('zorder', 0))
        p.set_zorder(z)
        subplot.add_patch(p)
Beispiel #6
0
    def _render_on_subplot(self, subplot):
        """
        Render this ellipse in a subplot.  This is the key function that
        defines how this ellipse graphics primitive is rendered in matplotlib's
        library.

        TESTS::

            sage: ellipse((0,0),3,1,pi/6,fill=True,alpha=0.3)

        ::

            sage: ellipse((3,2),1,2)
        """
        import matplotlib.patches as patches        
        options = self.options()
        p = patches.Ellipse(
                (self.x,self.y),
                self.r1*2.,self.r2*2.,self.angle/pi*180.)
        p.set_linewidth(float(options['thickness']))
        p.set_fill(options['fill'])
        a = float(options['alpha'])
        p.set_alpha(a)
        ec = to_mpl_color(options['edgecolor'])
        fc = to_mpl_color(options['facecolor'])
        if 'rgbcolor' in options: 
            ec = fc = to_mpl_color(options['rgbcolor'])
        p.set_edgecolor(ec)
        p.set_facecolor(fc)
        p.set_linestyle(options['linestyle'])
        z = int(options.pop('zorder', 0))
        p.set_zorder(z)
        subplot.add_patch(p)
Beispiel #7
0
    def _render_on_subplot(self,subplot):
        r"""
        TESTS:

        We check to make sure that \#2076 is fixed by verifying all
        the points are red::

            sage: point(((1,1), (2,2), (3,3)), rgbcolor=hue(1), size=30)
        """
        options = self.options()

        #Convert the color to a hex string so that the scatter
        #method does not interpret it as a list of 3 floating
        #point color specifications when there are
        #three points. This is mentioned in the matplotlib 0.98
        #documentation and fixes \#2076
        from matplotlib.colors import rgb2hex
        c = rgb2hex(to_mpl_color(options['rgbcolor']))

        a = float(options['alpha'])
        z = int(options.pop('zorder', 0))
        s = int(options['size'])
        faceted = options['faceted'] #faceted=True colors the edge of point
        scatteroptions={}
        if not faceted: scatteroptions['edgecolors'] = 'none'
        subplot.scatter(self.xdata, self.ydata, s=s, c=c, alpha=a, zorder=z, label=options['legend_label'], **scatteroptions)
Beispiel #8
0
    def _render_on_subplot(self, subplot):
        """
        Render this line on a matplotlib subplot.

        INPUT:

        - ``subplot`` -- a matplotlib subplot

        EXAMPLES:

        This implicitly calls this function::

            sage: line([(1,2), (3,-4), (2, 5), (1,2)])
        """
        import matplotlib.lines as lines

        options = dict(self.options())
        for o in ("alpha", "legend_color", "legend_label", "linestyle", "rgbcolor", "thickness"):
            if o in options:
                del options[o]
        p = lines.Line2D(self.xdata, self.ydata, **options)
        options = self.options()
        a = float(options["alpha"])
        p.set_alpha(a)
        p.set_linewidth(float(options["thickness"]))
        p.set_color(to_mpl_color(options["rgbcolor"]))
        p.set_label(options["legend_label"])
        # we don't pass linestyle in directly since the drawstyles aren't
        # pulled off automatically.  This (I think) is a bug in matplotlib 1.0.1
        if "linestyle" in options:
            from sage.plot.misc import get_matplotlib_linestyle

            p.set_linestyle(get_matplotlib_linestyle(options["linestyle"], return_type="short"))
        subplot.add_line(p)
Beispiel #9
0
    def _render_on_subplot(self, subplot):
        """
        Render this line on a matplotlib subplot.

        INPUT:

        - ``subplot`` -- a matplotlib subplot

        EXAMPLES:

        This implicitly calls this function::

            sage: line([(1,2), (3,-4), (2, 5), (1,2)])
            Graphics object consisting of 1 graphics primitive
        """
        import matplotlib.lines as lines
        options = dict(self.options())
        for o in ('alpha', 'legend_color', 'legend_label', 'linestyle',
                  'rgbcolor', 'thickness'):
            if o in options:
                del options[o]
        p = lines.Line2D(self.xdata, self.ydata, **options)
        options = self.options()
        a = float(options['alpha'])
        p.set_alpha(a)
        p.set_linewidth(float(options['thickness']))
        p.set_color(to_mpl_color(options['rgbcolor']))
        p.set_label(options['legend_label'])
        # we don't pass linestyle in directly since the drawstyles aren't
        # pulled off automatically.  This (I think) is a bug in matplotlib 1.0.1
        if 'linestyle' in options:
            from sage.plot.misc import get_matplotlib_linestyle
            p.set_linestyle(get_matplotlib_linestyle(options['linestyle'],
                                                     return_type='short'))
        subplot.add_line(p)
Beispiel #10
0
    def _render_on_subplot(self, subplot):
        """
        TESTS::

            sage: D = disk((2,-1), 2, (0, pi), color='black', thickness=3, fill=False); D
            Graphics object consisting of 1 graphics primitive

        Save alpha information in pdf (see :trac:`13732`)::

            sage: f = tmp_filename(ext='.pdf')
            sage: p = disk((0,0), 5, (0, pi/4), alpha=0.5)
            sage: p.save(f)

        """
        import matplotlib.patches as patches
        options = self.options()
        deg1 = self.rad1*(180./pi) #convert radians to degrees
        deg2 = self.rad2*(180./pi)
        z = int(options.pop('zorder', 0))
        p = patches.Wedge((float(self.x), float(self.y)), float(self.r), float(deg1),
                            float(deg2), zorder=z)
        a = float(options['alpha'])
        p.set_alpha(a)
        p.set_linewidth(float(options['thickness']))
        p.set_fill(options['fill'])
        c = to_mpl_color(options['rgbcolor'])
        p.set_edgecolor(c)
        p.set_facecolor(c)
        p.set_label(options['legend_label'])
        subplot.add_patch(p)
Beispiel #11
0
    def _render_on_subplot(self, subplot):
        """
        TESTS::

            sage: D = disk((2,-1), 2, (0, pi), color='black', thickness=3, fill=False); D

        Save alpha information in pdf (see :trac:`13732`)::

            sage: f = tmp_filename(ext='.pdf')
            sage: p = disk((0,0), 5, (0, pi/4), alpha=0.5)
            sage: p.save(f)

        """
        import matplotlib.patches as patches
        options = self.options()
        deg1 = self.rad1*(180./pi) #convert radians to degrees
        deg2 = self.rad2*(180./pi)
        z = int(options.pop('zorder', 0))
        p = patches.Wedge((float(self.x), float(self.y)), float(self.r), float(deg1),
                            float(deg2), zorder=z)
        a = float(options['alpha'])
        p.set_alpha(a)
        p.set_linewidth(float(options['thickness']))
        p.set_fill(options['fill'])
        c = to_mpl_color(options['rgbcolor'])
        p.set_edgecolor(c)
        p.set_facecolor(c)
        p.set_label(options['legend_label'])
        subplot.add_patch(p)
Beispiel #12
0
    def _render_on_subplot(self, subplot):
        r"""
        TESTS:

        We check to make sure that \#2076 is fixed by verifying all
        the points are red::

            sage: point(((1,1), (2,2), (3,3)), rgbcolor=hue(1), size=30)
        """
        options = self.options()

        #Convert the color to a hex string so that the scatter
        #method does not interpret it as a list of 3 floating
        #point color specifications when there are
        #three points. This is mentioned in the matplotlib 0.98
        #documentation and fixes \#2076
        from matplotlib.colors import rgb2hex
        c = rgb2hex(to_mpl_color(options['rgbcolor']))

        a = float(options['alpha'])
        z = int(options.pop('zorder', 0))
        s = int(options['size'])
        faceted = options['faceted']  #faceted=True colors the edge of point
        scatteroptions = {}
        if not faceted: scatteroptions['edgecolors'] = 'none'
        subplot.scatter(self.xdata,
                        self.ydata,
                        s=s,
                        c=c,
                        alpha=a,
                        zorder=z,
                        label=options['legend_label'],
                        **scatteroptions)
Beispiel #13
0
    def _render_on_subplot(self, subplot):
        """
        TESTS::

            sage: A = arc((1,1),3,4,pi/4,(pi,4*pi/3)); A
        """
        import matplotlib.patches as patches

        options = self.options()

        p = patches.Arc(
                (self.x,self.y),
                2.*self.r1,
                2.*self.r2,
                fmod(self.angle,2*pi)*(180./pi),
                self.s1*(180./pi),
                self.s2*(180./pi))
        p.set_linewidth(float(options['thickness']))
        a = float(options['alpha'])
        p.set_alpha(a)
        z = int(options.pop('zorder',1))
        p.set_zorder(z)
        c = to_mpl_color(options['rgbcolor'])
        p.set_linestyle(options['linestyle'])
        p.set_edgecolor(c)
        subplot.add_patch(p)
Beispiel #14
0
    def _render_on_subplot(self, subplot):
        """
        Render this line on a matplotlib subplot.

        INPUT:

        - ``subplot`` -- a matplotlib subplot

        EXAMPLES:

        This implicitly calls this function::

            sage: line([(1,2), (3,-4), (2, 5), (1,2)])
            Graphics object consisting of 1 graphics primitive
        """
        import matplotlib.lines as lines
        options = dict(self.options())
        for o in ('alpha', 'legend_color', 'legend_label', 'linestyle',
                  'rgbcolor', 'thickness'):
            if o in options:
                del options[o]
        p = lines.Line2D(self.xdata, self.ydata, **options)
        options = self.options()
        a = float(options['alpha'])
        p.set_alpha(a)
        p.set_linewidth(float(options['thickness']))
        p.set_color(to_mpl_color(options['rgbcolor']))
        p.set_label(options['legend_label'])
        # we don't pass linestyle in directly since the drawstyles aren't
        # pulled off automatically.  This (I think) is a bug in matplotlib 1.0.1
        if 'linestyle' in options:
            from sage.plot.misc import get_matplotlib_linestyle
            p.set_linestyle(get_matplotlib_linestyle(options['linestyle'],
                                                     return_type='short'))
        subplot.add_line(p)
Beispiel #15
0
    def _render_on_subplot(self, subplot):
        """
        Render this arrow in a subplot.  This is the key function that
        defines how this arrow graphics primitive is rendered in
        matplotlib's library.

        EXAMPLES::

        This function implicitly ends up rendering this arrow on a matplotlib subplot:
            sage: arrow(path=[[(0,1), (2,-1), (4,5)]])
        """
        options = self.options()
        width = float(options['width'])
        head = options.pop('head')
        if head == 0: style = '<|-'
        elif head == 1: style = '-|>'
        elif head == 2: style = '<|-|>'
        else: raise KeyError('head parameter must be one of 0 (start), 1 (end) or 2 (both).')
        arrowsize = float(options.get('arrowsize',5))
        head_width=arrowsize
        head_length=arrowsize*2.0
        color = to_mpl_color(options['rgbcolor'])
        from matplotlib.patches import FancyArrowPatch
        from matplotlib.path import Path
        bpath = Path(self.vertices, self.codes)
        p = FancyArrowPatch(path=bpath,
                            lw=width, arrowstyle='%s,head_width=%s,head_length=%s'%(style,head_width, head_length), 
                            fc=color, ec=color, linestyle=options['linestyle'])
        p.set_zorder(options['zorder'])
        p.set_label(options['legend_label'])
        subplot.add_patch(p)
        return p
Beispiel #16
0
    def _render_on_subplot(self, subplot):
        """
        Render this line on a matplotlib subplot.

        INPUT:

        - ``subplot`` -- a matplotlib subplot

        EXAMPLES:

        This implicitly calls this function::

            sage: line([(1,2), (3,-4), (2, 5), (1,2)])
        """
        import matplotlib.lines as lines
        options = dict(self.options())
        del options['alpha']
        del options['thickness']
        del options['rgbcolor']
        del options['legend_label']
        if 'linestyle' in options:
            del options['linestyle']
        p = lines.Line2D(self.xdata, self.ydata, **options)
        options = self.options()
        a = float(options['alpha'])
        p.set_alpha(a)
        p.set_linewidth(float(options['thickness']))
        p.set_color(to_mpl_color(options['rgbcolor']))
        p.set_label(options['legend_label'])
        # we don't pass linestyle in directly since the drawstyles aren't
        # pulled off automatically.  This (I think) is a bug in matplotlib 1.0.1
        if 'linestyle' in options:
            p.set_linestyle(options['linestyle'])
        subplot.add_line(p)
Beispiel #17
0
    def _render_on_subplot(self, subplot):
        """
        Render this arrow in a subplot.  This is the key function that
        defines how this arrow graphics primitive is rendered in
        matplotlib's library.

        EXAMPLES:

        This function implicitly ends up rendering this arrow on
        a matplotlib subplot::

            sage: arrow((0,1), (2,-1))

        TESTS:

        The length of the ends (shrinkA and shrinkB) should not depend
        on the width of the arrow, because Matplotlib already takes
        this into account. See :trac:`12836`::

            sage: fig = Graphics().matplotlib()
            sage: sp = fig.add_subplot(1,1,1)
            sage: a = arrow((0,0), (1,1))
            sage: b = arrow((0,0), (1,1), width=20)
            sage: p1 = a[0]._render_on_subplot(sp)
            sage: p2 = b[0]._render_on_subplot(sp)
            sage: p1.shrinkA == p2.shrinkA
            True
            sage: p1.shrinkB == p2.shrinkB
            True

        """
        options = self.options()
        head = options.pop('head')
        if head == 0: style = '<|-'
        elif head == 1: style = '-|>'
        elif head == 2: style = '<|-|>'
        else:
            raise KeyError(
                'head parameter must be one of 0 (start), 1 (end) or 2 (both).'
            )
        width = float(options['width'])
        arrowshorten_end = float(options.get('arrowshorten', 0)) / 2.0
        arrowsize = float(options.get('arrowsize', 5))
        head_width = arrowsize
        head_length = arrowsize * 2.0
        color = to_mpl_color(options['rgbcolor'])
        from matplotlib.patches import FancyArrowPatch
        p = FancyArrowPatch((self.xtail, self.ytail), (self.xhead, self.yhead),
                            lw=width,
                            arrowstyle='%s,head_width=%s,head_length=%s' %
                            (style, head_width, head_length),
                            shrinkA=arrowshorten_end,
                            shrinkB=arrowshorten_end,
                            fc=color,
                            ec=color,
                            linestyle=options['linestyle'])
        p.set_zorder(options['zorder'])
        p.set_label(options['legend_label'])
        subplot.add_patch(p)
        return p
Beispiel #18
0
    def _render_on_subplot(self, subplot):
        """
        TESTS::

            sage: A = arc((1,1),3,4,pi/4,(pi,4*pi/3)); A
        """
        import matplotlib.patches as patches

        options = self.options()

        p = patches.Arc(
                (self.x,self.y),
                2.*self.r1,
                2.*self.r2,
                fmod(self.angle,2*pi)*(180./pi),
                self.s1*(180./pi),
                self.s2*(180./pi))
        p.set_linewidth(float(options['thickness']))
        a = float(options['alpha'])
        p.set_alpha(a)
        z = int(options.pop('zorder',1))
        p.set_zorder(z)
        c = to_mpl_color(options['rgbcolor'])
        p.set_linestyle(options['linestyle'])
        p.set_edgecolor(c)
        subplot.add_patch(p)
Beispiel #19
0
    def _render_on_subplot(self, subplot):
        """
        Render this line on a matplotlib subplot. 

        INPUT:

        - ``subplot`` -- a matplotlib subplot

        EXAMPLES:

        This implicitly calls this function::

            sage: line([(1,2), (3,-4), (2, 5), (1,2)])
        """
        import matplotlib.lines as lines
        options = dict(self.options())
        del options['alpha']
        del options['thickness']
        del options['rgbcolor']
        del options['legend_label']
        if 'linestyle' in options: 
            del options['linestyle']
        p = lines.Line2D(self.xdata, self.ydata, **options)
        options = self.options()
        a = float(options['alpha'])
        p.set_alpha(a)
        p.set_linewidth(float(options['thickness']))
        p.set_color(to_mpl_color(options['rgbcolor']))  
        p.set_label(options['legend_label'])
        # we don't pass linestyle in directly since the drawstyles aren't 
        # pulled off automatically.  This (I think) is a bug in matplotlib 1.0.1
        if 'linestyle' in options: 
            p.set_linestyle(options['linestyle']) 
        subplot.add_line(p)
Beispiel #20
0
    def _render_on_subplot(self, subplot):
        """
        TESTS::

            sage: A = arc((1,1),3,4,pi/4,(pi,4*pi/3)); A
            Graphics object consisting of 1 graphics primitive
        """
        import matplotlib.patches as patches
        from sage.plot.misc import get_matplotlib_linestyle


        options = self.options()

        p = patches.Arc(
                (self.x,self.y),
                2.*self.r1,
                2.*self.r2,
                fmod(self.angle,2*pi)*(180./pi),
                self.s1*(180./pi),
                self.s2*(180./pi))
        p.set_linewidth(float(options['thickness']))
        a = float(options['alpha'])
        p.set_alpha(a)
        z = int(options.pop('zorder',1))
        p.set_zorder(z)
        c = to_mpl_color(options['rgbcolor'])
        p.set_linestyle(get_matplotlib_linestyle(options['linestyle'],return_type='long'))
        p.set_edgecolor(c)
        subplot.add_patch(p)
Beispiel #21
0
    def _render_on_subplot(self, subplot):
        """
        Render this arrow in a subplot.  This is the key function that
        defines how this arrow graphics primitive is rendered in
        matplotlib's library.

        EXAMPLES:

        This function implicitly ends up rendering this arrow on 
        a matplotlib subplot::

            sage: arrow((0,1), (2,-1))

        TESTS:

        The length of the ends (shrinkA and shrinkB) should not depend
        on the width of the arrow, because Matplotlib already takes
        this into account. See :trac:`12836`::

            sage: fig = Graphics().matplotlib()
            sage: sp = fig.add_subplot(1,1,1)
            sage: a = arrow((0,0), (1,1))
            sage: b = arrow((0,0), (1,1), width=20)
            sage: p1 = a[0]._render_on_subplot(sp)
            sage: p2 = b[0]._render_on_subplot(sp)
            sage: p1.shrinkA == p2.shrinkA
            True
            sage: p1.shrinkB == p2.shrinkB
            True

        """
        options = self.options()
        head = options.pop('head')
        if head == 0: style = '<|-'
        elif head == 1: style = '-|>'
        elif head == 2: style = '<|-|>'
        else: raise KeyError('head parameter must be one of 0 (start), 1 (end) or 2 (both).')
        width = float(options['width'])
        arrowshorten_end = float(options.get('arrowshorten',0))/2.0
        arrowsize = float(options.get('arrowsize',5))
        head_width=arrowsize
        head_length=arrowsize*2.0
        color = to_mpl_color(options['rgbcolor'])
        from matplotlib.patches import FancyArrowPatch
        p = FancyArrowPatch((self.xtail, self.ytail), (self.xhead, self.yhead),
                            lw=width, arrowstyle='%s,head_width=%s,head_length=%s'%(style,head_width, head_length), 
                            shrinkA=arrowshorten_end, shrinkB=arrowshorten_end,
                            fc=color, ec=color, linestyle=options['linestyle'])
        p.set_zorder(options['zorder'])
        p.set_label(options['legend_label'])
        subplot.add_patch(p)
        return p
Beispiel #22
0
    def _render_on_subplot(self, subplot):
        """
        Render this arrow in a subplot.

        This is the key function that defines how this arrow graphics
        primitive is rendered in matplotlib's library.

        EXAMPLES:

        This function implicitly ends up rendering this arrow on a matplotlib
        subplot::

            sage: arrow(path=[[(0,1), (2,-1), (4,5)]])
            Graphics object consisting of 1 graphics primitive
        """
        from sage.plot.misc import get_matplotlib_linestyle

        options = self.options()
        width = float(options['width'])
        head = options.pop('head')
        if head == 0:
            style = '<|-'
        elif head == 1:
            style = '-|>'
        elif head == 2:
            style = '<|-|>'
        else:
            raise KeyError(
                'head parameter must be one of 0 (start), 1 (end) or 2 (both).'
            )
        arrowsize = float(options.get('arrowsize', 5))
        head_width = arrowsize
        head_length = arrowsize * 2.0
        color = to_mpl_color(options['rgbcolor'])
        from matplotlib.patches import FancyArrowPatch
        from matplotlib.path import Path
        bpath = Path(self.vertices, self.codes)
        p = FancyArrowPatch(path=bpath,
                            lw=width,
                            arrowstyle='%s,head_width=%s,head_length=%s' %
                            (style, head_width, head_length),
                            fc=color,
                            ec=color,
                            linestyle=get_matplotlib_linestyle(
                                options['linestyle'], return_type='long'))
        p.set_zorder(options['zorder'])
        p.set_label(options['legend_label'])
        subplot.add_patch(p)
        return p
Beispiel #23
0
    def _render_on_subplot(self, subplot):
        """
        Render this ellipse in a subplot.  This is the key function that
        defines how this ellipse graphics primitive is rendered in matplotlib's
        library.

        TESTS::

            sage: ellipse((0,0),3,1,pi/6,fill=True,alpha=0.3)
            Graphics object consisting of 1 graphics primitive

        ::

            sage: ellipse((3,2),1,2)
            Graphics object consisting of 1 graphics primitive
        """
        import matplotlib.patches as patches
        from sage.plot.misc import get_matplotlib_linestyle

        options = self.options()
        p = patches.Ellipse((self.x, self.y), self.r1 * 2.0, self.r2 * 2.0, self.angle / pi * 180.0)
        p.set_linewidth(float(options["thickness"]))
        p.set_fill(options["fill"])
        a = float(options["alpha"])
        p.set_alpha(a)
        ec = to_mpl_color(options["edgecolor"])
        fc = to_mpl_color(options["facecolor"])
        if "rgbcolor" in options:
            ec = fc = to_mpl_color(options["rgbcolor"])
        p.set_edgecolor(ec)
        p.set_facecolor(fc)
        p.set_linestyle(get_matplotlib_linestyle(options["linestyle"], return_type="long"))
        p.set_label(options["legend_label"])
        z = int(options.pop("zorder", 0))
        p.set_zorder(z)
        subplot.add_patch(p)
Beispiel #24
0
    def _render_on_subplot(self, subplot):
        """
        Render this arrow in a subplot.  This is the key function that
        defines how this arrow graphics primitive is rendered in
        matplotlib's library.

        EXAMPLES::

        This function implicitly ends up rendering this arrow on a matplotlib subplot:
            sage: arrow(path=[[(0,1), (2,-1), (4,5)]])
            Graphics object consisting of 1 graphics primitive
        """
        from sage.plot.misc import get_matplotlib_linestyle

        options = self.options()
        width = float(options["width"])
        head = options.pop("head")
        if head == 0:
            style = "<|-"
        elif head == 1:
            style = "-|>"
        elif head == 2:
            style = "<|-|>"
        else:
            raise KeyError("head parameter must be one of 0 (start), 1 (end) or 2 (both).")
        arrowsize = float(options.get("arrowsize", 5))
        head_width = arrowsize
        head_length = arrowsize * 2.0
        color = to_mpl_color(options["rgbcolor"])
        from matplotlib.patches import FancyArrowPatch
        from matplotlib.path import Path

        bpath = Path(self.vertices, self.codes)
        p = FancyArrowPatch(
            path=bpath,
            lw=width,
            arrowstyle="%s,head_width=%s,head_length=%s" % (style, head_width, head_length),
            fc=color,
            ec=color,
        )
        p.set_linestyle(get_matplotlib_linestyle(options["linestyle"], return_type="long"))
        p.set_zorder(options["zorder"])
        p.set_label(options["legend_label"])
        subplot.add_patch(p)
        return p
Beispiel #25
0
    def _render_on_subplot(self, subplot):
        """
        Render this Bezier path in a subplot.  This is the key function that
        defines how this Bezier path graphics primitive is rendered in matplotlib's
        library.

        TESTS::

            sage: bezier_path([[(0,1),(.5,0),(1,1)]])
            Graphics object consisting of 1 graphics primitive

        ::

            sage: bezier_path([[(0,1),(.5,0),(1,1),(-3,5)]])
            Graphics object consisting of 1 graphics primitive
        """
        from matplotlib.patches import PathPatch
        from matplotlib.path import Path
        from sage.plot.misc import get_matplotlib_linestyle

        options = dict(self.options())

        del options['alpha']
        del options['thickness']
        del options['rgbcolor']
        del options['zorder']
        del options['fill']
        del options['linestyle']

        bpath = Path(self.vertices, self.codes)
        bpatch = PathPatch(bpath, **options)
        options = self.options()
        bpatch.set_linewidth(float(options['thickness']))
        bpatch.set_fill(options['fill'])
        bpatch.set_zorder(options['zorder'])
        a = float(options['alpha'])
        bpatch.set_alpha(a)
        c = to_mpl_color(options['rgbcolor'])
        bpatch.set_edgecolor(c)
        bpatch.set_facecolor(c)
        bpatch.set_linestyle(
            get_matplotlib_linestyle(options['linestyle'], return_type='long'))
        subplot.add_patch(bpatch)
Beispiel #26
0
    def _render_on_subplot(self, subplot):
        """
        Render this arrow in a subplot.  This is the key function that
        defines how this arrow graphics primitive is rendered in
        matplotlib's library.

        EXAMPLES:

        This function implicitly ends up rendering this arrow on 
        a matplotlib subplot::

            sage: arrow((0,1), (2,-1))
        """
        options = self.options()
        head = options.pop('head')
        if head == 0: style = '<|-'
        elif head == 1: style = '-|>'
        elif head == 2: style = '<|-|>'
        else:
            raise KeyError(
                'head parameter must be one of 0 (start), 1 (end) or 2 (both).'
            )
        width = float(options['width'])
        arrowshorten_end = float(options.get('arrowshorten',
                                             0)) / 2.0 + width * 2
        arrowsize = float(options.get('arrowsize', 5))
        head_width = arrowsize
        head_length = arrowsize * 2.0
        color = to_mpl_color(options['rgbcolor'])
        from matplotlib.patches import FancyArrowPatch
        p = FancyArrowPatch((self.xtail, self.ytail), (self.xhead, self.yhead),
                            lw=width,
                            arrowstyle='%s,head_width=%s,head_length=%s' %
                            (style, head_width, head_length),
                            shrinkA=arrowshorten_end,
                            shrinkB=arrowshorten_end,
                            fc=color,
                            ec=color,
                            linestyle=options['linestyle'])
        p.set_zorder(options['zorder'])
        p.set_label(options['legend_label'])
        subplot.add_patch(p)
        return p
Beispiel #27
0
    def _render_on_subplot(self, subplot):
        """
        Render this Bezier path in a subplot.  This is the key function that
        defines how this Bezier path graphics primitive is rendered in matplotlib's
        library.

        TESTS::

            sage: bezier_path([[(0,1),(.5,0),(1,1)]])
            Graphics object consisting of 1 graphics primitive

        ::

            sage: bezier_path([[(0,1),(.5,0),(1,1),(-3,5)]])
            Graphics object consisting of 1 graphics primitive
        """
        from matplotlib.patches import PathPatch
        from matplotlib.path import Path
        from sage.plot.misc import get_matplotlib_linestyle

        options = dict(self.options())

        del options['alpha']
        del options['thickness']
        del options['rgbcolor']
        del options['zorder']
        del options['fill']
        del options['linestyle']

        bpath = Path(self.vertices, self.codes)
        bpatch = PathPatch(bpath, **options)
        options = self.options()
        bpatch.set_linewidth(float(options['thickness']))
        bpatch.set_fill(options['fill'])
        bpatch.set_zorder(options['zorder'])
        a = float(options['alpha'])
        bpatch.set_alpha(a)
        c = to_mpl_color(options['rgbcolor'])
        bpatch.set_edgecolor(c)
        bpatch.set_facecolor(c)
        bpatch.set_linestyle(get_matplotlib_linestyle(options['linestyle'], return_type='long'))
        subplot.add_patch(bpatch)
Beispiel #28
0
    def _render_on_subplot(self, subplot):
        """
        TESTS::

            sage: D = disk((2,-1), 2, (0, pi), color='black', thickness=3, fill=False); D
        """
        import matplotlib.patches as patches        
        options = self.options()
        deg1 = self.rad1*(180./pi) #convert radians to degrees 
        deg2 = self.rad2*(180./pi)
        z = int(options.pop('zorder', 0))
        p = patches.Wedge((float(self.x), float(self.y)), float(self.r), float(deg1),
                            float(deg2), zorder=z)
        p.set_linewidth(float(options['thickness']))
        p.set_fill(options['fill'])
        p.set_alpha(options['alpha'])
        c = to_mpl_color(options['rgbcolor'])
        p.set_edgecolor(c)
        p.set_facecolor(c)
        p.set_label(options['legend_label'])
        subplot.add_patch(p)
Beispiel #29
0
    def _render_on_subplot(self, subplot):
        """
        TESTS::

            sage: D = disk((2,-1), 2, (0, pi), color='black', thickness=3, fill=False); D
        """
        import matplotlib.patches as patches        
        options = self.options()
        deg1 = self.rad1*(180./pi) #convert radians to degrees 
        deg2 = self.rad2*(180./pi)
        z = int(options.pop('zorder', 0))
        p = patches.Wedge((float(self.x), float(self.y)), float(self.r), float(deg1),
                            float(deg2), zorder=z)
        p.set_linewidth(float(options['thickness']))
        p.set_fill(options['fill'])
        p.set_alpha(options['alpha'])
        c = to_mpl_color(options['rgbcolor'])
        p.set_edgecolor(c)
        p.set_facecolor(c)
        p.set_label(options['legend_label'])
        subplot.add_patch(p)
Beispiel #30
0
    def _render_on_subplot(self, subplot):
        """
        TESTS::

            sage: A = arc((1,1),3,4,pi/4,(pi,4*pi/3)); A
            Graphics object consisting of 1 graphics primitive
        """
        from sage.plot.misc import get_matplotlib_linestyle

        options = self.options()

        p = self._matplotlib_arc()
        p.set_linewidth(float(options['thickness']))
        a = float(options['alpha'])
        p.set_alpha(a)
        z = int(options.pop('zorder', 1))
        p.set_zorder(z)
        c = to_mpl_color(options['rgbcolor'])
        p.set_linestyle(
            get_matplotlib_linestyle(options['linestyle'], return_type='long'))
        p.set_edgecolor(c)
        subplot.add_patch(p)
Beispiel #31
0
    def _render_on_subplot(self, subplot):
        """
        TESTS::

            sage: A = arc((1,1),3,4,pi/4,(pi,4*pi/3)); A
            Graphics object consisting of 1 graphics primitive
        """
        from sage.plot.misc import get_matplotlib_linestyle

        options = self.options()

        p = self._matplotlib_arc()
        p.set_linewidth(float(options['thickness']))
        a = float(options['alpha'])
        p.set_alpha(a)
        z = int(options.pop('zorder', 1))
        p.set_zorder(z)
        c = to_mpl_color(options['rgbcolor'])
        p.set_linestyle(get_matplotlib_linestyle(options['linestyle'],
                                                 return_type='long'))
        p.set_edgecolor(c)
        subplot.add_patch(p)
    def _render_on_subplot(self, subplot):
        r"""
        Render this arrow in a subplot.

        This version of the method uses a narrower arrow head,
        which is not customizable by parameters in the Sage class.
        """

        from sage.plot.misc import get_matplotlib_linestyle

        options = self.options()
        head = options.pop('head')
        if head == 0: style = '<|-'
        elif head == 1: style = '-|>'
        elif head == 2: style = '<|-|>'
        else: raise KeyError('head parameter must be one of 0 (start), 1 (end) or 2 (both).')
        style='fancy'
        width = float(options['width'])
        arrowshorten_end = float(options.get('arrowshorten', 0)) / 2.0
        arrowsize = float(options.get('arrowsize', 5))
        #head_width = arrowsize * 0.5
        head_width = arrowsize * 0.7
        tail_width = arrowsize * 0.7
        head_length = arrowsize * 2.0
        color = to_mpl_color(options['rgbcolor'])
        from matplotlib.patches import FancyArrowPatch
        p = FancyArrowPatch((self.xtail, self.ytail), (self.xhead, self.yhead),
                            lw=width,
                            arrowstyle='%s,head_width=%s,head_length=%s,tail_width=%s' % (style, head_width, head_length, tail_width),
                            shrinkA=arrowshorten_end, shrinkB=arrowshorten_end,
                            fc=color, ec=color,
                            linestyle=get_matplotlib_linestyle(options['linestyle'], return_type='long'))
        p.set_zorder(options['zorder'])
        p.set_label(options['legend_label'])

        subplot.add_patch(p)
        return p
Beispiel #33
0
def text(string, xy, **options):
    r"""
    Returns a 2D text graphics object at the point `(x,y)`.

    Type ``text.options`` for a dictionary of options for 2D text.

    2D OPTIONS:

    - ``fontsize`` - How big the text is. Either an integer that
      specifies the size in points or a string which specifies a size (one of
      'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large')

    - ``fontstyle`` - A string either 'normal', 'italic' or 'oblique'

    - ``fontweight`` - A numeric value in the range 0-1000 or a string (one of
      'ultralight', 'light', 'normal', 'regular', 'book',' 'medium', 'roman',
      'semibold', 'demibold', 'demi', 'bold', 'heavy', 'extra bold', 'black')

    - ``rgbcolor`` - The color as an RGB tuple

    - ``hue`` - The color given as a hue

    - ``alpha`` - A float (0.0 transparent through 1.0 opaque)

    - ``background_color`` - The background color

    - ``rotation`` - How to rotate the text: angle in degrees, vertical, horizontal

    - ``vertical_alignment`` - How to align vertically: top, center, bottom

    - ``horizontal_alignment`` - How to align horizontally: left, center, right

    - ``zorder`` - The layer level in which to draw

    - ``clip`` - (default: False) Whether to clip or not

    - ``axis_coords`` - (default: False) If True, use axis coordinates, so that
      (0,0) is the lower left and (1,1) upper right, regardless of the x and y
      range of plotted values.

    - ``bounding_box`` - A dictionary specifying a bounding box. Currently the text location.

    EXAMPLES::

        sage: text("Sage graphics are really neat because they use matplotlib!", (2,12))
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

        t = "Sage graphics are really neat because they use matplotlib!"
        sphinx_plot(text(t,(2,12)))

    Larger font, bold, colored red and transparent text::

        sage: text("I had a dream!", (2,12), alpha=0.3, fontsize='large', fontweight='bold', color='red')
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

        sphinx_plot(text("I had a dream!", (2,12), alpha=0.3, fontsize='large', fontweight='bold', color='red'))

    By setting ``horizontal_alignment`` to 'left' the text is guaranteed to be
    in the lower left no matter what::

        sage: text("I got a horse and he lives in a tree", (0,0), axis_coords=True, horizontal_alignment='left')
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

        t = "I got a horse and he lives in a tree"
        sphinx_plot(text(t, (0,0), axis_coords=True, horizontal_alignment='left'))

    Various rotations::

        sage: text("noitator", (0,0), rotation=45.0, horizontal_alignment='left', vertical_alignment='bottom')
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

        sphinx_plot(text("noitator", (0,0), rotation=45.0, horizontal_alignment='left', vertical_alignment='bottom'))

    ::

        sage: text("Sage is really neat!!",(0,0), rotation="vertical")
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

        sphinx_plot(text("Sage is really neat!!",(0,0), rotation="vertical"))

    You can also align text differently::

        sage: t1 = text("Hello",(1,1), vertical_alignment="top")
        sage: t2 = text("World", (1,0.5), horizontal_alignment="left")
        sage: t1 + t2   # render the sum
        Graphics object consisting of 2 graphics primitives

    .. PLOT::

        t1 = text("Hello",(1,1), vertical_alignment="top")
        t2 = text("World", (1,0.5), horizontal_alignment="left")
        sphinx_plot(t1 + t2)

    You can save text as part of PDF output::

        sage: text("sage", (0,0), rgbcolor=(0,0,0)).save(os.path.join(SAGE_TMP, 'a.pdf'))

    Some examples of bounding box::

        sage: bbox = {'boxstyle':"rarrow,pad=0.3", 'fc':"cyan", 'ec':"b", 'lw':2}
        sage: text("I feel good", (1,2), bounding_box=bbox)
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

         bbox = {'boxstyle':"rarrow,pad=0.3", 'fc':"cyan", 'ec':"b", 'lw':2}
         sphinx_plot(text("I feel good", (1,2), bounding_box=bbox))

    ::

        sage: text("So good", (0,0), bounding_box={'boxstyle':'round', 'fc':'w'})
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

        bbox = {'boxstyle':'round', 'fc':'w'}
        sphinx_plot(text("So good", (0,0), bounding_box=bbox))

    The possible options of the bounding box are 'boxstyle' (one of 'larrow',
    'rarrow', 'round', 'round4', 'roundtooth', 'sawtooth', 'square'), 'fc' or
    'facecolor', 'ec' or 'edgecolor', 'ha' or 'horizontalalignment', 'va' or
    'verticalalignment', 'lw' or 'linewidth'.

    A text with a background color::

        sage: text("So good", (-2,2), background_color='red')
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

        sphinx_plot(text("So good", (-2,2), background_color='red'))

    Text must be 2D (use the text3d command for 3D text)::

        sage: t = text("hi",(1,2,3))
        Traceback (most recent call last):
        ...
        ValueError: use text3d instead for text in 3d
        sage: t = text3d("hi",(1,2,3))

    Extra options will get passed on to show(), as long as they are valid::

        sage: text("MATH IS AWESOME", (0, 0), fontsize=40, axes=False)
        Graphics object consisting of 1 graphics primitive
        sage: text("MATH IS AWESOME", (0, 0), fontsize=40).show(axes=False) # These are equivalent
    """
    try:
        x, y = xy
    except ValueError:
        if isinstance(xy, (list, tuple)) and len(xy) == 3:
            raise ValueError("use text3d instead for text in 3d")
        raise
    from sage.plot.all import Graphics
    options['rgbcolor'] = to_mpl_color(options['rgbcolor'])
    point = (float(x), float(y))
    g = Graphics()
    g._set_extra_kwds(Graphics._extract_kwds_for_show(options, ignore='fontsize'))
    g.add_primitive(Text(string, point, options))
    return g
Beispiel #34
0
    def _render_on_subplot(self, subplot):
        r"""
        Render this arrow in a subplot.  This is the key function that
        defines how this arrow graphics primitive is rendered in
        matplotlib's library.

        EXAMPLES:

        This function implicitly ends up rendering this arrow on
        a matplotlib subplot::

            sage: arrow((0,1), (2,-1))
            Graphics object consisting of 1 graphics primitive

        TESTS:

        The length of the ends (shrinkA and shrinkB) should not depend
        on the width of the arrow, because Matplotlib already takes
        this into account. See :trac:`12836`::

            sage: fig = Graphics().matplotlib()
            sage: sp = fig.add_subplot(1,1,1)
            sage: a = arrow((0,0), (1,1))
            sage: b = arrow((0,0), (1,1), width=20)
            sage: p1 = a[0]._render_on_subplot(sp)
            sage: p2 = b[0]._render_on_subplot(sp)
            sage: p1.shrinkA == p2.shrinkA
            True
            sage: p1.shrinkB == p2.shrinkB
            True

        Dashed arrows should have solid arrowheads,
        :trac:`12852`. This test saves the plot of a dashed arrow to
        an EPS file. Within the EPS file, ``stroke`` will be called
        twice: once to draw the line, and again to draw the
        arrowhead. We check that both calls do not occur while the
        dashed line style is enabled::

            sage: a = arrow((0,0), (1,1), linestyle='dashed')
            sage: filename = tmp_filename(ext='.eps')
            sage: a.save(filename=filename)
            sage: with open(filename, 'r') as f:
            ....:     contents = f.read().replace('\n', ' ')
            sage: two_stroke_pattern = r'setdash.*stroke.*stroke.*setdash'
            sage: import re
            sage: two_stroke_re = re.compile(two_stroke_pattern)
            sage: two_stroke_re.search(contents) is None
            True
        """
        from sage.plot.misc import get_matplotlib_linestyle

        options = self.options()
        head = options.pop('head')
        if head == 0: style = '<|-'
        elif head == 1: style = '-|>'
        elif head == 2: style = '<|-|>'
        else:
            raise KeyError(
                'head parameter must be one of 0 (start), 1 (end) or 2 (both).'
            )
        width = float(options['width'])
        arrowshorten_end = float(options.get('arrowshorten', 0)) / 2.0
        arrowsize = float(options.get('arrowsize', 5))
        head_width = arrowsize
        head_length = arrowsize * 2.0
        color = to_mpl_color(options['rgbcolor'])
        from matplotlib.patches import FancyArrowPatch
        p = FancyArrowPatch((self.xtail, self.ytail), (self.xhead, self.yhead),
                            lw=width,
                            arrowstyle='%s,head_width=%s,head_length=%s' %
                            (style, head_width, head_length),
                            shrinkA=arrowshorten_end,
                            shrinkB=arrowshorten_end,
                            fc=color,
                            ec=color)
        p.set_linestyle(
            get_matplotlib_linestyle(options['linestyle'], return_type='long'))
        p.set_zorder(options['zorder'])
        p.set_label(options['legend_label'])

        if options['linestyle'] != 'solid':
            # The next few lines work around a design issue in matplotlib. Currently, the specified
            # linestyle is used to draw both the path and the arrowhead.  If linestyle is 'dashed', this
            # looks really odd.  This code is from Jae-Joon Lee in response to a post to the matplotlib mailing
            # list.  See http://sourceforge.net/mailarchive/forum.php?thread_name=CAG%3DuJ%2Bnw2dE05P9TOXTz_zp-mGP3cY801vMH7yt6vgP9_WzU8w%40mail.gmail.com&forum_name=matplotlib-users

            import matplotlib.patheffects as pe

            class CheckNthSubPath(object):
                def __init__(self, patch, n):
                    """
                    creates an callable object that returns True if the provided
                    path is the n-th path from the patch.
                    """
                    self._patch = patch
                    self._n = n

                def get_paths(self, renderer):
                    self._patch.set_dpi_cor(renderer.points_to_pixels(1.))
                    paths, fillables = self._patch.get_path_in_displaycoord()
                    return paths

                def __call__(self, renderer, gc, tpath, affine, rgbFace):
                    path = self.get_paths(renderer)[self._n]
                    vert1, code1 = path.vertices, path.codes
                    import numpy as np

                    return np.array_equal(vert1,
                                          tpath.vertices) and np.array_equal(
                                              code1, tpath.codes)

            class ConditionalStroke(pe.RendererBase):
                def __init__(self, condition_func, pe_list):
                    """
                    path effect that is only applied when the condition_func
                    returns True.
                    """
                    super(ConditionalStroke, self).__init__()
                    self._pe_list = pe_list
                    self._condition_func = condition_func

                def draw_path(self, renderer, gc, tpath, affine, rgbFace):

                    if self._condition_func(renderer, gc, tpath, affine,
                                            rgbFace):
                        for pe1 in self._pe_list:
                            pe1.draw_path(renderer, gc, tpath, affine, rgbFace)

            pe1 = ConditionalStroke(CheckNthSubPath(p, 0), [pe.Stroke()])
            pe2 = ConditionalStroke(CheckNthSubPath(p, 1),
                                    [pe.Stroke(linestyle="solid")])
            p.set_path_effects([pe1, pe2])

        subplot.add_patch(p)
        return p
Beispiel #35
0
    def _render_on_subplot(self, subplot):
        r"""
        Render this arrow in a subplot.  This is the key function that
        defines how this arrow graphics primitive is rendered in
        matplotlib's library.

        EXAMPLES:

        This function implicitly ends up rendering this arrow on
        a matplotlib subplot::

            sage: arrow((0,1), (2,-1))
            Graphics object consisting of 1 graphics primitive

        TESTS:

        The length of the ends (shrinkA and shrinkB) should not depend
        on the width of the arrow, because Matplotlib already takes
        this into account. See :trac:`12836`::

            sage: fig = Graphics().matplotlib()
            sage: sp = fig.add_subplot(1,1,1, label='axis1')
            sage: a = arrow((0,0), (1,1))
            sage: b = arrow((0,0), (1,1), width=20)
            sage: p1 = a[0]._render_on_subplot(sp)
            sage: p2 = b[0]._render_on_subplot(sp)
            sage: p1.shrinkA == p2.shrinkA
            True
            sage: p1.shrinkB == p2.shrinkB
            True

        Dashed arrows should have solid arrowheads, :trac:`12852`. We tried to
        make up a test for this, which turned out to be fragile and hence was
        removed. In general, robust testing of graphics seems basically need a
        human eye or AI.
        """
        from sage.plot.misc import get_matplotlib_linestyle

        options = self.options()
        head = options.pop('head')
        if head == 0: style = '<|-'
        elif head == 1: style = '-|>'
        elif head == 2: style = '<|-|>'
        else:
            raise KeyError(
                'head parameter must be one of 0 (start), 1 (end) or 2 (both).'
            )
        width = float(options['width'])
        arrowshorten_end = float(options.get('arrowshorten', 0)) / 2.0
        arrowsize = float(options.get('arrowsize', 5))
        head_width = arrowsize
        head_length = arrowsize * 2.0
        color = to_mpl_color(options['rgbcolor'])
        from matplotlib.patches import FancyArrowPatch
        p = FancyArrowPatch(
            (self.xtail, self.ytail), (self.xhead, self.yhead),
            lw=width,
            arrowstyle='%s,head_width=%s,head_length=%s' %
            (style, head_width, head_length),
            shrinkA=arrowshorten_end,
            shrinkB=arrowshorten_end,
            fc=color,
            ec=color,
            linestyle=get_matplotlib_linestyle(options['linestyle'],
                                               return_type='long'))
        p.set_zorder(options['zorder'])
        p.set_label(options['legend_label'])

        if options['linestyle'] != 'solid':
            # The next few lines work around a design issue in matplotlib.
            # Currently, the specified linestyle is used to draw both the path
            # and the arrowhead.  If linestyle is 'dashed', this looks really
            # odd. This code is from Jae-Joon Lee in response to a post to the
            # matplotlib mailing list.
            # See http://sourceforge.net/mailarchive/forum.php?thread_name=CAG%3DuJ%2Bnw2dE05P9TOXTz_zp-mGP3cY801vMH7yt6vgP9_WzU8w%40mail.gmail.com&forum_name=matplotlib-users

            import matplotlib.patheffects as pe

            class CheckNthSubPath(object):
                def __init__(self, patch, n):
                    """
                    creates an callable object that returns True if the
                    provided path is the n-th path from the patch.
                    """
                    self._patch = patch
                    self._n = n

                def get_paths(self, renderer):
                    self._patch.set_dpi_cor(renderer.points_to_pixels(1.))
                    paths, fillables = self._patch.get_path_in_displaycoord()
                    return paths

                def __call__(self, renderer, gc, tpath, affine, rgbFace):
                    path = self.get_paths(renderer)[self._n]
                    vert1, code1 = path.vertices, path.codes
                    import numpy as np

                    return np.array_equal(vert1,
                                          tpath.vertices) and np.array_equal(
                                              code1, tpath.codes)

            class ConditionalStroke(pe.RendererBase):
                def __init__(self, condition_func, pe_list):
                    """
                    path effect that is only applied when the condition_func
                    returns True.
                    """
                    super(ConditionalStroke, self).__init__()
                    self._pe_list = pe_list
                    self._condition_func = condition_func

                def draw_path(self, renderer, gc, tpath, affine, rgbFace):

                    if self._condition_func(renderer, gc, tpath, affine,
                                            rgbFace):
                        for pe1 in self._pe_list:
                            pe1.draw_path(renderer, gc, tpath, affine, rgbFace)

            pe1 = ConditionalStroke(CheckNthSubPath(p, 0), [pe.Stroke()])
            pe2 = ConditionalStroke(
                CheckNthSubPath(p, 1),
                [pe.Stroke(dashes={
                    'dash_offset': 0,
                    'dash_list': None
                })])
            p.set_path_effects([pe1, pe2])

        subplot.add_patch(p)
        return p
Beispiel #36
0
def text(string, xy, **options):
    r"""
    Returns a 2D text graphics object at the point `(x,y)`.

    Type ``text.options`` for a dictionary of options for 2D text.

    2D OPTIONS:

    - ``fontsize`` - How big the text is

    - ``rgbcolor`` - The color as an RGB tuple

    - ``hue`` - The color given as a hue

    - ``rotation`` - How to rotate the text: angle in degrees, vertical, horizontal

    - ``vertical_alignment`` - How to align vertically: top, center, bottom

    - ``horizontal_alignment`` - How to align horizontally: left, center, right

    - ``axis_coords`` - (default: False) if True, use axis coordinates, so that
      (0,0) is the lower left and (1,1) upper right, regardless of the x and y
      range of plotted values.

    EXAMPLES::

        sage: text("Sage is really neat!!",(2,12))
        Graphics object consisting of 1 graphics primitive

    The same text in larger font and colored red::

        sage: text("Sage is really neat!!",(2,12),fontsize=20,rgbcolor=(1,0,0))
        Graphics object consisting of 1 graphics primitive

    Same text but guaranteed to be in the lower left no matter what::

        sage: text("Sage is really neat!!",(0,0), axis_coords=True, horizontal_alignment='left')
        Graphics object consisting of 1 graphics primitive

    Same text rotated around the left, bottom corner of the text::

        sage: text("Sage is really neat!!",(0,0), rotation=45.0, horizontal_alignment='left', vertical_alignment='bottom')
        Graphics object consisting of 1 graphics primitive

    Same text oriented vertically::

        sage: text("Sage is really neat!!",(0,0), rotation="vertical")
        Graphics object consisting of 1 graphics primitive

    You can also align text differently::

        sage: t1 = text("Hello",(1,1), vertical_alignment="top")
        sage: t2 = text("World", (1,0.5), horizontal_alignment="left")
        sage: t1 + t2   # render the sum
        Graphics object consisting of 2 graphics primitives

    You can save text as part of PDF output::

        sage: text("sage", (0,0), rgbcolor=(0,0,0)).save(os.path.join(SAGE_TMP, 'a.pdf'))

    Text must be 2D (use the text3d command for 3D text)::

        sage: t = text("hi",(1,2,3))
        Traceback (most recent call last):
        ...
        ValueError: use text3d instead for text in 3d
        sage: t = text3d("hi",(1,2,3))

    Extra options will get passed on to show(), as long as they are valid::

        sage: text("MATH IS AWESOME", (0, 0), fontsize=40, axes=False)
        Graphics object consisting of 1 graphics primitive
        sage: text("MATH IS AWESOME", (0, 0), fontsize=40).show(axes=False) # These are equivalent
    """
    try:
        x, y = xy
    except ValueError:
        if isinstance(xy, (list, tuple)) and len(xy) == 3:
            raise ValueError("use text3d instead for text in 3d")
        raise
    from sage.plot.all import Graphics
    options['rgbcolor'] = to_mpl_color(options['rgbcolor'])
    point = (float(x), float(y))
    g = Graphics()
    g._set_extra_kwds(
        Graphics._extract_kwds_for_show(options, ignore='fontsize'))
    g.add_primitive(Text(string, point, options))
    return g
Beispiel #37
0
def text(string, xy, **options):
    r"""
    Returns a 2D text graphics object at the point `(x,y)`.

    Type ``text.options`` for a dictionary of options for 2D text.

    2D OPTIONS:

    - ``fontsize`` - How big the text is. Either an integer that
      specifies the size in points or a string which specifies a size (one of
      'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large')

    - ``fontstyle`` - A string either 'normal', 'italic' or 'oblique'

    - ``fontweight`` - A numeric value in the range 0-1000 or a string (one of
      'ultralight', 'light', 'normal', 'regular', 'book',' 'medium', 'roman',
      'semibold', 'demibold', 'demi', 'bold', 'heavy', 'extra bold', 'black')

    - ``rgbcolor`` - The color as an RGB tuple

    - ``hue`` - The color given as a hue

    - ``alpha`` - A float (0.0 transparent through 1.0 opaque)

    - ``background_color`` - The background color

    - ``rotation`` - How to rotate the text: angle in degrees, vertical, horizontal

    - ``vertical_alignment`` - How to align vertically: top, center, bottom

    - ``horizontal_alignment`` - How to align horizontally: left, center, right

    - ``zorder`` - The layer level in which to draw

    - ``clip`` - (default: False) Whether to clip or not

    - ``axis_coords`` - (default: False) If True, use axis coordinates, so that
      (0,0) is the lower left and (1,1) upper right, regardless of the x and y
      range of plotted values.

    - ``bounding_box`` - A dictionary specifying a bounding box. Currently the text location.

    EXAMPLES::

        sage: text("Sage graphics are really neat because they use matplotlib!", (2,12))
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

        t = "Sage graphics are really neat because they use matplotlib!"
        sphinx_plot(text(t,(2,12)))

    Larger font, bold, colored red and transparent text::

        sage: text("I had a dream!", (2,12), alpha=0.3, fontsize='large', fontweight='bold', color='red')
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

        sphinx_plot(text("I had a dream!", (2,12), alpha=0.3, fontsize='large', fontweight='bold', color='red'))

    By setting ``horizontal_alignment`` to 'left' the text is guaranteed to be
    in the lower left no matter what::

        sage: text("I got a horse and he lives in a tree", (0,0), axis_coords=True, horizontal_alignment='left')
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

        t = "I got a horse and he lives in a tree"
        sphinx_plot(text(t, (0,0), axis_coords=True, horizontal_alignment='left'))

    Various rotations::

        sage: text("noitator", (0,0), rotation=45.0, horizontal_alignment='left', vertical_alignment='bottom')
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

        sphinx_plot(text("noitator", (0,0), rotation=45.0, horizontal_alignment='left', vertical_alignment='bottom'))

    ::

        sage: text("Sage is really neat!!",(0,0), rotation="vertical")
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

        sphinx_plot(text("Sage is really neat!!",(0,0), rotation="vertical"))

    You can also align text differently::

        sage: t1 = text("Hello",(1,1), vertical_alignment="top")
        sage: t2 = text("World", (1,0.5), horizontal_alignment="left")
        sage: t1 + t2   # render the sum
        Graphics object consisting of 2 graphics primitives

    .. PLOT::

        t1 = text("Hello",(1,1), vertical_alignment="top")
        t2 = text("World", (1,0.5), horizontal_alignment="left")
        sphinx_plot(t1 + t2)

    You can save text as part of PDF output::

        sage: text("sage", (0,0), rgbcolor=(0,0,0)).save(os.path.join(SAGE_TMP, 'a.pdf'))

    Some examples of bounding box::

        sage: bbox = {'boxstyle':"rarrow,pad=0.3", 'fc':"cyan", 'ec':"b", 'lw':2}
        sage: text("I feel good", (1,2), bounding_box=bbox)
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

         bbox = {'boxstyle':"rarrow,pad=0.3", 'fc':"cyan", 'ec':"b", 'lw':2}
         sphinx_plot(text("I feel good", (1,2), bounding_box=bbox))

    ::

        sage: text("So good", (0,0), bounding_box={'boxstyle':'round', 'fc':'w'})
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

        bbox = {'boxstyle':'round', 'fc':'w'}
        sphinx_plot(text("So good", (0,0), bounding_box=bbox))

    The possible options of the bounding box are 'boxstyle' (one of 'larrow',
    'rarrow', 'round', 'round4', 'roundtooth', 'sawtooth', 'square'), 'fc' or
    'facecolor', 'ec' or 'edgecolor', 'ha' or 'horizontalalignment', 'va' or
    'verticalalignment', 'lw' or 'linewidth'.

    A text with a background color::

        sage: text("So good", (-2,2), background_color='red')
        Graphics object consisting of 1 graphics primitive

    .. PLOT::

        sphinx_plot(text("So good", (-2,2), background_color='red'))

    Text must be 2D (use the text3d command for 3D text)::

        sage: t = text("hi",(1,2,3))
        Traceback (most recent call last):
        ...
        ValueError: use text3d instead for text in 3d
        sage: t = text3d("hi",(1,2,3))

    Extra options will get passed on to show(), as long as they are valid::

        sage: text("MATH IS AWESOME", (0, 0), fontsize=40, axes=False)
        Graphics object consisting of 1 graphics primitive
        sage: text("MATH IS AWESOME", (0, 0), fontsize=40).show(axes=False) # These are equivalent
    """
    try:
        x, y = xy
    except ValueError:
        if isinstance(xy, (list, tuple)) and len(xy) == 3:
            raise ValueError("use text3d instead for text in 3d")
        raise
    from sage.plot.all import Graphics
    options['rgbcolor'] = to_mpl_color(options['rgbcolor'])
    point = (float(x), float(y))
    g = Graphics()
    g._set_extra_kwds(Graphics._extract_kwds_for_show(options, ignore='fontsize'))
    g.add_primitive(Text(string, point, options))
    return g
Beispiel #38
0
    def _render_on_subplot(self, subplot):
        r"""
        Render this arrow in a subplot.  This is the key function that
        defines how this arrow graphics primitive is rendered in
        matplotlib's library.

        EXAMPLES:

        This function implicitly ends up rendering this arrow on
        a matplotlib subplot::

            sage: arrow((0,1), (2,-1))

        TESTS:

        The length of the ends (shrinkA and shrinkB) should not depend
        on the width of the arrow, because Matplotlib already takes
        this into account. See :trac:`12836`::

            sage: fig = Graphics().matplotlib()
            sage: sp = fig.add_subplot(1,1,1)
            sage: a = arrow((0,0), (1,1))
            sage: b = arrow((0,0), (1,1), width=20)
            sage: p1 = a[0]._render_on_subplot(sp)
            sage: p2 = b[0]._render_on_subplot(sp)
            sage: p1.shrinkA == p2.shrinkA
            True
            sage: p1.shrinkB == p2.shrinkB
            True

        Dashed arrows should have solid arrowheads,
        :trac:`12852`. This test saves the plot of a dashed arrow to
        an EPS file. Within the EPS file, ``stroke`` will be called
        twice: once to draw the line, and again to draw the
        arrowhead. We check that both calls do not occur while the
        dashed line style is enabled::

            sage: a = arrow((0,0), (1,1), linestyle='dashed')
            sage: filename = tmp_filename(ext='.eps')
            sage: a.save(filename=filename)
            sage: with open(filename, 'r') as f:
            ....:     contents = f.read().replace('\n', ' ')
            sage: two_stroke_pattern = r'setdash.*stroke.*stroke.*setdash'
            sage: import re
            sage: two_stroke_re = re.compile(two_stroke_pattern)
            sage: two_stroke_re.search(contents) is None
            True
        """
        options = self.options()
        head = options.pop('head')
        if head == 0: style = '<|-'
        elif head == 1: style = '-|>'
        elif head == 2: style = '<|-|>'
        else: raise KeyError('head parameter must be one of 0 (start), 1 (end) or 2 (both).')
        width = float(options['width'])
        arrowshorten_end = float(options.get('arrowshorten',0))/2.0
        arrowsize = float(options.get('arrowsize',5))
        head_width=arrowsize
        head_length=arrowsize*2.0
        color = to_mpl_color(options['rgbcolor'])
        from matplotlib.patches import FancyArrowPatch
        p = FancyArrowPatch((self.xtail, self.ytail), (self.xhead, self.yhead),
                            lw=width, arrowstyle='%s,head_width=%s,head_length=%s'%(style,head_width, head_length),
                            shrinkA=arrowshorten_end, shrinkB=arrowshorten_end,
                            fc=color, ec=color, linestyle=options['linestyle'])
        p.set_zorder(options['zorder'])
        p.set_label(options['legend_label'])

        if options['linestyle']!='solid':
            # The next few lines work around a design issue in matplotlib. Currently, the specified
            # linestyle is used to draw both the path and the arrowhead.  If linestyle is 'dashed', this
            # looks really odd.  This code is from Jae-Joon Lee in response to a post to the matplotlib mailing
            # list.  See http://sourceforge.net/mailarchive/forum.php?thread_name=CAG%3DuJ%2Bnw2dE05P9TOXTz_zp-mGP3cY801vMH7yt6vgP9_WzU8w%40mail.gmail.com&forum_name=matplotlib-users

            import matplotlib.patheffects as pe
            class CheckNthSubPath(object):
                def __init__(self, patch, n):
                    """
                    creates an callable object that returns True if the provided
                    path is the n-th path from the patch.
                    """
                    self._patch = patch
                    self._n = n

                def get_paths(self, renderer):
                    self._patch.set_dpi_cor(renderer.points_to_pixels(1.))
                    paths, fillables = self._patch.get_path_in_displaycoord()
                    return paths

                def __call__(self, renderer, gc, tpath, affine, rgbFace):
                    path = self.get_paths(renderer)[self._n]
                    vert1, code1 = path.vertices, path.codes
                    import numpy as np

                    if np.all(vert1 == tpath.vertices) and np.all(code1 == tpath.codes):
                        return True
                    else:
                        return False


            class ConditionalStroke(pe._Base):

                def __init__(self, condition_func, pe_list):
                    """
                    path effect that is only applied when the condition_func
                    returns True.
                    """
                    super(ConditionalStroke, self).__init__()
                    self._pe_list = pe_list
                    self._condition_func = condition_func

                def draw_path(self, renderer, gc, tpath, affine, rgbFace):

                    if self._condition_func(renderer, gc, tpath, affine, rgbFace):
                        for pe1 in self._pe_list:
                            pe1.draw_path(renderer, gc, tpath, affine, rgbFace)

            pe1 = ConditionalStroke(CheckNthSubPath(p, 0),[pe.Stroke()])
            pe2 = ConditionalStroke(CheckNthSubPath(p, 1),[pe.Stroke(linestyle="solid")])
            p.set_path_effects([pe1, pe2])

        subplot.add_patch(p)
        return p
Beispiel #39
0
def text(string, xy, **options):
    r"""
    Returns a 2D text graphics object at the point `(x,y)`.
    
    Type ``text.options`` for a dictionary of options for 2D text.

    2D OPTIONS:

    - ``fontsize`` - How big the text is

    - ``rgbcolor`` - The color as an RGB tuple

    - ``hue`` - The color given as a hue

    - ``rotation`` - How to rotate the text: angle in degrees, vertical, horizontal

    - ``vertical_alignment`` - How to align vertically: top, center, bottom

    - ``horizontal_alignment`` - How to align horizontally: left, center, right

    - ``axis_coords`` - (default: False) if True, use axis coordinates, so that
      (0,0) is the lower left and (1,1) upper right, regardless of the x and y
      range of plotted values. 

    EXAMPLES::

        sage: text("Sage is really neat!!",(2,12))

    The same text in larger font and colored red::

        sage: text("Sage is really neat!!",(2,12),fontsize=20,rgbcolor=(1,0,0))

    Same text but guaranteed to be in the lower left no matter what::

        sage: text("Sage is really neat!!",(0,0), axis_coords=True, horizontal_alignment='left')

    Same text rotated around the left, bottom corner of the text::

        sage: text("Sage is really neat!!",(0,0), rotation=45.0, horizontal_alignment='left', vertical_alignment='bottom')

    Same text oriented vertically::

        sage: text("Sage is really neat!!",(0,0), rotation="vertical")

    You can also align text differently::

        sage: t1 = text("Hello",(1,1), vertical_alignment="top")
        sage: t2 = text("World", (1,0.5), horizontal_alignment="left")
        sage: t1 + t2   # render the sum

    You can save text as part of PDF output::

        sage: text("sage", (0,0), rgbcolor=(0,0,0)).save(SAGE_TMP + 'a.pdf')

    Text must be 2D (use the text3d command for 3D text)::

        sage: t = text("hi",(1,2,3))
        Traceback (most recent call last):
        ...
        ValueError: use text3d instead for text in 3d
        sage: t = text3d("hi",(1,2,3))

    Extra options will get passed on to show(), as long as they are valid::
    
        sage: text("MATH IS AWESOME", (0, 0), fontsize=40, axes=False)
        sage: text("MATH IS AWESOME", (0, 0), fontsize=40).show(axes=False) # These are equivalent
    """
    try:
        x, y = xy
    except ValueError:
        if isinstance(xy, (list, tuple)) and len(xy) == 3:
            raise ValueError, "use text3d instead for text in 3d"
        raise
    from sage.plot.plot import Graphics
    options['rgbcolor'] = to_mpl_color(options['rgbcolor'])
    point = (float(x), float(y))
    g = Graphics()
    g._set_extra_kwds(Graphics._extract_kwds_for_show(options, ignore='fontsize'))
    g.add_primitive(Text(string, point, options))
    return g