def plot_fan_stereographically(rays, walls, northsign=1, north=vector((-1,-1,-1)), right=vector((1,0,0)), colors=None, thickness=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 colors == None:
        colors = dict([('walls','black'),('rays','red')])

    if thickness == None:
        thickness = dict([('walls',0.5),('rays',20)])


    G = Graphics()
    
    for (u,v) in walls:
        G += _stereo_arc(vector(u),vector(v),vector(u+v),north=northsign*north,right=right,color=colors['walls'],thickness=thickness['walls'],zorder=len(G))
   
    for v in rays: 
        G += point(_stereo_coordinates(vector(v),north=northsign*north,right=right),color=colors['rays'],zorder=len(G),size=thickness['rays'])
    
    G.set_aspect_ratio(1)
    G._show_axes = False
    return G
    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
    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 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
    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