def plot_cluster_fan_stereographically(self, northsign=1, north=None, right=None, colors=None):
        from sage.plot.graphics import Graphics
        from sage.plot.point import point
        from sage.misc.flatten import flatten
        from sage.plot.line import line
        from sage.misc.functional import norm

        if self.rk !=3:
            raise ValueError("Can only stereographically project fans in 3d.")
        if not self.is_finite() and self._depth == infinity:
            raise ValueError("For infinite algebras you must specify the depth.")

        if north == None:
            if self.is_affine():
                north = vector(self.delta())
            else:
                north = vector( (-1,-1,-1) )
        if right == None:
            if self.is_affine():
                right = vector(self.gamma())
            else:
                right = vector( (1,0,0) )
        if colors == None:
            colors = dict([(0,'red'),(1,'green'),(2,'blue'),(3,'cyan'),(4,'yellow')])
        G = Graphics()

        roots = list(self.g_vectors())
        compatible = []
        while roots:
            x = roots.pop()
            for y in roots:
                if self.compatibility_degree(x,y) == 0:
                    compatible.append((x,y))
        for (u,v) in compatible:
            G += _stereo_arc(vector(u),vector(v),vector(u+v),north=northsign*north,right=right,thickness=0.5,color='black')

        for i in range(3):
            orbit = self.ith_orbit(i)
            for j in orbit:
                G += point(_stereo_coordinates(vector(orbit[j]),north=northsign*north,right=right),color=colors[i],zorder=len(G))

        if self.is_affine():
            tube_vectors = map(vector,flatten(self.affine_tubes()))
            for v in tube_vectors:
                G += point(_stereo_coordinates(v,north=northsign*north,right=right),color=colors[3],zorder=len(G))
            if north != vector(self.delta()):
                G += _stereo_arc(tube_vectors[0],tube_vectors[1],vector(self.delta()),north=northsign*north,right=right,thickness=2,color=colors[4],zorder=0)
            else:
                # FIXME: refactor this before publishing
                tube_projections = [
                        _stereo_coordinates(v,north=northsign*north,right=right)
                        for v in tube_vectors ]
                t=min((G.get_minmax_data()['xmax'],G.get_minmax_data()['ymax']))
                G += line([tube_projections[0],tube_projections[0]+t*(_normalize(tube_projections[0]-tube_projections[1]))],thickness=2,color=colors[4],zorder=0)
                G += line([tube_projections[1],tube_projections[1]+t*(_normalize(tube_projections[1]-tube_projections[0]))],thickness=2,color=colors[4],zorder=0)
        G.set_aspect_ratio(1)
        G._show_axes = False
        return G
def _arc(p,q,s,**kwds):
    #rewrite this to use polar_plot and get points to do filled triangles
    from sage.misc.functional import det
    from sage.plot.line import line
    from sage.misc.functional import norm
    from sage.symbolic.all import pi
    from sage.plot.arc import arc
     
    p,q,s = map( lambda x: vector(x), [p,q,s])
     
    # to avoid running into division by 0 we set to be colinear vectors that are
    # almost colinear
    if abs(det(matrix([p-s,q-s])))<0.01:
        return line((p,q),**kwds)
     
    (cx,cy)=var('cx','cy')
    equations=[
            2*cx*(s[0]-p[0])+2*cy*(s[1]-p[1]) == s[0]**2+s[1]**2-p[0]**2-p[1]**2,
            2*cx*(s[0]-q[0])+2*cy*(s[1]-q[1]) == s[0]**2+s[1]**2-q[0]**2-q[1]**2
            ]
    c = vector( [solve( equations, (cx,cy), solution_dict=True )[0][i] for i in [cx,cy]] )
     
    r = norm(p-c)
     
    a_p,a_q,a_s = map( _to_angle, [p-c,q-c,s-c])
    angles = [a_p,a_q,a_s]
    angles.sort()
     
    if a_s == angles[0]:
        return arc( c, r, angle=angles[2], sector=(0,2*pi-angles[2]+angles[1]), **kwds)
    if a_s == angles[1]:
        return arc( c, r, angle=angles[0], sector=(0,angles[2]-angles[0]), **kwds)
    if a_s == angles[2]:
        return arc( c, r, angle=angles[1], sector=(0,2*pi-angles[1]+angles[0]), **kwds)
    def plot_y(self, plot_points=128, **kwds):
        r"""Plot the y-part of the path in the complex y-plane.

        Additional arguments and keywords are passed to
        ``matplotlib.pyplot.plot``.

        Parameters
        ----------
        N : int
            The number of interpolating points used to plot.
        t0 : double
            Starting t-value in [0,1].
        t1 : double
            Ending t-value in [0,1].

        Returns
        -------
        plt : Sage plot.
            A plot of the complex y-projection of the path.

        """
        s = numpy.linspace(0, 1, plot_points, dtype=double)
        vals = numpy.array([self.get_y(si)[0] for si in s], dtype=complex)
        pts = [(real_part(y), imag_part(y)) for y in vals]
        plt = line(pts, **kwds)
        return plt
Example #4
0
    def plot_n_matrices_eigenvectors(self, n, side='right', color_index=0, draw_line=False):
        r"""
        INPUT:

        - ``n`` -- integer, length
        - ``side`` -- ``'left'`` or ``'right'``, drawing left or right
          eigenvectors
        - ``color_index`` -- 0 for first letter, -1 for last letter
        - ``draw_line`` -- boolean

        EXAMPLES::

            sage: from slabbe.matrix_cocycle import cocycles
            sage: ARP = cocycles.ARP()
            sage: G = ARP.plot_n_matrices_eigenvectors(2)
        """
        from sage.plot.graphics import Graphics
        from sage.plot.point import point
        from sage.plot.line import line
        from sage.plot.text import text
        from sage.plot.colors import hue
        from sage.modules.free_module_element import vector
        from .matrices import M3to2
        R = self.n_matrices_eigenvectors(n)
        L = [(w, M3to2*(a/sum(a)), M3to2*(b/sum(b))) for (w,a,b) in R]
        G = Graphics()
        alphabet = self._language._alphabet
        color_ = dict( (letter, hue(i/float(len(alphabet)))) for i,letter in
                enumerate(alphabet))
        for letter in alphabet:
            L_filtered = [(w,p1,p2) for (w,p1,p2) in L if w[color_index] == letter]
            words,rights,lefts = zip(*L_filtered)
            if side == 'right':
                G += point(rights, color=color_[letter], legend_label=letter)
            elif side == 'left':
                G += point(lefts,  color=color_[letter], legend_label=letter)
            else:
                raise ValueError("side(=%s) should be left or right" % side)

        if draw_line:
            for (a,b) in L:
                G += line([a,b], color='black', linestyle=":")
        G += line([M3to2*vector(a) for a in [(1,0,0), (0,1,0), (0,0,1), (1,0,0)]]) 
        title = "%s eigenvectors, colored by letter w[%s] of cylinder w" % (side, color_index)
        G += text(title, (0.5, 1.05), axis_coords=True)
        G.axes(False)
        return G
Example #5
0
    def show(self, boundary=True, **options):
        r"""
        Plot ``self``.

        EXAMPLES::

            sage: HyperbolicPlane().UHP().get_geodesic(0, 1).show()
            Graphics object consisting of 2 graphics primitives
        """
        opts = {'axes': False, 'aspect_ratio': 1}
        opts.update(self.graphics_options())
        opts.update(options)
        end_1, end_2 = [CC(k.coordinates()) for k in self.endpoints()]
        bd_1, bd_2 = [CC(k.coordinates()) for k in self.ideal_endpoints()]
        if (abs(real(end_1) - real(end_2)) < EPSILON) \
                or CC(infinity) in [end_1, end_2]: #on same vertical line
            # If one of the endpoints is infinity, we replace it with a
            # large finite  point
            if end_1 == CC(infinity):
                end_1 = (real(end_2), (imag(end_2) + 10))
                end_2 = (real(end_2), imag(end_2))
            elif end_2 == CC(infinity):
                end_2 = (real(end_1), (imag(end_1) + 10))
                end_1 = (real(end_1), imag(end_1))
            from sage.plot.line import line
            pic = line((end_1, end_2), **opts)
            if boundary:
                cent = min(bd_1, bd_2)
                bd_dict = {'bd_min': cent - 3, 'bd_max': cent + 3}
                bd_pic = self._model.get_background_graphic(**bd_dict)
                pic = bd_pic + pic
                return pic
        else:
            center = (bd_1 + bd_2)/2 # Circle center
            radius = abs(bd_1 - bd_2)/2
            theta1 = CC(end_1 - center).arg()
            theta2 = CC(end_2 - center).arg()
            if abs(theta1 - theta2) < EPSILON:
                theta2 += pi
            [theta1, theta2] = sorted([theta1, theta2])
            from sage.calculus.var import var
            from sage.plot.plot import parametric_plot
            x = var('x')
            pic = parametric_plot((radius*cos(x) + real(center),
                                   radius*sin(x) + imag(center)),
                                  (x, theta1, theta2), **opts)
            if boundary:
                # We want to draw a segment of the real line.  The
                # computations below compute the projection of the
                # geodesic to the real line, and then draw a little
                # to the left and right of the projection.
                shadow_1, shadow_2 = [real(k) for k in [end_1, end_2]]
                midpoint = (shadow_1 + shadow_2)/2
                length = abs(shadow_1 - shadow_2)
                bd_dict = {'bd_min': midpoint - length, 'bd_max': midpoint +
                           length}
                bd_pic = self._model.get_background_graphic(**bd_dict)
                pic = bd_pic + pic
            return pic
Example #6
0
def piecewise_linear_image(A,B):
    # Jumps up and down going around circle, not used
    v = circle_drops(A,B)
    G = Graphics()
    w = [(Rational(i)/len(v), j) for i,j in enumerate(v)]
    for pt in w:
        G += line([(pt[0],pt[1]),(pt[0]+Rational(1)/len(w),pt[1])])
    return G
Example #7
0
def legend_3d(hyperplane_arrangement, hyperplane_colors, length):
    r"""
    Create plot of a 3d legend for an arrangement of planes in 3-space.  The
    ``length`` parameter determines whether short or long labels are used in
    the legend.

    INPUT:

    - ``hyperplane_arrangement`` -- a hyperplane arrangement
    
    - ``hyperplane_colors`` -- list of colors

    - ``length`` -- either ``'short'`` or ``'long'``

    OUTPUT:

    - A graphics object.

    EXAMPLES::

        sage: a = hyperplane_arrangements.semiorder(3)
        sage: from sage.geometry.hyperplane_arrangement.plot import legend_3d
        sage: legend_3d(a, list(colors.values())[:6],length='long')
        Graphics object consisting of 6 graphics primitives

        sage: b = hyperplane_arrangements.semiorder(4)
        sage: c = b.essentialization()
        sage: legend_3d(c, list(colors.values())[:12], length='long')
        Graphics object consisting of 12 graphics primitives

        sage: legend_3d(c, list(colors.values())[:12], length='short')
        Graphics object consisting of 12 graphics primitives

        sage: p = legend_3d(c, list(colors.values())[:12], length='short')
        sage: p.set_legend_options(ncol=4)
        sage: type(p)
        <class 'sage.plot.graphics.Graphics'>
    """
    if hyperplane_arrangement.dimension() != 3:
        raise ValueError('arrangements must be in 3-space')
    hyps = hyperplane_arrangement.hyperplanes()
    N = len(hyperplane_arrangement)
    if length == 'short':
        labels = ['  ' + str(i) for i in range(N)]
    else:
        labels = ['  ' + hyps[i]._repr_linear(include_zero=False) for i in
                  range(N)]
    p = Graphics()
    for i in range(N):
        p += line([(0,0),(0,0)], color=hyperplane_colors[i], thickness=8,
                legend_label=labels[i], axes=False)
    p.set_legend_options(title='Hyperplanes', loc='center', labelspacing=0.4, 
            fancybox=True, font_size='x-large', ncol=2)
    p.legend(True)
    return p
Example #8
0
    def plot(self, **kwargs):
        """
        Plot this Newton polygon.

        .. NOTE::

            All usual rendering options (color, thickness, etc.) are available.

        EXAMPLES:

            sage: from sage.geometry.newton_polygon import NewtonPolygon
            sage: NP = NewtonPolygon([ (0,0), (1,1), (2,6) ])
            sage: polygon = NP.plot()
        """
        vertices = self.vertices()
        if len(vertices) == 0:
            from sage.plot.graphics import Graphics
            return Graphics()
        else:
            from sage.plot.line import line
            (xstart,ystart) = vertices[0]
            (xend,yend) = vertices[-1]
            if self.last_slope() is Infinity:
                return line([(xstart, ystart+1), (xstart,ystart+0.5)], linestyle="--", **kwargs) \
                     + line([(xstart, ystart+0.5)] + vertices + [(xend, yend+0.5)], **kwargs) \
                     + line([(xend, yend+0.5), (xend, yend+1)], linestyle="--", **kwargs)
            else:
                return line([(xstart, ystart+1), (xstart,ystart+0.5)], linestyle="--", **kwargs) \
                     + line([(xstart, ystart+0.5)] + vertices + [(xend+0.5, yend + 0.5*self.last_slope())], **kwargs) \
                     + line([(xend+0.5, yend + 0.5*self.last_slope()), (xend+1, yend+self.last_slope())], linestyle="--", **kwargs)
Example #9
0
    def show(self, boundary=True, **options):
        r"""
        Plot ``self``.

        EXAMPLES::

            sage: HyperbolicPlane().PD().get_geodesic(0, 1).show()
            Graphics object consisting of 2 graphics primitives
        """
        opts = dict([('axes', False), ('aspect_ratio', 1)])
        opts.update(self.graphics_options())
        opts.update(options)
        end_1, end_2 = [CC(k.coordinates()) for k in self.endpoints()]
        bd_1, bd_2 = [CC(k.coordinates()) for k in self.ideal_endpoints()]
        # Check to see if it's a line
        if bool(real(bd_1)*imag(bd_2) - real(bd_2)*imag(bd_1))**2 < EPSILON:
            from sage.plot.line import line
            pic = line([(real(bd_1),imag(bd_1)),(real(bd_2),imag(bd_2))],
                       **opts)
        else:
            # If we are here, we know it's not a line
            # So we compute the center and radius of the circle
            center = (1/(real(bd_1)*imag(bd_2) - real(bd_2)*imag(bd_1)) *
                ((imag(bd_2)-imag(bd_1)) + (real(bd_1)-real(bd_2))*I))
            radius = RR(abs(bd_1 - center)) # abs is Euclidean distance
            # Now we calculate the angles for the parametric plot
            theta1 = CC(end_1 - center).arg()
            theta2 = CC(end_2 - center).arg()
            if theta2 < theta1:
                theta1, theta2 = theta2, theta1
            from sage.calculus.var import var
            from sage.plot.plot import parametric_plot
            x = var('x')
            mid = (theta1 + theta2)/2.0
            if (radius*cos(mid) + real(center))**2 + \
               (radius*sin(mid) + imag(center))**2 > 1.0:
                # Swap theta1 and theta2
                tmp = theta1 + 2*pi
                theta1 = theta2
                theta2 = tmp
                pic = parametric_plot((radius*cos(x) + real(center),
                                       radius*sin(x) + imag(center)),
                                      (x, theta1, theta2), **opts)

            else:
                pic = parametric_plot((radius*cos(x) + real(center),
                                   radius*sin(x) + imag(center)),
                                  (x, theta1, theta2), **opts)
        if boundary:
            bd_pic = self._model.get_background_graphic()
            pic = bd_pic + pic
        return pic
Example #10
0
    def get_background_graphic(self, **bdry_options):
        r"""
        Return a graphic object that makes the model easier to visualize.
        For the upper half space, the background object is the ideal boundary.

        EXAMPLES::

            sage: hp = HyperbolicPlane().UHP().get_background_graphic()
        """
        from sage.plot.line import line
        bd_min = bdry_options.get('bd_min', -5)
        bd_max = bdry_options.get('bd_max', 5)
        return line(((bd_min, 0), (bd_max, 0)), color='black')
    def show(self, boundary=True, **options):
        r"""
        Plot ``self``.

        EXAMPLES:

        First some lines::

            sage: PD = HyperbolicPlane().PD()
            sage: PD.get_geodesic(0, 1).show()
            Graphics object consisting of 2 graphics primitives
            sage: PD.get_geodesic(0, 0.3+0.8*I).show()
            Graphics object consisting of 2 graphics primitives

        Then some generic geodesics::

            sage: PD.get_geodesic(-0.5, 0.3+0.4*I).show()
            Graphics object consisting of 2 graphics primitives
            sage: PD.get_geodesic(-1, exp(3*I*pi/7)).show(linestyle="dashed", color="red")
            Graphics object consisting of 2 graphics primitives
            sage: PD.get_geodesic(exp(2*I*pi/11), exp(1*I*pi/11)).show(thickness=6, color="orange")
            Graphics object consisting of 2 graphics primitives
        """
        opts = {'axes': False, 'aspect_ratio': 1}
        opts.update(self.graphics_options())
        opts.update(options)
        end_1, end_2 = [CC(k.coordinates()) for k in self.endpoints()]
        bd_1, bd_2 = [CC(k.coordinates()) for k in self.ideal_endpoints()]
        # Check to see if it's a line
        if abs(bd_1 + bd_2) < EPSILON:
            pic = line([end_1, end_2], **opts)
        else:
            # If we are here, we know it's not a line
            # So we compute the center and radius of the circle
            invdet = RR.one() / (real(bd_1)*imag(bd_2) - real(bd_2)*imag(bd_1))
            centerx = (imag(bd_2) - imag(bd_1)) * invdet
            centery = (real(bd_1) - real(bd_2)) * invdet
            center = centerx + I * centery
            radius = RR(abs(bd_1 - center))
            # Now we calculate the angles for the arc
            theta1 = CC(end_1 - center).arg()
            theta2 = CC(end_2 - center).arg()
            theta1, theta2 = sorted([theta1, theta2])
            # Make sure the sector is inside the disk
            if theta2 - theta1 > pi:
                theta1 += 2 * pi
            pic = arc((centerx, centery), radius,
                      sector=(theta1, theta2), **opts)
        if boundary:
            pic += self._model.get_background_graphic()
        return pic
    def show(self, boundary=True, **options):
        r"""
        Plot ``self``.

        EXAMPLES::

            sage: HyperbolicPlane().KM().get_geodesic((0,0), (1,0)).show()
            Graphics object consisting of 2 graphics primitives
        """
        opts = {'axes': False, 'aspect_ratio': 1}
        opts.update(self.graphics_options())
        pic = line([k.coordinates() for k in self.endpoints()], **opts)
        if boundary:
            pic += self._model.get_background_graphic()
        return pic
    def plot2d(self,depth=None):
        # FIXME: refactor this before publishing
        from sage.plot.line import line
        from sage.plot.graphics import Graphics
        if self._n !=2:
            raise ValueError("Can only 2d plot fans.")
        if depth == None:
            depth = self._depth
        if not self.is_finite() and depth==infinity:
            raise ValueError("For infinite algebras you must specify the depth.")

        colors = dict([(0,'red'),(1,'green')])
        G = Graphics()
        for i in range(2):
            orbit = self.ith_orbit(i,depth=depth)
            for j in orbit:
                G += line([(0,0),vector(orbit[j])],color=colors[i],thickness=0.5, zorder=2*j+1)
    
        G.set_aspect_ratio(1)
        G._show_axes = False
        return G
Example #14
0
    def plot(self, m, pointsize=100, thickness=3, axes=False):
        r"""
        Return 2d graphics object contained in the primal box [-m,m]^d.

        INPUT:

        - ``pointsize``, integer (default:``100``),
        - ``thickness``, integer (default:``3``),
        - ``axes``, bool (default:``False``),

        EXAMPLES::

            sage: from slabbe import BondPercolationSample
            sage: S = BondPercolationSample(0.5,2)
            sage: S.plot(2)           # optional long

        It works in 3d!!::

            sage: S = BondPercolationSample(0.5,3)
            sage: S.plot(3, pointsize=10, thickness=1)     # optional long
            Graphics3d Object

        """
        s = ""
        s += "\\begin{tikzpicture}\n"
        s += "[inner sep=0pt,thick,\n"
        s += "reddot/.style={fill=red,draw=red,circle,minimum size=5pt}]\n"
        s += "\\clip %s rectangle %s;\n" % ((-m-.4,-m-.4), (m+.4,m+.4))
        G = Graphics()
        for u in self.cluster_in_box(m+1):
            G += point(u, color='blue', size=pointsize)
        for (u,v) in self.edges_in_box(m+1):
            G += line((u,v), thickness=thickness, alpha=0.8)
        G += text("p=%.3f" % self._p, (0.5,1.03), axis_coords=True, color='black')
        G += circle((0,0), 0.5, color='red', thickness=thickness)
        if self._dimension == 2:
            G.axes(axes)
        return G
Example #15
0
    def show(self, **args):
        r"""
        Displays the pseudoline arrangement as a wiring diagram.

        INPUT:

        - ``**args`` -- any arguments to be forwarded to the ``show`` method. In
          particular, to tune the dimensions, use the ``figsize`` argument
          (example below).

        EXAMPLES::

            sage: from sage.geometry.pseudolines import PseudolineArrangement
            sage: permutations = [[3, 2, 1], [3, 2, 0], [3, 1, 0], [2, 1, 0]]
            sage: p = PseudolineArrangement(permutations)
            sage: p.show(figsize=[7,5])

        TESTS::

            sage: from sage.geometry.pseudolines import PseudolineArrangement
            sage: permutations = [[3, 2, 1], [3, 2, 0], [3, 0, 1], [2, 0, 1]]
            sage: p = PseudolineArrangement(permutations)
            sage: p.show()
            Traceback (most recent call last):
            ...
            ValueError: There has been a problem while plotting the figure...
        """
        x = 1
        from sage.plot.line import line
        from sage.plot.text import text

        lines = [[(0,self._n-1-i)] for i in range(self._n)]

        for i,j in self.transpositions():
            iy = lines[i][-1][1]
            jy = lines[j][-1][1]

            lines[i].append((x, iy))
            lines[j].append((x, jy))

            if abs(iy-jy) != 1:
                raise ValueError(
                    "There has been a problem while plotting the figure. It "+
                    "seems that the lines are not correctly ordered. Please "+
                    "check the pseudolines modules documentation, there is a "
                    +"warning about that. ")

            lines[i].append((x+2,jy))
            lines[j].append((x+2,iy))

            x += 2

        L = line([(1,1)])

        for i, l in enumerate(lines):
            l.append((x+2, l[-1][1]))
            L += line(l)

            L += text(str(i), (0, l[0][1]+.3), horizontal_alignment="right")
            L += text(str(i), (x+2, l[-1][1]+.3), horizontal_alignment="left")

        return L.show(axes = False, **args)
Example #16
0
    def list_plot(cls, points, **kwargs):
        r"""
        Returns a sage figure containing a list plot.

        INPUT:

        - ``cls`` -- class on which the function is invoked.

        - ``points`` -- list or tuple of 2D or 3D points to be plotted.

        - ``joined`` -- boolean (default: False) flag triggering the production
          of a graph whose points are joined instead of a scatter plot.

        - ``alpha`` -- number (default: not used) opacity value of the points
          (or lines) in the produced graph.

        - ``size`` -- integer (default: not used) size of the points (or lines)
          in the produced graph.

        Other named arguments affecting the graphic style are forwarded to
        matplotlib's ``plot`` or ``scatter``.

        OUTPUT:

        figure containing a list plot.

        EXAMPLES:

        The following instructions generate and show a figure showing three
        points:

        ::

            >>> points = ((1, 1), (3, -1), (7, 2))
            >>> from yaplf.graph import SagePlotter
            >>> SagePlotter.list_plot(points)

        The same graph can be obtained joining the single points:

        ::

            >>> SagePlotter.list_plot(points, joined = True)

        When ``joined`` is set to ``True``, the ``size``, ``color``, and
        ``alpha`` arguments affect respectively the line size, color, and
        opacity:

        ::

            >>> SagePlotter.list_plot(points, joined = True, size = 3,
            ... alpha = .2)

        When the first argument of ``list_plot`` is a list or tuple of
        three-sized list or tuples, the result is a 3D graph:

        ::
            >>> points = ((1, 3, -4), (2, 1, 2), (1, 6, 5))
            >>> SagePlotter.list_plot(points)


        AUTHORS:

        - Dario Malchiodi (2010-02-22)

        """

        try:
            joined = kwargs['joined']
            del kwargs['joined']
        except KeyError:
            joined = False

        if len(shape(points)) == 1:
            points = zip(range(len(points)), points)

        if len(points[0]) == 2:
            try:
                size = kwargs['size']
                del kwargs['size']
                if joined:
                    kwargs['thickness'] = size
                else:
                    kwargs['pointsize'] = size
            except KeyError:
                pass
        elif len(points[0]) == 3:
            try:
                alpha = kwargs['alpha']
                del kwargs['alpha']
                kwargs['opacity'] = alpha
                if joined:
                    size = kwargs['size']
                    del kwargs['size']
                    kwargs['thickness'] = size
            except KeyError:
                pass
        else:
            raise ValueError('scatter() only available for 2D and 3D points')

        if joined:
            return line(points, **kwargs)
        else:
            return point(points, **kwargs)
Example #17
0
    def plot(self, **kwds):
        r"""
        Plot the initial triangulation associated to ``self``.

        INPUT:

        - ``radius`` - the radius of the disk; by default the length of
          the circle is the number of vertices
        - ``points_color`` - the color of the vertices; default 'black'
        - ``points_size`` - the size of the vertices; default 7
        - ``triangulation_color`` - the color of the arcs; default 'black'
        - ``triangulation_thickness`` - the thickness of the arcs; default 0.5
        - ``shading_color`` - the color of the shading used on neuter
          intervals; default 'lightgray'
        - ``reflections_color`` - the color of the reflection axes; default
          'blue'
        - ``reflections_thickness`` - the thickness of the reflection axes;
          default 1

        EXAMPLES::

            sage: Y = SineGordonYsystem('A',(6,4,3))
            sage: Y.plot()  # long time 2s
            Graphics object consisting of 219 graphics primitives
        """
        # Set up plotting options
        if 'radius' in kwds:
            radius = kwds['radius']
        else:
            radius = ceil(self.r() / (2 * pi))
        points_opts = {}
        if 'points_color' in kwds:
            points_opts['color'] = kwds['points_color']
        else:
            points_opts['color'] = 'black'
        if 'points_size' in kwds:
            points_opts['size'] = kwds['points_size']
        else:
            points_opts['size'] = 7
        triangulation_opts = {}
        if 'triangulation_color' in kwds:
            triangulation_opts['color'] = kwds['triangulation_color']
        else:
            triangulation_opts['color'] = 'black'
        if 'triangulation_thickness' in kwds:
            triangulation_opts['thickness'] = kwds['triangulation_thickness']
        else:
            triangulation_opts['thickness'] = 0.5
        shading_opts = {}
        if 'shading_color' in kwds:
            shading_opts['color'] = kwds['shading_color']
        else:
            shading_opts['color'] = 'lightgray'
        reflections_opts = {}
        if 'reflections_color' in kwds:
            reflections_opts['color'] = kwds['reflections_color']
        else:
            reflections_opts['color'] = 'blue'
        if 'reflections_thickness' in kwds:
            reflections_opts['thickness'] = kwds['reflections_thickness']
        else:
            reflections_opts['thickness'] = 1
        # Helper functions

        def triangle(x):
            (a, b) = sorted(x[:2])
            for p in self.vertices():
                if (p, a) in self.triangulation() or (a, p) in self.triangulation():
                    if (p, b) in self.triangulation() or (b, p) in self.triangulation():
                        if p < a or p > b:
                            return sorted((a, b, p))

        def plot_arc(radius, p, q, **opts):
            # TODO: THIS SHOULD USE THE EXISTING PLOT OF ARCS!
            # plot the arc from p to q differently depending on the type of self
            p = ZZ(p)
            q = ZZ(q)
            t = var('t')
            if p - q in [1, -1]:
                def f(t):
                    return (radius * cos(t), radius * sin(t))
                (p, q) = sorted([p, q])
                angle_p = vertex_to_angle(p)
                angle_q = vertex_to_angle(q)
                return parametric_plot(f(t), (t, angle_q, angle_p), **opts)
            if self.type() == 'A':
                angle_p = vertex_to_angle(p)
                angle_q = vertex_to_angle(q)
                if angle_p < angle_q:
                    angle_p += 2 * pi
                internal_angle = angle_p - angle_q
                if internal_angle > pi:
                    (angle_p, angle_q) = (angle_q + 2 * pi, angle_p)
                    internal_angle = angle_p - angle_q
                angle_center = (angle_p+angle_q) / 2
                hypotenuse = radius / cos(internal_angle / 2)
                radius_arc = hypotenuse * sin(internal_angle / 2)
                center = (hypotenuse * cos(angle_center),
                          hypotenuse * sin(angle_center))
                center_angle_p = angle_p + pi / 2
                center_angle_q = angle_q + 3 * pi / 2

                def f(t):
                    return (radius_arc * cos(t) + center[0],
                            radius_arc * sin(t) + center[1])
                return parametric_plot(f(t), (t, center_angle_p,
                                              center_angle_q), **opts)
            elif self.type() == 'D':
                if p >= q:
                    q += self.r()
                px = -2 * pi * p / self.r() + pi / 2
                qx = -2 * pi * q / self.r() + pi / 2
                arc_radius = (px - qx) / 2
                arc_center = qx + arc_radius

                def f(t):
                    return exp(I * ((cos(t) + I * sin(t)) *
                                    arc_radius + arc_center)) * radius
                return parametric_plot((real_part(f(t)), imag_part(f(t))),
                                       (t, 0, pi), **opts)

        def vertex_to_angle(v):
            # v==0 corresponds to pi/2
            return -2 * pi * RR(v) / self.r() + 5 * pi / 2

        # Begin plotting
        P = Graphics()
        # Shade neuter intervals
        neuter_intervals = [x for x in flatten(self.intervals()[:-1],
                                               max_level=1)
                            if x[2] in ["NR", "NL"]]
        shaded_triangles = map(triangle, neuter_intervals)
        for (p, q, r) in shaded_triangles:
            points = list(plot_arc(radius, p, q)[0])
            points += list(plot_arc(radius, q, r)[0])
            points += list(reversed(plot_arc(radius, p, r)[0]))
            P += polygon2d(points, **shading_opts)
        # Disk boundary
        P += circle((0, 0), radius, **triangulation_opts)
        # Triangulation
        for (p, q) in self.triangulation():
            P += plot_arc(radius, p, q, **triangulation_opts)
        if self.type() == 'D':
            s = radius / 50.0
            P += polygon2d([(s, 5 * s), (s, 7 * s),
                            (3 * s, 5 * s), (3 * s, 7 * s)],
                           color=triangulation_opts['color'])
            P += bezier_path([[(0, 0), (2 * s, 1 * s), (2 * s, 6 * s)],
                              [(2 * s, 10 * s), (s, 20 * s)],
                              [(0, 30 * s), (0, radius)]],
                             **triangulation_opts)
            P += bezier_path([[(0, 0), (-2 * s, 1 * s), (-2 * s, 6 * s)],
                              [(-2 * s, 10 * s), (-s, 20 * s)],
                              [(0, 30 * s), (0, radius)]],
                             **triangulation_opts)
            P += point((0, 0), zorder=len(P), **points_opts)
        # Vertices
        v_points = {x: (radius * cos(vertex_to_angle(x)),
                        radius * sin(vertex_to_angle(x)))
                    for x in self.vertices()}
        for v in v_points:
            P += point(v_points[v], zorder=len(P), **points_opts)
        # Reflection axes
        P += line([(0, 1.1 * radius), (0, -1.1 * radius)],
                  zorder=len(P), **reflections_opts)
        axis_angle = vertex_to_angle(-0.5 * (self.rk() + (1, 1))[1])
        (a, b) = (1.1 * radius * cos(axis_angle),
                  1.1 * radius * sin(axis_angle))
        P += line([(a, b), (-a, -b)], zorder=len(P), **reflections_opts)
        # Wrap up
        P.set_aspect_ratio(1)
        P.axes(False)
        return P
Example #18
0
    def plot(self, chart=None, ambient_coords=None, mapping=None, prange=None,
             include_end_point=(True, True), end_point_offset=(0.001, 0.001),
             max_value=8, parameters=None, color='red',  style='-',
             thickness=1, plot_points=75, label_axes=True,
             aspect_ratio='automatic'):
        r"""
        Plot the current curve (``self``) in a Cartesian graph based on the
        coordinates of some ambient chart.

        The curve is drawn in terms of two (2D graphics) or three (3D graphics)
        coordinates of a given chart, called hereafter the *ambient chart*.
        The ambient chart's domain must overlap with the curve's codomain or
        with the codomain of the composite curve `\Phi\circ c`, where `c` is
        ``self`` and `\Phi` some manifold differential mapping (argument
        ``mapping`` below).

        INPUT:

        - ``chart`` -- (default: ``None``) the ambient chart (see above);
          if ``None``, the default chart of the codomain of the curve (or of
          the curve composed with `\Phi`) is used
        - ``ambient_coords`` -- (default: ``None``) tuple containing the 2 or 3
          coordinates of the ambient chart in terms of which the plot is
          performed; if ``None``, all the coordinates of the ambient chart are
          considered
        - ``mapping`` -- (default: ``None``) differentiable mapping `\Phi`
          (instance of
          :class:`~sage.geometry.manifolds.diffmapping.DiffMapping`)
          providing the link between ``self`` and the ambient chart ``chart``
          (cf. above); if ``None``, the ambient chart is supposed to be defined
          on the codomain of the curve ``self``.
        - ``prange`` -- (default: ``None``) range of the curve parameter for
          the plot; if ``None``, the entire parameter range declared during the
          curve construction is considered (with -Infinity
          replaced by ``-max_value`` and +Infinity by ``max_value``)
        - ``include_end_point`` -- (default: ``(True, True)``) determines
          whether the end points of ``prange`` are included in the plot
        - ``end_point_offset`` -- (default: ``(0.001, 0.001)``) offsets from
          the end points when they are not included in the plot: if
          ``include_end_point[0] == False``, the minimal value of the curve
          parameter used for the plot is ``prange[0] + end_point_offset[0]``,
          while if ``include_end_point[1] == False``, the maximal value is
          ``prange[1] - end_point_offset[1]``.
        - ``max_value`` -- (default: 8) numerical value substituted to
          +Infinity if the latter is the upper bound of the parameter range;
          similarly ``-max_value`` is the numerical valued substituted for
          -Infinity
        - ``parameters`` -- (default: ``None``) dictionary giving the numerical
          values of the parameters that may appear in the coordinate expression
          of ``self``
        - ``color`` -- (default: 'red') color of the drawn curve
        - ``style`` -- (default: '-') color of the drawn curve; NB: ``style``
          is effective only for 2D plots
        - ``thickness`` -- (default: 1) thickness of the drawn curve
        - ``plot_points`` -- (default: 75) number of points to plot the curve
        - ``label_axes`` -- (default: ``True``) boolean determining whether the
          labels of the coordinate axes of ``chart`` shall be added to the
          graph; can be set to ``False`` if the graph is 3D and must be
          superposed with another graph.
        - ``aspect_ratio`` -- (default: 'automatic') aspect ratio of the plot;
          the default value ('automatic') applies only for 2D plots; for
          3D plots, the default value is ``1`` instead.

        OUTPUT:

        - a graphic object, either an instance of
          :class:`~sage.plot.graphics.Graphics` for a 2D plot (i.e. based on
          2 coordinates of ``chart``) or an instance of
          :class:`~sage.plot.plot3d.base.Graphics3d` for a 3D plot (i.e.
          based on 3 coordinates of ``chart``)

        EXAMPLES:

        Plot of the lemniscate of Gerono::

            sage: R2 = Manifold(2, 'R^2')
            sage: X.<x,y> = R2.chart()
            sage: R.<t> = RealLine()
            sage: c = R2.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi), name='c')
            sage: c.plot()  # 2D plot
            Graphics object consisting of 1 graphics primitive

        Plot for a subinterval of the curve's domain::

            sage: c.plot(prange=(0,pi))
            Graphics object consisting of 1 graphics primitive

        Plot with various options::

            sage: c.plot(color='green', style=':', thickness=3, aspect_ratio=1)
            Graphics object consisting of 1 graphics primitive

        Plot via a mapping to another manifold: loxodrome of a sphere viewed
        in `\RR^3`::

            sage: S2 = Manifold(2, 'S^2')
            sage: U = S2.open_subset('U')
            sage: XS.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
            sage: R3 = Manifold(3, 'R^3')
            sage: X3.<x,y,z> = R3.chart()
            sage: F = S2.diff_mapping(R3, {(XS, X3): [sin(th)*cos(ph),
            ....:                     sin(th)*sin(ph), cos(th)]}, name='F')
            sage: F.display()
            F: S^2 --> R^3
            on U: (th, ph) |--> (x, y, z) = (cos(ph)*sin(th), sin(ph)*sin(th), cos(th))
            sage: c = S2.curve([2*atan(exp(-t/10)), t], (t, -oo, +oo), name='c')
            sage: graph_c = c.plot(mapping=F, max_value=40,
            ....:                  plot_points=200, thickness=2, label_axes=False)  # 3D plot
            sage: graph_S2 = XS.plot(X3, mapping=F, nb_values=11, color='black') # plot of the sphere
            sage: show(graph_c + graph_S2) # the loxodrome + the sphere

        Example of use of the argument ``parameters``: we define a curve with
        some symbolic parameters ``a`` and ``b``::

            sage: a, b = var('a b')
            sage: c = R2.curve([a*cos(t) + b, a*sin(t)], (t, 0, 2*pi), name='c')

        To make a plot, we set spectific values for ``a`` and ``b`` by means
        of the Python dictionary ``parameters``::

            sage: c.plot(parameters={a: 2, b: -3}, aspect_ratio=1)
            Graphics object consisting of 1 graphics primitive

        """
        from sage.rings.infinity import Infinity
        from sage.misc.functional import numerical_approx
        from sage.plot.graphics import Graphics
        from sage.plot.line import line
        from sage.geometry.manifolds.chart import Chart
        from sage.geometry.manifolds.utilities import set_axes_labels
        #
        # The "effective" curve to be plotted
        #
        if mapping is None:
            eff_curve = self
        else:
            eff_curve = mapping.restrict(self.codomain()) * self
        #
        # The chart w.r.t. which the curve is plotted
        #
        if chart is None:
            chart = eff_curve._codomain.default_chart()
        elif not isinstance(chart, Chart):
            raise TypeError("{} is not a chart".format(chart))
        #
        # Coordinates of the above chart w.r.t. which the curve is plotted
        #
        if ambient_coords is None:
            ambient_coords = chart[:]  # all chart coordinates are used
        n_pc = len(ambient_coords)
        if n_pc != 2 and n_pc !=3:
            raise ValueError("The number of coordinates involved in the " +
                             "plot must be either 2 or 3, not {}".format(n_pc))
        ind_pc = [chart[:].index(pc) for pc in ambient_coords] # indices of plot
                                                            # coordinates
        #
        # Parameter range for the plot
        #
        if prange is None:
            prange = (self._domain.lower_bound(), self._domain.upper_bound())
        elif not isinstance(prange, (tuple, list)):
            raise TypeError("{} is neither a tuple nor a list".format(prange))
        elif len(prange) != 2:
            raise ValueError("the argument prange must be a tuple/list " +
                             "of 2 elements")
        tmin = prange[0]
        tmax = prange[1]
        if tmin == -Infinity:
            tmin = -max_value
        elif not include_end_point[0]:
            tmin = tmin + end_point_offset[0]
        if tmax == Infinity:
            tmax = max_value
        elif not include_end_point[1]:
            tmax = tmax - end_point_offset[1]
        tmin = numerical_approx(tmin)
        tmax = numerical_approx(tmax)
        #
        # The coordinate expression of the effective curve
        #
        canon_chart = self._domain.canonical_chart()
        transf = None
        for chart_pair in eff_curve._coord_expression:
            if chart_pair == (canon_chart, chart):
                transf = eff_curve._coord_expression[chart_pair]
                break
        else:
            # Search for a subchart
            for chart_pair in eff_curve._coord_expression:
                for schart in chart._subcharts:
                    if chart_pair == (canon_chart, schart):
                        transf = eff_curve._coord_expression[chart_pair]
        if transf is None:
            raise ValueError("No expression has been found for " +
                              "{} in terms of {}".format(self, format))
        #
        # List of points for the plot curve
        #
        plot_curve = []
        dt = (tmax - tmin) / (plot_points - 1)
        t = tmin
        if parameters is None:
            for i in range(plot_points):
                x = transf(t, simplify=False)
                plot_curve.append( [numerical_approx(x[j]) for j in ind_pc] )
                t += dt
        else:
             for i in range(plot_points):
                x = transf(t, simplify=False)
                plot_curve.append(
                               [numerical_approx( x[j].substitute(parameters) )
                                for j in ind_pc] )
                t += dt
        #
        # The plot
        #
        resu = Graphics()
        resu += line(plot_curve, color=color, linestyle=style,
                     thickness=thickness)
        if n_pc==2:  # 2D graphic
            resu.set_aspect_ratio(aspect_ratio)
            if label_axes:
                # We update the dictionary _extra_kwds (options to be passed
                # to show()), instead of using the method
                # Graphics.axes_labels() since the latter is not robust w.r.t.
                # graph addition
                resu._extra_kwds['axes_labels'] = [r'$'+latex(pc)+r'$'
                                                   for pc in ambient_coords]
        else: # 3D graphic
            if aspect_ratio == 'automatic':
                aspect_ratio = 1
            resu.aspect_ratio(aspect_ratio)
            if label_axes:
                labels = [str(pc) for pc in ambient_coords]
                resu = set_axes_labels(resu, *labels)
        return resu
Example #19
0
File: curve.py Project: shalec/sage
    def plot(self,
             chart=None,
             ambient_coords=None,
             mapping=None,
             prange=None,
             include_end_point=(True, True),
             end_point_offset=(0.001, 0.001),
             parameters=None,
             color='red',
             style='-',
             label_axes=True,
             **kwds):
        r"""
        Plot the current curve in a Cartesian graph based on the
        coordinates of some ambient chart.

        The curve is drawn in terms of two (2D graphics) or three (3D graphics)
        coordinates of a given chart, called hereafter the *ambient chart*.
        The ambient chart's domain must overlap with the curve's codomain or
        with the codomain of the composite curve `\Phi\circ c`, where `c` is
        the current curve and `\Phi` some manifold differential map (argument
        ``mapping`` below).

        INPUT:

        - ``chart`` -- (default: ``None``) the ambient chart (see above);
          if ``None``, the default chart of the codomain of the curve (or of
          the curve composed with `\Phi`) is used

        - ``ambient_coords`` -- (default: ``None``) tuple containing the 2
          or 3 coordinates of the ambient chart in terms of which the plot
          is performed; if ``None``, all the coordinates of the ambient chart
          are considered

        - ``mapping`` -- (default: ``None``) differentiable mapping `\Phi`
          (instance of
          :class:`~sage.manifolds.differentiable.diff_map.DiffMap`)
          providing the link between the curve and the ambient chart ``chart``
          (cf. above); if ``None``, the ambient chart is supposed to be defined
          on the codomain of the curve.

        - ``prange`` -- (default: ``None``) range of the curve parameter for
          the plot; if ``None``, the entire parameter range declared during the
          curve construction is considered (with -Infinity
          replaced by ``-max_range`` and +Infinity by ``max_range``)

        - ``include_end_point`` -- (default: ``(True, True)``) determines
          whether the end points of ``prange`` are included in the plot

        - ``end_point_offset`` -- (default: ``(0.001, 0.001)``) offsets from
          the end points when they are not included in the plot: if
          ``include_end_point[0] == False``, the minimal value of the curve
          parameter used for the plot is ``prange[0] + end_point_offset[0]``,
          while if ``include_end_point[1] == False``, the maximal value is
          ``prange[1] - end_point_offset[1]``.

        - ``max_range`` -- (default: 8) numerical value substituted to
          +Infinity if the latter is the upper bound of the parameter range;
          similarly ``-max_range`` is the numerical valued substituted for
          -Infinity

        - ``parameters`` -- (default: ``None``) dictionary giving the numerical
          values of the parameters that may appear in the coordinate expression
          of the curve

        - ``color`` -- (default: 'red') color of the drawn curve

        - ``style`` -- (default: '-') color of the drawn curve; NB: ``style``
          is effective only for 2D plots

        - ``thickness`` -- (default: 1) thickness of the drawn curve

        - ``plot_points`` -- (default: 75) number of points to plot the curve

        - ``label_axes`` -- (default: ``True``) boolean determining whether the
          labels of the coordinate axes of ``chart`` shall be added to the
          graph; can be set to ``False`` if the graph is 3D and must be
          superposed with another graph.

        - ``aspect_ratio`` -- (default: ``'automatic'``) aspect ratio of the
          plot; the default value (``'automatic'``) applies only for 2D plots;
          for 3D plots, the default value is ``1`` instead

        OUTPUT:

        - a graphic object, either an instance of
          :class:`~sage.plot.graphics.Graphics` for a 2D plot (i.e. based on
          2 coordinates of ``chart``) or an instance of
          :class:`~sage.plot.plot3d.base.Graphics3d` for a 3D plot (i.e.
          based on 3 coordinates of ``chart``)

        EXAMPLES:

        Plot of the lemniscate of Gerono::

            sage: R2 = Manifold(2, 'R^2')
            sage: X.<x,y> = R2.chart()
            sage: R.<t> = RealLine()
            sage: c = R2.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi), name='c')
            sage: c.plot()  # 2D plot
            Graphics object consisting of 1 graphics primitive

        .. PLOT::

            R2 = Manifold(2, 'R^2')
            X = R2.chart('x y')
            t = RealLine().canonical_coordinate()
            c = R2.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi), name='c')
            g = c.plot()
            sphinx_plot(g)

        Plot for a subinterval of the curve's domain::

            sage: c.plot(prange=(0,pi))
            Graphics object consisting of 1 graphics primitive

        .. PLOT::

            R2 = Manifold(2, 'R^2')
            X = R2.chart('x y')
            t = RealLine().canonical_coordinate()
            c = R2.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi), name='c')
            g = c.plot(prange=(0,pi))
            sphinx_plot(g)

        Plot with various options::

            sage: c.plot(color='green', style=':', thickness=3, aspect_ratio=1)
            Graphics object consisting of 1 graphics primitive

        .. PLOT::

            R2 = Manifold(2, 'R^2')
            X = R2.chart('x y')
            t = RealLine().canonical_coordinate()
            c = R2.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi), name='c')
            g = c.plot(color='green', style=':', thickness=3, aspect_ratio=1)
            sphinx_plot(g)

        Plot via a mapping to another manifold: loxodrome of a sphere viewed
        in `\RR^3`::

            sage: S2 = Manifold(2, 'S^2')
            sage: U = S2.open_subset('U')
            sage: XS.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
            sage: R3 = Manifold(3, 'R^3')
            sage: X3.<x,y,z> = R3.chart()
            sage: F = S2.diff_map(R3, {(XS, X3): [sin(th)*cos(ph),
            ....:                      sin(th)*sin(ph), cos(th)]}, name='F')
            sage: F.display()
            F: S^2 --> R^3
            on U: (th, ph) |--> (x, y, z) = (cos(ph)*sin(th), sin(ph)*sin(th), cos(th))
            sage: c = S2.curve([2*atan(exp(-t/10)), t], (t, -oo, +oo), name='c')
            sage: graph_c = c.plot(mapping=F, max_range=40,
            ....:                  plot_points=200, thickness=2, label_axes=False)  # 3D plot
            sage: graph_S2 = XS.plot(X3, mapping=F, number_values=11, color='black') # plot of the sphere
            sage: show(graph_c + graph_S2) # the loxodrome + the sphere

        .. PLOT::

            S2 = Manifold(2, 'S^2')
            U = S2.open_subset('U')
            XS = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
            th, ph = XS[:]
            R3 = Manifold(3, 'R^3')
            X3 = R3.chart('x y z')
            F = S2.diff_map(R3, {(XS, X3): [sin(th)*cos(ph), sin(th)*sin(ph),
                                            cos(th)]}, name='F')
            t = RealLine().canonical_coordinate()
            c = S2.curve([2*atan(exp(-t/10)), t], (t, -oo, +oo), name='c')
            graph_c = c.plot(mapping=F, max_range=40, plot_points=200,
                             thickness=2, label_axes=False)
            graph_S2 = XS.plot(X3, mapping=F, number_values=11, color='black')
            sphinx_plot(graph_c + graph_S2)

        Example of use of the argument ``parameters``: we define a curve with
        some symbolic parameters ``a`` and ``b``::

            sage: a, b = var('a b')
            sage: c = R2.curve([a*cos(t) + b, a*sin(t)], (t, 0, 2*pi), name='c')

        To make a plot, we set spectific values for ``a`` and ``b`` by means
        of the Python dictionary ``parameters``::

            sage: c.plot(parameters={a: 2, b: -3}, aspect_ratio=1)
            Graphics object consisting of 1 graphics primitive

        .. PLOT::

            R2 = Manifold(2, 'R^2')
            X = R2.chart('x y')
            t = RealLine().canonical_coordinate()
            a, b = var('a b')
            c = R2.curve([a*cos(t) + b, a*sin(t)], (t, 0, 2*pi), name='c')
            g = c.plot(parameters={a: 2, b: -3}, aspect_ratio=1)
            sphinx_plot(g)

        """
        from sage.rings.infinity import Infinity
        from sage.misc.functional import numerical_approx
        from sage.plot.graphics import Graphics
        from sage.plot.line import line
        from sage.manifolds.chart import RealChart
        from sage.manifolds.utilities import set_axes_labels
        #
        # Get the @options from kwds
        #
        thickness = kwds.pop('thickness')
        plot_points = kwds.pop('plot_points')
        max_range = kwds.pop('max_range')
        aspect_ratio = kwds.pop('aspect_ratio')
        #
        # The "effective" curve to be plotted
        #
        if mapping is None:
            eff_curve = self
        else:
            eff_curve = mapping.restrict(self.codomain()) * self
        #
        # The chart w.r.t. which the curve is plotted
        #
        if chart is None:
            chart = eff_curve._codomain.default_chart()
        elif not isinstance(chart, RealChart):
            raise TypeError("{} is not a real chart".format(chart))
        #
        # Coordinates of the above chart w.r.t. which the curve is plotted
        #
        if ambient_coords is None:
            ambient_coords = chart[:]  # all chart coordinates are used
        n_pc = len(ambient_coords)
        if n_pc != 2 and n_pc != 3:
            raise ValueError("the number of coordinates involved in the " +
                             "plot must be either 2 or 3, not {}".format(n_pc))
        # indices of plot coordinates
        ind_pc = [chart[:].index(pc) for pc in ambient_coords]
        #
        # Parameter range for the plot
        #
        if prange is None:
            prange = (self._domain.lower_bound(), self._domain.upper_bound())
        elif not isinstance(prange, (tuple, list)):
            raise TypeError("{} is neither a tuple nor a list".format(prange))
        elif len(prange) != 2:
            raise ValueError("the argument prange must be a tuple/list " +
                             "of 2 elements")
        tmin = prange[0]
        tmax = prange[1]
        if tmin == -Infinity:
            tmin = -max_range
        elif not include_end_point[0]:
            tmin = tmin + end_point_offset[0]
        if tmax == Infinity:
            tmax = max_range
        elif not include_end_point[1]:
            tmax = tmax - end_point_offset[1]
        tmin = numerical_approx(tmin)
        tmax = numerical_approx(tmax)
        #
        # The coordinate expression of the effective curve
        #
        canon_chart = self._domain.canonical_chart()
        transf = None
        for chart_pair in eff_curve._coord_expression:
            if chart_pair == (canon_chart, chart):
                transf = eff_curve._coord_expression[chart_pair]
                break
        else:
            # Search for a subchart
            for chart_pair in eff_curve._coord_expression:
                for schart in chart._subcharts:
                    if chart_pair == (canon_chart, schart):
                        transf = eff_curve._coord_expression[chart_pair]
        if transf is None:
            raise ValueError("No expression has been found for " +
                             "{} in terms of {}".format(self, chart))
        #
        # List of points for the plot curve
        #
        plot_curve = []
        dt = (tmax - tmin) / (plot_points - 1)
        t = tmin
        if parameters is None:
            for i in range(plot_points):
                x = transf(t, simplify=False)
                plot_curve.append([numerical_approx(x[j]) for j in ind_pc])
                t += dt
        else:
            for i in range(plot_points):
                x = transf(t, simplify=False)
                plot_curve.append([
                    numerical_approx(x[j].substitute(parameters))
                    for j in ind_pc
                ])
                t += dt
        #
        # The plot
        #
        resu = Graphics()
        resu += line(plot_curve,
                     color=color,
                     linestyle=style,
                     thickness=thickness)
        if n_pc == 2:  # 2D graphic
            resu.set_aspect_ratio(aspect_ratio)
            if label_axes:
                # We update the dictionary _extra_kwds (options to be passed
                # to show()), instead of using the method
                # Graphics.axes_labels() since the latter is not robust w.r.t.
                # graph addition
                resu._extra_kwds['axes_labels'] = [
                    r'$' + latex(pc) + r'$' for pc in ambient_coords
                ]
        else:  # 3D graphic
            if aspect_ratio == 'automatic':
                aspect_ratio = 1
            resu.aspect_ratio(aspect_ratio)
            if label_axes:
                labels = [str(pc) for pc in ambient_coords]
                resu = set_axes_labels(resu, *labels)
        return resu
Example #20
0
    def _graphics(self, plot_curve, ambient_coords, thickness=1,
                  aspect_ratio='automatic', color='red', style='-',
                  label_axes=True):
        r"""
        Plot a 2D or 3D curve in a Cartesian graph with axes labeled by
        the ambient coordinates; it is invoked by the methods
        :meth:`plot` of
        :class:`~sage.manifolds.differentiable.curve.DifferentiableCurve`,
        and its subclasses
        (:class:`~sage.manifolds.differentiable.integrated_curve.IntegratedCurve`,
        :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedAutoparallelCurve`,
        and
        :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedGeodesic`).

        TESTS::

            sage: M = Manifold(2, 'R^2')
            sage: X.<x,y> = M.chart()
            sage: R.<t> = RealLine()
            sage: c = M.curve([cos(t), sin(t)], (t, 0, 2*pi), name='c')
            sage: graph = c._graphics([[1,2], [3,4]], [x,y])
            sage: graph._objects[0].xdata == [1,3]
            True
            sage: graph._objects[0].ydata == [2,4]
            True
            sage: graph._objects[0]._options['thickness'] == 1
            True
            sage: graph._extra_kwds['aspect_ratio'] == 'automatic'
            True
            sage: graph._objects[0]._options['rgbcolor'] == 'red'
            True
            sage: graph._objects[0]._options['linestyle'] == '-'
            True
            sage: l = [r'$'+latex(x)+r'$', r'$'+latex(y)+r'$']
            sage: graph._extra_kwds['axes_labels'] == l
            True

        """

        from sage.plot.graphics import Graphics
        from sage.plot.line import line
        from sage.manifolds.utilities import set_axes_labels


        #
        # The plot
        #
        n_pc = len(ambient_coords)
        resu = Graphics()
        resu += line(plot_curve, color=color, linestyle=style,
                     thickness=thickness)
        if n_pc == 2:  # 2D graphic
            resu.set_aspect_ratio(aspect_ratio)
            if label_axes:
                # We update the dictionary _extra_kwds (options to be passed
                # to show()), instead of using the method
                # Graphics.axes_labels() since the latter is not robust w.r.t.
                # graph addition
                resu._extra_kwds['axes_labels'] = [r'$'+latex(pc)+r'$'
                                                   for pc in ambient_coords]
        else: # 3D graphic
            if aspect_ratio == 'automatic':
                aspect_ratio = 1
            resu.aspect_ratio(aspect_ratio)
            if label_axes:
                labels = [str(pc) for pc in ambient_coords]
                resu = set_axes_labels(resu, *labels)
        return resu
Example #21
0
    def _graphics(self, plot_curve, ambient_coords, thickness=1,
                  aspect_ratio='automatic', color='red', style='-',
                  label_axes=True):
        r"""
        Plot a 2D or 3D curve in a Cartesian graph with axes labeled by
        the ambient coordinates; it is invoked by the methods
        :meth:`plot` of
        :class:`~sage.manifolds.differentiable.curve.DifferentiableCurve`,
        and its subclasses
        (:class:`~sage.manifolds.differentiable.integrated_curve.IntegratedCurve`,
        :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedAutoparallelCurve`,
        and
        :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedGeodesic`).

        TESTS::

            sage: M = Manifold(2, 'R^2')
            sage: X.<x,y> = M.chart()
            sage: R.<t> = RealLine()
            sage: c = M.curve([cos(t), sin(t)], (t, 0, 2*pi), name='c')
            sage: graph = c._graphics([[1,2], [3,4]], [x,y])
            sage: graph._objects[0].xdata == [1,3]
            True
            sage: graph._objects[0].ydata == [2,4]
            True
            sage: graph._objects[0]._options['thickness'] == 1
            True
            sage: graph._extra_kwds['aspect_ratio'] == 'automatic'
            True
            sage: graph._objects[0]._options['rgbcolor'] == 'red'
            True
            sage: graph._objects[0]._options['linestyle'] == '-'
            True
            sage: l = [r'$'+latex(x)+r'$', r'$'+latex(y)+r'$']
            sage: graph._extra_kwds['axes_labels'] == l
            True

        """
        from sage.plot.graphics import Graphics
        from sage.plot.line import line
        from sage.manifolds.utilities import set_axes_labels

        #
        # The plot
        #
        n_pc = len(ambient_coords)
        resu = Graphics()
        resu += line(plot_curve, color=color, linestyle=style,
                     thickness=thickness)
        if n_pc == 2:  # 2D graphic
            resu.set_aspect_ratio(aspect_ratio)
            if label_axes:
                # We update the dictionary _extra_kwds (options to be passed
                # to show()), instead of using the method
                # Graphics.axes_labels() since the latter is not robust w.r.t.
                # graph addition
                resu._extra_kwds['axes_labels'] = [r'$'+latex(pc)+r'$'
                                                   for pc in ambient_coords]
        else: # 3D graphic
            if aspect_ratio == 'automatic':
                aspect_ratio = 1
            resu.aspect_ratio(aspect_ratio)
            if label_axes:
                labels = [str(pc) for pc in ambient_coords]
                resu = set_axes_labels(resu, *labels)
        return resu
Example #22
0
def legend_3d(hyperplane_arrangement, hyperplane_colors, length):
    r"""
    Create plot of a 3d legend for an arrangement of planes in 3-space.  The
    ``length`` parameter determines whether short or long labels are used in
    the legend.

    INPUT:

    - ``hyperplane_arrangement`` -- a hyperplane arrangement
    
    - ``hyperplane_colors`` -- list of colors

    - ``length`` -- either ``'short'`` or ``'long'``

    OUTPUT:

    - A graphics object.

    EXAMPLES::

        sage: a = hyperplane_arrangements.semiorder(3)
        sage: from sage.geometry.hyperplane_arrangement.plot import legend_3d
        sage: legend_3d(a, list(colors.values())[:6],length='long')
        Graphics object consisting of 6 graphics primitives

        sage: b = hyperplane_arrangements.semiorder(4)
        sage: c = b.essentialization()
        sage: legend_3d(c, list(colors.values())[:12], length='long')
        Graphics object consisting of 12 graphics primitives

        sage: legend_3d(c, list(colors.values())[:12], length='short')
        Graphics object consisting of 12 graphics primitives

        sage: p = legend_3d(c, list(colors.values())[:12], length='short')
        sage: p.set_legend_options(ncol=4)
        sage: type(p)
        <class 'sage.plot.graphics.Graphics'>
    """
    if hyperplane_arrangement.dimension() != 3:
        raise ValueError('arrangements must be in 3-space')
    hyps = hyperplane_arrangement.hyperplanes()
    N = len(hyperplane_arrangement)
    if length == 'short':
        labels = ['  ' + str(i) for i in range(N)]
    else:
        labels = [
            '  ' + hyps[i]._repr_linear(include_zero=False) for i in range(N)
        ]
    p = Graphics()
    for i in range(N):
        p += line([(0, 0), (0, 0)],
                  color=hyperplane_colors[i],
                  thickness=8,
                  legend_label=labels[i],
                  axes=False)
    p.set_legend_options(title='Hyperplanes',
                         loc='center',
                         labelspacing=0.4,
                         fancybox=True,
                         font_size='x-large',
                         ncol=2)
    p.legend(True)
    return p
Example #23
0
def plot_phase_trajectories(func,
                            inits,
                            xbound,
                            ybound,
                            tbound=(0, 10, 100),
                            use_sage=False,
                            axis=None,
                            f_kwargs={},
                            odeint_kwargs={},
                            plt_kwargs={'color': 'blue'}):
    """function for plotting the  phase space trajectories of ordinary
    differential equations (ODEs) of the form dy/dt = f(y, t), where y can be
    a n-dim vector (see scipy.integrate.odeint for reference).
    Inspired by plotdf; reference: github.com/jmoy

    Parameters:
        func - RHS of ODE; callable(t, y)
        inits - initial values for plotting trajectories
        xbound, ybound - sequences with len = 2 gives min and max values for x
            and y respectivly
        tbound - sequence with len = 3 gives min, max and step for t values to
            calculate the trajectories for
        use_sage - whether to use sage for plotting instead of matplotlib
        axis - matplotlib axis to draw plot in; if None, current will be used
        odeint_kwargs - dict containing kwargs for scipy.integrate.odeint
        plt_kwargs - dict containing kwargs for matplotlib.pyplot; can also be
            used for sage-Graphics objects

    Returns:
        list containing matplotlib-artist objects (Line2D)
        or one sage-Graphics object
    """
    f = lambda x, t: func(t, x, **f_kwargs)
    if use_sage:
        from sage.plot.graphics import Graphics
        from sage.plot.line import line

    elif axis is None:
        axis = plt.gca()

    def f_neg(x, t):
        return -f(x, t)

    artists = [] if not use_sage else Graphics()
    t = np.linspace(*tbound)
    for i in inits:
        sol_fwd = odeint(f, i, t, **odeint_kwargs)  # forward solution
        sol_bwd = odeint(f_neg, i, t, **odeint_kwargs)  # backward solution
        sol = np.vstack((np.flipud(sol_bwd),
                         sol_fwd))  # flip sol_bwd and put both together
        sol_x = sol[:, 0]  # left column of sol
        sol_y = sol[:, 1]  # right column of sol
        sol_x_masked = np.ma.masked_outside(sol_x,
                                            *xbound)  # mask data to prevent
        sol_y_masked = np.ma.masked_outside(sol_y,
                                            *ybound)  #  blow-up of solution
        if not use_sage:
            artists.append(axis.plot(sol_x_masked, sol_y_masked, **plt_kwargs))
        else:
            artists += line(zip(sol_x_masked, sol_y_masked),
                            plt_kwargs,
                            xmin=xbound[0],
                            xmax=xbound[1])

    if not use_sage:
        plt.xlim(xbound)
        plt.ylim(ybound)

    return artists
Example #24
0
    def _plot(self, geosub, color=None):
        r"""
        EXAMPLES::

            sage: from EkEkstar import kFace, GeoSub
            sage: sub = {1:[1,2], 2:[1,3], 3:[1]}
            sage: geosub = GeoSub(sub,2, dual=True)
            sage: _ = kFace((10,21,33), (1,))._plot(geosub)              # case A
            sage: _ = kFace((10,21,33), (1,2), dual=True)._plot(geosub)  # case C
            sage: _ = kFace((10,21,33), (1,), dual=True)._plot(geosub)   # case E

        ::

            sage: sub = {1: [1, 3, 2, 3], 2: [2, 3], 3: [3, 2, 3, 1, 3, 2, 3]}
            sage: geosub = GeoSub(sub, 2, dual=True)
            sage: _ = kFace((10,21,33), (1,2), dual=True)._plot(geosub)  # case B

        ::

            sage: sub = {1:[1,2,3,3,3,3], 2:[1,3], 3:[1]}
            sage: geosub = GeoSub(sub,2, dual=True)
            sage: _ = kFace((0,0,0),(1,2), dual=True)._plot(geosub)      # case A
        """
        v = self.vector()
        t = self.type()
        if color != None:
            col = color
        else:
            col = self._color
        G = Graphics()

        K = geosub.field()
        b = K.gen()

        num = geosub._sigma_dict.keys()

        if self.is_dual():
            h = list(set(num) - set(t))
            B = b
            vec = geosub.dominant_left_eigenvector()
            emb = geosub.contracting_eigenvalues_indices()
        else:
            h = list(t)
            B = b**(-1)  # TODO: this seems useless (why?)
            vec = -geosub.dominant_left_eigenvector()
            emb = geosub.dilating_eigenvalues_indices()

        el = v * vec
        iter = 0

        conjugates = geosub.complex_embeddings()

        if len(h) == 1:
            if conjugates[emb[0]].is_real() == True:
                bp = zero_vector(CC, len(emb))
                for i in range(len(emb)):
                    bp[i] = K(el).complex_embeddings()[emb[i]]
                bp1 = zero_vector(CC, len(emb))
                for i in range(len(emb)):
                    bp1[i] = K(
                        (el + vec[h[0] - 1])).complex_embeddings()[emb[i]]
                if len(emb) == 1:
                    return line([bp[0], bp1[0]], color=col, thickness=3)
                else:
                    return line([bp, bp1], color=col, thickness=3)
            else:
                bp = K(el).complex_embeddings()[emb[0]]
                bp1 = K((el + vec[h[0] - 1])).complex_embeddings()[emb[0]]
                return line([bp, bp1], color=col, thickness=3)
        elif len(h) == 2:
            if conjugates[emb[0]].is_real() == True:
                bp = (K(el).complex_embeddings()[emb[0]],
                      K(el).complex_embeddings()[emb[1]])
                bp1 = (K(el + vec[h[0] - 1]).complex_embeddings()[emb[0]],
                       K(el + vec[h[0] - 1]).complex_embeddings()[emb[1]])
                bp2 = (K(el + vec[h[0] - 1] +
                         vec[h[1] - 1]).complex_embeddings()[emb[0]],
                       K(el + vec[h[0] - 1] +
                         vec[h[1] - 1]).complex_embeddings()[emb[1]])
                bp3 = (K(el + vec[h[1] - 1]).complex_embeddings()[emb[0]],
                       K(el + vec[h[1] - 1]).complex_embeddings()[emb[1]])
                return polygon2d([bp, bp1, bp2, bp3],
                                 color=col,
                                 thickness=.1,
                                 alpha=0.8)
            else:
                bp = K(el).complex_embeddings()[emb[0]]
                bp1 = K(el + vec[h[0] - 1]).complex_embeddings()[emb[0]]
                bp2 = K(el + vec[h[0] - 1] +
                        vec[h[1] - 1]).complex_embeddings()[emb[0]]
                bp3 = K(el + vec[h[1] - 1]).complex_embeddings()[emb[0]]
                return polygon2d([[bp[0], bp[1]], [bp1[0], bp1[1]],
                                  [bp2[0], bp2[1]], [bp3[0], bp3[1]]],
                                 color=col,
                                 thickness=.1,
                                 alpha=0.8)

        else:
            raise NotImplementedError(
                "Plotting is implemented only for patches in two or three dimensions."
            )
        return G
    def plot_cluster_fan_stereographically(self,
                                           northsign=1,
                                           north=None,
                                           right=None,
                                           colors=None,
                                           d_vectors=False):
        from sage.plot.graphics import Graphics
        from sage.plot.point import point
        from sage.misc.flatten import flatten
        from sage.plot.line import line
        from sage.misc.functional import norm

        if self.rk != 3:
            raise ValueError("Can only stereographically project fans in 3d.")
        if not self.is_finite() and self._depth == infinity:
            raise ValueError(
                "For infinite algebras you must specify the depth.")

        if north == None:
            if self.is_affine():
                north = vector(self.delta())
            else:
                north = vector((-1, -1, -1))
        if right == None:
            if self.is_affine():
                right = vector(self.gamma())
            else:
                right = vector((1, 0, 0))
        if colors == None:
            colors = dict([(0, 'red'), (1, 'green'), (2, 'blue'), (3, 'cyan'),
                           (4, 'yellow')])
        G = Graphics()

        roots = list(self.g_vectors())
        compatible = []
        while roots:
            x = roots.pop()
            if x in self.initial_cluster() and d_vectors:
                x1 = -self.simple_roots()[list(
                    self.initial_cluster()).index(x)]
            else:
                x1 = x
            for y in roots:
                if self.compatibility_degree(x, y) == 0:
                    if y in self.initial_cluster() and d_vectors:
                        y1 = -self.simple_roots()[list(
                            self.initial_cluster()).index(y)]
                    else:
                        y1 = y
                    compatible.append((x1, y1))
        for (u, v) in compatible:
            G += _stereo_arc(vector(u),
                             vector(v),
                             vector(u + v),
                             north=northsign * north,
                             right=right,
                             thickness=0.5,
                             color='black')

        for i in range(3):
            orbit = self.ith_orbit(i)
            if d_vectors:
                orbit[0] = -self.simple_roots()[list(
                    self.initial_cluster()).index(orbit[0])]
            for j in orbit:
                G += point(_stereo_coordinates(vector(orbit[j]),
                                               north=northsign * north,
                                               right=right),
                           color=colors[i],
                           zorder=len(G))

        if self.is_affine():
            tube_vectors = map(vector, flatten(self.affine_tubes()))
            for v in tube_vectors:
                G += point(_stereo_coordinates(v,
                                               north=northsign * north,
                                               right=right),
                           color=colors[3],
                           zorder=len(G))
            if north != vector(self.delta()):
                G += _stereo_arc(tube_vectors[0],
                                 tube_vectors[1],
                                 vector(self.delta()),
                                 north=northsign * north,
                                 right=right,
                                 thickness=2,
                                 color=colors[4],
                                 zorder=0)
            else:
                # FIXME: refactor this before publishing
                tube_projections = [
                    _stereo_coordinates(v,
                                        north=northsign * north,
                                        right=right) for v in tube_vectors
                ]
                t = min(
                    (G.get_minmax_data()['xmax'], G.get_minmax_data()['ymax']))
                G += line([
                    tube_projections[0], tube_projections[0] + t *
                    (_normalize(tube_projections[0] - tube_projections[1]))
                ],
                          thickness=2,
                          color=colors[4],
                          zorder=0)
                G += line([
                    tube_projections[1], tube_projections[1] + t *
                    (_normalize(tube_projections[1] - tube_projections[0]))
                ],
                          thickness=2,
                          color=colors[4],
                          zorder=0)
        G.set_aspect_ratio(1)
        G._show_axes = False
        return G
Example #26
0
    def plot(self):
        r"""
        Return a graphical object of the Fully Packed Loop

        EXAMPLES:

        Here is the fully packed loop for

        .. MATH::

            \begin{pmatrix} 0&1&1 \\ 1&-1&1 \\ 0&1&0 \end{pmatrix}:

        .. PLOT::
            :width: 200 px

            A = AlternatingSignMatrix([[0, 1, 0], [1, -1, 1], [0, 1, 0]])
            fpl = FullyPackedLoop(A)
            p = fpl.plot()
            sphinx_plot(p)

        Here is how Sage represents this::

            sage: A = AlternatingSignMatrix([[0, 1, 0], [1, -1, 1], [0, 1, 0]])
            sage: fpl = FullyPackedLoop(A)
            sage: print(fpl.plot().description())
            Line defined by 2 points:       [(-1.0, 1.0), (0.0, 1.0)]
            Line defined by 2 points:       [(0.0, 0.0), (0.0, -1.0)]
            Line defined by 2 points:       [(0.0, 0.0), (1.0, 0.0)]
            Line defined by 2 points:       [(0.0, 2.0), (0.0, 3.0)]
            Line defined by 2 points:       [(0.0, 2.0), (0.0, 3.0)]
            Line defined by 2 points:       [(0.0, 2.0), (1.0, 2.0)]
            Line defined by 2 points:       [(1.0, 1.0), (0.0, 1.0)]
            Line defined by 2 points:       [(1.0, 1.0), (2.0, 1.0)]
            Line defined by 2 points:       [(2.0, 0.0), (1.0, 0.0)]
            Line defined by 2 points:       [(2.0, 0.0), (2.0, -1.0)]
            Line defined by 2 points:       [(2.0, 2.0), (1.0, 2.0)]
            Line defined by 2 points:       [(2.0, 2.0), (2.0, 3.0)]
            Line defined by 2 points:       [(2.0, 2.0), (2.0, 3.0)]
            Line defined by 2 points:       [(3.0, 1.0), (2.0, 1.0)]
            Line defined by 2 points:       [(3.0, 1.0), (2.0, 1.0)]

        Here are the other 3 by 3 Alternating Sign Matrices and their corresponding
        fully packed loops:

        .. MATH::

            A = \begin{pmatrix} 1&0&0 \\ 0&1&0 \\ 0&0&1 \\ \end{pmatrix}

        gives:

        .. PLOT::
            :width: 200 px

            A = AlternatingSignMatrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
            fpl = FullyPackedLoop(A)
            p = fpl.plot()
            sphinx_plot(p)

        .. MATH::

            A = \begin{pmatrix} 1&0&0 \\ 0&0&1 \\ 0&1&0 \\ \end{pmatrix}

        gives:

        .. PLOT::
            :width: 200 px

            A = AlternatingSignMatrix([[1, 0, 0], [0, 0, 1], [0, 1, 0]])
            fpl = FullyPackedLoop(A)
            p = fpl.plot()
            sphinx_plot(p)

        .. MATH::

            A = \begin{pmatrix} 0&1&0\\ 1&0&0\\ 0&0&1\\ \end{pmatrix}

        gives:

        .. PLOT::
            :width: 200 px

            A = AlternatingSignMatrix([[0, 1, 0], [1, 0, 0], [0, 0, 1]])
            fpl = FullyPackedLoop(A)
            p = fpl.plot()
            sphinx_plot(p)

        .. MATH::

            A = \begin{pmatrix} 0&1&0\\ 0&0&1\\ 1&0&0\\ \end{pmatrix}

        gives:

        .. PLOT::
            :width: 200 px

            A = AlternatingSignMatrix([[0, 1, 0], [0, 0, 1], [1, 0, 0]])
            fpl = FullyPackedLoop(A)
            p = fpl.plot()
            sphinx_plot(p)

        .. MATH::

            A = \begin{pmatrix} 0&0&1\\ 1&0&0\\ 0&1&0\\ \end{pmatrix}

        gives:

        .. PLOT::
            :width: 200 px

            A = AlternatingSignMatrix([[0, 0, 1], [1, 0, 0], [0, 1, 0]])
            fpl = FullyPackedLoop(A)
            p = fpl.plot()
            sphinx_plot(p)

        .. MATH::

            A = \begin{pmatrix} 0&0&1\\ 0&1&0\\ 1&0&0\\ \end{pmatrix}

        gives:

        .. PLOT::
            :width: 200 px

            A = AlternatingSignMatrix([[0, 0, 1], [0, 1, 0], [1, 0, 0]])
            fpl = FullyPackedLoop(A)
            p = fpl.plot()
            sphinx_plot(p)

        EXAMPLES::

            sage: A = AlternatingSignMatrix([[0, 1, 0, 0], [1, -1, 0, 1], \
            [0, 1, 0, 0],[0, 0, 1, 0]])
            sage: fpl = FullyPackedLoop(A)
            sage: print(fpl.plot().description())
            Line defined by 2 points:       [(-1.0, 0.0), (0.0, 0.0)]
            Line defined by 2 points:       [(-1.0, 2.0), (0.0, 2.0)]
            Line defined by 2 points:       [(0.0, 1.0), (0.0, 0.0)]
            Line defined by 2 points:       [(0.0, 1.0), (1.0, 1.0)]
            Line defined by 2 points:       [(0.0, 3.0), (0.0, 4.0)]
            Line defined by 2 points:       [(0.0, 3.0), (0.0, 4.0)]
            Line defined by 2 points:       [(0.0, 3.0), (1.0, 3.0)]
            Line defined by 2 points:       [(1.0, 0.0), (1.0, -1.0)]
            Line defined by 2 points:       [(1.0, 0.0), (2.0, 0.0)]
            Line defined by 2 points:       [(1.0, 2.0), (0.0, 2.0)]
            Line defined by 2 points:       [(1.0, 2.0), (2.0, 2.0)]
            Line defined by 2 points:       [(2.0, 1.0), (1.0, 1.0)]
            Line defined by 2 points:       [(2.0, 1.0), (2.0, 2.0)]
            Line defined by 2 points:       [(2.0, 3.0), (1.0, 3.0)]
            Line defined by 2 points:       [(2.0, 3.0), (2.0, 4.0)]
            Line defined by 2 points:       [(2.0, 3.0), (2.0, 4.0)]
            Line defined by 2 points:       [(3.0, 0.0), (2.0, 0.0)]
            Line defined by 2 points:       [(3.0, 0.0), (3.0, -1.0)]
            Line defined by 2 points:       [(3.0, 2.0), (3.0, 1.0)]
            Line defined by 2 points:       [(3.0, 2.0), (3.0, 3.0)]
            Line defined by 2 points:       [(4.0, 1.0), (3.0, 1.0)]
            Line defined by 2 points:       [(4.0, 1.0), (3.0, 1.0)]
            Line defined by 2 points:       [(4.0, 3.0), (3.0, 3.0)]
            Line defined by 2 points:       [(4.0, 3.0), (3.0, 3.0)]

        Here is the plot:

        .. PLOT::
            :width: 300 px

            A = AlternatingSignMatrix([[0, 1, 0, 0], [1, -1, 0, 1], [0, 1, 0, 0],[0, 0, 1, 0]])
            fpl = FullyPackedLoop(A)
            p = fpl.plot()
            sphinx_plot(p)

        """
        G = Graphics()
        n=len(self._six_vertex_model)-1
        for j,row in enumerate(reversed(self._six_vertex_model)):
            for i,entry in enumerate(row):
                if i == 0 and (i+j+n+1) % 2 ==0:
                    G+= line([(i-1,j),(i,j)])
                if i == n and (i+j+n+1) % 2 ==0:
                    G+= line([(i+1,j),(i,j)])
                if j == 0 and (i+j+n) % 2 ==0:
                    G+= line([(i,j),(i,j-1)])
                if j == n and (i+j+n) % 2 ==0:
                    G+= line([(i,j),(i,j+1)])
                if entry == 0: # LR
                    if (i+j+n) % 2==0:
                        G += line([(i,j), (i+1,j)])
                    else:
                        G += line([(i,j),(i,j+1)])
                elif entry == 1: # LU
                    if (i+j+n) % 2 ==0:
                        G += line([(i,j), (i,j+1)])
                    else:
                        G += line([(i+1,j), (i,j)])
                elif entry == 2: # LD
                    if (i+j+n) % 2 == 0:
                        pass
                    else:
                        G += line([(i,j+1), (i,j)])
                        G += line([(i+1,j), (i,j)])
                elif entry == 3: # UD
                    if (i+j+n) % 2 == 0:
                        G += line([(i,j), (i,j+1)])
                    else:
                        G += line([(i+1,j), (i,j)])
                elif entry == 4: # UR
                    if (i+j+n) % 2 ==0:
                        G += line([(i,j), (i,j+1)])
                        G += line([(i,j), (i+1,j)])
                    else:
                        pass
                elif entry == 5: # RD
                    if (i+j+n) % 2 ==0:
                        G += line([(i,j), (i+1,j)])
                    else:
                        G += line([(i,j+1), (i,j)])
        G.axes(False)
        return G
Example #27
0
    def plot(self, **kwds):
        r"""
        Plot the initial triangulation associated to ``self``.

        INPUT:

        - ``radius`` - the radius of the disk; by default the length of
          the circle is the number of vertices
        - ``points_color`` - the color of the vertices; default 'black'
        - ``points_size`` - the size of the vertices; default 7
        - ``triangulation_color`` - the color of the arcs; default 'black'
        - ``triangulation_thickness`` - the thickness of the arcs; default 0.5
        - ``shading_color`` - the color of the shading used on neuter
          intervals; default 'lightgray'
        - ``reflections_color`` - the color of the reflection axes; default
          'blue'
        - ``reflections_thickness`` - the thickness of the reflection axes;
          default 1

        EXAMPLES::

            sage: Y = SineGordonYsystem('A',(6,4,3));
            sage: Y.plot()      # not tested
        """
        # Set up plotting options
        if 'radius' in kwds:
            radius = kwds['radius']
        else:
            radius = ceil(self.r() / (2 * pi))
        points_opts = {}
        if 'points_color' in kwds:
            points_opts['color'] = kwds['points_color']
        else:
            points_opts['color'] = 'black'
        if 'points_size' in kwds:
            points_opts['size'] = kwds['points_size']
        else:
            points_opts['size'] = 7
        triangulation_opts = {}
        if 'triangulation_color' in kwds:
            triangulation_opts['color'] = kwds['triangulation_color']
        else:
            triangulation_opts['color'] = 'black'
        if 'triangulation_thickness' in kwds:
            triangulation_opts['thickness'] = kwds['triangulation_thickness']
        else:
            triangulation_opts['thickness'] = 0.5
        shading_opts = {}
        if 'shading_color' in kwds:
            shading_opts['color'] = kwds['shading_color']
        else:
            shading_opts['color'] = 'lightgray'
        reflections_opts = {}
        if 'reflections_color' in kwds:
            reflections_opts['color'] = kwds['reflections_color']
        else:
            reflections_opts['color'] = 'blue'
        if 'reflections_thickness' in kwds:
            reflections_opts['thickness'] = kwds['reflections_thickness']
        else:
            reflections_opts['thickness'] = 1
        # Helper functions

        def triangle(x):
            (a, b) = sorted(x[:2])
            for p in self.vertices():
                if (p, a) in self.triangulation() or (a, p) in self.triangulation():
                    if (p, b) in self.triangulation() or (b, p) in self.triangulation():
                        if p < a or p > b:
                            return sorted((a, b, p))

        def plot_arc(radius, p, q, **opts):
            # plot the arc from p to q differently depending on the type of self
            p = ZZ(p)
            q = ZZ(q)
            t = var('t')
            if p - q in [1, -1]:
                def f(t):
                    return (radius * cos(t), radius * sin(t))
                (p, q) = sorted([p, q])
                angle_p = vertex_to_angle(p)
                angle_q = vertex_to_angle(q)
                return parametric_plot(f(t), (t, angle_q, angle_p), **opts)
            if self.type() == 'A':
                angle_p = vertex_to_angle(p)
                angle_q = vertex_to_angle(q)
                if angle_p < angle_q:
                    angle_p += 2 * pi
                internal_angle = angle_p - angle_q
                if internal_angle > pi:
                    (angle_p, angle_q) = (angle_q + 2 * pi, angle_p)
                    internal_angle = angle_p - angle_q
                angle_center = (angle_p+angle_q) / 2
                hypotenuse = radius / cos(internal_angle / 2)
                radius_arc = hypotenuse * sin(internal_angle / 2)
                center = (hypotenuse * cos(angle_center),
                          hypotenuse * sin(angle_center))
                center_angle_p = angle_p + pi / 2
                center_angle_q = angle_q + 3 * pi / 2

                def f(t):
                    return (radius_arc * cos(t) + center[0],
                            radius_arc * sin(t) + center[1])
                return parametric_plot(f(t), (t, center_angle_p,
                                              center_angle_q), **opts)
            elif self.type() == 'D':
                if p >= q:
                    q += self.r()
                px = -2 * pi * p / self.r() + pi / 2
                qx = -2 * pi * q / self.r() + pi / 2
                arc_radius = (px - qx) / 2
                arc_center = qx + arc_radius

                def f(t):
                    return exp(I * ((cos(t) + I * sin(t)) *
                                    arc_radius + arc_center)) * radius
                return parametric_plot((real_part(f(t)), imag_part(f(t))),
                                       (t, 0, pi), **opts)

        def vertex_to_angle(v):
            # v==0 corresponds to pi/2
            return -2 * pi * RR(v) / self.r() + 5 * pi / 2

        # Begin plotting
        P = Graphics()
        # Shade neuter intervals
        neuter_intervals = [x for x in flatten(self.intervals()[:-1],
                                               max_level=1)
                            if x[2] in ["NR", "NL"]]
        shaded_triangles = map(triangle, neuter_intervals)
        for (p, q, r) in shaded_triangles:
            points = list(plot_arc(radius, p, q)[0])
            points += list(plot_arc(radius, q, r)[0])
            points += list(reversed(plot_arc(radius, p, r)[0]))
            P += polygon2d(points, **shading_opts)
        # Disk boundary
        P += circle((0, 0), radius, **triangulation_opts)
        # Triangulation
        for (p, q) in self.triangulation():
            P += plot_arc(radius, p, q, **triangulation_opts)
        if self.type() == 'D':
            s = radius / 50.0
            P += polygon2d([(s, 5 * s), (s, 7 * s),
                            (3 * s, 5 * s), (3 * s, 7 * s)],
                           color=triangulation_opts['color'])
            P += bezier_path([[(0, 0), (2 * s, 1 * s), (2 * s, 6 * s)],
                              [(2 * s, 10 * s), (s, 20 * s)],
                              [(0, 30 * s), (0, radius)]],
                             **triangulation_opts)
            P += bezier_path([[(0, 0), (-2 * s, 1 * s), (-2 * s, 6 * s)],
                              [(-2 * s, 10 * s), (-s, 20 * s)],
                              [(0, 30 * s), (0, radius)]],
                             **triangulation_opts)
            P += point((0, 0), zorder=len(P), **points_opts)
        # Vertices
        v_points = {x: (radius * cos(vertex_to_angle(x)),
                        radius * sin(vertex_to_angle(x)))
                    for x in self.vertices()}
        for v in v_points:
            P += point(v_points[v], zorder=len(P), **points_opts)
        # Reflection axes
        P += line([(0, 1.1 * radius), (0, -1.1 * radius)],
                  zorder=len(P), **reflections_opts)
        axis_angle = vertex_to_angle(-0.5 * (self.rk() + (1, 1))[1])
        (a, b) = (1.1 * radius * cos(axis_angle),
                  1.1 * radius * sin(axis_angle))
        P += line([(a, b), (-a, -b)], zorder=len(P), **reflections_opts)
        # Wrap up
        P.set_aspect_ratio(1)
        P.axes(False)
        return P
Example #28
0
    def show(self, **args):
        r"""
        Displays the pseudoline arrangement as a wiring diagram.

        INPUT:

        - ``**args`` -- any arguments to be forwarded to the ``show`` method. In
          particular, to tune the dimensions, use the ``figsize`` argument
          (example below).

        EXAMPLES::

            sage: from sage.geometry.pseudolines import PseudolineArrangement
            sage: permutations = [[3, 2, 1], [3, 2, 0], [3, 1, 0], [2, 1, 0]]
            sage: p = PseudolineArrangement(permutations)
            sage: p.show(figsize=[7,5])

        TESTS::

            sage: from sage.geometry.pseudolines import PseudolineArrangement
            sage: permutations = [[3, 2, 1], [3, 2, 0], [3, 0, 1], [2, 0, 1]]
            sage: p = PseudolineArrangement(permutations)
            sage: p.show()
            Traceback (most recent call last):
            ...
            ValueError: There has been a problem while plotting the figure...
        """
        x = 1
        from sage.plot.line import line
        from sage.plot.text import text

        lines = [[(0, self._n - 1 - i)] for i in range(self._n)]

        for i, j in self.transpositions():
            iy = lines[i][-1][1]
            jy = lines[j][-1][1]

            lines[i].append((x, iy))
            lines[j].append((x, jy))

            if abs(iy - jy) != 1:
                raise ValueError(
                    "There has been a problem while plotting the figure. It " +
                    "seems that the lines are not correctly ordered. Please " +
                    "check the pseudolines modules documentation, there is a "
                    + "warning about that. ")

            lines[i].append((x + 2, jy))
            lines[j].append((x + 2, iy))

            x += 2

        L = line([(1, 1)])

        for i, l in enumerate(lines):
            l.append((x + 2, l[-1][1]))
            L += line(l)

            L += text(str(i), (0, l[0][1] + .3), horizontal_alignment="right")
            L += text(str(i), (x + 2, l[-1][1] + .3),
                      horizontal_alignment="left")

        return L.show(axes=False, **args)
Example #29
0
    def plot_paths_2d(self,
                      start_sys,
                      end_sys,
                      input_ring,
                      c_skew=.001,
                      endpoints=True,
                      saved_start=None,
                      rand_colors=False):
        """
        This returns a graphics object of solution paths in the complex plane.

        INPUT:

        - start_sys -- a square polynomial system, given as a list of polynomials
        - end_sys -- same type as start_sys
        - input_ring -- for coercion of the variables into the desired ring.
        - c_skew -- optional. the imaginary part of homotopy multiplier; nonzero values
          are often necessary to avoid intermediate path collisions
        - endpoints -- optional.  Whether to draw in the ends of paths as points.
        - saved_start -- optional.  A phc output file.  If not given, start system solutions
          are computed via the phc.blackbox function.

        OUTPUT:

        - lines and points of solution paths

        EXAMPLES::

            sage: from sage.interfaces.phc import *
            sage: from sage.structure.sage_object import SageObject
            sage: R2.<x,y> = PolynomialRing(QQ,2)
            sage: start_sys = [x^5-y^2,y^5-1]
            sage: sol = phc.blackbox(start_sys, R2)    # optional -- phc
            sage: start_save = sol.save_as_start()     # optional -- phc
            sage: end_sys = [x^5-25,y^5-x^2]           # optional -- phc
            sage: testing = phc.plot_paths_2d(start_sys, end_sys, R2)  # optional -- phc
            sage: type(testing)                        # optional -- phc (normally use plot here)
            <class 'sage.plot.graphics.Graphics'>
        """
        paths = phc.path_track(start_sys,
                               end_sys,
                               input_ring,
                               c_skew=c_skew,
                               saved_start=saved_start)
        path_lines = []
        sol_pts = []
        if rand_colors:
            r_color = {}
            for a_var in input_ring.gens():
                var_name = str(a_var)
                r_color[var_name] = (random(), random(), random())
        for a_sol in paths:
            for a_var in input_ring.gens():
                var_name = str(a_var)
                temp_line = []
                for data in a_sol:
                    temp_line.append(
                        [data[var_name].real(), data[var_name].imag()])
                if rand_colors:
                    path_lines.append(
                        line(temp_line, rgbcolor=r_color[var_name]))
                else:
                    path_lines.append(line(temp_line))
        if endpoints:
            sol_pts = []
            for a_sol in paths:
                for a_var in input_ring.gens():
                    var_name = str(a_var)
                    sol_pts.append(
                        point([
                            a_sol[0][var_name].real(),
                            a_sol[0][var_name].imag()
                        ]))
                    sol_pts.append(
                        point([
                            a_sol[-1][var_name].real(),
                            a_sol[-1][var_name].imag()
                        ]))
            return sum(sol_pts) + sum(path_lines)
        else:
            return sum(path_lines)
        def plot(self, size=[[0],[0]], projection='usual', simple_roots=True, fundamental_weights=True, alcovewalks=[]):
            r"""
            Return a graphics object built from a space of weight(space/lattice).
            There is a different technic to plot if the Cartan type is affine or not.
            The graphics returned is a Graphics object.

            This function is experimental, and is subject to short term evolutions.

            EXAMPLES::

              By default, the plot returned has no axes and the ratio between axes is 1.
                sage: G = RootSystem(['C',2]).weight_lattice().plot()
                sage: G.axes(True)
                sage: G.set_aspect_ratio(2)

              For a non affine Cartan type, the plot method work for type with 2 generators,
              it will draw the hyperlane(line for this dimension) accrow the fundamentals weights.
                sage: G = RootSystem(['A',2]).weight_lattice().plot()
                sage: G = RootSystem(['B',2]).weight_lattice().plot()
                sage: G = RootSystem(['G',2]).weight_lattice().plot()

              The plot returned has a size of one fundamental polygon by default. We can
              ask plot to give a bigger plot by using the argument size
                sage: G = RootSystem(['G',2,1]).weight_space().plot(size = [[0..1],[-1..1]])
                sage: G = RootSystem(['A',2,1]).weight_space().plot(size = [[-1..1],[-1..1]])

              A very important argument is the projection which will draw the plot. There are
              some usual projections is this method. If you want to draw in the plane a very
              special Cartan type, Sage will ask you to specify the projection. The projection
              is a matrix over a ring. In practice, calcul over float is a good way to draw.
                sage: L = RootSystem(['A',2,1]).weight_space()
                sage: G = L.plot(projection=matrix(RR, [[0,0.5,-0.5],[0,0.866,0.866]]))
                sage: G = RootSystem(['C',2,1]).weight_space().plot()

              By default, the plot method draw the simple roots, this can be disabled by setting
              the argument simple_roots=False
                sage: G = RootSystem(['A',2]).weight_space().plot(simple_roots=False)

              By default, the plot method draw the fundamental weights,this can be disabled by
              setting the argument fundamental_weights=False
                sage: G = RootSystem(['A',2]).weight_space().plot(fundamental_weights=False, simple_roots=False)

              There is in a plot an argument to draw alcoves walks. The good way to do this is
              to use the crystals theory. the plot method contains only the drawing part...
                sage: L = RootSystem(['A',2,1]).weight_space()
                sage: G = L.plot(size=[[-1..1],[-1..1]],alcovewalks=[[0,2,0,1,2,1,2,0,2,1]])
            """

            from sage.plot.all import Graphics
            from sage.plot.line import line
            from cartan_type import CartanType
            from sage.matrix.constructor import matrix
            from sage.rings.all import QQ, RR
            from sage.plot.arrow import arrow
            from sage.plot.point import point

            # We begin with an empty plot G
            G = Graphics()

            ct = self.cartan_type()
            n = ct.n

            # Define a set of colors
            # TODO : Colors in option ?
            colors=[(0,1,0),(1,0,0),(0,0,1),(1,1,0),(0,1,1),(1,0,1)]

            # plot the affine types:
            if ct.is_affine():

                # Check the projection
                # TODO : try to have usual_projection for main plotable types
                if projection == 'usual':
                    if ct == CartanType(['A',2,1]):
                        projection = matrix(RR, [[0,0.5,-0.5],[0,0.866,0.866]])
                    elif ct == CartanType(['C',2,1]):
                        projection = matrix(QQ, [[0,1,1],[0,0,1]])
                    elif ct == CartanType(['G',2,1]):
                        projection = matrix(RR, [[0,0.5,0],[0,0.866,1.732]])
                    else:
                        raise 'There is no usual projection for this Cartan type, you have to give one in argument'

                assert(n + 1 == projection.ncols())
                assert(2 == projection.nrows())

                # Check the size is correct with the lattice
                assert(len(size) == n)

                # Select the center of the translated fundamental polygon to plot
                translation_factors = ct.translation_factors()
                simple_roots = self.simple_roots()
                translation_vectors = [translation_factors[i]*simple_roots[i] for i in ct.classical().index_set()]

                initial = [[]]
                for i in range(n):
                    prod_list = []
                    for elem in size[i]:
                        for partial_list in initial:
                            prod_list.append( [elem]+partial_list );
                    initial = prod_list;

                part_lattice = []
                for combinaison in prod_list:
                    elem_lattice = self.zero()
                    for i in range(n):
                        elem_lattice = elem_lattice + combinaison[i]*translation_vectors[i]
                    part_lattice.append(elem_lattice)

                # Get the vertices of the fundamental alcove
                fundamental_weights = self.fundamental_weights()
                vertices = map(lambda x: (1/x.level())*x, fundamental_weights.list())

                # Recup the group which act on the fundamental polygon
                classical = self.weyl_group().classical()

                for center in part_lattice:
                    for w in classical:
                        # for each center of polygon and each element of classical
                        # parabolic subgroup, we have to draw an alcove.

                        #first, iterate over pairs of fundamental weights, drawing lines border of polygons:
                        for i in range(1,n+1):
                            for j in range(i+1,n+1):
                                p1=projection*((w.action(vertices[i])).to_vector() + center.to_vector())
                                p2=projection*((w.action(vertices[j])).to_vector() + center.to_vector())
                                G+=line([p1,p2],rgbcolor=(0,0,0),thickness=2)

                        #next, get all lines from point to a fundamental weight, that separe different
                        #chanber in a same polygon (important: associate a color with a fundamental weight)
                        pcenter = projection*(center.to_vector())
                        for i in range(1,n+1):
                            p3=projection*((w.action(vertices[i])).to_vector() + center.to_vector())
                            G+=line([p3,pcenter], rgbcolor=colors[n-i+1])

                #Draw alcovewalks
                #FIXME : The good way to draw this is to use the alcoves walks works made in Cristals
                #The code here just draw like example and import the good things.
                rho = (1/self.rho().level())*self.rho()
                W = self.weyl_group()
                for walk in alcovewalks:
                    target = W.from_reduced_word(walk).action(rho)
                    for i in range(len(walk)):
                        walk.pop()
                        origin = W.from_reduced_word(walk).action(rho)
                        G+=arrow(projection*(origin.to_vector()),projection*(target.to_vector()), rgbcolor=(0.6,0,0.6), width=1, arrowsize=5)
                        target = origin

            else:
                # non affine plot

                # Check the projection
                # TODO : try to have usual_projection for main plotable types
                if projection == 'usual':
                    if ct == CartanType(['A',2]):
                        projection = matrix(RR, [[0.5,-0.5],[0.866,0.866]])
                    elif ct == CartanType(['B',2]):
                        projection = matrix(QQ, [[1,0],[1,1]])
                    elif ct == CartanType(['C',2]):
                        projection = matrix(QQ, [[1,1],[0,1]])
                    elif ct == CartanType(['G',2]):
                        projection = matrix(RR, [[0.5,0],[0.866,1.732]])
                    else:
                        raise 'There is no usual projection for this Cartan type, you have to give one in argument'

                # Get the fundamental weights
                fundamental_weights = self.fundamental_weights()
                WeylGroup = self.weyl_group()

                #Draw not the alcove but the cones delimited by the hyperplanes
                #The size of the line depend of the fundamental weights.
                pcenter = projection*(self.zero().to_vector())
                for w in WeylGroup:
                    for i in range(1,n+1):
                        p3=3*projection*((w.action(fundamental_weights[i])).to_vector())
                        G+=line([p3,pcenter], rgbcolor=colors[n-i+1])

            #Draw the simple roots
            if simple_roots:
                SimpleRoots = self.simple_roots()
                if ct.is_affine():
                    G+=arrow((0,0), projection*(SimpleRoots[0].to_vector()), rgbcolor=(0,0,0))
                for j in range(1,n+1):
                    G+=arrow((0,0),projection*(SimpleRoots[j].to_vector()), rgbcolor=colors[j])

            #Draw the fundamental weights
            if fundamental_weights:
                FundWeight = self.fundamental_weights()
                for j in range(1,n+1):
                    G+=point(projection*(FundWeight[j].to_vector()), rgbcolor=colors[j], pointsize=60)

            G.set_aspect_ratio(1)
            G.axes(False)
            return G
        def plot(self,
                 size=[[0], [0]],
                 projection='usual',
                 simple_roots=True,
                 fundamental_weights=True,
                 alcovewalks=[]):
            r"""
            Return a graphics object built from a space of weight(space/lattice).
            There is a different technic to plot if the Cartan type is affine or not.
            The graphics returned is a Graphics object.

            This function is experimental, and is subject to short term evolutions.

            EXAMPLES::

              By default, the plot returned has no axes and the ratio between axes is 1.
                sage: G = RootSystem(['C',2]).weight_lattice().plot()
                sage: G.axes(True)
                sage: G.set_aspect_ratio(2)

              For a non affine Cartan type, the plot method work for type with 2 generators,
              it will draw the hyperlane(line for this dimension) accrow the fundamentals weights.
                sage: G = RootSystem(['A',2]).weight_lattice().plot()
                sage: G = RootSystem(['B',2]).weight_lattice().plot()
                sage: G = RootSystem(['G',2]).weight_lattice().plot()

              The plot returned has a size of one fundamental polygon by default. We can
              ask plot to give a bigger plot by using the argument size
                sage: G = RootSystem(['G',2,1]).weight_space().plot(size = [[0..1],[-1..1]])
                sage: G = RootSystem(['A',2,1]).weight_space().plot(size = [[-1..1],[-1..1]])

              A very important argument is the projection which will draw the plot. There are
              some usual projections is this method. If you want to draw in the plane a very
              special Cartan type, Sage will ask you to specify the projection. The projection
              is a matrix over a ring. In practice, calcul over float is a good way to draw.
                sage: L = RootSystem(['A',2,1]).weight_space()
                sage: G = L.plot(projection=matrix(RR, [[0,0.5,-0.5],[0,0.866,0.866]]))
                sage: G = RootSystem(['C',2,1]).weight_space().plot()

              By default, the plot method draw the simple roots, this can be disabled by setting
              the argument simple_roots=False
                sage: G = RootSystem(['A',2]).weight_space().plot(simple_roots=False)

              By default, the plot method draw the fundamental weights,this can be disabled by
              setting the argument fundamental_weights=False
                sage: G = RootSystem(['A',2]).weight_space().plot(fundamental_weights=False, simple_roots=False)

              There is in a plot an argument to draw alcoves walks. The good way to do this is
              to use the crystals theory. the plot method contains only the drawing part...
                sage: L = RootSystem(['A',2,1]).weight_space()
                sage: G = L.plot(size=[[-1..1],[-1..1]],alcovewalks=[[0,2,0,1,2,1,2,0,2,1]])
            """

            from sage.plot.all import Graphics
            from sage.plot.line import line
            from cartan_type import CartanType
            from sage.matrix.constructor import matrix
            from sage.rings.all import QQ, RR
            from sage.plot.arrow import arrow
            from sage.plot.point import point

            # We begin with an empty plot G
            G = Graphics()

            ct = self.cartan_type()
            n = ct.n

            # Define a set of colors
            # TODO : Colors in option ?
            colors = [(0, 1, 0), (1, 0, 0), (0, 0, 1), (1, 1, 0), (0, 1, 1),
                      (1, 0, 1)]

            # plot the affine types:
            if ct.is_affine():

                # Check the projection
                # TODO : try to have usual_projection for main plotable types
                if projection == 'usual':
                    if ct == CartanType(['A', 2, 1]):
                        projection = matrix(
                            RR, [[0, 0.5, -0.5], [0, 0.866, 0.866]])
                    elif ct == CartanType(['C', 2, 1]):
                        projection = matrix(QQ, [[0, 1, 1], [0, 0, 1]])
                    elif ct == CartanType(['G', 2, 1]):
                        projection = matrix(RR,
                                            [[0, 0.5, 0], [0, 0.866, 1.732]])
                    else:
                        raise 'There is no usual projection for this Cartan type, you have to give one in argument'

                assert (n + 1 == projection.ncols())
                assert (2 == projection.nrows())

                # Check the size is correct with the lattice
                assert (len(size) == n)

                # Select the center of the translated fundamental polygon to plot
                translation_factors = ct.translation_factors()
                simple_roots = self.simple_roots()
                translation_vectors = [
                    translation_factors[i] * simple_roots[i]
                    for i in ct.classical().index_set()
                ]

                initial = [[]]
                for i in range(n):
                    prod_list = []
                    for elem in size[i]:
                        for partial_list in initial:
                            prod_list.append([elem] + partial_list)
                    initial = prod_list

                part_lattice = []
                for combinaison in prod_list:
                    elem_lattice = self.zero()
                    for i in range(n):
                        elem_lattice = elem_lattice + combinaison[
                            i] * translation_vectors[i]
                    part_lattice.append(elem_lattice)

                # Get the vertices of the fundamental alcove
                fundamental_weights = self.fundamental_weights()
                vertices = map(lambda x: (1 / x.level()) * x,
                               fundamental_weights.list())

                # Recup the group which act on the fundamental polygon
                classical = self.weyl_group().classical()

                for center in part_lattice:
                    for w in classical:
                        # for each center of polygon and each element of classical
                        # parabolic subgroup, we have to draw an alcove.

                        #first, iterate over pairs of fundamental weights, drawing lines border of polygons:
                        for i in range(1, n + 1):
                            for j in range(i + 1, n + 1):
                                p1 = projection * (
                                    (w.action(vertices[i])).to_vector() +
                                    center.to_vector())
                                p2 = projection * (
                                    (w.action(vertices[j])).to_vector() +
                                    center.to_vector())
                                G += line([p1, p2],
                                          rgbcolor=(0, 0, 0),
                                          thickness=2)

                        #next, get all lines from point to a fundamental weight, that separe different
                        #chanber in a same polygon (important: associate a color with a fundamental weight)
                        pcenter = projection * (center.to_vector())
                        for i in range(1, n + 1):
                            p3 = projection * (
                                (w.action(vertices[i])).to_vector() +
                                center.to_vector())
                            G += line([p3, pcenter],
                                      rgbcolor=colors[n - i + 1])

                #Draw alcovewalks
                #FIXME : The good way to draw this is to use the alcoves walks works made in Cristals
                #The code here just draw like example and import the good things.
                rho = (1 / self.rho().level()) * self.rho()
                W = self.weyl_group()
                for walk in alcovewalks:
                    target = W.from_reduced_word(walk).action(rho)
                    for i in range(len(walk)):
                        walk.pop()
                        origin = W.from_reduced_word(walk).action(rho)
                        G += arrow(projection * (origin.to_vector()),
                                   projection * (target.to_vector()),
                                   rgbcolor=(0.6, 0, 0.6),
                                   width=1,
                                   arrowsize=5)
                        target = origin

            else:
                # non affine plot

                # Check the projection
                # TODO : try to have usual_projection for main plotable types
                if projection == 'usual':
                    if ct == CartanType(['A', 2]):
                        projection = matrix(RR, [[0.5, -0.5], [0.866, 0.866]])
                    elif ct == CartanType(['B', 2]):
                        projection = matrix(QQ, [[1, 0], [1, 1]])
                    elif ct == CartanType(['C', 2]):
                        projection = matrix(QQ, [[1, 1], [0, 1]])
                    elif ct == CartanType(['G', 2]):
                        projection = matrix(RR, [[0.5, 0], [0.866, 1.732]])
                    else:
                        raise 'There is no usual projection for this Cartan type, you have to give one in argument'

                # Get the fundamental weights
                fundamental_weights = self.fundamental_weights()
                WeylGroup = self.weyl_group()

                #Draw not the alcove but the cones delimited by the hyperplanes
                #The size of the line depend of the fundamental weights.
                pcenter = projection * (self.zero().to_vector())
                for w in WeylGroup:
                    for i in range(1, n + 1):
                        p3 = 3 * projection * (
                            (w.action(fundamental_weights[i])).to_vector())
                        G += line([p3, pcenter], rgbcolor=colors[n - i + 1])

            #Draw the simple roots
            if simple_roots:
                SimpleRoots = self.simple_roots()
                if ct.is_affine():
                    G += arrow((0, 0),
                               projection * (SimpleRoots[0].to_vector()),
                               rgbcolor=(0, 0, 0))
                for j in range(1, n + 1):
                    G += arrow((0, 0),
                               projection * (SimpleRoots[j].to_vector()),
                               rgbcolor=colors[j])

            #Draw the fundamental weights
            if fundamental_weights:
                FundWeight = self.fundamental_weights()
                for j in range(1, n + 1):
                    G += point(projection * (FundWeight[j].to_vector()),
                               rgbcolor=colors[j],
                               pointsize=60)

            G.set_aspect_ratio(1)
            G.axes(False)
            return G