Example #1
0
    def family_of_vectors(self, vectors):
        r"""
        Return a plot of a family of vectors.

        INPUT:

        - ``vectors`` -- family or vectors in ``self``

        The vectors are labelled by their index.

        EXAMPLES::

            sage: L = RootSystem(["A",2]).root_lattice()
            sage: options = L.plot_parse_options()
            sage: alpha = L.simple_roots()
            sage: p = options.family_of_vectors(alpha); p
            sage: list(p)
            [Arrow from (0.0,0.0) to (1.0,0.0),
             Text '$1$' at the point (1.05,0.0),
             Arrow from (0.0,0.0) to (0.0,1.0),
             Text '$2$' at the point (0.0,1.05)]

        Handling of colors and labels::

            sage: color=lambda i: "purple" if i==1 else None
            sage: options = L.plot_parse_options(labels=False, color=color)
            sage: p = options.family_of_vectors(alpha)
            sage: list(p)
            [Arrow from (0.0,0.0) to (1.0,0.0)]
            sage: p[0].options()['rgbcolor']
            'purple'

        Matplotlib emits a warning for arrows of length 0 and draws
        nothing anyway. So we do not draw them at all::

            sage: L = RootSystem(["A",2,1]).ambient_space()
            sage: options = L.plot_parse_options()
            sage: Lambda = L.fundamental_weights()
            sage: p = options.family_of_vectors(Lambda); p
            sage: list(p)
            [Text '$0$' at the point (0.0,0.0),
             Arrow from (0.0,0.0) to (0.5,0.866024518389),
             Text '$1$' at the point (0.525,0.909325744308),
             Arrow from (0.0,0.0) to (-0.5,0.866024518389),
             Text '$2$' at the point (-0.525,0.909325744308)]
        """
        from sage.plot.arrow import arrow

        tail = self.origin_projected
        G = self.empty()
        for i in vectors.keys():
            if self.color(i) is None:
                continue
            head = self.projection(vectors[i])
            if head != tail:
                G += arrow(tail, head, rgbcolor=self.color(i), arrowsize=self._arrowsize)
            G += self.text(i, 1.05 * head)
        return self.finalize(G)
Example #2
0
File: plot.py Project: biasse/sage
    def family_of_vectors(self, vectors):
        r"""
        Return a plot of a family of vectors.

        INPUT:

        - ``vectors`` -- family or vectors in ``self``

        The vectors are labelled by their index.

        EXAMPLES::

            sage: L = RootSystem(["A",2]).root_lattice()
            sage: options = L.plot_parse_options()
            sage: alpha = L.simple_roots()
            sage: p = options.family_of_vectors(alpha); p
            sage: list(p)
            [Arrow from (0.0,0.0) to (1.0,0.0),
             Text '$1$' at the point (1.05,0.0),
             Arrow from (0.0,0.0) to (0.0,1.0),
             Text '$2$' at the point (0.0,1.05)]

        Handling of colors and labels::

            sage: color=lambda i: "purple" if i==1 else None
            sage: options = L.plot_parse_options(labels=False, color=color)
            sage: p = options.family_of_vectors(alpha)
            sage: list(p)
            [Arrow from (0.0,0.0) to (1.0,0.0)]
            sage: p[0].options()['rgbcolor']
            'purple'

        Matplotlib emits a warning for arrows of length 0 and draws
        nothing anyway. So we do not draw them at all::

            sage: L = RootSystem(["A",2,1]).ambient_space()
            sage: options = L.plot_parse_options()
            sage: Lambda = L.fundamental_weights()
            sage: p = options.family_of_vectors(Lambda); p
            sage: list(p)
            [Text '$0$' at the point (0.0,0.0),
             Arrow from (0.0,0.0) to (0.5,0.866024518389),
             Text '$1$' at the point (0.525,0.909325744308),
             Arrow from (0.0,0.0) to (-0.5,0.866024518389),
             Text '$2$' at the point (-0.525,0.909325744308)]
        """
        from sage.plot.arrow import arrow
        tail = self.origin_projected
        G = self.empty()
        for i in vectors.keys():
            if self.color(i) is None:
                continue
            head = self.projection(vectors[i])
            if head != tail:
                G += arrow(tail, head, rgbcolor=self.color(i))
            G += self.text(i, 1.05 * head)
        return self.finalize(G)
Example #3
0
    def plot(self, color='sign'):
        """
        Return a plot of ``self``.

        INPUT:

        - ``color`` -- can be any of the following:

          * ``4`` - use 4 colors: black, red, blue, and green with each
            corresponding to up, right, down, and left respectively
          * ``2`` - use 2 colors: red for horizontal, blue for vertical arrows
          * ``'sign'`` - use red for right and down arrows, blue for left
            and up arrows
          * a list of 4 colors for each direction
          * a function which takes a direction and a boolean corresponding
            to the sign

        EXAMPLES::

            sage: M = SixVertexModel(2, boundary_conditions='ice')
            sage: print(M[0].plot().description())
            Arrow from (-1.0,0.0) to (0.0,0.0)
            Arrow from (-1.0,1.0) to (0.0,1.0)
            Arrow from (0.0,0.0) to (0.0,-1.0)
            Arrow from (0.0,0.0) to (1.0,0.0)
            Arrow from (0.0,1.0) to (0.0,0.0)
            Arrow from (0.0,1.0) to (0.0,2.0)
            Arrow from (1.0,0.0) to (1.0,-1.0)
            Arrow from (1.0,0.0) to (1.0,1.0)
            Arrow from (1.0,1.0) to (0.0,1.0)
            Arrow from (1.0,1.0) to (1.0,2.0)
            Arrow from (2.0,0.0) to (1.0,0.0)
            Arrow from (2.0,1.0) to (1.0,1.0)
        """
        from sage.plot.graphics import Graphics
        from sage.plot.circle import circle
        from sage.plot.arrow import arrow

        if color == 4:
            color_list = ['black', 'red', 'blue', 'green']
            cfunc = lambda d,pm: color_list[d]
        elif color == 2:
            cfunc = lambda d,pm: 'red' if d % 2 == 0 else 'blue'
        elif color == 1 or color is None:
            cfunc = lambda d,pm: 'black'
        elif color == 'sign':
            cfunc = lambda d,pm: 'red' if pm else 'blue' # RD are True
        elif isinstance(color, (list, tuple)):
            cfunc = lambda d,pm: color[d]
        else:
            cfunc = color

        G = Graphics()
        for j,row in enumerate(reversed(self)):
            for i,entry in enumerate(row):
                if entry == 0: # LR
                    G += arrow((i,j+1), (i,j), color=cfunc(2, True))
                    G += arrow((i,j), (i+1,j), color=cfunc(1, True))
                    if j == 0:
                        G += arrow((i,j-1), (i,j), color=cfunc(0, False))
                    if i == 0:
                        G += arrow((i,j), (i-1,j), color=cfunc(3, False))
                elif entry == 1: # LU
                    G += arrow((i,j), (i,j+1), color=cfunc(0, False))
                    G += arrow((i+1,j), (i,j), color=cfunc(3, False))
                    if j == 0:
                        G += arrow((i,j-1), (i,j), color=cfunc(0, False))
                    if i == 0:
                        G += arrow((i,j), (i-1,j), color=cfunc(3, False))
                elif entry == 2: # LD
                    G += arrow((i,j+1), (i,j), color=cfunc(2, True))
                    G += arrow((i+1,j), (i,j), color=cfunc(3, False))
                    if j == 0:
                        G += arrow((i,j), (i,j-1), color=cfunc(2, True))
                    if i == 0:
                        G += arrow((i,j), (i-1,j), color=cfunc(3, False))
                elif entry == 3: # UD
                    G += arrow((i,j), (i,j+1), color=cfunc(0, False))
                    G += arrow((i+1,j), (i,j), color=cfunc(3, False))
                    if j == 0:
                        G += arrow((i,j), (i,j-1), color=cfunc(2, True))
                    if i == 0:
                        G += arrow((i-1,j), (i,j), color=cfunc(1, True))
                elif entry == 4: # UR
                    G += arrow((i,j), (i,j+1), color=cfunc(0, False))
                    G += arrow((i,j), (i+1,j), color=cfunc(1, True))
                    if j == 0:
                        G += arrow((i,j-1), (i,j), color=cfunc(0, False))
                    if i == 0:
                        G += arrow((i-1,j), (i,j), color=cfunc(1, True))
                elif entry == 5: # RD
                    G += arrow((i,j+1), (i,j), color=cfunc(2, True))
                    G += arrow((i,j), (i+1,j), color=cfunc(1, True))
                    if j == 0:
                        G += arrow((i,j), (i,j-1), color=cfunc(2, True))
                    if i == 0:
                        G += arrow((i-1,j), (i,j), color=cfunc(1, True))
        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
Example #5
0
    def plot(self, color='sign'):
        """
        Return a plot of ``self``.

        INPUT:

        - ``color`` -- can be any of the following:

          * ``4`` - use 4 colors: black, red, blue, and green with each
            corresponding to up, right, down, and left respectively
          * ``2`` - use 2 colors: red for horizontal, blue for vertical arrows
          * ``'sign'`` - use red for right and down arrows, blue for left
            and up arrows
          * a list of 4 colors for each direction
          * a function which takes a direction and a boolean corresponding
            to the sign

        EXAMPLES::

            sage: M = SixVertexModel(2, boundary_conditions='ice')
            sage: print(M[0].plot().description())
            Arrow from (-1.0,0.0) to (0.0,0.0)
            Arrow from (-1.0,1.0) to (0.0,1.0)
            Arrow from (0.0,0.0) to (0.0,-1.0)
            Arrow from (0.0,0.0) to (1.0,0.0)
            Arrow from (0.0,1.0) to (0.0,0.0)
            Arrow from (0.0,1.0) to (0.0,2.0)
            Arrow from (1.0,0.0) to (1.0,-1.0)
            Arrow from (1.0,0.0) to (1.0,1.0)
            Arrow from (1.0,1.0) to (0.0,1.0)
            Arrow from (1.0,1.0) to (1.0,2.0)
            Arrow from (2.0,0.0) to (1.0,0.0)
            Arrow from (2.0,1.0) to (1.0,1.0)
        """
        from sage.plot.graphics import Graphics
        from sage.plot.arrow import arrow

        if color == 4:
            color_list = ['black', 'red', 'blue', 'green']
            cfunc = lambda d,pm: color_list[d]
        elif color == 2:
            cfunc = lambda d,pm: 'red' if d % 2 == 0 else 'blue'
        elif color == 1 or color is None:
            cfunc = lambda d,pm: 'black'
        elif color == 'sign':
            cfunc = lambda d,pm: 'red' if pm else 'blue' # RD are True
        elif isinstance(color, (list, tuple)):
            cfunc = lambda d,pm: color[d]
        else:
            cfunc = color

        G = Graphics()
        for j,row in enumerate(reversed(self)):
            for i,entry in enumerate(row):
                if entry == 0: # LR
                    G += arrow((i,j+1), (i,j), color=cfunc(2, True))
                    G += arrow((i,j), (i+1,j), color=cfunc(1, True))
                    if j == 0:
                        G += arrow((i,j-1), (i,j), color=cfunc(0, False))
                    if i == 0:
                        G += arrow((i,j), (i-1,j), color=cfunc(3, False))
                elif entry == 1: # LU
                    G += arrow((i,j), (i,j+1), color=cfunc(0, False))
                    G += arrow((i+1,j), (i,j), color=cfunc(3, False))
                    if j == 0:
                        G += arrow((i,j-1), (i,j), color=cfunc(0, False))
                    if i == 0:
                        G += arrow((i,j), (i-1,j), color=cfunc(3, False))
                elif entry == 2: # LD
                    G += arrow((i,j+1), (i,j), color=cfunc(2, True))
                    G += arrow((i+1,j), (i,j), color=cfunc(3, False))
                    if j == 0:
                        G += arrow((i,j), (i,j-1), color=cfunc(2, True))
                    if i == 0:
                        G += arrow((i,j), (i-1,j), color=cfunc(3, False))
                elif entry == 3: # UD
                    G += arrow((i,j), (i,j+1), color=cfunc(0, False))
                    G += arrow((i+1,j), (i,j), color=cfunc(3, False))
                    if j == 0:
                        G += arrow((i,j), (i,j-1), color=cfunc(2, True))
                    if i == 0:
                        G += arrow((i-1,j), (i,j), color=cfunc(1, True))
                elif entry == 4: # UR
                    G += arrow((i,j), (i,j+1), color=cfunc(0, False))
                    G += arrow((i,j), (i+1,j), color=cfunc(1, True))
                    if j == 0:
                        G += arrow((i,j-1), (i,j), color=cfunc(0, False))
                    if i == 0:
                        G += arrow((i-1,j), (i,j), color=cfunc(1, True))
                elif entry == 5: # RD
                    G += arrow((i,j+1), (i,j), color=cfunc(2, True))
                    G += arrow((i,j), (i+1,j), color=cfunc(1, True))
                    if j == 0:
                        G += arrow((i,j), (i,j-1), color=cfunc(2, True))
                    if i == 0:
                        G += arrow((i-1,j), (i,j), color=cfunc(1, True))
        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