Esempio n. 1
0
def circle_image(A, B):
    G = Graphics()
    G += circle((0, 0), 1, color='grey')
    from collections import defaultdict
    tmp = defaultdict(int)
    for a in A:
        for j in range(a):
            if gcd(j, a) == 1:
                rational = Rational(j) / Rational(a)
                tmp[(rational.numerator(), rational.denominator())] += 1

    for b in B:
        for j in range(b):
            if gcd(j, b) == 1:
                rational = Rational(j) / Rational(b)
                tmp[(rational.numerator(), rational.denominator())] -= 1
    C = ComplexField()
    for val in tmp:
        if tmp[val] > 0:
            G += text(str(tmp[val]),
                      exp(C(-.2 + 2 * 3.14159 * I * val[0] / val[1])),
                      fontsize=30,
                      axes=False,
                      color="green")
        if tmp[val] < 0:
            G += text(str(abs(tmp[val])),
                      exp(C(.2 + 2 * 3.14159 * I * val[0] / val[1])),
                      fontsize=30,
                      axes=False,
                      color="blue")
    return G
Esempio n. 2
0
    def plot(self, polygon_label=True):
        r"""
        Returns a plot of the GraphicalPolygon.

        EXAMPLES::

            sage: from flatsurf import *
            sage: s = similarity_surfaces.example()
            sage: from flatsurf.graphical.surface import GraphicalSurface
            sage: gs = GraphicalSurface(s)
            sage: gs.graphical_polygon(0).set_fill_color("red")
            sage: gs.graphical_polygon(0).plot()
            Graphics object consisting of 5 graphics primitives
        """
        from sage.plot.point import point2d
        from sage.plot.polygon import polygon2d
        from sage.plot.graphics import Graphics
        from sage.plot.text import text

        p = polygon2d(self._v, **self.polygon_options())

        if self._label is not None and polygon_label:
            p += text(str(self._label), sum(self._v) / len(self._v), **self.polygon_label_options())

        if self._edge_labels:
            opt = self.edge_label_options()
            n = self.base_polygon().num_edges()
            for i in range(n):
                lab = str(i) if self._edge_labels is True else self._edge_labels[i]
                if lab:
                    e = self._v[(i + 1) % n] - self._v[i]
                    no = V((-e[1], e[0]))
                    p += text(lab, self._v[i] + 0.3 * e + 0.05 * no, **self.edge_label_options())

        return p
Esempio n. 3
0
    def plot3d_cube(self, mv, title=True):
        """
        Displays F,U,R faces of the cube after the given move mv, where mv
        is a string in the Singmaster notation. Mostly included for the
        purpose of drawing pictures and checking moves.

        The first one below is "superflip+4 spot" (in 26q\* moves) and the
        second one is the superflip (in 20f\* moves). Type show(P) to view
        them.

        EXAMPLES::

            sage: rubik = CubeGroup()
            sage: P = rubik.plot3d_cube("U^2*F*U^2*L*R^(-1)*F^2*U*F^3*B^3*R*L*U^2*R*D^3*U*L^3*R*D*R^3*L^3*D^2")
            sage: P = rubik.plot3d_cube("R*L*D^2*B^3*L^2*F^2*R^2*U^3*D*R^3*D^2*F^3*B^3*D^3*F^2*D^3*R^2*U^3*F^2*D^3")
        """
        g = self.parse(mv)
        state = self.facets(g)
        clr_any = white
        shown_labels = range(1, 9) + range(17, 33)
        clr = [color_of_square(state[c - 1]) for c in shown_labels]
        cubiesR = [
            plot3d_cubie(cubie_centers(c), cubie_colors(c, state))
            for c in [32, 31, 30, 29, 28, 27, 26, 25]
        ]
        cubeR = sum(cubiesR)
        cubiesU = [
            plot3d_cubie(cubie_centers(c), cubie_colors(c, state))
            for c in range(1, 9)
        ]
        cubeU = sum(cubiesU)
        cubiesF = [
            plot3d_cubie(cubie_centers(c), cubie_colors(c, state))
            for c in [22, 23, 24, 20, 21]
        ]
        cubeF = sum(cubiesF)
        centerR = polygon_plot3d(
            [[1, 3, 1], [2, 3, 1], [2, 3, 2], [1, 3, 2], [1, 3, 1]],
            rgbcolor=green)
        centerF = polygon_plot3d(
            [[3, 1, 1], [3, 2, 1], [3, 2, 2], [3, 1, 2], [3, 1, 1]],
            rgbcolor=red)
        centerU = polygon_plot3d(
            [[1, 1, 3], [1, 2, 3], [2, 2, 3], [2, 1, 3], [1, 1, 3]],
            rgbcolor=lpurple)
        centers = centerF + centerR + centerU
        P = cubeR + cubeF + cubeU + centers
        P.axes(show=False)
        if title == True:
            t1 = text('Up, Front, and Right faces. ', (-0.2, -2.5))
            t2 = text('      sagemath.org', (0.8, -3.1), rgbcolor=lgrey)
            t3 = text("     ", (3.5, 0), rgbcolor=white)
            P = P + t1 + t2 + t3
            P.axes(show=False)
            return P
        return P
Esempio n. 4
0
    def plot_label(self, label, **options):
        r"""
        Write the label of the polygon as text.

        Set ``position`` to a pair (x,y) to determine where
        the label is drawn (in graphical coordinates). If this parameter
        is not provided, the label is positioned in the baricenter
        of the polygon.

        Other options are processed as in sage.plot.text.text.
        """
        if "position" in options:
            return text(str(label), options.pop("position"), **options)
        else:
            return text(str(label), sum(self._v) / len(self._v), **options)
Esempio n. 5
0
    def plot_label(self, label, **options):
        r"""
        Write the label of the polygon as text.

        Set ``position`` to a pair (x,y) to determine where
        the label is drawn (in graphical coordinates). If this parameter
        is not provided, the label is positioned in the baricenter
        of the polygon.

        Other options are processed as in sage.plot.text.text.
        """
        if "position" in options:
            return text(str(label), options.pop("position"), **options)
        else:
            return text(str(label), sum(self._v) / len(self._v), **options)
Esempio n. 6
0
    def plot_n_cylinders(self, n, labels=True):
        r"""
        EXAMPLES::

            sage: from slabbe.markov_transformation import markov_transformations
            sage: T = markov_transformations.Selmer()
            sage: G = T.plot_n_cylinders(3)

        TESTS::

            sage: G = T.plot_n_cylinders(0)
        """
        from sage.plot.graphics import Graphics
        from sage.plot.polygon import polygon
        from sage.plot.text import text
        M3to2 = projection_matrix(3, 2)
        G = Graphics()
        for w, cyl in self.n_cylinders_iterator(n):
            columns = cyl.columns()
            G += polygon((M3to2 * col / col.norm(1) for col in columns),
                         fill=False)
            if labels:
                sum_cols = sum(columns)
                G += text("{}".format(w), M3to2 * sum_cols / sum_cols.norm(1))
        return G
Esempio n. 7
0
 def plot_cube(self, mv, title=True, colors = [lpurple, yellow, red, green, orange, blue]):
     """
     Input the move mv, as a string in the Singmaster notation, and
     output the 2-d plot of the cube in that state.
     
     Type P.show() to display any of the plots below.
     
     EXAMPLES::
     
         sage: rubik = CubeGroup()
         sage: P = rubik.plot_cube("R^2*U^2*R^2*U^2*R^2*U^2", title = False)
         sage: # (R^2U^2)^3  permutes 2 pairs of edges (uf,ub)(fr,br)
         sage: P = rubik.plot_cube("R*L*D^2*B^3*L^2*F^2*R^2*U^3*D*R^3*D^2*F^3*B^3*D^3*F^2*D^3*R^2*U^3*F^2*D^3")
         sage: # the superflip (in 20f* moves)
         sage: P = rubik.plot_cube("U^2*F*U^2*L*R^(-1)*F^2*U*F^3*B^3*R*L*U^2*R*D^3*U*L^3*R*D*R^3*L^3*D^2")
         sage: # "superflip+4 spot" (in 26q* moves)
     """
     g = self.parse(mv)
     state = self.facets(g)
     #print state
     cubies = [create_poly(index2singmaster(state[x]), color_of_square(x+1, colors)) for x in range(48)]
     centers = [create_poly('%s_center' % "ulfrbd"[i], colors[i]) for i in range(6)]
     clrs = sum(cubies) + sum(centers)
     clrs.axes(show=False)
     if title == True:
         t = text('sagemath.org', (7.8,-3.5),rgbcolor=lgrey)
         P = clrs+t
         P.axes(show=False)
         return P
     return clrs
Esempio n. 8
0
    def return_plot(self, interval=(0,1), adaptive_recursion=4,
            plot_points=4,
            adaptive_tolerance=0.10):
        r"""
        Return a plot of percolation probability using basic sage plot settings.

        INPUT:

        - ``interval``, default=(0,1)
        - ``adaptive_recursion``, default=0
        - ``plot_points``, default=10
        - ``adaptive_tolerance`` default=0.10

        EXAMPLES::

            sage: from slabbe import PercolationProbability
            sage: T = PercolationProbability(d=2, n=10, stop=100)
            sage: T.return_plot()           # optional long
            Graphics object consisting of 1 graphics primitive
        """
        P = plot(self, interval, adaptive_recursion=adaptive_recursion,
                 plot_points=plot_points,
                 adaptive_tolerance=adaptive_tolerance)
        P += text(repr(self), (0.8,0.2))
        return P
Esempio n. 9
0
    def plot_cube(self, mv, title=True, colors = [lpurple, yellow, red, green, orange, blue]):
        """
        Input the move mv, as a string in the Singmaster notation, and
        output the 2-d plot of the cube in that state.

        Type P.show() to display any of the plots below.

        EXAMPLES::

            sage: rubik = CubeGroup()
            sage: P = rubik.plot_cube("R^2*U^2*R^2*U^2*R^2*U^2", title = False)
            sage: # (R^2U^2)^3  permutes 2 pairs of edges (uf,ub)(fr,br)
            sage: P = rubik.plot_cube("R*L*D^2*B^3*L^2*F^2*R^2*U^3*D*R^3*D^2*F^3*B^3*D^3*F^2*D^3*R^2*U^3*F^2*D^3")
            sage: # the superflip (in 20f* moves)
            sage: P = rubik.plot_cube("U^2*F*U^2*L*R^(-1)*F^2*U*F^3*B^3*R*L*U^2*R*D^3*U*L^3*R*D*R^3*L^3*D^2")
            sage: # "superflip+4 spot" (in 26q* moves)
        """
        g = self.parse(mv)
        state = self.facets(g)
        #print state
        cubies = [create_poly(index2singmaster(state[x]), color_of_square(x+1, colors)) for x in range(48)]
        centers = [create_poly('%s_center' % "ulfrbd"[i], colors[i]) for i in range(6)]
        clrs = sum(cubies) + sum(centers)
        clrs.axes(show=False)
        if title == True:
            t = text('sagemath.org', (7.8,-3.5),rgbcolor=lgrey)
            P = clrs+t
            P.axes(show=False)
            return P
        return clrs
Esempio n. 10
0
    def return_plot(self,
                    interval=(0, 1),
                    adaptive_recursion=4,
                    plot_points=4,
                    adaptive_tolerance=0.10):
        r"""
        Return a plot of percolation probability using basic sage plot settings.

        INPUT:

        - ``interval``, default=(0,1)
        - ``adaptive_recursion``, default=0
        - ``plot_points``, default=10
        - ``adaptive_tolerance`` default=0.10

        EXAMPLES::

            sage: from slabbe import PercolationProbability
            sage: T = PercolationProbability(d=2, n=10, stop=100)
            sage: T.return_plot()           # optional long
            Graphics object consisting of 1 graphics primitive
        """
        P = plot(self,
                 interval,
                 adaptive_recursion=adaptive_recursion,
                 plot_points=plot_points,
                 adaptive_tolerance=adaptive_tolerance)
        P += text(repr(self), (0.8, 0.2))
        return P
Esempio n. 11
0
 def plot(self):
     from sage.functions.trig import sin, cos
     from sage.plot.circle import circle
     from sage.plot.point import point
     from sage.plot.text import text
     p = circle((0,0),1)
     for i in range(self._dimension):
         a = self._alpha[i]
         p += point([cos(2*pi*a),sin(2*pi*a)], color='blue', size=100)
         p += text(r"$\alpha_%i$"%(self._i_alpha[i]+1),
                   [1.2*cos(2*pi*a),1.2*sin(2*pi*a)],fontsize=40)
     for i in range(self._dimension):
         b = self._beta[i]
         p += point([cos(2*pi*b),sin(2*pi*b)], color='red', size=100)
         p += text(r"$\beta_%i$"%(self._i_beta[i]+1),
                   [1.2*cos(2*pi*b),1.2*sin(2*pi*b)],fontsize=40)
     p.show(axes=False, xmin=-1, xmax=1, ymin=-1, ymax=1)
Esempio n. 12
0
def eqn_list_to_curve_plot(L, rat_pts):
    xpoly_rng = PolynomialRing(QQ, 'x')
    poly_tup = [xpoly_rng(tup) for tup in L]
    f = poly_tup[0]
    h = poly_tup[1]
    g = f + h**2 / 4
    if len(g.real_roots()) == 0 and g(0) < 0:
        return text(r"$X(\mathbb{R})=\emptyset$", (1, 1), fontsize=50)
    X0 = [real(z[0]) for z in g.base_extend(CC).roots()
          ] + [real(z[0]) for z in g.derivative().base_extend(CC).roots()]
    a, b = inflate_interval(min(X0), max(X0), 1.5)
    groots = [a] + g.real_roots() + [b]
    if b - a < 1e-7:
        a = -3
        b = 3
        groots = [a, b]
    ngints = len(groots) - 1
    plotzones = []
    npts = 100
    for j in range(ngints):
        c = groots[j]
        d = groots[j + 1]
        if g((c + d) / 2) < 0:
            continue
        (c, d) = inflate_interval(c, d, 1.1)
        s = (d - c) / npts
        u = c
        yvals = []
        for i in range(npts + 1):
            v = g(u)
            if v > 0:
                v = sqrt(v)
                w = -h(u) / 2
                yvals.append(w + v)
                yvals.append(w - v)
            u += s
        (m, M) = inflate_interval(min(yvals), max(yvals), 1.2)
        plotzones.append((c, d, m, M))
    x = var('x')
    y = var('y')
    plot = sum(
        implicit_plot(y**2 + y * h(x) - f(x), (x, R[0], R[1]), (y, R[2], R[3]),
                      aspect_ratio='automatic',
                      plot_points=500,
                      zorder=1) for R in plotzones)
    xmin = min([R[0] for R in plotzones])
    xmax = max([R[1] for R in plotzones])
    ymin = min([R[2] for R in plotzones])
    ymax = max([R[3] for R in plotzones])
    for P in rat_pts:
        (x, y, z) = P
        z = ZZ(z)
        if z:  # Do not attempt to plot points at infinity
            x = ZZ(x) / z
            y = ZZ(y) / z**3
            if x >= xmin and x <= xmax and y >= ymin and y <= ymax:
                plot += point((x, y), color='red', size=40, zorder=2)
    return plot
Esempio n. 13
0
 def plot_profile(self):
     from sage.plot.line import line2d
     from sage.plot.point import point
     from sage.plot.text import text
     p_color, p_number, p_ev = self.profile()
     d = len(p_color)
     color = lambda i: 'blue' if p_color[i] else 'red'
     p = lambda i: [0,0] if i == -1 else [i+1,p_number[i]]
     plt = point([0,0],marker='x',size=100)
     for i in range(d):
         plt += line2d([p(i-1),p(i)],alpha=.5)
         plt += point(p(i), color=color(i), size=100)
         if p_color[i]:
             [x,y] = p(i)
             plt += text(r"$\alpha_%i$"%(self._i_alpha[p_ev[i]]+1), [x,y+.2], fontsize = 40)
         else:
             [x,y] = p(i)
             plt += text(r"$\beta_%i$"%(self._i_beta[p_ev[i]]+1), [x,y+.2], fontsize = 40)
     plt.show(axes=False, ymin=0, xmin=0, xmax=d)
Esempio n. 14
0
    def plot3d_cube(self,mv,title=True):
        """
        Displays F,U,R faces of the cube after the given move mv, where mv
        is a string in the Singmaster notation. Mostly included for the
        purpose of drawing pictures and checking moves.

        The first one below is "superflip+4 spot" (in 26q\* moves) and the
        second one is the superflip (in 20f\* moves). Type show(P) to view
        them.

        EXAMPLES::

            sage: rubik = CubeGroup()
            sage: P = rubik.plot3d_cube("U^2*F*U^2*L*R^(-1)*F^2*U*F^3*B^3*R*L*U^2*R*D^3*U*L^3*R*D*R^3*L^3*D^2")
            sage: P = rubik.plot3d_cube("R*L*D^2*B^3*L^2*F^2*R^2*U^3*D*R^3*D^2*F^3*B^3*D^3*F^2*D^3*R^2*U^3*F^2*D^3")
        """
        g = self.parse(mv)
        state = self.facets(g)
        clr_any = white
        shown_labels = range(1,9)+range(17,33)
        clr = [color_of_square(state[c-1]) for c in shown_labels]
        cubiesR = [plot3d_cubie(cubie_centers(c),cubie_colors(c,state)) for c in [32,31,30,29,28,27,26,25]]
        cubeR = sum(cubiesR)
        cubiesU = [plot3d_cubie(cubie_centers(c),cubie_colors(c,state)) for c in range(1,9)]
        cubeU = sum(cubiesU)
        cubiesF = [plot3d_cubie(cubie_centers(c),cubie_colors(c,state)) for c in [22,23,24,20,21]]
        cubeF = sum(cubiesF)
        centerR =  polygon_plot3d([[1,3,1],[2,3,1],[2,3,2],[1,3,2],[1,3,1]],rgbcolor=green)
        centerF =  polygon_plot3d([[3,1,1],[3,2,1],[3,2,2],[3,1,2],[3,1,1]],rgbcolor=red)
        centerU =  polygon_plot3d([[1,1,3],[1,2,3],[2,2,3],[2,1,3],[1,1,3]],rgbcolor=lpurple)
        centers = centerF+centerR+centerU
        P = cubeR+cubeF+cubeU+centers
        P.axes(show=False)
        if title == True:
            t1 = text('Up, Front, and Right faces. '   , (-0.2,-2.5))
            t2  = text('      sagemath.org', (0.8,-3.1),rgbcolor=lgrey)
            t3 = text("     ",(3.5,0),rgbcolor=white)
            P = P+t1+t2+t3
            P.axes(show=False)
            return P
        return P
Esempio n. 15
0
def eqn_list_to_curve_plot(L,rat_pts):
    xpoly_rng = PolynomialRing(QQ,'x')
    poly_tup = [xpoly_rng(tup) for tup in L]
    f = poly_tup[0]
    h = poly_tup[1]
    g = f+h**2/4
    if len(g.real_roots())==0 and g(0)<0:
        return text("$X(\mathbb{R})=\emptyset$",(1,1),fontsize=50)
    X0 = [real(z[0]) for z in g.base_extend(CC).roots()]+[real(z[0]) for z in g.derivative().base_extend(CC).roots()]
    a,b = inflate_interval(min(X0),max(X0),1.5)
    groots = [a]+g.real_roots()+[b]
    if b-a<1e-7:
        a=-3
        b=3
        groots=[a,b]
    ngints = len(groots)-1
    plotzones = []
    npts = 100
    for j in range(ngints):
        c = groots[j]
        d = groots[j+1]
        if g((c+d)/2)<0:
            continue
        (c,d) = inflate_interval(c,d,1.1)
        s = (d-c)/npts
        u = c
        yvals = []
        for i in range(npts+1):
            v = g(u)
            if v>0:
                v = sqrt(v)
                w = -h(u)/2
                yvals.append(w+v)
                yvals.append(w-v)
            u += s
        (m,M) = inflate_interval(min(yvals),max(yvals),1.2)
        plotzones.append((c,d,m,M))
    x = var('x')
    y = var('y')
    plot=sum(implicit_plot(y**2 + y*h(x) - f(x), (x,R[0],R[1]),(y,R[2],R[3]), aspect_ratio='automatic', plot_points=500, zorder=1) for R in plotzones)
    xmin=min([R[0] for R in plotzones])
    xmax=max([R[1] for R in plotzones])
    ymin=min([R[2] for R in plotzones])
    ymax=max([R[3] for R in plotzones])
    for P in rat_pts:
    	(x,y,z)=eval(P.replace(':',','))
        z=ZZ(z)
     	if z: # Do not attempt to plot points at infinity
      		x=ZZ(x)/z
      		y=ZZ(y)/z**3
      		if x >= xmin and x <= xmax and y >= ymin and y <= ymax:
       			plot += point((x,y),color='red',size=40,zorder=2)
    return plot
Esempio n. 16
0
    def text(self, label, position):
        r"""
        Return text widget with label ``label`` at position ``position``

        INPUT:

        - ``label`` -- a string, or a Sage object upon which latex will
          be called

        - ``position`` -- a position

        EXAMPLES::

            sage: L = RootSystem(["A",2]).root_lattice()
            sage: options = L.plot_parse_options()
            sage: list(options.text("coucou", [0,1]))
            [Text 'coucou' at the point (0.0,1.0)]
            sage: list(options.text(L.simple_root(1), [0,1]))
            [Text '$\alpha_{1}$' at the point (0.0,1.0)]

            sage: options = RootSystem(["A",2]).root_lattice().plot_parse_options(labels=False)
            sage: options.text("coucou", [0,1])
            0

            sage: options = RootSystem(["B",3]).root_lattice().plot_parse_options()
            sage: print options.text("coucou", [0,1,2]).x3d_str()
            <Transform translation='0 1 2'>
            <Shape><Text string='coucou' solid='true'/><Appearance><Material diffuseColor='0.0 0.0 0.0' shininess='1' specularColor='0.0 0.0 0.0'/></Appearance></Shape>
            <BLANKLINE>
            </Transform>
        """
        if self.labels:
            if self.dimension <= 2:
                if not isinstance(label, basestring):
                    label = "$" + str(latex(label)) + "$"
                from sage.plot.text import text

                return text(label, position, fontsize=15)
            elif self.dimension == 3:
                # LaTeX labels not yet supported in 3D
                if isinstance(label, basestring):
                    label = label.replace("{", "").replace("}", "").replace("$", "").replace("_", "")
                else:
                    label = str(label)
                from sage.plot.plot3d.shapes2 import text3d

                return text3d(label, position)
            else:
                raise NotImplementedError("Plots in dimension > 3")
        else:
            return self.empty()
Esempio n. 17
0
File: plot.py Progetto: biasse/sage
    def text(self, label, position):
        r"""
        Return text widget with label ``label`` at position ``position``

        INPUT:

        - ``label`` -- a string, or a Sage object upon which latex will
          be called

        - ``position`` -- a position

        EXAMPLES::

            sage: L = RootSystem(["A",2]).root_lattice()
            sage: options = L.plot_parse_options()
            sage: list(options.text("coucou", [0,1]))
            [Text 'coucou' at the point (0.0,1.0)]
            sage: list(options.text(L.simple_root(1), [0,1]))
            [Text '$\alpha_{1}$' at the point (0.0,1.0)]

            sage: options = RootSystem(["A",2]).root_lattice().plot_parse_options(labels=False)
            sage: options.text("coucou", [0,1])
            0

            sage: options = RootSystem(["B",3]).root_lattice().plot_parse_options()
            sage: print options.text("coucou", [0,1,2]).x3d_str()
            <Transform translation='0 1 2'>
            <Shape><Text string='coucou' solid='true'/><Appearance><Material diffuseColor='0.0 0.0 0.0' shininess='1' specularColor='0.0 0.0 0.0'/></Appearance></Shape>
            <BLANKLINE>
            </Transform>
        """
        if self.labels:
            if self.dimension <= 2:
                if not isinstance(label, basestring):
                    label = "$" + str(latex(label)) + "$"
                from sage.plot.text import text
                return text(label, position, fontsize=15)
            elif self.dimension == 3:
                # LaTeX labels not yet supported in 3D
                if isinstance(label, basestring):
                    label = label.replace("{", "").replace("}", "").replace(
                        "$", "").replace("_", "")
                else:
                    label = str(label)
                from sage.plot.plot3d.shapes2 import text3d
                return text3d(label, position)
            else:
                raise NotImplementedError("Plots in dimension > 3")
        else:
            return self.empty()
Esempio n. 18
0
def circle_image(A,B):
    G = Graphics()
    G += circle((0,0), 1 , color = 'grey')
    from collections import defaultdict
    tmp = defaultdict(int)
    for a in A:
        for j in range(a):
            if gcd(j,a) == 1:
                rational = Rational(j)/Rational(a)
                tmp[(rational.numerator(),rational.denominator())] += 1
    
    for b in B:
        for j in range(b):
            if gcd(j,b) == 1:
                rational = Rational(j)/Rational(b)
                tmp[(rational.numerator(),rational.denominator())] -= 1
    C = ComplexField()
    for val in tmp:
        if tmp[val] > 0:
            G += text(str(tmp[val]),exp(C(2*3.14159*I*val[0]/val[1])), fontsize = 30, axes = False, color = "green")
        if tmp[val] < 0:
            G += text(str(abs(tmp[val])),exp(C(2*3.14159*I*val[0]/val[1])), fontsize = 30, axes = False, color = "red")
    return G
Esempio n. 19
0
 def plot(self):
     from sage.functions.trig import sin, cos
     from sage.plot.circle import circle
     from sage.plot.point import point
     from sage.plot.text import text
     p = circle((0, 0), 1)
     for i in range(self._dimension):
         a = self._alpha[i]
         p += point([cos(2 * pi * a), sin(2 * pi * a)],
                    color='blue',
                    size=100)
         p += text(r"$\alpha_%i$" % (self._i_alpha[i] + 1),
                   [1.2 * cos(2 * pi * a), 1.2 * sin(2 * pi * a)],
                   fontsize=40)
     for i in range(self._dimension):
         b = self._beta[i]
         p += point([cos(2 * pi * b), sin(2 * pi * b)],
                    color='red',
                    size=100)
         p += text(r"$\beta_%i$" % (self._i_beta[i] + 1),
                   [1.2 * cos(2 * pi * b), 1.2 * sin(2 * pi * b)],
                   fontsize=40)
     p.show(axes=False, xmin=-1, xmax=1, ymin=-1, ymax=1)
Esempio n. 20
0
 def plot_profile(self):
     from sage.plot.line import line2d
     from sage.plot.point import point
     from sage.plot.text import text
     p_color, p_number, p_ev = self.profile()
     d = len(p_color)
     color = lambda i: 'blue' if p_color[i] else 'red'
     p = lambda i: [0, 0] if i == -1 else [i + 1, p_number[i]]
     plt = point([0, 0], marker='x', size=100)
     for i in range(d):
         plt += line2d([p(i - 1), p(i)], alpha=.5)
         plt += point(p(i), color=color(i), size=100)
         if p_color[i]:
             [x, y] = p(i)
             plt += text(r"$\alpha_%i$" % (self._i_alpha[p_ev[i]] + 1),
                         [x, y + .2],
                         fontsize=40)
         else:
             [x, y] = p(i)
             plt += text(r"$\beta_%i$" % (self._i_beta[p_ev[i]] + 1),
                         [x, y + .2],
                         fontsize=40)
     plt.show(axes=False, ymin=0, xmin=0, xmax=d)
Esempio n. 21
0
def circle_image(A, B):
    G = Graphics()
    G += circle((0, 0), 1, color='black', thickness=3)
    G += circle(
        (0, 0), 1.4, color='black', alpha=0
    )  # This adds an invisible framing circle to the plot, which protects the aspect ratio from being skewed.
    from collections import defaultdict
    tmp = defaultdict(int)
    for a in A:
        for j in range(a):
            if gcd(j, a) == 1:
                rational = Rational(j) / Rational(a)
                tmp[(rational.numerator(), rational.denominator())] += 1

    for b in B:
        for j in range(b):
            if gcd(j, b) == 1:
                rational = Rational(j) / Rational(b)
                tmp[(rational.numerator(), rational.denominator())] -= 1
    C = ComplexField()
    color1 = (41 / 255, 95 / 255, 45 / 255)
    color2 = (0 / 255, 0 / 255, 150 / 255)
    for val in tmp:
        if tmp[val] > 0:
            G += text(str(tmp[val]),
                      exp(C(-.2 + 2 * 3.14159 * I * val[0] / val[1])),
                      fontsize=30,
                      axes=False,
                      color=color1)
        if tmp[val] < 0:
            G += text(str(abs(tmp[val])),
                      exp(C(.2 + 2 * 3.14159 * I * val[0] / val[1])),
                      fontsize=30,
                      axes=False,
                      color=color2)
    return G
Esempio n. 22
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
Esempio n. 23
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
Esempio n. 24
0
    def triangulation(self):
        r"""
        Plot a regular polygon with some diagonals.

        If ``self`` is positive and integral then this will be a triangulation.

        .. PLOT::
            :width: 600 px

            G = path_tableaux.FriezePattern([1,2,7,5,3,7,4,1]).triangulation()
            p = graphics_array(G, 7, 6)
            sphinx_plot(p)

        EXAMPLES::

            sage: path_tableaux.FriezePattern([1,2,7,5,3,7,4,1]).triangulation()
            Graphics object consisting of 25 graphics primitives

            sage: path_tableaux.FriezePattern([1,2,1/7,5,3]).triangulation()
            Graphics object consisting of 12 graphics primitives

            sage: K.<sqrt2> = NumberField(x^2-2)
            sage: path_tableaux.FriezePattern([1,sqrt2,1,sqrt2,3,2*sqrt2,5,3*sqrt2,1], field=K).triangulation()
            Graphics object consisting of 24 graphics primitives
        """
        n = len(self) - 1
        cd = CylindricalDiagram(self).diagram
        from sage.plot.plot import Graphics
        from sage.plot.line import line
        from sage.plot.text import text
        from sage.functions.trig import sin, cos
        from sage.all import pi
        G = Graphics()
        G.set_aspect_ratio(1.0)

        vt = [(cos(2 * theta * pi / (n)), sin(2 * theta * pi / (n)))
              for theta in range(n + 1)]
        for i, p in enumerate(vt):
            G += text(str(i), [1.05 * p[0], 1.05 * p[1]])

        for i, r in enumerate(cd):
            for j, a in enumerate(r[:n]):
                if a == 1:
                    G += line([vt[i], vt[j]])

        G.axes(False)
        return G
Esempio n. 25
0
def eqn_list_to_curve_plot(L):
    xpoly_rng = PolynomialRing(QQ, 'x')
    poly_tup = [xpoly_rng(tup) for tup in L]
    f = poly_tup[0]
    h = poly_tup[1]
    g = f + h**2 / 4
    if len(g.real_roots()) == 0 and g(0) < 0:
        return text("$X(\mathbb{R})=\emptyset$", (1, 1), fontsize=50)
    X0 = [real(z[0]) for z in g.base_extend(CC).roots()
          ] + [real(z[0]) for z in g.derivative().base_extend(CC).roots()]
    a, b = inflate_interval(min(X0), max(X0), 1.5)
    groots = [a] + g.real_roots() + [b]
    if b - a < 1e-7:
        a = -3
        b = 3
        groots = [a, b]
    ngints = len(groots) - 1
    plotzones = []
    npts = 100
    for j in range(ngints):
        c = groots[j]
        d = groots[j + 1]
        if g((c + d) / 2) < 0:
            continue
        (c, d) = inflate_interval(c, d, 1.1)
        s = (d - c) / npts
        u = c
        yvals = []
        for i in range(npts + 1):
            v = g(u)
            if v > 0:
                v = sqrt(v)
                w = -h(u) / 2
                yvals.append(w + v)
                yvals.append(w - v)
            u += s
        (m, M) = inflate_interval(min(yvals), max(yvals), 1.2)
        plotzones.append((c, d, m, M))
    x = var('x')
    y = var('y')
    return sum(
        implicit_plot(y**2 + y * h(x) - f(x), (x, R[0], R[1]), (y, R[2], R[3]),
                      aspect_ratio='automatic',
                      plot_points=500) for R in plotzones)
Esempio n. 26
0
def eqn_list_to_curve_plot(L):
    xpoly_rng = PolynomialRing(QQ,'x')
    poly_tup = [xpoly_rng(tup) for tup in L]
    f = poly_tup[0]
    h = poly_tup[1]
    g = f+h**2/4
    if len(g.real_roots())==0 and g(0)<0:
        return text("$X(\mathbb{R})=\emptyset$",(1,1),fontsize=50)
    X0 = [real(z[0]) for z in g.base_extend(CC).roots()]+[real(z[0]) for z in g.derivative().base_extend(CC).roots()]
    a,b = inflate_interval(min(X0),max(X0),1.5)
    groots = [a]+g.real_roots()+[b]
    if b-a<1e-7:
        a=-3
        b=3
        groots=[a,b]
    ngints = len(groots)-1
    plotzones = []
    npts = 100
    for j in range(ngints):
        c = groots[j]
        d = groots[j+1]
        if g((c+d)/2)<0:
            continue
        (c,d) = inflate_interval(c,d,1.1)
        s = (d-c)/npts
        u = c
        yvals = []
        for i in range(npts+1):
            v = g(u)
            if v>0:
                v = sqrt(v)
                w = -h(u)/2
                yvals.append(w+v)
                yvals.append(w-v)
            u += s
        (m,M) = inflate_interval(min(yvals),max(yvals),1.2)
        plotzones.append((c,d,m,M))
    x = var('x')
    y = var('y')
    return sum(implicit_plot(y**2 + y*h(x) - f(x), (x,R[0],R[1]),
        (y,R[2],R[3]), aspect_ratio='automatic', plot_points=500) for R in
        plotzones)
Esempio n. 27
0
    def plot_n_cylinders(self, n, labels=True):
        r"""
        EXAMPLES::

            sage: from slabbe.matrix_cocycle import cocycles
            sage: C = cocycles.Sorted_ARP()
            sage: G = C.plot_n_cylinders(3)
        """
        from sage.plot.graphics import Graphics
        from sage.plot.polygon import polygon
        from sage.plot.text import text
        from matrices import M3to2
        G = Graphics()
        for w,cyl in self.n_cylinders_iterator(n):
            columns = cyl.columns()
            G += polygon((M3to2*col/col.norm(1) for col in columns), fill=False) 
            if labels:
                sum_cols = sum(columns)
                G += text("{}".format(w), M3to2*sum_cols/sum_cols.norm(1))
        return G
Esempio n. 28
0
    def plot_n_cylinders(self, n, labels=True):
        r"""
        EXAMPLES::

            sage: from slabbe.matrix_cocycle import cocycles
            sage: C = cocycles.Sorted_ARP()
            sage: G = C.plot_n_cylinders(3)
        """
        from sage.plot.graphics import Graphics
        from sage.plot.polygon import polygon
        from sage.plot.text import text
        from .matrices import M3to2
        G = Graphics()
        for w,cyl in self.n_cylinders_iterator(n):
            columns = cyl.columns()
            G += polygon((M3to2*col/col.norm(1) for col in columns), fill=False) 
            if labels:
                sum_cols = sum(columns)
                G += text("{}".format(w), M3to2*sum_cols/sum_cols.norm(1))
        return G
Esempio n. 29
0
    def plot(self):
        r"""
        EXAMPLES::

            sage: from slabbe import PolyhedronPartition
            sage: h = 1/2
            sage: p = Polyhedron([(0,h),(0,1),(h,1)])
            sage: q = Polyhedron([(0,0), (0,h), (h,1), (1,1), (1,h), (h,0)])
            sage: r = Polyhedron([(h,0), (1,0), (1,h)])
            sage: P = PolyhedronPartition([p,q,r])
            sage: P.plot()
            Graphics object consisting of 21 graphics primitives
        """
        from sage.plot.graphics import Graphics
        from sage.plot.text import text
        G = Graphics()
        for key,P in self:
            G += P.plot(fill='white')
            G += text(key, P.center())
        return G
Esempio n. 30
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
Esempio n. 31
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
Esempio n. 32
0
    def plot_n_cylinders(self, n, labels=True):
        r"""
        EXAMPLES::

            sage: from slabbe.markov_transformation import markov_transformations
            sage: T = markov_transformations.Selmer()
            sage: G = T.plot_n_cylinders(3)

        TESTS::

            sage: G = T.plot_n_cylinders(0)
        """
        from sage.plot.graphics import Graphics
        from sage.plot.polygon import polygon
        from sage.plot.text import text
        M3to2 = projection_matrix(3, 2)
        G = Graphics()
        for w,cyl in self.n_cylinders_iterator(n):
            columns = cyl.columns()
            G += polygon((M3to2*col/col.norm(1) for col in columns), fill=False) 
            if labels:
                sum_cols = sum(columns)
                G += text("{}".format(w), M3to2*sum_cols/sum_cols.norm(1))
        return G
Esempio n. 33
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)
Esempio n. 34
0
    def plot_edge_label(self, i, label, **options):
        r"""
        Write label on the i-th edge.

        A parameter ``t`` in the interval [0,1] can be provided to position the
        label along the edge. A value of t=0 will position it at the starting
        vertex and t=1 will position it at the terminating vertex. Defaults to
        0.3.

        If the parameter ``position`` can take the values "outside", "inside"
        or "edge" to indicate if the label should be drawn outside the polygon,
        inside the polygon or on the edge. Defaults to "inside".

        A ``push_off`` perturbation parameter controls how far off the edge the label is pushed.

        Other options are processed as in sage.plot.text.text.
        """
        e = self._v[(i + 1) % self.base_polygon().num_edges()] - self._v[i]

        if "position" in options:
            if options["position"] not in ["inside", "outside", "edge"]:
                raise ValueError(
                    "The 'position' parameter must take the value 'inside', 'outside', or 'edge'."
                )
            pos = options.pop("position")
        else:
            pos = "inside"

        if pos == "outside":
            # position outside polygon.
            if "horizontal_alignment" in options:
                pass
            elif e[1] > 0:
                options["horizontal_alignment"] = "left"
            elif e[1] < 0:
                options["horizontal_alignment"] = "right"
            else:
                options["horizontal_alignment"] = "center"

            if "vertical_alignment" in options:
                pass
            elif e[0] > 0:
                options["vertical_alignment"] = "top"
            elif e[0] < 0:
                options["vertical_alignment"] = "bottom"
            else:
                options["vertical_alignment"] = "center"

        elif pos == "inside":
            # position inside polygon.
            if "horizontal_alignment" in options:
                pass
            elif e[1] < 0:
                options["horizontal_alignment"] = "left"
            elif e[1] > 0:
                options["horizontal_alignment"] = "right"
            else:
                options["horizontal_alignment"] = "center"

            if "vertical_alignment" in options:
                pass
            elif e[0] < 0:
                options["vertical_alignment"] = "top"
            elif e[0] > 0:
                options["vertical_alignment"] = "bottom"
            else:
                options["vertical_alignment"] = "center"

        else:
            # centered on edge.
            if "horizontal_alignment" in options:
                pass
            else:
                options["horizontal_alignment"] = "center"
            if "vertical_alignment" in options:
                pass
            else:
                options["vertical_alignment"] = "center"

        if "t" in options:
            t = RDF(options.pop("t"))
        else:
            t = 0.3

        if "push_off" in options:
            push_off = RDF(options.pop("push_off"))
        else:
            push_off = 0.03
        if pos == "outside":
            push_off = -push_off
        # Now push_off stores the amount it should be pushed into the polygon

        no = V((-e[1], e[0]))
        return text(label, self._v[i] + t * e + push_off * no, **options)
Esempio n. 35
0
    def plot_edge_label(self, i, label, **options):
        r"""
        Write label on the i-th edge.

        A parameter ``t`` in the interval [0,1] can be provided to position the
        label along the edge. A value of t=0 will position it at the starting
        vertex and t=1 will position it at the terminating vertex. Defaults to
        0.3.

        If the parameter ``position`` can take the values "outside", "inside"
        or "edge" to indicate if the label should be drawn outside the polygon,
        inside the polygon or on the edge. Defaults to "inside".

        A ``push_off`` perturbation parameter controls how far off the edge the label is pushed.

        Other options are processed as in sage.plot.text.text.
        """
        e = self._v[(i+1)%self.base_polygon().num_edges()] - self._v[i]

        if "position" in options:
            if options["position"] not in ["inside", "outside", "edge"]:
                raise ValueError("The 'position' parameter must take the value 'inside', 'outside', or 'edge'.")
            pos = options.pop("position")
        else:
            pos = "inside"

        if pos == "outside":
            # position outside polygon.
            if "horizontal_alignment" in options:
                pass
            elif e[1] > 0:
                options["horizontal_alignment"]="left"
            elif e[1] < 0:
                options["horizontal_alignment"]="right"
            else:
                options["horizontal_alignment"]="center"

            if "vertical_alignment" in options:
                pass
            elif e[0] > 0:
                options["vertical_alignment"]="top"
            elif e[0] < 0:
                options["vertical_alignment"]="bottom"
            else:
                options["vertical_alignment"]="center"

        elif pos == "inside":
            # position inside polygon.
            if "horizontal_alignment" in options:
                pass
            elif e[1] < 0:
                options["horizontal_alignment"]="left"
            elif e[1] > 0:
                options["horizontal_alignment"]="right"
            else:
                options["horizontal_alignment"]="center"

            if "vertical_alignment" in options:
                pass
            elif e[0] < 0:
                options["vertical_alignment"]="top"
            elif e[0] > 0:
                options["vertical_alignment"]="bottom"
            else:
                options["vertical_alignment"]="center"

        else:
            # centered on edge.
            if "horizontal_alignment" in options:
                pass
            else:
                options["horizontal_alignment"]="center"
            if "vertical_alignment" in options:
                pass
            else:
                options["vertical_alignment"]="center"

        if "t" in options:
            t = RDF(options.pop("t"))
        else:
            t = 0.3

        if "push_off" in options:
            push_off = RDF(options.pop("push_off"))
        else:
            push_off = 0.03
        if pos == "outside":
            push_off = -push_off
        # Now push_off stores the amount it should be pushed into the polygon

        no = V((-e[1], e[0]))
        return text(label, self._v[i] + t * e + push_off * no, **options)
Esempio n. 36
0
    def plot(self,
             chart=None,
             ambient_coords=None,
             mapping=None,
             size=10,
             color='black',
             label=None,
             label_color=None,
             fontsize=10,
             label_offset=0.1,
             parameters=None):
        r"""
        Plot the current point (``self``) in a Cartesian graph based on the
        coordinates of some ambient chart.

        The point is drawn in terms of two (2D graphics) or three (3D graphics)
        coordinates of a given chart, called hereafter the *ambient chart*.
        The domain of the ambient chart must contain the point, or its image
        by a differentiable mapping `\Phi`.

        INPUT:

        - ``chart`` -- (default: ``None``) the ambient chart (see above); if
          ``None``, the ambient chart is set the default chart of
          ``self.containing_set()``
        - ``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 the point `p` represented by ``self``
          and the ambient chart ``chart``: the domain of ``chart`` must
          contain `\Phi(p)`; if ``None``, the identity mapping is assumed
        - ``size`` -- (default: 10) size of the point once drawn as a small
          disk or sphere
        - ``color`` -- (default: 'black') color of the point
        - ``label`` -- (default: ``None``) label printed next to the point;
          if ``None``, the point's name is used.
        - ``label_color`` -- (default: ``None``) color to print the label;
          if ``None``, the value of ``color`` is used
        - ``fontsize`` -- (default: 10) size of the font used to print the
          label
        - ``label_offset`` -- (default: 0.1) determines the separation between
          the point and its label
        - ``parameters`` -- (default: ``None``) dictionary giving the numerical
          values of the parameters that may appear in the point coordinates

        OUTPUT:

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

        EXAMPLES:

        Drawing a point on a 2-dimensional manifold::

            sage: M = Manifold(2, 'M')
            sage: X.<x,y> = M.chart()
            sage: p = M.point((1,3), name='p')
            sage: g = p.plot(X)
            sage: print g
            Graphics object consisting of 2 graphics primitives
            sage: gX = X.plot() # plot of the coordinate grid
            sage: show(g+gX) # display of the point atop the coordinate grid

        Actually, since ``X`` is the default chart of the open set in which
        ``p`` has been defined, it can be skipped in the arguments of
        ``plot``::

            sage: g = p.plot()
            sage: show(g+gX)

        Call with some options::

            sage: g = p.plot(chart=X, size=40, color='green', label='$P$',
            ....:            label_color='blue', fontsize=20, label_offset=0.3)
            sage: show(g+gX)

        Use of the ``parameters`` option to set a numerical value of some
        symbolic variable::

            sage: a = var('a')
            sage: q = M.point((a,2*a), name='q')
            sage: gq = q.plot(parameters={a:-2})
            sage: show(g+gX+gq)

        The numerical value is used only for the plot::

            sage: q.coord()
            (a, 2*a)

        Drawing a point on a 3-dimensional manifold::

            sage: M = Manifold(3, 'M')
            sage: X.<x,y,z> = M.chart()
            sage: p = M.point((2,1,3), name='p')
            sage: g = p.plot()
            sage: print g
            Graphics3d Object
            sage: gX = X.plot(nb_values=5) # coordinate mesh cube
            sage: show(g+gX) # display of the point atop the coordinate mesh

        Call with some options::

            sage: g = p.plot(chart=X, size=40, color='green', label='P_1',
            ....:            label_color='blue', fontsize=20, label_offset=0.3)
            sage: show(g+gX)

        An example of plot via a differential mapping: plot of a point on a
        2-sphere viewed in the 3-dimensional space ``M``::

            sage: S2 = Manifold(2, 'S^2')
            sage: U = S2.open_subset('U') # the open set covered by spherical coord.
            sage: XS.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
            sage: p = U.point((pi/4, pi/8), name='p')
            sage: F = S2.diff_mapping(M, {(XS, X): [sin(th)*cos(ph),
            ....:                         sin(th)*sin(ph), cos(th)]}, name='F')
            sage: F.display()
            F: S^2 --> M
            on U: (th, ph) |--> (x, y, z) = (cos(ph)*sin(th), sin(ph)*sin(th), cos(th))
            sage: g = p.plot(chart=X, mapping=F)
            sage: gS2 = XS.plot(chart=X, mapping=F, nb_values=9)
            sage: show(g+gS2)

        Use of the option ``ambient_coords`` for plots on a 4-dimensional
        manifold::

            sage: M = Manifold(4, 'M')
            sage: X.<t,x,y,z> = M.chart()
            sage: p = M.point((1,2,3,4), name='p')
            sage: g = p.plot(X, ambient_coords=(t,x,y))  # the coordinate z is skipped
            sage: gX = X.plot(X, ambient_coords=(t,x,y), nb_values=5)
            sage: show(g+gX) # 3D plot
            sage: g = p.plot(X, ambient_coords=(t,y,z))  # the coordinate x is skipped
            sage: gX = X.plot(X, ambient_coords=(t,y,z), nb_values=5)
            sage: show(g+gX) # 3D plot
            sage: g = p.plot(X, ambient_coords=(y,z))  # the coordinates t and x are skipped
            sage: gX = X.plot(X, ambient_coords=(y,z))
            sage: show(g+gX) # 2D plot

        """
        from sage.plot.point import point2d
        from sage.plot.text import text
        from sage.plot.graphics import Graphics
        from sage.plot.plot3d.shapes2 import point3d, text3d
        from sage.geometry.manifolds.chart import Chart
        # The ambient chart:
        if chart is None:
            chart = self.containing_set().default_chart()
        elif not isinstance(chart, Chart):
            raise TypeError("the argument 'chart' must be a coordinate chart")
        # The effective point to be plotted:
        if mapping is None:
            eff_point = self
        else:
            eff_point = mapping(self)
        # The coordinates of the ambient chart used for the plot:
        if ambient_coords is None:
            ambient_coords = chart._xx
        elif not isinstance(ambient_coords, tuple):
            ambient_coords = tuple(ambient_coords)
        nca = len(ambient_coords)
        if nca != 2 and nca != 3:
            raise TypeError("Bad number of ambient coordinates: " + str(nca))
        # The point coordinates:
        coords = eff_point.coord(chart)
        xx = chart[:]
        xp = [coords[xx.index(c)] for c in ambient_coords]
        if parameters is not None:
            xps = [coord.substitute(parameters) for coord in xp]
            xp = xps
        xlab = [coord + label_offset for coord in xp]
        if label_color is None:
            label_color = color
        resu = Graphics()
        if nca == 2:
            if label is None:
                label = r'$' + self._latex_name + r'$'
            resu += point2d(xp, color=color, size=size) + \
                    text(label, xlab, fontsize=fontsize, color=label_color)
        else:
            if label is None:
                label = self._name
            resu += point3d(xp, color=color, size=size) + \
                    text3d(label, xlab, fontsize=fontsize, color=label_color)
        return resu
Esempio n. 37
0
    def plot(self,
             chart=None,
             ambient_coords=None,
             mapping=None,
             label=None,
             parameters=None,
             **kwds):
        r"""
        For real manifolds, plot ``self`` in a Cartesian graph based
        on the coordinates of some ambient chart.

        The point is drawn in terms of two (2D graphics) or three (3D graphics)
        coordinates of a given chart, called hereafter the *ambient chart*.
        The domain of the ambient chart must contain the point, or its image
        by a continuous manifold map `\Phi`.

        INPUT:

        - ``chart`` -- (default: ``None``) the ambient chart (see above); if
          ``None``, the ambient chart is set the default chart of
          ``self.parent()``
        - ``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``)
          :class:`~sage.manifolds.continuous_map.ContinuousMap`; continuous
          manifold map `\Phi` providing the link between the current point
          `p` and the ambient chart ``chart``: the domain of ``chart`` must
          contain `\Phi(p)`; if ``None``, the identity map is assumed
        - ``label`` -- (default: ``None``) label printed next to the point;
          if ``None``, the point's name is used
        - ``parameters`` -- (default: ``None``) dictionary giving the numerical
          values of the parameters that may appear in the point coordinates
        - ``size`` -- (default: 10) size of the point once drawn as a small
          disk or sphere
        - ``color`` -- (default: ``'black'``) color of the point
        - ``label_color`` -- (default: ``None``) color to print the label;
          if ``None``, the value of ``color`` is used
        - ``fontsize`` -- (default: 10) size of the font used to print the
          label
        - ``label_offset`` -- (default: 0.1) determines the separation between
          the point and its label

        OUTPUT:

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

        EXAMPLES:

        Drawing a point on a 2-dimensional manifold::

            sage: M = Manifold(2, 'M', structure='topological')
            sage: X.<x,y> = M.chart()
            sage: p = M.point((1,3), name='p')
            sage: g = p.plot(X)
            sage: print(g)
            Graphics object consisting of 2 graphics primitives
            sage: gX = X.plot(max_range=4) # plot of the coordinate grid
            sage: g + gX # display of the point atop the coordinate grid
            Graphics object consisting of 20 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M', structure='topological')
            X = M.chart('x y'); x,y = X[:]
            p = M.point((1,3), name='p')
            g = p.plot(X)
            gX = X.plot(max_range=4)
            sphinx_plot(g+gX)

        Actually, since ``X`` is the default chart of the open set in which
        ``p`` has been defined, it can be skipped in the arguments of
        ``plot``::

            sage: g = p.plot()
            sage: g + gX
            Graphics object consisting of 20 graphics primitives

        Call with some options::

            sage: g = p.plot(chart=X, size=40, color='green', label='$P$',
            ....:            label_color='blue', fontsize=20, label_offset=0.3)
            sage: g + gX
            Graphics object consisting of 20 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M', structure='topological')
            X = M.chart('x y'); x,y = X[:]
            p = M.point((1,3), name='p')
            g = p.plot(chart=X, size=40, color='green', label='$P$', \
                       label_color='blue', fontsize=20, label_offset=0.3)
            gX = X.plot(max_range=4)
            sphinx_plot(g+gX)

        Use of the ``parameters`` option to set a numerical value of some
        symbolic variable::

            sage: a = var('a')
            sage: q = M.point((a,2*a), name='q')
            sage: gq = q.plot(parameters={a:-2}, label_offset=0.2)
            sage: g + gX + gq
            Graphics object consisting of 22 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M', structure='topological')
            X = M.chart('x y'); x,y = X[:]
            p = M.point((1,3), name='p')
            g = p.plot(chart=X, size=40, color='green', label='$P$', \
                       label_color='blue', fontsize=20, label_offset=0.3)
            var('a')
            q = M.point((a,2*a), name='q')
            gq = q.plot(parameters={a:-2}, label_offset=0.2)
            gX = X.plot(max_range=4)
            sphinx_plot(g+gX+gq)

        The numerical value is used only for the plot::

            sage: q.coord()
            (a, 2*a)

        Drawing a point on a 3-dimensional manifold::

            sage: M = Manifold(3, 'M', structure='topological')
            sage: X.<x,y,z> = M.chart()
            sage: p = M.point((2,1,3), name='p')
            sage: g = p.plot()
            sage: print(g)
            Graphics3d Object
            sage: gX = X.plot(number_values=5) # coordinate mesh cube
            sage: g + gX # display of the point atop the coordinate mesh
            Graphics3d Object

        Call with some options::

            sage: g = p.plot(chart=X, size=40, color='green', label='P_1',
            ....:            label_color='blue', fontsize=20, label_offset=0.3)
            sage: g + gX
            Graphics3d Object

        An example of plot via a mapping: plot of a point on a 2-sphere viewed
        in the 3-dimensional space ``M``::

            sage: S2 = Manifold(2, 'S^2', structure='topological')
            sage: U = S2.open_subset('U') # the open set covered by spherical coord.
            sage: XS.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
            sage: p = U.point((pi/4, pi/8), name='p')
            sage: F = S2.continuous_map(M, {(XS, X): [sin(th)*cos(ph),
            ....:                           sin(th)*sin(ph), cos(th)]}, name='F')
            sage: F.display()
            F: S^2 --> M
            on U: (th, ph) |--> (x, y, z) = (cos(ph)*sin(th), sin(ph)*sin(th), cos(th))
            sage: g = p.plot(chart=X, mapping=F)
            sage: gS2 = XS.plot(chart=X, mapping=F, number_values=9)
            sage: g + gS2
            Graphics3d Object

        Use of the option ``ambient_coords`` for plots on a 4-dimensional
        manifold::

            sage: M = Manifold(4, 'M', structure='topological')
            sage: X.<t,x,y,z> = M.chart()
            sage: p = M.point((1,2,3,4), name='p')
            sage: g = p.plot(X, ambient_coords=(t,x,y), label_offset=0.4)  # the coordinate z is skipped
            sage: gX = X.plot(X, ambient_coords=(t,x,y), number_values=5)  # long time
            sage: g + gX # 3D plot  # long time
            Graphics3d Object
            sage: g = p.plot(X, ambient_coords=(t,y,z), label_offset=0.4)  # the coordinate x is skipped
            sage: gX = X.plot(X, ambient_coords=(t,y,z), number_values=5)  # long time
            sage: g + gX # 3D plot  # long time
            Graphics3d Object
            sage: g = p.plot(X, ambient_coords=(y,z), label_offset=0.4)  # the coordinates t and x are skipped
            sage: gX = X.plot(X, ambient_coords=(y,z))
            sage: g + gX # 2D plot
            Graphics object consisting of 20 graphics primitives

        .. PLOT::

            M = Manifold(4, 'M', structure='topological')
            X = M.chart('t x y z'); t,x,y,z = X[:]
            p = M.point((1,2,3,4), name='p')
            g = p.plot(X, ambient_coords=(y,z), label_offset=0.4)
            gX = X.plot(X, ambient_coords=(y,z))
            sphinx_plot(g+gX)

        """
        from sage.plot.point import point2d
        from sage.plot.text import text
        from sage.plot.graphics import Graphics
        from sage.plot.plot3d.shapes2 import point3d, text3d
        from sage.manifolds.chart import Chart
        if self._manifold.base_field_type() != 'real':
            raise NotImplementedError(
                'plot of points on manifolds over fields different'
                ' from the real field is not implemented')
        # The ambient chart:
        if chart is None:
            chart = self.parent().default_chart()
        elif not isinstance(chart, Chart):
            raise TypeError("the argument 'chart' must be a coordinate chart")
        # The effective point to be plotted:
        if mapping is None:
            eff_point = self
        else:
            eff_point = mapping(self)
        # The coordinates of the ambient chart used for the plot:
        if ambient_coords is None:
            ambient_coords = chart[:]
        elif not isinstance(ambient_coords, tuple):
            ambient_coords = tuple(ambient_coords)
        nca = len(ambient_coords)
        if nca != 2 and nca != 3:
            raise TypeError(
                "invalid number of ambient coordinates: {}".format(nca))

        # Extract the kwds options
        size = kwds['size']
        color = kwds['color']
        label_color = kwds['label_color']
        fontsize = kwds['fontsize']
        label_offset = kwds['label_offset']

        # The point coordinates:
        coords = eff_point.coord(chart)
        xx = chart[:]
        xp = [coords[xx.index(c)] for c in ambient_coords]
        if parameters is not None:
            xps = [coord.substitute(parameters) for coord in xp]
            xp = xps
        xlab = [coord + label_offset for coord in xp]
        if label_color is None:
            label_color = color
        resu = Graphics()
        if nca == 2:
            if label is None:
                label = r'$' + self._latex_name + r'$'
            resu += (point2d(xp, color=color, size=size) +
                     text(label, xlab, fontsize=fontsize, color=label_color))
        else:
            if label is None:
                label = self._name
            resu += (point3d(xp, color=color, size=size) +
                     text3d(label, xlab, fontsize=fontsize, color=label_color))
        return resu
Esempio n. 38
0
File: iet.py Progetto: sagemath/sage
    def plot_two_intervals(self,
                           position=(0,0),
                           vertical_alignment='center',
                           horizontal_alignment='left',
                           interval_height=0.1,
                           labels_height=0.05,
                           fontsize=14,
                           labels=True,
                           colors=None):
        r"""
        Returns a picture of the interval exchange transformation.

        INPUT:

        - ``position`` - a 2-uple of the position

        - ``horizontal_alignment`` - left (default), center or right

        - ``labels`` - boolean (default: True)

        - ``fontsize`` - the size of the label


        OUTPUT:

        2d plot -- a plot of the two intervals (domain and range)

        EXAMPLES::

            sage: t = iet.IntervalExchangeTransformation(('a b','b a'),[1,1])
            sage: t.plot_two_intervals()
            Graphics object consisting of 8 graphics primitives
        """
        from sage.plot.all import Graphics
        from sage.plot.line import line2d
        from sage.plot.text import text
        from sage.plot.colors import rainbow

        G = Graphics()

        lengths = [float(_) for _ in self._lengths]
        total_length = sum(lengths)

        if colors is None:
            colors = rainbow(len(self._permutation), 'rgbtuple')

        if horizontal_alignment == 'left':
            s = position[0]
        elif horizontal_alignment == 'center':
            s = position[0] - total_length / 2
        elif horizontal_alignment == 'right':
            s = position[0] - total_length
        else:
            raise ValueError("horizontal_alignement must be left, center or right")

        top_height = position[1] + interval_height
        for i in self._permutation._intervals[0]:
            G += line2d([(s,top_height), (s+lengths[i],top_height)],
                        rgbcolor=colors[i])
            if labels:
                G += text(str(self._permutation._alphabet.unrank(i)),
                          (s+float(lengths[i])/2, top_height+labels_height),
                          horizontal_alignment='center',
                          rgbcolor=colors[i],
                          fontsize=fontsize)

            s += lengths[i]

        if horizontal_alignment == 'left':
            s = position[0]
        elif horizontal_alignment == 'center':
            s = position[0] - total_length / 2
        elif horizontal_alignment == 'right':
            s = position[0] - total_length
        else:
            raise ValueError("horizontal_alignement must be left, center or right")

        bottom_height = position[1] - interval_height
        for i in self._permutation._intervals[1]:
            G += line2d([(s,bottom_height), (s+lengths[i],bottom_height)],
                        rgbcolor=colors[i])
            if labels:
                G += text(str(self._permutation._alphabet.unrank(i)),
                          (s+float(lengths[i])/2, bottom_height-labels_height),
                          horizontal_alignment='center',
                          rgbcolor=colors[i],
                          fontsize=fontsize)
            s += lengths[i]

        return G
Esempio n. 39
0
    def plot(self,
             chart=None,
             ambient_coords=None,
             mapping=None,
             color='blue',
             print_label=True,
             label=None,
             label_color=None,
             fontsize=10,
             label_offset=0.1,
             parameters=None,
             **extra_options):
        r"""
        Plot the vector in a Cartesian graph based on the coordinates of some
        ambient chart.

        The vector is drawn in terms of two (2D graphics) or three (3D graphics)
        coordinates of a given chart, called hereafter the *ambient chart*.
        The vector's base point `p` (or its image `\Phi(p)` by some
        differentiable mapping `\Phi`) must lie in the ambient chart's domain.
        If `\Phi` is different from the identity mapping, the vector
        actually depicted is `\mathrm{d}\Phi_p(v)`, where `v` is the current
        vector (``self``) (see the example of a vector tangent to the
        2-sphere below, where `\Phi: S^2 \to \RR^3`).

        INPUT:

        - ``chart`` -- (default: ``None``) the ambient chart (see above); if
          ``None``, it is set to the default chart of the open set containing
          the point at which the vector (or the vector image via the
          differential `\mathrm{d}\Phi_p` of ``mapping``) is defined

        - ``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``)
          :class:`~sage.manifolds.differentiable.diff_map.DiffMap`;
          differentiable mapping `\Phi` providing the link between the
          point `p` at which the vector is defined and the ambient chart
          ``chart``: the domain of ``chart`` must contain `\Phi(p)`;
          if ``None``, the identity mapping is assumed

        - ``scale`` -- (default: 1) value by which the length of the arrow
          representing the vector is multiplied

        - ``color`` -- (default: 'blue') color of the arrow representing the
          vector

        - ``print_label`` -- (boolean; default: ``True``) determines whether a
          label is printed next to the arrow representing the vector

        - ``label`` -- (string; default: ``None``) label printed next to the
          arrow representing the vector; if ``None``, the vector's symbol is
          used, if any

        - ``label_color`` -- (default: ``None``) color to print the label;
          if ``None``, the value of ``color`` is used

        - ``fontsize`` -- (default: 10) size of the font used to print the
          label

        - ``label_offset`` -- (default: 0.1) determines the separation between
          the vector arrow and the label

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

        - ``**extra_options`` -- extra options for the arrow plot, like
          ``linestyle``, ``width`` or ``arrowsize`` (see
          :func:`~sage.plot.arrow.arrow2d` and
          :func:`~sage.plot.plot3d.shapes.arrow3d` for details)

        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:

        Vector tangent to a 2-dimensional manifold::

            sage: M = Manifold(2, 'M')
            sage: X.<x,y> = M.chart()
            sage: p = M((2,2), name='p')
            sage: Tp = M.tangent_space(p)
            sage: v = Tp((2, 1), name='v') ; v
            Tangent vector v at Point p on the 2-dimensional differentiable
             manifold M

        Plot of the vector alone (arrow + label)::

            sage: v.plot()
            Graphics object consisting of 2 graphics primitives

        Plot atop of the chart grid::

            sage: X.plot() + v.plot()
            Graphics object consisting of 20 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M')
            X = M.chart('x y'); x, y = X[:]
            p = M((2,2), name='p'); Tp = M.tangent_space(p)
            v = Tp((2, 1), name='v')
            g = X.plot() + v.plot()
            sphinx_plot(g)

        Plots with various options::

            sage: X.plot() + v.plot(color='green', scale=2, label='V')
            Graphics object consisting of 20 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M')
            X = M.chart('x y'); x, y = X[:]
            p = M((2,2), name='p'); Tp = M.tangent_space(p)
            v = Tp((2, 1), name='v')
            g = X.plot() + v.plot(color='green', scale=2, label='V')
            sphinx_plot(g)

        ::

            sage: X.plot() + v.plot(print_label=False)
            Graphics object consisting of 19 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M')
            X = M.chart('x y'); x, y = X[:]
            p = M((2,2), name='p'); Tp = M.tangent_space(p)
            v = Tp((2, 1), name='v')
            g = X.plot() + v.plot(print_label=False)
            sphinx_plot(g)

        ::

            sage: X.plot() + v.plot(color='green', label_color='black',
            ....:                   fontsize=20, label_offset=0.2)
            Graphics object consisting of 20 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M')
            X = M.chart('x y'); x, y = X[:]
            p = M((2,2), name='p'); Tp = M.tangent_space(p)
            v = Tp((2, 1), name='v')
            g = X.plot() + v.plot(color='green', label_color='black', fontsize=20, label_offset=0.2)
            sphinx_plot(g)

        ::

            sage: X.plot() + v.plot(linestyle=':', width=4, arrowsize=8,
            ....:                   fontsize=20)
            Graphics object consisting of 20 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M')
            X = M.chart('x y'); x, y = X[:]
            p = M((2,2), name='p'); Tp = M.tangent_space(p)
            v = Tp((2, 1), name='v')
            g = X.plot() + v.plot(linestyle=':', width=4, arrowsize=8, fontsize=20)
            sphinx_plot(g)

        Plot with specific values of some free parameters::

            sage: var('a b')
            (a, b)
            sage: v = Tp((1+a, -b^2), name='v') ; v.display()
            v = (a + 1) d/dx - b^2 d/dy
            sage: X.plot() + v.plot(parameters={a: -2, b: 3})
            Graphics object consisting of 20 graphics primitives

        Special case of the zero vector::

            sage: v = Tp.zero() ; v
            Tangent vector zero at Point p on the 2-dimensional differentiable
             manifold M
            sage: X.plot() + v.plot()
            Graphics object consisting of 19 graphics primitives

        Vector tangent to a 4-dimensional manifold::

            sage: M = Manifold(4, 'M')
            sage: X.<t,x,y,z> = M.chart()
            sage: p = M((0,1,2,3), name='p')
            sage: Tp = M.tangent_space(p)
            sage: v = Tp((5,4,3,2), name='v') ; v
            Tangent vector v at Point p on the 4-dimensional differentiable
             manifold M

        We cannot make a 4D plot directly::

            sage: v.plot()
            Traceback (most recent call last):
            ...
            ValueError: the number of coordinates involved in the plot must
             be either 2 or 3, not 4

        Rather, we have to select some chart coordinates for the plot, via
        the argument ``ambient_coords``. For instance, for a 2-dimensional
        plot in terms of the coordinates `(x, y)`::

            sage: v.plot(ambient_coords=(x,y))
            Graphics object consisting of 2 graphics primitives

        .. PLOT::

            M = Manifold(4, 'M')
            X = M.chart('t x y z'); t,x,y,z = X[:]
            p = M((0,1,2,3), name='p'); Tp = M.tangent_space(p)
            v = Tp((5,4,3,2), name='v')
            g = X.plot(ambient_coords=(x,y)) + v.plot(ambient_coords=(x,y))
            sphinx_plot(g)

        This plot involves only the components `v^x` and `v^y` of `v`.
        Similarly, for a 3-dimensional plot in terms of the coordinates
        `(t, x, y)`::

            sage: g = v.plot(ambient_coords=(t,x,z))
            sage: print(g)
            Graphics3d Object

        This plot involves only the components `v^t`,  `v^x` and `v^z` of `v`.
        A nice 3D view atop the coordinate grid is obtained via::

            sage: (X.plot(ambient_coords=(t,x,z))  # long time
            ....:  + v.plot(ambient_coords=(t,x,z),
            ....:           label_offset=0.5, width=6))
            Graphics3d Object

        .. PLOT::

            M = Manifold(4, 'M')
            X = M.chart('t x y z'); t,x,y,z = X[:]
            p = M((0,1,2,3), name='p'); Tp = M.tangent_space(p)
            v = Tp((5,4,3,2), name='v')
            g = X.plot(ambient_coords=(t,x,z)) + v.plot(ambient_coords=(t,x,z),
                       label_offset=0.5, width=6)
            sphinx_plot(g)

        An example of plot via a differential mapping: plot of a vector tangent
        to a 2-sphere viewed in `\RR^3`::

            sage: S2 = Manifold(2, 'S^2')
            sage: U = S2.open_subset('U') # the open set covered by spherical coord.
            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() # the standard embedding of S^2 into R^3
            F: S^2 --> R^3
            on U: (th, ph) |--> (x, y, z) = (cos(ph)*sin(th), sin(ph)*sin(th), cos(th))
            sage: p = U.point((pi/4, 7*pi/4), name='p')
            sage: v = XS.frame()[1].at(p) ; v  # the coordinate vector d/dphi at p
            Tangent vector d/dph at Point p on the 2-dimensional differentiable
             manifold S^2
            sage: graph_v = v.plot(mapping=F)
            sage: graph_S2 = XS.plot(chart=X3, mapping=F, number_values=9)  # long time
            sage: graph_v + graph_S2  # long time
            Graphics3d Object

        .. 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')
            p = U.point((pi/4, 7*pi/4), name='p')
            v = XS.frame()[1].at(p)
            graph_v = v.plot(mapping=F)
            graph_S2 = XS.plot(chart=X3, mapping=F, number_values=9)
            sphinx_plot(graph_v + graph_S2)

        """
        from sage.plot.arrow import arrow2d
        from sage.plot.text import text
        from sage.plot.graphics import Graphics
        from sage.plot.plot3d.shapes import arrow3d
        from sage.plot.plot3d.shapes2 import text3d
        from sage.misc.functional import numerical_approx
        from sage.manifolds.differentiable.chart import DiffChart

        scale = extra_options.pop("scale")

        #
        # The "effective" vector to be plotted
        #
        if mapping is None:
            eff_vector = self
            base_point = self._point
        else:
            #!# check
            # For efficiency, the method FiniteRankFreeModuleMorphism._call_()
            # is called instead of FiniteRankFreeModuleMorphism.__call__()
            eff_vector = mapping.differential(self._point)._call_(self)
            base_point = mapping(self._point)
        #
        # The chart w.r.t. which the vector is plotted
        #
        if chart is None:
            chart = base_point.parent().default_chart()
        elif not isinstance(chart, DiffChart):
            raise TypeError("{} is not a chart".format(chart))
        #
        # Coordinates of the above chart w.r.t. which the vector 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 coordinates involved in the plot:
        ind_pc = [chart[:].index(pc) for pc in ambient_coords]
        #
        # Components of the vector w.r.t. the chart frame
        #
        basis = chart.frame().at(base_point)
        vcomp = eff_vector.comp(basis=basis)[:]
        xp = base_point.coord(chart=chart)
        #
        # The arrow
        #
        resu = Graphics()
        if parameters is None:
            coord_tail = [numerical_approx(xp[i]) for i in ind_pc]
            coord_head = [
                numerical_approx(xp[i] + scale * vcomp[i]) for i in ind_pc
            ]
        else:
            coord_tail = [
                numerical_approx(xp[i].substitute(parameters)) for i in ind_pc
            ]
            coord_head = [
                numerical_approx(
                    (xp[i] + scale * vcomp[i]).substitute(parameters))
                for i in ind_pc
            ]
        if coord_head != coord_tail:
            if n_pc == 2:
                resu += arrow2d(tailpoint=coord_tail,
                                headpoint=coord_head,
                                color=color,
                                **extra_options)
            else:
                resu += arrow3d(coord_tail,
                                coord_head,
                                color=color,
                                **extra_options)
        #
        # The label
        #
        if print_label:
            if label is None:
                if n_pc == 2 and self._latex_name is not None:
                    label = r'$' + self._latex_name + r'$'
                if n_pc == 3 and self._name is not None:
                    label = self._name
            if label is not None:
                xlab = [xh + label_offset for xh in coord_head]
                if label_color is None:
                    label_color = color
                if n_pc == 2:
                    resu += text(label,
                                 xlab,
                                 fontsize=fontsize,
                                 color=label_color)
                else:
                    resu += text3d(label,
                                   xlab,
                                   fontsize=fontsize,
                                   color=label_color)
        return resu
Esempio n. 40
0
    def plot_two_intervals(self,
                           position=(0, 0),
                           vertical_alignment='center',
                           horizontal_alignment='left',
                           interval_height=0.1,
                           labels_height=0.05,
                           fontsize=14,
                           labels=True,
                           colors=None):
        r"""
        Returns a picture of the interval exchange transformation.

        INPUT:

        - ``position`` - a 2-uple of the position

        - ``horizontal_alignment`` - left (default), center or right

        - ``labels`` - boolean (default: True)

        - ``fontsize`` - the size of the label


        OUTPUT:

        2d plot -- a plot of the two intervals (domain and range)

        EXAMPLES::

            sage: t = iet.IntervalExchangeTransformation(('a b','b a'),[1,1])
            sage: t.plot_two_intervals()
            Graphics object consisting of 8 graphics primitives
        """
        from sage.plot.all import Graphics
        from sage.plot.line import line2d
        from sage.plot.text import text
        from sage.plot.colors import rainbow

        G = Graphics()

        lengths = [float(_) for _ in self._lengths]
        total_length = sum(lengths)

        if colors is None:
            colors = rainbow(len(self._permutation), 'rgbtuple')

        if horizontal_alignment == 'left':
            s = position[0]
        elif horizontal_alignment == 'center':
            s = position[0] - total_length / 2
        elif horizontal_alignment == 'right':
            s = position[0] - total_length
        else:
            raise ValueError(
                "horizontal_alignement must be left, center or right")

        top_height = position[1] + interval_height
        for i in self._permutation._intervals[0]:
            G += line2d([(s, top_height), (s + lengths[i], top_height)],
                        rgbcolor=colors[i])
            if labels:
                G += text(
                    str(self._permutation._alphabet.unrank(i)),
                    (s + float(lengths[i]) / 2, top_height + labels_height),
                    horizontal_alignment='center',
                    rgbcolor=colors[i],
                    fontsize=fontsize)

            s += lengths[i]

        if horizontal_alignment == 'left':
            s = position[0]
        elif horizontal_alignment == 'center':
            s = position[0] - total_length / 2
        elif horizontal_alignment == 'right':
            s = position[0] - total_length
        else:
            raise ValueError(
                "horizontal_alignement must be left, center or right")

        bottom_height = position[1] - interval_height
        for i in self._permutation._intervals[1]:
            G += line2d([(s, bottom_height), (s + lengths[i], bottom_height)],
                        rgbcolor=colors[i])
            if labels:
                G += text(
                    str(self._permutation._alphabet.unrank(i)),
                    (s + float(lengths[i]) / 2, bottom_height - labels_height),
                    horizontal_alignment='center',
                    rgbcolor=colors[i],
                    fontsize=fontsize)
            s += lengths[i]

        return G
Esempio n. 41
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)
Esempio n. 42
0
def plot_hyperplane(hyperplane, **kwds):
    r"""
    Return the plot of a single hyperplane.

    INPUT:

    - ``**kwds`` -- plot options: see below

    OUTPUT:

    A graphics object of the plot.

    .. RUBRIC:: Plot Options

    Beside the usual plot options (enter ``plot?``), the plot command for
    hyperplanes includes the following:

    - ``hyperplane_label`` -- Boolean value or string (default: ``True``).
      If ``True``, the hyperplane is labeled with its equation, if a
      string, it is labeled by that string, otherwise it is not
      labeled.

    - ``label_color`` -- (Default: ``'black'``) Color for hyperplane_label.

    - ``label_fontsize`` -- Size for ``hyperplane_label`` font (default: 14)
      (does not work in 3d, yet).

    - ``label_offset`` -- (Default: 0-dim: 0.1, 1-dim: (0,1),
      2-dim: (0,0,0.2)) Amount by which label is offset from
      ``hyperplane.point()``.

    - ``point_size`` -- (Default: 50) Size of points in a zero-dimensional
      arrangement or of an arrangement over a finite field.

    - ``ranges`` -- Range for the parameters for the parametric plot of the
      hyperplane. If a single positive number ``r`` is given for the
      value of ``ranges``, then the ranges for all parameters are set to
      `[-r, r]`.  Otherwise, for a line in the plane, ``ranges`` has the
      form ``[a, b]`` (default: [-3,3]), and for a plane in 3-space, the
      ``ranges`` has the form ``[[a, b], [c, d]]`` (default: [[-3,3],[-3,3]]).
      (The ranges are centered around ``hyperplane.point()``.)

    EXAMPLES::

        sage: H1.<x> = HyperplaneArrangements(QQ)
        sage: a = 3*x + 4
        sage: a.plot()    # indirect doctest
        Graphics object consisting of 3 graphics primitives
        sage: a.plot(point_size=100,hyperplane_label='hello')
        Graphics object consisting of 3 graphics primitives

    
        sage: H2.<x,y> = HyperplaneArrangements(QQ)
        sage: b = 3*x + 4*y + 5
        sage: b.plot()
        Graphics object consisting of 2 graphics primitives
        sage: b.plot(ranges=(1,5),label_offset=(2,-1))
        Graphics object consisting of 2 graphics primitives
        sage: opts = {'hyperplane_label':True, 'label_color':'green',
        ....:         'label_fontsize':24, 'label_offset':(0,1.5)}
        sage: b.plot(**opts)
        Graphics object consisting of 2 graphics primitives

        sage: H3.<x,y,z> = HyperplaneArrangements(QQ)
        sage: c = 2*x + 3*y + 4*z + 5
        sage: c.plot()
        Graphics3d Object
        sage: c.plot(label_offset=(1,0,1), color='green', label_color='red', frame=False)
        Graphics3d Object
        sage: d = -3*x + 2*y + 2*z + 3
        sage: d.plot(opacity=0.8)
        Graphics3d Object
        sage: e = 4*x + 2*z + 3
        sage: e.plot(ranges=[[-1,1],[0,8]], label_offset=(2,2,1), aspect_ratio=1)
        Graphics3d Object
    """
    if hyperplane.base_ring().characteristic() != 0:
        raise NotImplementedError('base field must have characteristic zero')
    elif hyperplane.dimension() not in [0, 1, 2]: # dimension of hyperplane, not ambient space
        raise ValueError('can only plot hyperplanes in dimensions 1, 2, 3')
    # handle extra keywords
    if 'hyperplane_label' in kwds:
        hyp_label = kwds.pop('hyperplane_label')
        if not hyp_label:
            has_hyp_label = False
        else:
            has_hyp_label = True
    else: # default
        hyp_label = True
        has_hyp_label = True
    if has_hyp_label:
        if hyp_label: # then label hyperplane with its equation
            if hyperplane.dimension() == 2: # jmol does not like latex
                label = hyperplane._repr_linear(include_zero=False)
            else:
                label = hyperplane._latex_()
        else:
            label = hyp_label # a string
    if 'label_color' in kwds:
        label_color = kwds.pop('label_color')
    else:
        label_color = 'black'
    if 'label_fontsize' in kwds:
        label_fontsize = kwds.pop('label_fontsize')
    else:
        label_fontsize = 14
    if 'label_offset' in kwds:
        has_offset = True
        label_offset = kwds.pop('label_offset')
    else:
        has_offset = False # give default values below
    if 'point_size' in kwds:
        pt_size = kwds.pop('point_size')
    else:
        pt_size = 50
    if 'ranges' in kwds:
        ranges_set = True
        ranges = kwds.pop('ranges')
    else:
        ranges_set = False # give default values below
    # the extra keywords have now been handled
    # now create the plot
    if hyperplane.dimension() == 0: # a point on a line
        x, = hyperplane.A() 
        d = hyperplane.b()
        p = point((d/x,0), size = pt_size, **kwds)
        if has_hyp_label:
            if not has_offset:
                label_offset = 0.1
            p += text(label, (d/x,label_offset),
                    color=label_color,fontsize=label_fontsize)
            p += text('',(d/x,label_offset+0.4)) # add space at top
        if 'ymax' not in kwds:
            kwds['ymax'] = 0.5
    elif hyperplane.dimension() == 1: # a line in the plane
        pnt = hyperplane.point()
        w = hyperplane.linear_part().matrix()
        x, y = hyperplane.A()
        d = hyperplane.b()
        t = SR.var('t')
        if ranges_set:
            if type(ranges) in [list,tuple]:
                t0, t1 = ranges
            else:  # ranges should be a single positive number
                t0, t1 = -ranges, ranges
        else: # default
            t0, t1 = -3, 3
        p = parametric_plot(pnt+t*w[0], (t,t0,t1), **kwds)
        if has_hyp_label:
            if has_offset:
                b0, b1 = label_offset
            else:
                b0, b1 = 0, 0.2
            label = text(label,(pnt[0]+b0,pnt[1]+b1),
                    color=label_color,fontsize=label_fontsize)
            p += label
    elif hyperplane.dimension() == 2: # a plane in 3-space
        pnt = hyperplane.point()
        w = hyperplane.linear_part().matrix()
        a, b, c = hyperplane.A()
        d = hyperplane.b()
        s,t = SR.var('s t')
        if ranges_set:
            if type(ranges) in [list,tuple]:
                s0, s1 = ranges[0]
                t0, t1 = ranges[1]
            else: # ranges should be a single positive integers
                s0, s1 = -ranges, ranges
                t0, t1 = -ranges, ranges
        else: # default
            s0, s1 = -3, 3
            t0, t1 = -3, 3
        p = parametric_plot3d(pnt+s*w[0]+t*w[1],(s,s0,s1),(t,t0,t1),**kwds)
        if has_hyp_label: 
            if has_offset:
                b0, b1, b2 = label_offset
            else:
                b0, b1, b2 = 0, 0, 0
            label = text3d(label,(pnt[0]+b0,pnt[1]+b1,pnt[2]+b2),
                    color=label_color,fontsize=label_fontsize)
            p += label
    return p
Esempio n. 43
0
    def plot(self, chart=None, ambient_coords=None, mapping=None, size=10,
             color='black', label=None, label_color=None, fontsize=10,
             label_offset=0.1, parameters=None):
        r"""
        Plot the current point (``self``) in a Cartesian graph based on the
        coordinates of some ambient chart.

        The point is drawn in terms of two (2D graphics) or three (3D graphics)
        coordinates of a given chart, called hereafter the *ambient chart*.
        The domain of the ambient chart must contain the point, or its image
        by a differentiable mapping `\Phi`.

        INPUT:

        - ``chart`` -- (default: ``None``) the ambient chart (see above); if
          ``None``, the ambient chart is set the default chart of
          ``self.containing_set()``
        - ``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 the point `p` represented by ``self``
          and the ambient chart ``chart``: the domain of ``chart`` must
          contain `\Phi(p)`; if ``None``, the identity mapping is assumed
        - ``size`` -- (default: 10) size of the point once drawn as a small
          disk or sphere
        - ``color`` -- (default: 'black') color of the point
        - ``label`` -- (default: ``None``) label printed next to the point;
          if ``None``, the point's name is used.
        - ``label_color`` -- (default: ``None``) color to print the label;
          if ``None``, the value of ``color`` is used
        - ``fontsize`` -- (default: 10) size of the font used to print the
          label
        - ``label_offset`` -- (default: 0.1) determines the separation between
          the point and its label
        - ``parameters`` -- (default: ``None``) dictionary giving the numerical
          values of the parameters that may appear in the point coordinates

        OUTPUT:

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

        EXAMPLES:

        Drawing a point on a 2-dimensional manifold::

            sage: M = Manifold(2, 'M')
            sage: X.<x,y> = M.chart()
            sage: p = M.point((1,3), name='p')
            sage: g = p.plot(X)
            sage: print g
            Graphics object consisting of 2 graphics primitives
            sage: gX = X.plot() # plot of the coordinate grid
            sage: show(g+gX) # display of the point atop the coordinate grid

        Actually, since ``X`` is the default chart of the open set in which
        ``p`` has been defined, it can be skipped in the arguments of
        ``plot``::

            sage: g = p.plot()
            sage: show(g+gX)

        Call with some options::

            sage: g = p.plot(chart=X, size=40, color='green', label='$P$',
            ....:            label_color='blue', fontsize=20, label_offset=0.3)
            sage: show(g+gX)

        Use of the ``parameters`` option to set a numerical value of some
        symbolic variable::

            sage: a = var('a')
            sage: q = M.point((a,2*a), name='q')
            sage: gq = q.plot(parameters={a:-2})
            sage: show(g+gX+gq)

        The numerical value is used only for the plot::

            sage: q.coord()
            (a, 2*a)

        Drawing a point on a 3-dimensional manifold::

            sage: M = Manifold(3, 'M')
            sage: X.<x,y,z> = M.chart()
            sage: p = M.point((2,1,3), name='p')
            sage: g = p.plot()
            sage: print g
            Graphics3d Object
            sage: gX = X.plot(nb_values=5) # coordinate mesh cube
            sage: show(g+gX) # display of the point atop the coordinate mesh

        Call with some options::

            sage: g = p.plot(chart=X, size=40, color='green', label='P_1',
            ....:            label_color='blue', fontsize=20, label_offset=0.3)
            sage: show(g+gX)

        An example of plot via a differential mapping: plot of a point on a
        2-sphere viewed in the 3-dimensional space ``M``::

            sage: S2 = Manifold(2, 'S^2')
            sage: U = S2.open_subset('U') # the open set covered by spherical coord.
            sage: XS.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
            sage: p = U.point((pi/4, pi/8), name='p')
            sage: F = S2.diff_mapping(M, {(XS, X): [sin(th)*cos(ph),
            ....:                         sin(th)*sin(ph), cos(th)]}, name='F')
            sage: F.display()
            F: S^2 --> M
            on U: (th, ph) |--> (x, y, z) = (cos(ph)*sin(th), sin(ph)*sin(th), cos(th))
            sage: g = p.plot(chart=X, mapping=F)
            sage: gS2 = XS.plot(chart=X, mapping=F, nb_values=9)
            sage: show(g+gS2)

        Use of the option ``ambient_coords`` for plots on a 4-dimensional
        manifold::

            sage: M = Manifold(4, 'M')
            sage: X.<t,x,y,z> = M.chart()
            sage: p = M.point((1,2,3,4), name='p')
            sage: g = p.plot(X, ambient_coords=(t,x,y))  # the coordinate z is skipped
            sage: gX = X.plot(X, ambient_coords=(t,x,y), nb_values=5)
            sage: show(g+gX) # 3D plot
            sage: g = p.plot(X, ambient_coords=(t,y,z))  # the coordinate x is skipped
            sage: gX = X.plot(X, ambient_coords=(t,y,z), nb_values=5)
            sage: show(g+gX) # 3D plot
            sage: g = p.plot(X, ambient_coords=(y,z))  # the coordinates t and x are skipped
            sage: gX = X.plot(X, ambient_coords=(y,z))
            sage: show(g+gX) # 2D plot

        """
        from sage.plot.point import point2d
        from sage.plot.text import text
        from sage.plot.graphics import Graphics
        from sage.plot.plot3d.shapes2 import point3d, text3d
        from sage.geometry.manifolds.chart import Chart
        # The ambient chart:
        if chart is None:
            chart = self.containing_set().default_chart()
        elif not isinstance(chart, Chart):
            raise TypeError("the argument 'chart' must be a coordinate chart")
        # The effective point to be plotted:
        if mapping is None:
            eff_point = self
        else:
            eff_point = mapping(self)
        # The coordinates of the ambient chart used for the plot:
        if ambient_coords is None:
            ambient_coords = chart._xx
        elif not isinstance(ambient_coords, tuple):
            ambient_coords = tuple(ambient_coords)
        nca = len(ambient_coords)
        if nca != 2 and nca !=3:
            raise TypeError("Bad number of ambient coordinates: " + str(nca))
        # The point coordinates:
        coords = eff_point.coord(chart)
        xx = chart[:]
        xp = [coords[xx.index(c)] for c in ambient_coords]
        if parameters is not None:
            xps = [coord.substitute(parameters) for coord in xp]
            xp = xps
        xlab = [coord + label_offset for coord in xp]
        if label_color is None:
            label_color = color
        resu = Graphics()
        if nca == 2:
            if label is None:
                label = r'$' + self._latex_name + r'$'
            resu += point2d(xp, color=color, size=size) + \
                    text(label, xlab, fontsize=fontsize, color=label_color)
        else:
            if label is None:
                label = self._name
            resu += point3d(xp, color=color, size=size) + \
                    text3d(label, xlab, fontsize=fontsize, color=label_color)
        return resu
Esempio n. 44
0
    def plot(self, chart=None, ambient_coords=None, mapping=None, label=None, parameters=None, **kwds):
        r"""
        For real manifolds, plot ``self`` in a Cartesian graph based
        on the coordinates of some ambient chart.

        The point is drawn in terms of two (2D graphics) or three (3D graphics)
        coordinates of a given chart, called hereafter the *ambient chart*.
        The domain of the ambient chart must contain the point, or its image
        by a continuous manifold map `\Phi`.

        INPUT:

        - ``chart`` -- (default: ``None``) the ambient chart (see above); if
          ``None``, the ambient chart is set the default chart of
          ``self.parent()``
        - ``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``)
          :class:`~sage.manifolds.continuous_map.ContinuousMap`; continuous
          manifold map `\Phi` providing the link between the current point
          `p` and the ambient chart ``chart``: the domain of ``chart`` must
          contain `\Phi(p)`; if ``None``, the identity map is assumed
        - ``label`` -- (default: ``None``) label printed next to the point;
          if ``None``, the point's name is used
        - ``parameters`` -- (default: ``None``) dictionary giving the numerical
          values of the parameters that may appear in the point coordinates
        - ``size`` -- (default: 10) size of the point once drawn as a small
          disk or sphere
        - ``color`` -- (default: ``'black'``) color of the point
        - ``label_color`` -- (default: ``None``) color to print the label;
          if ``None``, the value of ``color`` is used
        - ``fontsize`` -- (default: 10) size of the font used to print the
          label
        - ``label_offset`` -- (default: 0.1) determines the separation between
          the point and its label

        OUTPUT:

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

        EXAMPLES:

        Drawing a point on a 2-dimensional manifold::

            sage: M = Manifold(2, 'M', structure='topological')
            sage: X.<x,y> = M.chart()
            sage: p = M.point((1,3), name='p')
            sage: g = p.plot(X)
            sage: print(g)
            Graphics object consisting of 2 graphics primitives
            sage: gX = X.plot(max_range=4) # plot of the coordinate grid
            sage: g + gX # display of the point atop the coordinate grid
            Graphics object consisting of 20 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M', structure='topological')
            X = M.chart('x y'); x,y = X[:]
            p = M.point((1,3), name='p')
            g = p.plot(X)
            gX = X.plot(max_range=4)
            sphinx_plot(g+gX)

        Actually, since ``X`` is the default chart of the open set in which
        ``p`` has been defined, it can be skipped in the arguments of
        ``plot``::

            sage: g = p.plot()
            sage: g + gX
            Graphics object consisting of 20 graphics primitives

        Call with some options::

            sage: g = p.plot(chart=X, size=40, color='green', label='$P$',
            ....:            label_color='blue', fontsize=20, label_offset=0.3)
            sage: g + gX
            Graphics object consisting of 20 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M', structure='topological')
            X = M.chart('x y'); x,y = X[:]
            p = M.point((1,3), name='p')
            g = p.plot(chart=X, size=40, color='green', label='$P$', \
                       label_color='blue', fontsize=20, label_offset=0.3)
            gX = X.plot(max_range=4)
            sphinx_plot(g+gX)

        Use of the ``parameters`` option to set a numerical value of some
        symbolic variable::

            sage: a = var('a')
            sage: q = M.point((a,2*a), name='q')
            sage: gq = q.plot(parameters={a:-2}, label_offset=0.2)
            sage: g + gX + gq
            Graphics object consisting of 22 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M', structure='topological')
            X = M.chart('x y'); x,y = X[:]
            p = M.point((1,3), name='p')
            g = p.plot(chart=X, size=40, color='green', label='$P$', \
                       label_color='blue', fontsize=20, label_offset=0.3)
            var('a')
            q = M.point((a,2*a), name='q')
            gq = q.plot(parameters={a:-2}, label_offset=0.2)
            gX = X.plot(max_range=4)
            sphinx_plot(g+gX+gq)

        The numerical value is used only for the plot::

            sage: q.coord()
            (a, 2*a)

        Drawing a point on a 3-dimensional manifold::

            sage: M = Manifold(3, 'M', structure='topological')
            sage: X.<x,y,z> = M.chart()
            sage: p = M.point((2,1,3), name='p')
            sage: g = p.plot()
            sage: print(g)
            Graphics3d Object
            sage: gX = X.plot(nb_values=5) # coordinate mesh cube
            sage: g + gX # display of the point atop the coordinate mesh
            Graphics3d Object

        Call with some options::

            sage: g = p.plot(chart=X, size=40, color='green', label='P_1',
            ....:            label_color='blue', fontsize=20, label_offset=0.3)
            sage: g + gX
            Graphics3d Object

        An example of plot via a mapping: plot of a point on a 2-sphere viewed
        in the 3-dimensional space ``M``::

            sage: S2 = Manifold(2, 'S^2', structure='topological')
            sage: U = S2.open_subset('U') # the open set covered by spherical coord.
            sage: XS.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
            sage: p = U.point((pi/4, pi/8), name='p')
            sage: F = S2.continuous_map(M, {(XS, X): [sin(th)*cos(ph),
            ....:                           sin(th)*sin(ph), cos(th)]}, name='F')
            sage: F.display()
            F: S^2 --> M
            on U: (th, ph) |--> (x, y, z) = (cos(ph)*sin(th), sin(ph)*sin(th), cos(th))
            sage: g = p.plot(chart=X, mapping=F)
            sage: gS2 = XS.plot(chart=X, mapping=F, nb_values=9)
            sage: g + gS2
            Graphics3d Object

        Use of the option ``ambient_coords`` for plots on a 4-dimensional
        manifold::

            sage: M = Manifold(4, 'M', structure='topological')
            sage: X.<t,x,y,z> = M.chart()
            sage: p = M.point((1,2,3,4), name='p')
            sage: g = p.plot(X, ambient_coords=(t,x,y), label_offset=0.4)  # the coordinate z is skipped
            sage: gX = X.plot(X, ambient_coords=(t,x,y), nb_values=5)  # long time
            sage: g + gX # 3D plot  # long time
            Graphics3d Object
            sage: g = p.plot(X, ambient_coords=(t,y,z), label_offset=0.4)  # the coordinate x is skipped
            sage: gX = X.plot(X, ambient_coords=(t,y,z), nb_values=5)  # long time
            sage: g + gX # 3D plot  # long time
            Graphics3d Object
            sage: g = p.plot(X, ambient_coords=(y,z), label_offset=0.4)  # the coordinates t and x are skipped
            sage: gX = X.plot(X, ambient_coords=(y,z))
            sage: g + gX # 2D plot
            Graphics object consisting of 20 graphics primitives

        .. PLOT::

            M = Manifold(4, 'M', structure='topological')
            X = M.chart('t x y z'); t,x,y,z = X[:]
            p = M.point((1,2,3,4), name='p')
            g = p.plot(X, ambient_coords=(y,z), label_offset=0.4)
            gX = X.plot(X, ambient_coords=(y,z))
            sphinx_plot(g+gX)

        """
        from sage.plot.point import point2d
        from sage.plot.text import text
        from sage.plot.graphics import Graphics
        from sage.plot.plot3d.shapes2 import point3d, text3d
        from sage.manifolds.chart import Chart

        if self._manifold.base_field_type() != "real":
            raise NotImplementedError(
                "plot of points on manifolds over fields different" " from the real field is not implemented"
            )
        # The ambient chart:
        if chart is None:
            chart = self.parent().default_chart()
        elif not isinstance(chart, Chart):
            raise TypeError("the argument 'chart' must be a coordinate chart")
        # The effective point to be plotted:
        if mapping is None:
            eff_point = self
        else:
            eff_point = mapping(self)
        # The coordinates of the ambient chart used for the plot:
        if ambient_coords is None:
            ambient_coords = chart[:]
        elif not isinstance(ambient_coords, tuple):
            ambient_coords = tuple(ambient_coords)
        nca = len(ambient_coords)
        if nca != 2 and nca != 3:
            raise TypeError("invalid number of ambient coordinates: {}".format(nca))

        # Extract the kwds options
        size = kwds["size"]
        color = kwds["color"]
        label_color = kwds["label_color"]
        fontsize = kwds["fontsize"]
        label_offset = kwds["label_offset"]

        # The point coordinates:
        coords = eff_point.coord(chart)
        xx = chart[:]
        xp = [coords[xx.index(c)] for c in ambient_coords]
        if parameters is not None:
            xps = [coord.substitute(parameters) for coord in xp]
            xp = xps
        xlab = [coord + label_offset for coord in xp]
        if label_color is None:
            label_color = color
        resu = Graphics()
        if nca == 2:
            if label is None:
                label = r"$" + self._latex_name + r"$"
            resu += point2d(xp, color=color, size=size) + text(label, xlab, fontsize=fontsize, color=label_color)
        else:
            if label is None:
                label = self._name
            resu += point3d(xp, color=color, size=size) + text3d(label, xlab, fontsize=fontsize, color=label_color)
        return resu
Esempio n. 45
0
def plot_hyperplane(hyperplane, **kwds):
    r"""
    Return the plot of a single hyperplane.

    INPUT:

    - ``**kwds`` -- plot options: see below

    OUTPUT:

    A graphics object of the plot.

    .. RUBRIC:: Plot Options

    Beside the usual plot options (enter ``plot?``), the plot command for
    hyperplanes includes the following:

    - ``hyperplane_label`` -- Boolean value or string (default: ``True``).
      If ``True``, the hyperplane is labeled with its equation, if a
      string, it is labeled by that string, otherwise it is not
      labeled.

    - ``label_color`` -- (Default: ``'black'``) Color for hyperplane_label.

    - ``label_fontsize`` -- Size for ``hyperplane_label`` font (default: 14)
      (does not work in 3d, yet).

    - ``label_offset`` -- (Default: 0-dim: 0.1, 1-dim: (0,1),
      2-dim: (0,0,0.2)) Amount by which label is offset from
      ``hyperplane.point()``.

    - ``point_size`` -- (Default: 50) Size of points in a zero-dimensional
      arrangement or of an arrangement over a finite field.

    - ``ranges`` -- Range for the parameters for the parametric plot of the
      hyperplane. If a single positive number ``r`` is given for the
      value of ``ranges``, then the ranges for all parameters are set to
      `[-r, r]`.  Otherwise, for a line in the plane, ``ranges`` has the
      form ``[a, b]`` (default: [-3,3]), and for a plane in 3-space, the
      ``ranges`` has the form ``[[a, b], [c, d]]`` (default: [[-3,3],[-3,3]]).
      (The ranges are centered around ``hyperplane.point()``.)

    EXAMPLES::

        sage: H1.<x> = HyperplaneArrangements(QQ)
        sage: a = 3*x + 4
        sage: a.plot()    # indirect doctest
        Graphics object consisting of 3 graphics primitives
        sage: a.plot(point_size=100,hyperplane_label='hello')
        Graphics object consisting of 3 graphics primitives

    
        sage: H2.<x,y> = HyperplaneArrangements(QQ)
        sage: b = 3*x + 4*y + 5
        sage: b.plot()
        Graphics object consisting of 2 graphics primitives
        sage: b.plot(ranges=(1,5),label_offset=(2,-1))
        Graphics object consisting of 2 graphics primitives
        sage: opts = {'hyperplane_label':True, 'label_color':'green',
        ....:         'label_fontsize':24, 'label_offset':(0,1.5)}
        sage: b.plot(**opts)
        Graphics object consisting of 2 graphics primitives

        sage: H3.<x,y,z> = HyperplaneArrangements(QQ)
        sage: c = 2*x + 3*y + 4*z + 5
        sage: c.plot()
        Graphics3d Object
        sage: c.plot(label_offset=(1,0,1), color='green', label_color='red', frame=False)
        Graphics3d Object
        sage: d = -3*x + 2*y + 2*z + 3
        sage: d.plot(opacity=0.8)
        Graphics3d Object
        sage: e = 4*x + 2*z + 3
        sage: e.plot(ranges=[[-1,1],[0,8]], label_offset=(2,2,1), aspect_ratio=1)
        Graphics3d Object
    """
    if hyperplane.base_ring().characteristic():
        raise NotImplementedError('base field must have characteristic zero')
    elif hyperplane.dimension() not in [
            0, 1, 2
    ]:  # dimension of hyperplane, not ambient space
        raise ValueError('can only plot hyperplanes in dimensions 1, 2, 3')
    # handle extra keywords
    if 'hyperplane_label' in kwds:
        hyp_label = kwds.pop('hyperplane_label')
        if not hyp_label:
            has_hyp_label = False
        else:
            has_hyp_label = True
    else:  # default
        hyp_label = True
        has_hyp_label = True
    if has_hyp_label:
        if hyp_label:  # then label hyperplane with its equation
            if hyperplane.dimension() == 2:  # jmol does not like latex
                label = hyperplane._repr_linear(include_zero=False)
            else:
                label = hyperplane._latex_()
        else:
            label = hyp_label  # a string
    if 'label_color' in kwds:
        label_color = kwds.pop('label_color')
    else:
        label_color = 'black'
    if 'label_fontsize' in kwds:
        label_fontsize = kwds.pop('label_fontsize')
    else:
        label_fontsize = 14
    if 'label_offset' in kwds:
        has_offset = True
        label_offset = kwds.pop('label_offset')
    else:
        has_offset = False  # give default values below
    if 'point_size' in kwds:
        pt_size = kwds.pop('point_size')
    else:
        pt_size = 50
    if 'ranges' in kwds:
        ranges_set = True
        ranges = kwds.pop('ranges')
    else:
        ranges_set = False  # give default values below
    # the extra keywords have now been handled
    # now create the plot
    if hyperplane.dimension() == 0:  # a point on a line
        x, = hyperplane.A()
        d = hyperplane.b()
        p = point((d / x, 0), size=pt_size, **kwds)
        if has_hyp_label:
            if not has_offset:
                label_offset = 0.1
            p += text(label, (d / x, label_offset),
                      color=label_color,
                      fontsize=label_fontsize)
            p += text('', (d / x, label_offset + 0.4))  # add space at top
        if 'ymax' not in kwds:
            kwds['ymax'] = 0.5
    elif hyperplane.dimension() == 1:  # a line in the plane
        pnt = hyperplane.point()
        w = hyperplane.linear_part().matrix()
        t = SR.var('t')
        if ranges_set:
            if isinstance(ranges, (list, tuple)):
                t0, t1 = ranges
            else:  # ranges should be a single positive number
                t0, t1 = -ranges, ranges
        else:  # default
            t0, t1 = -3, 3
        p = parametric_plot(pnt + t * w[0], (t, t0, t1), **kwds)
        if has_hyp_label:
            if has_offset:
                b0, b1 = label_offset
            else:
                b0, b1 = 0, 0.2
            label = text(label, (pnt[0] + b0, pnt[1] + b1),
                         color=label_color,
                         fontsize=label_fontsize)
            p += label
    elif hyperplane.dimension() == 2:  # a plane in 3-space
        pnt = hyperplane.point()
        w = hyperplane.linear_part().matrix()
        s, t = SR.var('s t')
        if ranges_set:
            if isinstance(ranges, (list, tuple)):
                s0, s1 = ranges[0]
                t0, t1 = ranges[1]
            else:  # ranges should be a single positive integers
                s0, s1 = -ranges, ranges
                t0, t1 = -ranges, ranges
        else:  # default
            s0, s1 = -3, 3
            t0, t1 = -3, 3
        p = parametric_plot3d(pnt + s * w[0] + t * w[1], (s, s0, s1),
                              (t, t0, t1), **kwds)
        if has_hyp_label:
            if has_offset:
                b0, b1, b2 = label_offset
            else:
                b0, b1, b2 = 0, 0, 0
            label = text3d(label, (pnt[0] + b0, pnt[1] + b1, pnt[2] + b2),
                           color=label_color,
                           fontsize=label_fontsize)
            p += label
    return p
Esempio n. 46
0
    def plot(self, chart=None, ambient_coords=None, mapping=None,
             color='blue', print_label=True, label=None, label_color=None,
             fontsize=10, label_offset=0.1, parameters=None, **extra_options):
        r"""
        Plot the vector in a Cartesian graph based on the coordinates of some
        ambient chart.

        The vector is drawn in terms of two (2D graphics) or three (3D graphics)
        coordinates of a given chart, called hereafter the *ambient chart*.
        The vector's base point `p` (or its image `\Phi(p)` by some
        differentiable mapping `\Phi`) must lie in the ambient chart's domain.
        If `\Phi` is different from the identity mapping, the vector
        actually depicted is `\mathrm{d}\Phi_p(v)`, where `v` is the current
        vector (``self``) (see the example of a vector tangent to the
        2-sphere below, where `\Phi: S^2 \to \RR^3`).

        INPUT:

        - ``chart`` -- (default: ``None``) the ambient chart (see above); if
          ``None``, it is set to the default chart of the open set containing
          the point at which the vector (or the vector image via the
          differential `\mathrm{d}\Phi_p` of ``mapping``) is defined

        - ``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``)
          :class:`~sage.manifolds.differentiable.diff_map.DiffMap`;
          differentiable mapping `\Phi` providing the link between the
          point `p` at which the vector is defined and the ambient chart
          ``chart``: the domain of ``chart`` must contain `\Phi(p)`;
          if ``None``, the identity mapping is assumed

        - ``scale`` -- (default: 1) value by which the length of the arrow
          representing the vector is multiplied

        - ``color`` -- (default: 'blue') color of the arrow representing the
          vector

        - ``print_label`` -- (boolean; default: ``True``) determines whether a
          label is printed next to the arrow representing the vector

        - ``label`` -- (string; default: ``None``) label printed next to the
          arrow representing the vector; if ``None``, the vector's symbol is
          used, if any

        - ``label_color`` -- (default: ``None``) color to print the label;
          if ``None``, the value of ``color`` is used

        - ``fontsize`` -- (default: 10) size of the font used to print the
          label

        - ``label_offset`` -- (default: 0.1) determines the separation between
          the vector arrow and the label

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

        - ``**extra_options`` -- extra options for the arrow plot, like
          ``linestyle``, ``width`` or ``arrowsize`` (see
          :func:`~sage.plot.arrow.arrow2d` and
          :func:`~sage.plot.plot3d.shapes.arrow3d` for details)

        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:

        Vector tangent to a 2-dimensional manifold::

            sage: M = Manifold(2, 'M')
            sage: X.<x,y> = M.chart()
            sage: p = M((2,2), name='p')
            sage: Tp = M.tangent_space(p)
            sage: v = Tp((2, 1), name='v') ; v
            Tangent vector v at Point p on the 2-dimensional differentiable
             manifold M

        Plot of the vector alone (arrow + label)::

            sage: v.plot()
            Graphics object consisting of 2 graphics primitives

        Plot atop of the chart grid::

            sage: X.plot() + v.plot()
            Graphics object consisting of 20 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M')
            X = M.chart('x y'); x, y = X[:]
            p = M((2,2), name='p'); Tp = M.tangent_space(p)
            v = Tp((2, 1), name='v')
            g = X.plot() + v.plot()
            sphinx_plot(g)

        Plots with various options::

            sage: X.plot() + v.plot(color='green', scale=2, label='V')
            Graphics object consisting of 20 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M')
            X = M.chart('x y'); x, y = X[:]
            p = M((2,2), name='p'); Tp = M.tangent_space(p)
            v = Tp((2, 1), name='v')
            g = X.plot() + v.plot(color='green', scale=2, label='V')
            sphinx_plot(g)

        ::

            sage: X.plot() + v.plot(print_label=False)
            Graphics object consisting of 19 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M')
            X = M.chart('x y'); x, y = X[:]
            p = M((2,2), name='p'); Tp = M.tangent_space(p)
            v = Tp((2, 1), name='v')
            g = X.plot() + v.plot(print_label=False)
            sphinx_plot(g)

        ::

            sage: X.plot() + v.plot(color='green', label_color='black',
            ....:                   fontsize=20, label_offset=0.2)
            Graphics object consisting of 20 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M')
            X = M.chart('x y'); x, y = X[:]
            p = M((2,2), name='p'); Tp = M.tangent_space(p)
            v = Tp((2, 1), name='v')
            g = X.plot() + v.plot(color='green', label_color='black', fontsize=20, label_offset=0.2)
            sphinx_plot(g)

        ::

            sage: X.plot() + v.plot(linestyle=':', width=4, arrowsize=8,
            ....:                   fontsize=20)
            Graphics object consisting of 20 graphics primitives

        .. PLOT::

            M = Manifold(2, 'M')
            X = M.chart('x y'); x, y = X[:]
            p = M((2,2), name='p'); Tp = M.tangent_space(p)
            v = Tp((2, 1), name='v')
            g = X.plot() + v.plot(linestyle=':', width=4, arrowsize=8, fontsize=20)
            sphinx_plot(g)

        Plot with specific values of some free parameters::

            sage: var('a b')
            (a, b)
            sage: v = Tp((1+a, -b^2), name='v') ; v.display()
            v = (a + 1) d/dx - b^2 d/dy
            sage: X.plot() + v.plot(parameters={a: -2, b: 3})
            Graphics object consisting of 20 graphics primitives

        Special case of the zero vector::

            sage: v = Tp.zero() ; v
            Tangent vector zero at Point p on the 2-dimensional differentiable
             manifold M
            sage: X.plot() + v.plot()
            Graphics object consisting of 19 graphics primitives

        Vector tangent to a 4-dimensional manifold::

            sage: M = Manifold(4, 'M')
            sage: X.<t,x,y,z> = M.chart()
            sage: p = M((0,1,2,3), name='p')
            sage: Tp = M.tangent_space(p)
            sage: v = Tp((5,4,3,2), name='v') ; v
            Tangent vector v at Point p on the 4-dimensional differentiable
             manifold M

        We cannot make a 4D plot directly::

            sage: v.plot()
            Traceback (most recent call last):
            ...
            ValueError: the number of coordinates involved in the plot must
             be either 2 or 3, not 4

        Rather, we have to select some chart coordinates for the plot, via
        the argument ``ambient_coords``. For instance, for a 2-dimensional
        plot in terms of the coordinates `(x, y)`::

            sage: v.plot(ambient_coords=(x,y))
            Graphics object consisting of 2 graphics primitives

        .. PLOT::

            M = Manifold(4, 'M')
            X = M.chart('t x y z'); t,x,y,z = X[:]
            p = M((0,1,2,3), name='p'); Tp = M.tangent_space(p)
            v = Tp((5,4,3,2), name='v')
            g = X.plot(ambient_coords=(x,y)) + v.plot(ambient_coords=(x,y))
            sphinx_plot(g)

        This plot involves only the components `v^x` and `v^y` of `v`.
        Similarly, for a 3-dimensional plot in terms of the coordinates
        `(t, x, y)`::

            sage: g = v.plot(ambient_coords=(t,x,z))
            sage: print(g)
            Graphics3d Object

        This plot involves only the components `v^t`,  `v^x` and `v^z` of `v`.
        A nice 3D view atop the coordinate grid is obtained via::

            sage: (X.plot(ambient_coords=(t,x,z))  # long time
            ....:  + v.plot(ambient_coords=(t,x,z),
            ....:           label_offset=0.5, width=6))
            Graphics3d Object

        .. PLOT::

            M = Manifold(4, 'M')
            X = M.chart('t x y z'); t,x,y,z = X[:]
            p = M((0,1,2,3), name='p'); Tp = M.tangent_space(p)
            v = Tp((5,4,3,2), name='v')
            g = X.plot(ambient_coords=(t,x,z)) + v.plot(ambient_coords=(t,x,z),
                       label_offset=0.5, width=6)
            sphinx_plot(g)

        An example of plot via a differential mapping: plot of a vector tangent
        to a 2-sphere viewed in `\RR^3`::

            sage: S2 = Manifold(2, 'S^2')
            sage: U = S2.open_subset('U') # the open set covered by spherical coord.
            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() # the standard embedding of S^2 into R^3
            F: S^2 --> R^3
            on U: (th, ph) |--> (x, y, z) = (cos(ph)*sin(th), sin(ph)*sin(th), cos(th))
            sage: p = U.point((pi/4, 7*pi/4), name='p')
            sage: v = XS.frame()[1].at(p) ; v  # the coordinate vector d/dphi at p
            Tangent vector d/dph at Point p on the 2-dimensional differentiable
             manifold S^2
            sage: graph_v = v.plot(mapping=F)
            sage: graph_S2 = XS.plot(chart=X3, mapping=F, number_values=9)  # long time
            sage: graph_v + graph_S2  # long time
            Graphics3d Object

        .. 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')
            p = U.point((pi/4, 7*pi/4), name='p')
            v = XS.frame()[1].at(p)
            graph_v = v.plot(mapping=F)
            graph_S2 = XS.plot(chart=X3, mapping=F, number_values=9)
            sphinx_plot(graph_v + graph_S2)

        """
        from sage.plot.arrow import arrow2d
        from sage.plot.text import text
        from sage.plot.graphics import Graphics
        from sage.plot.plot3d.shapes import arrow3d
        from sage.plot.plot3d.shapes2 import text3d
        from sage.misc.functional import numerical_approx
        from sage.manifolds.differentiable.chart import DiffChart

        scale = extra_options.pop("scale")

        #
        # The "effective" vector to be plotted
        #
        if mapping is None:
            eff_vector = self
            base_point = self._point
        else:
            #!# check
            # For efficiency, the method FiniteRankFreeModuleMorphism._call_()
            # is called instead of FiniteRankFreeModuleMorphism.__call__()
            eff_vector = mapping.differential(self._point)._call_(self)
            base_point = mapping(self._point)
        #
        # The chart w.r.t. which the vector is plotted
        #
        if chart is None:
            chart = base_point.parent().default_chart()
        elif not isinstance(chart, DiffChart):
            raise TypeError("{} is not a chart".format(chart))
        #
        # Coordinates of the above chart w.r.t. which the vector 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 coordinates involved in the plot:
        ind_pc = [chart[:].index(pc) for pc in ambient_coords]
        #
        # Components of the vector w.r.t. the chart frame
        #
        basis = chart.frame().at(base_point)
        vcomp = eff_vector.comp(basis=basis)[:]
        xp = base_point.coord(chart=chart)
        #
        # The arrow
        #
        resu = Graphics()
        if parameters is None:
            coord_tail = [numerical_approx(xp[i]) for i in ind_pc]
            coord_head = [numerical_approx(xp[i] + scale*vcomp[i])
                          for i in ind_pc]
        else:
            coord_tail = [numerical_approx(xp[i].substitute(parameters))
                          for i in ind_pc]
            coord_head = [numerical_approx(
                           (xp[i] + scale*vcomp[i]).substitute(parameters))
                          for i in ind_pc]
        if coord_head != coord_tail:
            if n_pc == 2:
                resu += arrow2d(tailpoint=coord_tail, headpoint=coord_head,
                                color=color, **extra_options)
            else:
                resu += arrow3d(coord_tail, coord_head, color=color,
                                **extra_options)
        #
        # The label
        #
        if print_label:
            if label is None:
                if n_pc == 2 and self._latex_name is not None:
                    label = r'$' + self._latex_name + r'$'
                if n_pc == 3 and self._name is not None:
                    label = self._name
            if label is not None:
                xlab = [xh + label_offset for xh in coord_head]
                if label_color is None:
                    label_color = color
                if n_pc == 2:
                    resu += text(label, xlab, fontsize=fontsize,
                                 color=label_color)
                else:
                    resu += text3d(label, xlab, fontsize=fontsize,
                                   color=label_color)
        return resu