Ticket #12857: 12857_split_graphics.patch

File 12857_split_graphics.patch, 229.6 KB (added by jdemeyer, 9 years ago)
  • doc/en/reference/plotting.rst

    # HG changeset patch
    # User Jeroen Demeyer <jdemeyer@cage.ugent.be>
    # Date 1335122880 -7200
    # Node ID 4951048c5bf6179e94512227f037367d272081fc
    # Parent  685f91188edbcebd6a1aa426460a51ee0ae8a3d6
    Split off Graphics class from plot.py to graphics.py
    
    diff --git a/doc/en/reference/plotting.rst b/doc/en/reference/plotting.rst
    a b  
    55   :maxdepth: 2
    66
    77   sage/plot/plot
     8   sage/plot/graphics
    89   sage/plot/animate
    910   sage/plot/arc
    1011   sage/plot/arrow
  • sage/calculus/riemann.pyx

    diff --git a/sage/calculus/riemann.pyx b/sage/calculus/riemann.pyx
    a b  
    3030
    3131from sage.plot.primitive import GraphicPrimitive
    3232from sage.misc.decorators import options
    33 from sage.plot.plot import list_plot, Graphics, setup_for_eval_on_grid
     33from sage.plot.all import list_plot, Graphics
     34from sage.plot.misc import setup_for_eval_on_grid
    3435
    3536from sage.ext.fast_eval import fast_callable
    3637
  • sage/combinat/e_one_star.py

    diff --git a/sage/combinat/e_one_star.py b/sage/combinat/e_one_star.py
    a b  
    206206#  the License, or (at your option) any later version.
    207207#                  http://www.gnu.org/licenses/
    208208#*****************************************************************************
     209
    209210from sage.misc.functional import det
    210211from sage.structure.sage_object import SageObject
    211212from sage.combinat.words.morphism import WordMorphism
    212213from sage.matrix.constructor import matrix
    213214from sage.modules.free_module_element import vector
    214 from sage.plot.plot import Graphics
    215 from sage.plot.plot import rainbow
     215from sage.plot.all import Graphics
    216216from sage.plot.colors import Color
    217217from sage.plot.polygon import polygon
    218218from sage.plot.line import line
  • sage/combinat/iet/iet.py

    diff --git a/sage/combinat/iet/iet.py b/sage/combinat/iet/iet.py
    a b  
    757757            sage: t = iet.IntervalExchangeTransformation(('a b c d','d a c b'),[1,1,1,1])
    758758            sage: t.plot_function(rgbcolor=(0,1,0))
    759759        """
    760         from sage.plot.plot import Graphics
     760        from sage.plot.all import Graphics
    761761        from sage.plot.plot import line2d
    762762
    763763        G = Graphics()
     
    803803            sage: t = iet.IntervalExchangeTransformation(('a b','b a'),[1,1])
    804804            sage: t.plot_two_intervals()
    805805        """
    806         from sage.plot.plot import Graphics
     806        from sage.plot.all import Graphics
    807807        from sage.plot.plot import line2d
    808808        from sage.plot.plot import text
    809809        from sage.plot.colors import rainbow
  • sage/combinat/posets/hasse_diagram.py

    diff --git a/sage/combinat/posets/hasse_diagram.py b/sage/combinat/posets/hasse_diagram.py
    a b  
    123123            sage: levels = H.level_sets()
    124124            sage: heights = dict([[i, levels[i]] for i in range(len(levels))])
    125125            sage: type(H.plot(label_elements=True))
    126             <class 'sage.plot.plot.Graphics'>
     126            <class 'sage.plot.graphics.Graphics'>
    127127       
    128128        ::
    129129       
  • sage/combinat/posets/posets.py

    diff --git a/sage/combinat/posets/posets.py b/sage/combinat/posets/posets.py
    a b  
    932932            sage: D.plot(label_elements=False)
    933933            sage: D.plot()
    934934            sage: type(D.plot())
    935             <class 'sage.plot.plot.Graphics'>
     935            <class 'sage.plot.graphics.Graphics'>
    936936            sage: elm_labs = {1:'a', 2:'b', 3:'c', 4:'d', 5:'e'}
    937937            sage: D.plot(element_labels=elm_labs)
    938938 
  • sage/combinat/root_system/weight_lattice_realizations.py

    diff --git a/sage/combinat/root_system/weight_lattice_realizations.py b/sage/combinat/root_system/weight_lattice_realizations.py
    a b  
    837837                sage: G = L.plot(size=[[-1..1],[-1..1]],alcovewalks=[[0,2,0,1,2,1,2,0,2,1]])
    838838            """
    839839
    840             from sage.plot.plot import Graphics
     840            from sage.plot.all import Graphics
    841841            from sage.plot.line import line
    842842            from cartan_type import CartanType
    843843            from sage.matrix.constructor import matrix
  • sage/combinat/tiling.py

    diff --git a/sage/combinat/tiling.py b/sage/combinat/tiling.py
    a b  
    224224from sage.misc.cachefunc import cached_method, cached_function
    225225from sage.misc.misc import prod
    226226from sage.combinat.all import WeylGroup
    227 from sage.plot.plot import Graphics
     227from sage.plot.all import Graphics
    228228from sage.plot.polygon import polygon
    229229from sage.plot.line import line
    230230from sage.plot.circle import circle
  • sage/combinat/words/paths.py

    diff --git a/sage/combinat/words/paths.py b/sage/combinat/words/paths.py
    a b  
    181181from sage.combinat.words.words import Words_over_OrderedAlphabet
    182182from sage.combinat.words.word import FiniteWord_class
    183183from sage.combinat.words.alphabet import OrderedAlphabet
    184 from sage.plot.plot import arrow, line, polygon, point, Graphics
     184from sage.plot.all import arrow, line, polygon, point, Graphics
    185185from sage.modules.free_module_element import vector
    186186from sage.rings.all import ZZ, RR, QuadraticField
    187187from word_datatypes import (WordDatatype_str,
  • sage/combinat/words/suffix_trees.py

    diff --git a/sage/combinat/words/suffix_trees.py b/sage/combinat/words/suffix_trees.py
    a b  
    467467
    468468            sage: from sage.combinat.words.suffix_trees import SuffixTrie
    469469            sage: type(SuffixTrie(Word("cacao")).plot())
    470             <class 'sage.plot.plot.Graphics'>
     470            <class 'sage.plot.graphics.Graphics'>
    471471        """
    472472        tree = self.to_digraph()
    473473        for (u,v,label) in tree.edge_iterator():
     
    868868
    869869            sage: from sage.combinat.words.suffix_trees import ImplicitSuffixTree
    870870            sage: type(ImplicitSuffixTree(Word('cacao')).plot(word_labels=True))
    871             <class 'sage.plot.plot.Graphics'>
     871            <class 'sage.plot.graphics.Graphics'>
    872872            sage: type(ImplicitSuffixTree(Word('cacao')).plot(word_labels=False))
    873             <class 'sage.plot.plot.Graphics'>
     873            <class 'sage.plot.graphics.Graphics'>
    874874        """
    875875        tree = self.to_digraph(word_labels=word_labels)
    876876        if word_labels:
  • sage/games/quantumino.py

    diff --git a/sage/games/quantumino.py b/sage/games/quantumino.py
    a b  
    167167#                  http://www.gnu.org/licenses/ 
    168168#*****************************************************************************
    169169from sage.structure.sage_object import SageObject
    170 from sage.plot.plot import Graphics
     170from sage.plot.all import Graphics
    171171from sage.plot.plot3d.platonic import cube
    172172from sage.plot.plot3d.shapes2 import text3d
    173173from sage.modules.free_module_element import vector
  • sage/geometry/lattice_polytope.py

    diff --git a/sage/geometry/lattice_polytope.py b/sage/geometry/lattice_polytope.py
    a b  
    23652365
    23662366        Plot with facets of different colors::
    23672367
    2368             sage: c.plot3d(facet_colors=sage.plot.plot.rainbow(c.nfacets(), 'rgbtuple'))
     2368            sage: c.plot3d(facet_colors=rainbow(c.nfacets(), 'rgbtuple'))
    23692369
    23702370        It is also possible to plot lower dimensional polytops in 3D (let's
    23712371        also change labels of vertices)::
  • sage/graphs/generic_graph.py

    diff --git a/sage/graphs/generic_graph.py b/sage/graphs/generic_graph.py
    a b  
    1597115971            sage: E.relabel(gamma)
    1597215972            sage: a,b = D.is_isomorphic(E, certify=True); a
    1597315973            True
    15974             sage: from sage.plot.plot import GraphicsArray
     15974            sage: from sage.plot.graphics import GraphicsArray
    1597515975            sage: from sage.graphs.generic_graph_pyx import spring_layout_fast
    1597615976            sage: position_D = spring_layout_fast(D)
    1597715977            sage: position_E = {}
  • sage/graphs/graph_database.py

    diff --git a/sage/graphs/graph_database.py b/sage/graphs/graph_database.py
    a b  
    103103   
    104104        sage: from sage.graphs.graph_database import graph6_to_plot
    105105        sage: type(graph6_to_plot('D??'))
    106         <class 'sage.plot.plot.Graphics'>
     106        <class 'sage.plot.graphics.Graphics'>
    107107    """
    108108    g = Graph(str(graph6))
    109109    return g.plot(layout='circular',vertex_size=30,vertex_labels=False,graph_border=False)
  • sage/graphs/graph_generators.py

    diff --git a/sage/graphs/graph_generators.py b/sage/graphs/graph_generators.py
    a b  
    595595            ...           n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    596596            ...       j.append(n)
    597597            ...
    598             sage: G = sage.plot.plot.GraphicsArray(j)
     598            sage: G = sage.plot.graphics.GraphicsArray(j)
    599599            sage: G.show() # long time
    600600
    601601        TESTS:
     
    949949            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    950950            ...    j.append(n)
    951951            ...
    952             sage: G = sage.plot.plot.GraphicsArray(j)
     952            sage: G = sage.plot.graphics.GraphicsArray(j)
    953953            sage: G.show() # long time
    954954        """
    955955        pos_dict = {}
     
    10421042            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    10431043            ...    j.append(n)
    10441044            ...
    1045             sage: G = sage.plot.plot.GraphicsArray(j)
     1045            sage: G = sage.plot.graphics.GraphicsArray(j)
    10461046            sage: G.show() # long time
    10471047       
    10481048        Compare to plotting with the spring-layout algorithm::
     
    10601060            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    10611061            ...    j.append(n)
    10621062            ...
    1063             sage: G = sage.plot.plot.GraphicsArray(j)
     1063            sage: G = sage.plot.graphics.GraphicsArray(j)
    10641064            sage: G.show() # long time
    10651065        """
    10661066        pos_dict = {}
     
    16331633            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    16341634            ...    j.append(n)
    16351635            ...
    1636             sage: G = sage.plot.plot.GraphicsArray(j)
     1636            sage: G = sage.plot.graphics.GraphicsArray(j)
    16371637            sage: G.show() # long time
    16381638        """
    16391639        pos_dict = {}
     
    16851685            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    16861686            ...    j.append(n)
    16871687            ...
    1688             sage: G = sage.plot.plot.GraphicsArray(j)
     1688            sage: G = sage.plot.graphics.GraphicsArray(j)
    16891689            sage: G.show() # long time
    16901690        """
    16911691        pos_dict = {}
     
    18531853            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    18541854            ...    j.append(n)
    18551855            ...
    1856             sage: G = sage.plot.plot.GraphicsArray(j)
     1856            sage: G = sage.plot.graphics.GraphicsArray(j)
    18571857            sage: G.show() # long time
    18581858       
    18591859        Compared to plotting with the spring-layout algorithm
     
    18731873            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    18741874            ...    j.append(n)
    18751875            ...
    1876             sage: G = sage.plot.plot.GraphicsArray(j)
     1876            sage: G = sage.plot.graphics.GraphicsArray(j)
    18771877            sage: G.show() # long time
    18781878        """
    18791879        pos_dict = {}
     
    19211921            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    19221922            ...    j.append(n)
    19231923            ...
    1924             sage: G = sage.plot.plot.GraphicsArray(j)
     1924            sage: G = sage.plot.graphics.GraphicsArray(j)
    19251925            sage: G.show() # long time
    19261926       
    19271927        Next, using the spring-layout algorithm::
     
    19401940            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    19411941            ...    j.append(n)
    19421942            ...
    1943             sage: G = sage.plot.plot.GraphicsArray(j)
     1943            sage: G = sage.plot.graphics.GraphicsArray(j)
    19441944            sage: G.show() # long time
    19451945       
    19461946        Compare the plotting::
     
    20072007            ...    for m in range(2):
    20082008            ...        n.append(g[i + m].plot(vertex_size=50, vertex_labels=False))
    20092009            ...    j.append(n)
    2010             sage: G = sage.plot.plot.GraphicsArray(j)
     2010            sage: G = sage.plot.graphics.GraphicsArray(j)
    20112011            sage: G.show() # long time
    20122012        """
    20132013        import networkx
     
    20592059            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    20602060            ...    j.append(n)
    20612061            ...
    2062             sage: G = sage.plot.plot.GraphicsArray(j)
     2062            sage: G = sage.plot.graphics.GraphicsArray(j)
    20632063            sage: G.show() # long time
    20642064        """
    20652065        return graph.Graph({0:[1,3,4], 1:[2,5], 2:[3,6], 3:[7], 4:[5,7],\
     
    21172117            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    21182118            ...    j.append(n)
    21192119            ...
    2120             sage: G = sage.plot.plot.GraphicsArray(j)
     2120            sage: G = sage.plot.graphics.GraphicsArray(j)
    21212121            sage: G.show() # long time
    21222122        """
    21232123        import networkx
     
    21792179            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    21802180            ...    j.append(n)
    21812181            ...
    2182             sage: G = sage.plot.plot.GraphicsArray(j)
     2182            sage: G = sage.plot.graphics.GraphicsArray(j)
    21832183            sage: G.show() # long time
    21842184        """
    21852185        import networkx
     
    22382238            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    22392239            ...    j.append(n)
    22402240            ...
    2241             sage: G = sage.plot.plot.GraphicsArray(j)
     2241            sage: G = sage.plot.graphics.GraphicsArray(j)
    22422242            sage: G.show() # long time
    22432243        """
    22442244        import networkx
     
    40324032            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    40334033            ...    j.append(n)
    40344034            ...
    4035             sage: G = sage.plot.plot.GraphicsArray(j)
     4035            sage: G = sage.plot.graphics.GraphicsArray(j)
    40364036            sage: G.show() # long time
    40374037       
    40384038        Compare to plotting with the spring-layout algorithm::
     
    40504050            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    40514051            ...    j.append(n)
    40524052            ...
    4053             sage: G = sage.plot.plot.GraphicsArray(j)
     4053            sage: G = sage.plot.graphics.GraphicsArray(j)
    40544054            sage: G.show() # long time
    40554055       
    40564056        Passing a 1 into adjacency should give the cycle.
     
    41294129            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    41304130            ...    j.append(n)
    41314131            ...
    4132             sage: G = sage.plot.plot.GraphicsArray(j)
     4132            sage: G = sage.plot.graphics.GraphicsArray(j)
    41334133            sage: G.show() # long time
    41344134       
    41354135        We compare to plotting with the spring-layout algorithm::
     
    41484148            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    41494149            ...    j.append(n)
    41504150            ...
    4151             sage: G = sage.plot.plot.GraphicsArray(j)
     4151            sage: G = sage.plot.graphics.GraphicsArray(j)
    41524152            sage: G.show() # long time
    41534153       
    41544154        Compare the constructors (results will vary)
     
    42544254            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    42554255            ...    j.append(n)
    42564256            ...
    4257             sage: G = sage.plot.plot.GraphicsArray(j)
     4257            sage: G = sage.plot.graphics.GraphicsArray(j)
    42584258            sage: G.show() # long time
    42594259       
    42604260        We compare to plotting with the spring-layout algorithm::
     
    42724272            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    42734273            ...    j.append(n)
    42744274            ...
    4275             sage: G = sage.plot.plot.GraphicsArray(j)
     4275            sage: G = sage.plot.graphics.GraphicsArray(j)
    42764276            sage: G.show() # long time
    42774277
    42784278        Trac ticket #12155::
     
    43744374            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    43754375            ...    j.append(n)
    43764376            ...
    4377             sage: G = sage.plot.plot.GraphicsArray(j)
     4377            sage: G = sage.plot.graphics.GraphicsArray(j)
    43784378            sage: G.show(figsize=[6,4]) # long time
    43794379       
    43804380        Use the plot options to display larger `n`-cubes
     
    44644464            ...       for j in range(3):
    44654465            ...           n.append(A[3*i + j].plot(vertex_size=20, vertex_labels=False))
    44664466            ...       B.append(n)
    4467             sage: G = sage.plot.plot.GraphicsArray(B)
     4467            sage: G = sage.plot.graphics.GraphicsArray(B)
    44684468            sage: G.show()  # long time
    44694469
    44704470        For `n = 1`, the friendship graph `F_1` is isomorphic to the cycle
     
    50885088            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    50895089            ...    j.append(n)
    50905090            ...
    5091             sage: G = sage.plot.plot.GraphicsArray(j)
     5091            sage: G = sage.plot.graphics.GraphicsArray(j)
    50925092            sage: G.show() # long time
    50935093            sage: graphs.RandomGNP(4,1)
    50945094            Complete graph: Graph on 4 vertices
     
    51765176            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    51775177            ...    j.append(n)
    51785178            ...
    5179             sage: G = sage.plot.plot.GraphicsArray(j)
     5179            sage: G = sage.plot.graphics.GraphicsArray(j)
    51805180            sage: G.show()  # long time
    51815181
    51825182        """
     
    52945294            ...        n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False))
    52955295            ...    j.append(n)
    52965296            ...
    5297             sage: G = sage.plot.plot.GraphicsArray(j)
     5297            sage: G = sage.plot.graphics.GraphicsArray(j)
    52985298            sage: G.show()  # long time
    52995299        """
    53005300        if seed is None:
  • sage/interfaces/phc.py

    diff --git a/sage/interfaces/phc.py b/sage/interfaces/phc.py
    a b  
    659659            sage: end_sys = [x^5-25,y^5-x^2]           #optional
    660660            sage: testing = phc.plot_paths_2d(start_sys, end_sys, R2)  #optional
    661661            sage: type(testing)                        #optional (normally use plot here)
    662             <class 'sage.plot.plot.Graphics'>
     662            <class 'sage.plot.graphics.Graphics'>
    663663        """
    664664        paths = phc.path_track(start_sys, end_sys, input_ring, c_skew = c_skew, saved_start = saved_start)
    665665        path_lines = []
  • sage/misc/html.py

    diff --git a/sage/misc/html.py b/sage/misc/html.py
    a b  
    308308            <th>a</th>
    309309        """       
    310310        column_tag = "<th>%s</th>" if header else "<td>%s</td>"
    311         from sage.plot.plot import Graphics
     311        from sage.plot.all import Graphics
    312312        import types
    313313        if isinstance(row, types.GeneratorType):
    314314            row = list(row)
  • sage/misc/latex.py

    diff --git a/sage/misc/latex.py b/sage/misc/latex.py
    a b  
    22332233    import __builtin__
    22342234    __builtin__._=object
    22352235
    2236     from sage.plot.plot import Graphics
     2236    from sage.plot.all import Graphics
    22372237    from sage.plot.plot3d.base import Graphics3d
    22382238    if isinstance(object, (Graphics, Graphics3d)):
    22392239        print repr(object)
  • sage/modular/arithgroup/farey_symbol.pyx

    diff --git a/sage/modular/arithgroup/farey_symbol.pyx b/sage/modular/arithgroup/farey_symbol.pyx
    a b  
    4040from congroup_sl2z import SL2Z
    4141from sage.modular.cusps import Cusp
    4242
    43 from sage.plot.plot import Graphics
     43from sage.plot.all import Graphics
    4444from sage.plot.colors import to_mpl_color
    4545from sage.plot.misc import options, rename_keyword
    4646from sage.plot.all import hyperbolic_arc, hyperbolic_triangle, text
  • sage/plot/all.py

    diff --git a/sage/plot/all.py b/sage/plot/all.py
    a b  
    1 from plot import (Graphics, plot,
    2                   graphics_array,
    3                   list_plot, parametric_plot,
    4                   polar_plot,
    5                   is_Graphics,
    6                   show_default)
    7 
     1from graphics import show_default, Graphics, is_Graphics
     2from plot import plot, graphics_array, list_plot, parametric_plot, polar_plot
    83from line import line, line2d
    94from arrow import arrow, arrow2d
    105from bar_chart import bar_chart
  • sage/plot/animate.py

    diff --git a/sage/plot/animate.py b/sage/plot/animate.py
    a b  
    100100        """
    101101        w = []
    102102        for x in v:
    103             if not isinstance(x, plot.Graphics):
     103            if not isinstance(x, sage.plot.graphics.Graphics):
    104104                x = plot.plot(x, (kwds.get('xmin',0), kwds.get('xmax', 1)))
    105105            w.append(x)
    106106        if len(w) == 0:
    107             w = [plot.Graphics()]
     107            w = [sage.plot.graphics.Graphics()]
    108108        self.__frames = w
    109109        self.__kwds = kwds
    110110
  • sage/plot/arc.py

    diff --git a/sage/plot/arc.py b/sage/plot/arc.py
    a b  
    349349        ...
    350350        NotImplementedError
    351351    """
    352     from sage.plot.plot import Graphics
     352    from sage.plot.all import Graphics
    353353    if len(center)==2:
    354354        if r2 is None: r2 = r1
    355355        g = Graphics()
  • sage/plot/arrow.py

    diff --git a/sage/plot/arrow.py b/sage/plot/arrow.py
    a b  
    419419        sage: arrow2d((-2, 2), (7,1), frame=True)
    420420        sage: arrow2d((-2, 2), (7,1)).show(frame=True)
    421421    """
    422     from sage.plot.plot import Graphics
     422    from sage.plot.all import Graphics
    423423    g = Graphics()
    424424    g._set_extra_kwds(Graphics._extract_kwds_for_show(options))
    425425    if headpoint is not None and tailpoint is not None:
  • sage/plot/bar_chart.py

    diff --git a/sage/plot/bar_chart.py b/sage/plot/bar_chart.py
    a b  
    1919#                  http://www.gnu.org/licenses/
    2020#*****************************************************************************
    2121from sage.plot.primitive import GraphicPrimitive
    22 from sage.plot.plot import minmax_data, Graphics
     22from sage.plot.plot import minmax_data
     23from sage.plot.graphics import Graphics
    2324from sage.misc.decorators import options, rename_keyword
    2425
    2526#TODO: make bar_chart more general
  • sage/plot/bezier_path.py

    diff --git a/sage/plot/bezier_path.py b/sage/plot/bezier_path.py
    a b  
    266266        sage: curve = bezier_path(path, linestyle='dashed', rgbcolor='green')
    267267        sage: curve
    268268
    269     Extra options will get passed on to :meth:`~sage.plot.plot.Graphics.show`, as long as they are valid::
     269    Extra options will get passed on to :meth:`~Graphics.show`, as long as they are valid::
    270270
    271271        sage: bezier_path([[(0,1),(.5,0),(1,1)]], fontsize=50)
    272272        sage: bezier_path([[(0,1),(.5,0),(1,1)]]).show(fontsize=50) # These are equivalent
    273273    """
    274     from sage.plot.plot import Graphics
     274    from sage.plot.all import Graphics
    275275    g = Graphics()
    276276    g._set_extra_kwds(g._extract_kwds_for_show(options))
    277277    g.add_primitive(BezierPath(path, options))
  • sage/plot/circle.py

    diff --git a/sage/plot/circle.py b/sage/plot/circle.py
    a b  
    312312        sage: P.aspect_ratio()
    313313        1.0
    314314    """
    315     from sage.plot.plot import Graphics
     315    from sage.plot.all import Graphics
    316316    g = Graphics()
    317317    g._set_extra_kwds(Graphics._extract_kwds_for_show(options))
    318318    g.add_primitive(Circle(center[0], center[1], radius, options))
  • sage/plot/colors.py

    diff --git a/sage/plot/colors.py b/sage/plot/colors.py
    a b  
    44This module defines a :class:`Color` object and helper functions (see,
    55e.g., :func:`hue`, :func:`rainbow`), as well as a set of
    66:data:`colors` and :data:`colormaps` to use with
    7 :class:`sage.plot.plot.Graphics` objects in Sage.
     7:class:`Graphics` objects in Sage.
    88
    99For a list of pre-defined colors in Sage, evaluate::
    1010
  • sage/plot/complex_plot.pyx

    diff --git a/sage/plot/complex_plot.pyx b/sage/plot/complex_plot.pyx
    a b  
    314314
    315315        sage: complex_plot(sqrt, (-5, 5), (-5, 5))
    316316    """
    317     from sage.plot.plot import Graphics
     317    from sage.plot.all import Graphics
    318318    from sage.plot.misc import setup_for_eval_on_grid
    319319    from sage.ext.fast_callable import fast_callable
    320320    from sage.rings.complex_double import CDF
  • sage/plot/contour_plot.py

    diff --git a/sage/plot/contour_plot.py b/sage/plot/contour_plot.py
    a b  
    473473        sage: x,y = var('x,y')
    474474        sage: contour_plot(x-y^2,(x,-5,5),(y,-3,3),contours=[-4,-2,0], fill=False)
    475475    """
    476     from sage.plot.plot import Graphics
     476    from sage.plot.all import Graphics
    477477    from sage.plot.misc import setup_for_eval_on_grid
    478478    g, ranges = setup_for_eval_on_grid([f], [xrange, yrange], options['plot_points'])
    479479    g = g[0]
     
    744744
    745745    """
    746746
    747     from sage.plot.plot import Graphics
     747    from sage.plot.all import Graphics
    748748    from sage.plot.misc import setup_for_eval_on_grid
    749749    import numpy
    750750
  • sage/plot/density_plot.py

    diff --git a/sage/plot/density_plot.py b/sage/plot/density_plot.py
    a b  
    221221
    222222        sage: density_plot(log(x) + log(y), (x, 1, 10), (y, 1, 10)).show(dpi=20) # These are equivalent
    223223    """
    224     from sage.plot.plot import Graphics
     224    from sage.plot.all import Graphics
    225225    from sage.plot.misc import setup_for_eval_on_grid
    226226    g, ranges = setup_for_eval_on_grid([f], [xrange, yrange], options['plot_points'])
    227227    g = g[0]
  • sage/plot/disk.py

    diff --git a/sage/plot/disk.py b/sage/plot/disk.py
    a b  
    282282        ...
    283283        ValueError: The center point of a plotted disk should have two or three coordinates.
    284284    """
    285     from sage.plot.plot import Graphics
     285    from sage.plot.all import Graphics
    286286    g = Graphics()
    287287    g._set_extra_kwds(Graphics._extract_kwds_for_show(options))
    288288    g.add_primitive(Disk(point, radius, angle, options))
  • sage/plot/ellipse.py

    diff --git a/sage/plot/ellipse.py b/sage/plot/ellipse.py
    a b  
    272272        ...
    273273        NotImplementedError: plotting ellipse in 3D is not implemented
    274274    """
    275     from sage.plot.plot import Graphics
     275    from sage.plot.all import Graphics
    276276    g = Graphics()
    277277    g._set_extra_kwds(Graphics._extract_kwds_for_show(options))
    278278    g.add_primitive(Ellipse(center[0],center[1],r1,r2,angle,options))
  • .py

    diff --git a/sage/plot/plot.py b/sage/plot/graphics.py
    copy from sage/plot/plot.py
    copy to sage/plot/graphics.py
    old new  
    11r"""
    2 2D Plotting
     2Graphics objects
    33
    4 Sage provides extensive 2D plotting functionality. The underlying
    5 rendering is done using the matplotlib Python library.
    6 
    7 The following graphics primitives are supported:
    8 
    9 
    10 -  :func:`~sage.plot.arrow.arrow` - an arrow from a min point to a max point.
    11 
    12 -  :func:`~sage.plot.circle.circle` - a circle with given radius
    13 
    14 -  :func:`~sage.plot.ellipse.ellipse` - an ellipse with given radii
    15    and angle
    16 
    17 -  :func:`~sage.plot.arc.arc` - an arc of a circle or an ellipse
    18 
    19 -  :func:`~sage.plot.disk.disk` - a filled disk (i.e. a sector or wedge of a circle)
    20 
    21 -  :func:`~sage.plot.line.line` - a line determined by a sequence of points (this need not
    22    be straight!)
    23 
    24 -  :func:`~sage.plot.point.point` - a point
    25 
    26 -  :func:`~sage.plot.text.text` - some text
    27 
    28 -  :func:`~sage.plot.polygon.polygon` - a filled polygon
    29 
    30 
    31 The following plotting functions are supported:
    32 
    33 
    34 -  :func:`plot` - plot of a function or other Sage object (e.g., elliptic
    35    curve).
    36 
    37 -  :func:`parametric_plot`
    38 
    39 -  :func:`~sage.plot.contour_plot.implicit_plot`
    40 
    41 -  :func:`polar_plot`
    42 
    43 -  :func:`~sage.plot.contour_plot.region_plot`
    44 
    45 -  :func:`list_plot`
    46 
    47 -  :func:`~sage.plot.scatter_plot.scatter_plot`
    48 
    49 -  :func:`~sage.plot.bar_chart.bar_chart`
    50 
    51 -  :func:`~sage.plot.contour_plot.contour_plot`
    52 
    53 -  :func:`~sage.plot.density_plot.density_plot`
    54 
    55 -  :func:`~sage.plot.plot_field.plot_vector_field`
    56 
    57 -  :func:`~sage.plot.plot_field.plot_slope_field`
    58 
    59 -  :func:`~sage.plot.matrix_plot.matrix_plot`
    60 
    61 -  :func:`~sage.plot.complex_plot.complex_plot`
    62 
    63 -  :func:`graphics_array`
    64 
    65 
    66 The following miscellaneous Graphics functions are included:
    67 
    68 
    69 -  :func:`Graphics`
    70 
    71 -  :func:`is_Graphics`
    72 
    73 -  :func:`~sage.plot.colors.hue`
    74 
    75 
    76 Type ``?`` after each primitive in Sage for help and examples.
    77 
    78 EXAMPLES:
    79 
    80 We draw a curve::
    81 
    82     sage: plot(x^2, (x,0,5))
    83 
    84 We draw a circle and a curve::
    85 
    86     sage: circle((1,1), 1) + plot(x^2, (x,0,5))
    87 
    88 Notice that the aspect ratio of the above plot makes the plot very tall because
    89 the plot adopts the default aspect ratio of the circle (to make the circle appear
    90 like a circle).  We can change the aspect ratio to be what we normally expect for a plot
    91 by explicitly asking for an 'automatic' aspect ratio::
    92 
    93     sage: show(circle((1,1), 1) + plot(x^2, (x,0,5)), aspect_ratio='automatic')
    94 
    95 The aspect ratio describes the apparently height/width ratio of a unit square.  If you want the vertical units to be twice as big as the horizontal units, specify an aspect ratio of 2::
    96 
    97     sage: show(circle((1,1), 1) + plot(x^2, (x,0,5)), aspect_ratio=2)
    98 
    99 The ``figsize`` option adjusts the figure size.  The default figsize is 4.  To make a figure that is roughly twice as big, use ``figsize=8``::
    100 
    101     sage: show(circle((1,1), 1) + plot(x^2, (x,0,5)), figsize=8)
    102 
    103 You can also give separate horizontal and vertical dimensions::
    104 
    105     sage: show(circle((1,1), 1) + plot(x^2, (x,0,5)), figsize=[4,8])
    106 
    107 Note that the axes will not cross if the data is not on both sides of
    108 both axes, even if it is quite close::
    109 
    110     sage: plot(x^3,(x,1,10))
    111 
    112 When the labels have quite different orders of magnitude or are very
    113 large, scientific notation (the `e` notation for powers of ten) is used::
    114 
    115     sage: plot(x^2,(x,480,500))  # no scientific notation
    116 
    117 ::
    118 
    119     sage: plot(x^2,(x,300,500))  # scientific notation on y-axis
    120 
    121 But you can fix your own tick labels, if you know what to expect and
    122 have a preference::
    123 
    124     sage: plot(x^2,(x,300,500),ticks=[None,50000])
    125 
    126 We construct a plot involving several graphics objects::
    127 
    128     sage: G = plot(cos(x), (x, -5, 5), thickness=5, color='green')
    129     sage: P = polygon([[1,2], [5,6], [5,0]], color='red')
    130     sage: G + P
    131 
    132 Next we construct the reflection of the above polygon about the
    133 `y`-axis by iterating over the list of first-coordinates of
    134 the first graphic element of `P` (which is the actual
    135 Polygon; note that `P` is a Graphics object, which consists
    136 of a single polygon)::
    137 
    138     sage: Q = polygon([(-x,y) for x,y in P[0]], color='blue')
    139     sage: Q   # show it
    140 
    141 We combine together different graphics objects using "+"::
    142 
    143     sage: H = G + P + Q
    144     sage: print H
    145     Graphics object consisting of 3 graphics primitives
    146     sage: type(H)
    147     <class 'sage.plot.plot.Graphics'>
    148     sage: H[1]
    149     Polygon defined by 3 points
    150     sage: list(H[1])
    151     [(1.0, 2.0), (5.0, 6.0), (5.0, 0.0)]
    152     sage: H       # show it
    153 
    154 We can put text in a graph::
    155 
    156     sage: L = [[cos(pi*i/100)^3,sin(pi*i/100)] for i in range(200)]
    157     sage: p = line(L, rgbcolor=(1/4,1/8,3/4))
    158     sage: t = text('A Bulb', (1.5, 0.25))
    159     sage: x = text('x axis', (1.5,-0.2))
    160     sage: y = text('y axis', (0.4,0.9))
    161     sage: g = p+t+x+y
    162     sage: g.show(xmin=-1.5, xmax=2, ymin=-1, ymax=1)
    163 
    164 We plot the Riemann zeta function along the critical line and see
    165 the first few zeros::
    166 
    167     sage: i = CDF.0      # define i this way for maximum speed.
    168     sage: p1 = plot(lambda t: arg(zeta(0.5+t*i)), 1,27,rgbcolor=(0.8,0,0))
    169     sage: p2 = plot(lambda t: abs(zeta(0.5+t*i)), 1,27,color=hue(0.7))
    170     sage: print p1 + p2
    171     Graphics object consisting of 2 graphics primitives
    172     sage: p1 + p2    # display it
    173 
    174 Many concentric circles shrinking toward the origin::
    175 
    176     sage: show(sum(circle((i,0), i, hue=sin(i/10)) for i in [10,9.9,..,0]))
    177 
    178 Here is a pretty graph::
    179 
    180     sage: g = Graphics()
    181     sage: for i in range(60):
    182     ...    p = polygon([(i*cos(i),i*sin(i)), (0,i), (i,0)],\
    183     ...                color=hue(i/40+0.4), alpha=0.2)
    184     ...    g = g + p
    185     ...
    186     sage: g.show(dpi=200, axes=False)
    187 
    188 Another graph::
    189 
    190     sage: x = var('x')
    191     sage: P = plot(sin(x)/x, -4,4, color='blue') + \
    192     ...       plot(x*cos(x), -4,4, color='red') + \
    193     ...       plot(tan(x),-4,4, color='green')
    194     ...
    195     sage: P.show(ymin=-pi,ymax=pi)
    196 
    197 PYX EXAMPLES: These are some examples of plots similar to some of
    198 the plots in the PyX (http://pyx.sourceforge.net) documentation:
    199 
    200 Symbolline::
    201 
    202     sage: y(x) = x*sin(x^2)
    203     sage: v = [(x, y(x)) for x in [-3,-2.95,..,3]]
    204     sage: show(points(v, rgbcolor=(0.2,0.6, 0.1), pointsize=30) + plot(spline(v), -3.1, 3))
    205 
    206 Cycliclink::
    207 
    208     sage: x = var('x')
    209     sage: g1 = plot(cos(20*x)*exp(-2*x), 0, 1)
    210     sage: g2 = plot(2*exp(-30*x) - exp(-3*x), 0, 1)
    211     sage: show(graphics_array([g1, g2], 2, 1), xmin=0)
    212 
    213 Pi Axis::
    214 
    215     sage: g1 = plot(sin(x), 0, 2*pi)
    216     sage: g2 = plot(cos(x), 0, 2*pi, linestyle = "--")
    217     sage: (g1+g2).show(ticks=pi/6, tick_formatter=pi)  # show their sum, nicely formatted
    218 
    219 An illustration of integration::
    220 
    221     sage: f(x) = (x-3)*(x-5)*(x-7)+40
    222     sage: P = line([(2,0),(2,f(2))], color='black')
    223     sage: P += line([(8,0),(8,f(8))], color='black')
    224     sage: P += polygon([(2,0),(2,f(2))] + [(x, f(x)) for x in [2,2.1,..,8]] + [(8,0),(2,0)],  rgbcolor=(0.8,0.8,0.8),aspect_ratio='automatic')
    225     sage: P += text("$\\int_{a}^b f(x) dx$", (5, 20), fontsize=16, color='black')
    226     sage: P += plot(f, (1, 8.5), thickness=3)
    227     sage: P    # show the result
    228 
    229 
    230 
    231 NUMERICAL PLOTTING:
    232 
    233 Sage includes Matplotlib, which provides 2D plotting with an interface
    234 that is a likely very familiar to people doing numerical
    235 computation. For example,
    236 
    237 ::
    238 
    239     sage: from pylab import *
    240     sage: t = arange(0.0, 2.0, 0.01)
    241     sage: s = sin(2*pi*t)
    242     sage: P = plot(t, s, linewidth=1.0)
    243     sage: xl = xlabel('time (s)')
    244     sage: yl = ylabel('voltage (mV)')
    245     sage: t = title('About as simple as it gets, folks')
    246     sage: grid(True)
    247     sage: savefig(os.path.join(SAGE_TMP, 'sage.png'))
    248 
    249 We test that ``imshow`` works as well, verifying that
    250 Trac ticket 2900 is fixed in Matplotlib.
    251 
    252 ::
    253 
    254     sage: imshow([[(0,0,0)]])
    255     <matplotlib.image.AxesImage object at ...>
    256     sage: savefig(os.path.join(SAGE_TMP, 'foo.png'))
    257 
    258 Since the above overwrites many Sage plotting functions, we reset
    259 the state of Sage, so that the examples below work!
    260 
    261 ::
    262 
    263     sage: reset()
    264 
    265 See http://matplotlib.sourceforge.net for complete documentation
    266 about how to use Matplotlib.
    267 
    268 TESTS: We test dumping and loading a plot.
    269 
    270 ::
    271 
    272     sage: p = plot(sin(x), (x, 0,2*pi))
    273     sage: Q = loads(dumps(p))
    274 
    275 Verify that a clean sage startup does *not* import matplotlib::
    276 
    277     sage: os.system("sage -c \"if 'matplotlib' in sys.modules: sys.exit(1)\"")
    278     0
     4This file contains the definition of the classes :class:`Graphics` and
     5:class:`GraphicsArray`.  Usually, you don't create these classes directly
     6(although you can do it), you would use :func:`plot` or
     7:func:`graphics_array` instead.
    2798
    2809AUTHORS:
    28110
    282 - Alex Clemesha and William Stein (2006-04-10): initial version
    283 
    284 - David Joyner: examples
    285 
    286 - Alex Clemesha (2006-05-04) major update
    287 
    288 - William Stein (2006-05-29): fine tuning, bug fixes, better server
    289   integration
    290 
    291 - William Stein (2006-07-01): misc polish
    292 
    293 - Alex Clemesha (2006-09-29): added contour_plot, frame axes, misc
    294   polishing
    295 
    296 - Robert Miller (2006-10-30): tuning, NetworkX primitive
    297 
    298 - Alex Clemesha (2006-11-25): added plot_vector_field, matrix_plot,
    299   arrow, bar_chart, Axes class usage (see axes.py)
    300 
    301 - Bobby Moretti and William Stein (2008-01): Change plot to specify
    302   ranges using the (varname, min, max) notation.
    303 
    304 - William Stein (2008-01-19): raised the documentation coverage from a
    305   miserable 12 percent to a 'wopping' 35 percent, and fixed and
    306   clarified numerous small issues.
    307 
    308 - Jason Grout (2009-09-05): shifted axes and grid functionality over
    309   to matplotlib; fixed a number of smaller issues.
    310 
    311 - Jason Grout (2010-10): rewrote aspect ratio portions of the code
     11- Jeroen Demeyer (2012-04-19): split off this file from plot.py (:trac:`12857`)
    31212
    31313"""
    31414
    315 ############################################################################
    316 #  Copyright (C) 2006 Alex Clemesha <clemesha@gmail.com> and William Stein <wstein@gmail.com>
     15#*****************************************************************************
     16#       Copyright (C) 2006 Alex Clemesha <clemesha@gmail.com>
     17#       Copyright (C) 2006-2008 William Stein <wstein@gmail.com>
     18#       Copyright (C) 2010 Jason Grout
     19#
    31720#  Distributed under the terms of the GNU General Public License (GPL)
     21#  as published by the Free Software Foundation; either version 2 of
     22#  the License, or (at your option) any later version.
    31823#                  http://www.gnu.org/licenses/
    319 ############################################################################
     24#*****************************************************************************
    32025
    321 import os, types
    322 
     26import os
     27import sage.misc.misc
     28from sage.misc.html import html
    32329from sage.structure.sage_object import SageObject
    324 
    325 ## IMPORTANT: Do *not* import matplotlib at module scope.  It takes a
    326 ## surprisingly long time to initialize itself.  It's better if it is
    327 ## imported in functions, so it only gets started if it is actually
    328 ## going to be used.
     30from sage.misc.decorators import suboptions
     31from colors import rgbcolor
    32932
    33033ALLOWED_EXTENSIONS = ['.eps', '.pdf', '.png', '.ps', '.sobj', '.svg']
    331 #DEFAULT_FIGSIZE=(6, 3.70820393249937)
    33234DEFAULT_DPI = 100
    333 EMBEDDED_MODE = False
    334 DOCTEST_MODE = False
    335 import sage.misc.misc
    336 from sage.misc.misc import srange
    33735DOCTEST_MODE_FILE = os.path.join(sage.misc.misc.SAGE_TMP, 'test.png')
    33836SHOW_DEFAULT = True
    33937
     
    38179# GraphicsPrimitive.  See primitive.py
    38280do_verify = True
    38381
    384 from sage.misc.randstate import current_randstate #for plot adaptive refinement
    385 import os #for viewing and writing images
    386 from math import sin, cos, pi #for polar_plot
    387 from sage.structure.sage_object import SageObject
    388 
    389 from sage.ext.fast_eval import fast_float, fast_float_constant, is_fast_float
    390 
    391 from sage.misc.html import html
    392 
    393 from sage.misc.decorators import options, suboptions, rename_keyword
    394 
    395 from colors import hue, rainbow, rgbcolor, Color, to_mpl_color
    396 
    397 import operator
    398 
    399 ############### WARNING ###
    400 # Try not to import any matplotlib stuff here -- matplotlib is
    401 # slow to import.  (I did benchmarking and found that by not
    402 # importing here, and instead importing when needed below, that
    403 # Sage startup times are much improved.)  - William
    404 ###############
    405 
    40682def is_Graphics(x):
    40783    """
    40884    Return True if `x` is a Graphics object.
    40985   
    41086    EXAMPLES::
    41187   
    412         sage: from sage.plot.plot import is_Graphics
     88        sage: from sage.plot.graphics import is_Graphics
    41389        sage: is_Graphics(1)
    41490        False
    41591        sage: is_Graphics(disk((0.0, 0.0), 1, (0, pi/2)))
     
    443119
    444120    TESTS:
    445121
    446     From trac #4604, ensure Graphics can handle 3d objects::
     122    From :trac:`4604`, ensure Graphics can handle 3d objects::
    447123
    448124        sage: g = Graphics()
    449125        sage: g += sphere((1, 1, 1), 2)
     
    482158        -  ``ratio`` - a positive real number or 'automatic'
    483159       
    484160       
    485         EXAMPLES: We create a plot of the upper half of a circle, but it 
     161        EXAMPLES: We create a plot of the upper half of a circle, but it
    486162        doesn't look round because the aspect ratio is off::
    487163       
    488164            sage: P = plot(sqrt(1-x^2),(x,-1,1)); P
     
    598274
    599275        - ``borderaxespad`` - (default: None) float, length between the axes and the legend
    600276
    601         - ``back_color`` - (default: (0.9, 0.9, 0.9)) This parameter can be a string 
     277        - ``back_color`` - (default: (0.9, 0.9, 0.9)) This parameter can be a string
    602278          denoting a color or an RGB tuple. The string can be a color name
    603279          as in ('red', 'green', 'yellow', ...) or a floating point number
    604280          like '0.8' which gets expanded to (0.8, 0.8, 0.8). The
     
    611287
    612288        - ``labelspacing`` - (default: 0.02) float, vertical space between legend entries
    613289
    614         - ``loc`` - (default: 'best') May be a string, an integer or a tuple. String or 
     290        - ``loc`` - (default: 'best') May be a string, an integer or a tuple. String or
    615291              integer inputs must be one of the following:
    616292
    617293          - 0, 'best'
     
    636312
    637313          - 10, 'center'
    638314
    639           - Tuple arguments represent an absolute (x, y) position on the plot 
     315          - Tuple arguments represent an absolute (x, y) position on the plot
    640316            in axes coordinates (meaning from 0 to 1 in each direction).
    641317
    642318        - ``markerscale`` - (default: 0.6) float, how much to scale the markers in the legend.
    643319
    644320        - ``numpoints`` - (default: 2) integer, the number of points in the legend for line
    645321
    646         - ``borderpad`` - (default: 0.6) float, the fractional whitespace inside the legend border 
     322        - ``borderpad`` - (default: 0.6) float, the fractional whitespace inside the legend border
    647323          (between 0 and 1)
    648324
    649         - ``font_family`` - (default: 'sans-serif') string, one of 'serif', 'sans-serif', 
     325        - ``font_family`` - (default: 'sans-serif') string, one of 'serif', 'sans-serif',
    650326          'cursive', 'fantasy', 'monospace'
    651327
    652328        - ``font_style`` - (default: 'normal') string, one of 'normal', 'italic', 'oblique'
    653329
    654330        - ``font_variant`` - (default: 'normal') string, one of 'normal', 'small-caps'
    655331
    656         - ``font_weight`` - (default: 'medium') string, one of 'black', 'extra bold', 'bold', 
     332        - ``font_weight`` - (default: 'medium') string, one of 'black', 'extra bold', 'bold',
    657333          'semibold', 'medium', 'normal', 'light'
    658334
    659         - ``font_size`` - (default: 'medium') string, one of 'xx-small', 'x-small', 'small', 
     335        - ``font_size`` - (default: 'medium') string, one of 'xx-small', 'x-small', 'small',
    660336          'medium', 'large', 'x-large', 'xx-large' or an absolute font size (e.g. 12)
    661337
    662338        -  ``shadow`` - (default: False) boolean - draw a shadow behind the legend
     
    682358            sage: p.set_legend_options()['shadow']
    683359            True
    684360       
    685         To set the legend position to the center of the plot, all these 
     361        To set the legend position to the center of the plot, all these
    686362        methods are roughly equivalent::
    687363
    688364            sage: p.set_legend_options(loc='center'); p
     
    710386        .. warning::
    711387
    712388           Changing the dictionary returned by this function does not
    713            change the axes range for this object.  To do that, use the 
     389           change the axes range for this object.  To do that, use the
    714390           :meth:`set_axes_range` method.
    715391
    716392        EXAMPLES::
     
    13361012
    13371013    def plot(self, *args, **kwds):
    13381014        """
    1339         Draw a 2D plot of this graphics object, which just returns this 
     1015        Draw a 2D plot of this graphics object, which just returns this
    13401016        object since this is already a 2D graphics object.
    13411017       
    13421018        EXAMPLES::
     
    14211097                        figsize=None, fig_tight=True,
    14221098                        filename=None,
    14231099                        dpi=DEFAULT_DPI, axes=None, axes_labels=None,frame=False,
    1424                         fontsize=None, 
     1100                        fontsize=None,
    14251101                        aspect_ratio=None,
    14261102                        gridlines=None, gridlinesstyle=None,
    14271103                        vgridlinesstyle=None, hgridlinesstyle=None,transparent=False,
    14281104                        show_legend=None, legend_options={},
    1429                         axes_pad=.02, ticks_integer=False, 
     1105                        axes_pad=.02, ticks_integer=False,
    14301106                        ticks=None, tick_formatter=None)
    14311107
    1432     @suboptions('legend', numpoints=2, borderpad=0.6, markerscale=0.6, shadow=False, 
    1433                 labelspacing=0.02, handlelength=0.05, handletextpad=0.5, borderaxespad=None, 
    1434                 loc='best', font_size='medium', font_family='sans-serif', font_style='normal', 
    1435                 font_weight='medium', font_variant='normal', back_color=(0.9, 0.9, 0.9), 
     1108    @suboptions('legend', numpoints=2, borderpad=0.6, markerscale=0.6, shadow=False,
     1109                labelspacing=0.02, handlelength=0.05, handletextpad=0.5, borderaxespad=None,
     1110                loc='best', font_size='medium', font_family='sans-serif', font_style='normal',
     1111                font_weight='medium', font_variant='normal', back_color=(0.9, 0.9, 0.9),
    14361112                title=None, ncol=1, columnspacing=None, fancybox=False)
    14371113    def show(self, **kwds):
    14381114        """
     
    15181194          are integers (the ``ticks`` option, if specified, will
    15191195          override this)
    15201196
    1521         - ``ticks`` - A matplotlib locator for the major ticks, or 
     1197        - ``ticks`` - A matplotlib locator for the major ticks, or
    15221198          a number. There are several options.  For more information about
    1523           locators, type ``from matplotlib import ticker`` and then 
     1199          locators, type ``from matplotlib import ticker`` and then
    15241200          ``ticker?``.
    15251201
    15261202          - If this is a locator object, then it is the locator for
    1527             the horizontal axis.  A value of None means use the default 
     1203            the horizontal axis.  A value of None means use the default
    15281204            locator.
    15291205
    1530           - If it is a list of two locators, then the first is for the 
     1206          - If it is a list of two locators, then the first is for the
    15311207            horizontal axis and one for the vertical axis.  A value of
    1532             None means use the default locator (so a value of 
     1208            None means use the default locator (so a value of
    15331209            [None, my_locator] uses my_locator for the vertical axis and
    15341210            the default for the horizontal axis).
    15351211
    15361212          - If in either case above one of the entries is a number `m`
    1537             (something which can be coerced to a float), it will be 
     1213            (something which can be coerced to a float), it will be
    15381214            replaced by a MultipleLocator which places major ticks at
    15391215            integer multiples of `m`.  See examples.
    15401216
    1541           - If in either case above one of the entries is a list of 
    1542             numbers, it will be replaced by a FixedLocator which places 
     1217          - If in either case above one of the entries is a list of
     1218            numbers, it will be replaced by a FixedLocator which places
    15431219            ticks at the locations specified.  This includes the case of
    15441220            of the empty list, which will give no ticks.  See examples.
    15451221
    15461222        - ``tick_formatter`` - A matplotlib formatter for the major
    1547           ticks. There are several options.  For more information about 
    1548           formatters, type ``from matplotlib import ticker`` and then 
     1223          ticks. There are several options.  For more information about
     1224          formatters, type ``from matplotlib import ticker`` and then
    15491225          ``ticker?``.
    15501226
    15511227          If the value of this keyword is a single item, then this will
    15521228          give the formatting for the horizontal axis *only* (except for
    1553           the ``"latex"`` option).  If it is a list or tuple, the first 
     1229          the ``"latex"`` option).  If it is a list or tuple, the first
    15541230          is for the horizontal axis, the second for the vertical axis.
    15551231          The options are below:
    15561232
    1557           - If one of the entries is a formatter object, then it used. 
     1233          - If one of the entries is a formatter object, then it used.
    15581234            A value of None means to use the default locator (so using
    1559             ``tick_formatter=[None, my_formatter]`` uses my_formatter 
     1235            ``tick_formatter=[None, my_formatter]`` uses my_formatter
    15601236            for the vertical axis and the default for the horizontal axis).
    15611237
    1562           - If one of the entries is a symbolic constant such as `\pi`, 
    1563             `e`, or `sqrt(2)`, ticks will be formatted nicely at rational 
     1238          - If one of the entries is a symbolic constant such as `\pi`,
     1239            `e`, or `sqrt(2)`, ticks will be formatted nicely at rational
    15641240            multiples of this constant.
    15651241
    1566           .. warning:: This should only be used with the ``ticks`` option 
     1242          .. warning:: This should only be used with the ``ticks`` option
    15671243             using nice rational multiples of that constant!
    15681244
    1569           - If one of the entries is the string ``"latex"``, then the 
    1570             formatting will be nice typesetting of the ticks.  This is 
    1571             intended to be used when the tick locator for at least one of 
     1245          - If one of the entries is the string ``"latex"``, then the
     1246            formatting will be nice typesetting of the ticks.  This is
     1247            intended to be used when the tick locator for at least one of
    15721248            the axes is a list including some symbolic elements.  See examples.
    15731249
    15741250        - ``show_legend`` - (default: None) If True, show the legend
     
    15821258       
    15831259        You could also just make the picture larger by changing ``figsize``::
    15841260
    1585             sage: c.show(figsize=8, xmin=-1, xmax=3, ymin=-1, ymax=3)       
     1261            sage: c.show(figsize=8, xmin=-1, xmax=3, ymin=-1, ymax=3)
    15861262       
    15871263        You can turn off the drawing of the axes::
    15881264       
     
    16011277
    16021278            sage: plot(sin(x), (x, -4, 4), transparent=True)
    16031279
    1604         Add grid lines at the major ticks of the axes. 
     1280        Add grid lines at the major ticks of the axes.
    16051281       
    16061282        ::
    16071283       
     
    17341410
    17351411            sage: plot(1.5/(1+e^(-x)), (x, -10, 10)) # doesn't quite show value of inflection point
    17361412
    1737         :: 
     1413        ::
    17381414
    17391415            sage: plot(1.5/(1+e^(-x)), (x, -10, 10), ticks=[None, 1.5/4]) # It's right at f(x)=0.75!
    17401416
    1741         But be careful to leave enough room for at least two major ticks, so that 
     1417        But be careful to leave enough room for at least two major ticks, so that
    17421418        the user can tell what the scale is.
    17431419
    17441420        ::
     
    17481424            ...
    17491425            ValueError: Expand the range of the independent variable to allow two multiples of your tick locator (option `ticks`).
    17501426
    1751         We can also do custom formatting if you need it.  See above for full 
     1427        We can also do custom formatting if you need it.  See above for full
    17521428        details.
    17531429
    17541430        ::
     
    17771453        # This option should not be passed on to save().
    17781454        linkmode = kwds.pop('linkmode', False)
    17791455
    1780         if DOCTEST_MODE:
     1456        if sage.plot.plot.DOCTEST_MODE:
    17811457            kwds.pop('filename', None)
    17821458            self.save(DOCTEST_MODE_FILE, **kwds)
    1783         elif EMBEDDED_MODE:
    1784             kwds.setdefault('filename', sage.misc.misc.graphics_filename()) 
     1459        elif sage.plot.plot.EMBEDDED_MODE:
     1460            kwds.setdefault('filename', sage.misc.misc.graphics_filename())
    17851461            self.save(**kwds)
    17861462            if linkmode == True:
    17871463                return "<img src='cell://%s'>" % kwds['filename']
     
    18651541       
    18661542        .. warning::
    18671543
    1868            The returned dictionary is mutable, but changing it does 
     1544           The returned dictionary is mutable, but changing it does
    18691545           not change the xmin/xmax/ymin/ymax data.  The minmax data is a function
    18701546           of the primitives which make up this Graphics object.  To change the
    1871            range of the axes, call methods :meth:`xmin`, :meth:`xmax`, 
    1872            :meth:`ymin`, :meth:`ymax`, or :meth:`set_axes_range`. 
     1547           range of the axes, call methods :meth:`xmin`, :meth:`xmax`,
     1548           :meth:`ymin`, :meth:`ymax`, or :meth:`set_axes_range`.
    18731549
    18741550        EXAMPLES::
    18751551
     
    18921568            ymax = max(d['ymax'] for d in minmax_data)
    18931569            # check for NaN's: weird thing -- only way I know to check if a float
    18941570            # is a NaN is to check if it is not equal to itself.
    1895             if xmin!=xmin: 
     1571            if xmin!=xmin:
    18961572                xmin=0; sage.misc.misc.verbose("xmin was NaN (setting to 0)", level=0)
    18971573            if xmax!=xmax:
    18981574                xmax=0; sage.misc.misc.verbose("xmax was NaN (setting to 0)", level=0)
    1899             if ymin!=ymin: 
     1575            if ymin!=ymin:
    19001576                ymin=0; sage.misc.misc.verbose("ymin was NaN (setting to 0)", level=0)
    1901             if ymax!=ymax: 
     1577            if ymax!=ymax:
    19021578                ymax=0; sage.misc.misc.verbose("ymax was NaN (setting to 0)", level=0)
    19031579        else:
    19041580            xmin = xmax = ymin = ymax = 0
     
    19121588        return {'xmin':xmin, 'xmax':xmax, 'ymin':ymin, 'ymax':ymax}
    19131589       
    19141590    def matplotlib(self, filename=None,
    1915                    xmin=None, xmax=None, ymin=None, ymax=None, 
    1916                    figsize=None, figure=None, sub=None, 
     1591                   xmin=None, xmax=None, ymin=None, ymax=None,
     1592                   figsize=None, figure=None, sub=None,
    19171593                   axes=None, axes_labels=None, fontsize=None,
    1918                    frame=False, verify=True, 
     1594                   frame=False, verify=True,
    19191595                   aspect_ratio = None,
    19201596                   gridlines=None, gridlinesstyle=None,
    19211597                   vgridlinesstyle=None, hgridlinesstyle=None,
     
    19461622
    19471623        TESTS:
    19481624
    1949         We verify that #10291 is fixed::
     1625        We verify that :trac:`10291` is fixed::
    19501626
    19511627          sage: p = plot(sin(x), (x, -2*pi, 2*pi))
    19521628          sage: figure = p.matplotlib()
     
    22441920            # Make the zero tick labels disappear if the axes cross
    22451921            # inside the picture
    22461922            if xmiddle and ymiddle:
     1923                from sage.plot.plot import SelectiveFormatter
    22471924                subplot.yaxis.set_major_formatter(SelectiveFormatter(subplot.yaxis.get_major_formatter(),skip_values=[0]))
    22481925                subplot.xaxis.set_major_formatter(SelectiveFormatter(subplot.xaxis.get_major_formatter(),skip_values=[0]))
    22491926
     
    22611938            from matplotlib.ticker import AutoMinorLocator, FixedLocator, NullLocator
    22621939            if isinstance(x_locator, (NullLocator, FixedLocator)):
    22631940                subplot.xaxis.set_minor_locator(NullLocator())
    2264             else: 
     1941            else:
    22651942                subplot.xaxis.set_minor_locator(AutoMinorLocator())
    22661943            if isinstance(y_locator, (NullLocator, FixedLocator)):
    22671944                subplot.yaxis.set_minor_locator(NullLocator())
    2268             else: 
     1945            else:
    22691946                subplot.yaxis.set_minor_locator(AutoMinorLocator())
    22701947
    22711948            ticklabels=subplot.xaxis.get_majorticklabels() + \
     
    23962073        # This option makes the xlim and ylim limits not take effect
    23972074        # todo: figure out which limits were specified, and let the
    23982075        # free limits autoscale
    2399         #subplot.autoscale_view(tight=True) 
     2076        #subplot.autoscale_view(tight=True)
    24002077        return figure
    24012078       
    24022079    # ALLOWED_EXTENSIONS is the list of recognized formats.
    2403     # filename argument is written explicitly so that it can be used as a 
     2080    # filename argument is written explicitly so that it can be used as a
    24042081    # positional one, which is a very likely usage for this function.
    2405     @suboptions('legend', numpoints=2, borderpad=0.6, markerscale=0.6, shadow=False, 
    2406                 labelspacing=0.02, handlelength=0.05, handletextpad=0.5, borderaxespad=None, 
    2407                 loc='best', font_size='medium', font_family='sans-serif', font_style='normal', 
    2408                 font_weight='medium', font_variant='normal', back_color=(0.9, 0.9, 0.9), 
     2082    @suboptions('legend', numpoints=2, borderpad=0.6, markerscale=0.6, shadow=False,
     2083                labelspacing=0.02, handlelength=0.05, handletextpad=0.5, borderaxespad=None,
     2084                loc='best', font_size='medium', font_family='sans-serif', font_style='normal',
     2085                font_weight='medium', font_variant='normal', back_color=(0.9, 0.9, 0.9),
    24092086                title=None, ncol=1, columnspacing=None, fancybox=False)
    24102087    def save(self, filename=None, **kwds):
    24112088        r"""
     
    24352112       
    24362113        OUTPUT:
    24372114       
    2438         - none.       
     2115        - none.
    24392116
    24402117        EXAMPLES::
    24412118       
     
    24452122
    24462123        To make a figure bigger or smaller, use ``figsize``::
    24472124
    2448             sage: c.save(filename, figsize=5, xmin=-1, xmax=3, ymin=-1, ymax=3)       
     2125            sage: c.save(filename, figsize=5, xmin=-1, xmax=3, ymin=-1, ymax=3)
    24492126
    24502127        By default, the figure grows to include all of the graphics and text,
    24512128        so the final image may not be exactly the figure size you specified.
    2452         If you want a figure to be exactly a certain size, specify the keyword 
     2129        If you want a figure to be exactly a certain size, specify the keyword
    24532130        ``fig_tight=False``::
    24542131
    2455             sage: c.save(filename, figsize=[8,4], fig_tight=False, 
    2456             ...       xmin=-1, xmax=3, ymin=-1, ymax=3)       
     2132            sage: c.save(filename, figsize=[8,4], fig_tight=False,
     2133            ...       xmin=-1, xmax=3, ymin=-1, ymax=3)
    24572134       
    24582135        You can also pass extra options to the plot command instead of this
    24592136        method, e.g. ::
     
    24652142       
    24662143            sage: plot(x^2 - 5, (x, 0, 5), ymin=0)
    24672144           
    2468         (This test verifies that Trac #8632 is fixed.)
     2145        (This test verifies that :trac:`8632` is fixed.)
    24692146
    24702147        TESTS:
    24712148
     
    24752152            sage: P.set_legend_options(back_color=(1,0,0))
    24762153            sage: P.set_legend_options(loc=7)
    24772154            sage: filename=os.path.join(SAGE_TMP, 'test.png')
    2478             sage: P.save(filename) 
     2155            sage: P.save(filename)
    24792156
    2480         This plot should save with the frame shown, showing Trac #7524
    2481         is fixed (same issue as #7981 and #8632)::
     2157        This plot should save with the frame shown, showing :trac:`7524`
     2158        is fixed (same issue as :trac:`7981` and :trac:`8632`)::
    24822159
    2483             sage: var('x,y')               
     2160            sage: var('x,y')
    24842161            (x, y)
    24852162            sage: a = plot_vector_field((x,-y),(x,-1,1),(y,-1,1))
    24862163            sage: filename=os.path.join(SAGE_TMP, 'test2.png')
     
    25072184            SageObject.save(self, filename)
    25082185        else:
    25092186            figure = self.matplotlib(**options)
    2510             # You can output in PNG, PS, EPS, PDF, or SVG format, depending on the file extension. 
     2187            # You can output in PNG, PS, EPS, PDF, or SVG format, depending on the file extension.
    25112188            # matplotlib looks at the file extension to see what the renderer should be.
    25122189            # The default is FigureCanvasAgg for PNG's because this is by far the most
    25132190            # common type of files rendered, like in the notebook, for example.
     
    25282205                figure.savefig(filename, dpi=dpi,
    25292206                           transparent=transparent)
    25302207
    2531 #Currently not used - see comment immediately above about
    2532 #figure.canvas.mpl_connect('draw_event', pad_for_tick_labels)
    2533 # TODO - figure out how to use this, add documentation
    2534 #def pad_for_tick_labels(event):
    2535 #    import matplotlib.transforms as mtransforms
    2536 #    figure=event.canvas.figure
    2537 #    bboxes = []
    2538 #    for ax in figure.axes:
    2539 #        bbox = ax.xaxis.get_label().get_window_extent()
    2540 #        # the figure transform goes from relative coords->pixels and we
    2541 #        # want the inverse of that
    2542 #        bboxi = bbox.inverse_transformed(figure.transFigure)
    2543 #        bboxes.append(bboxi)
    2544 #
    2545 #        bbox = ax.yaxis.get_label().get_window_extent()
    2546 #        bboxi = bbox.inverse_transformed(figure.transFigure)
    2547 #        bboxes.append(bboxi)
    2548 #        for label in (ax.get_xticklabels()+ax.get_yticklabels() \
    2549 #                          + ax.get_xticklabels(minor=True) \
    2550 #                          +ax.get_yticklabels(minor=True)):
    2551 #            bbox = label.get_window_extent()
    2552 #            bboxi = bbox.inverse_transformed(figure.transFigure)
    2553 #            bboxes.append(bboxi)
    2554 #   
    2555 #    # this is the bbox that bounds all the bboxes, again in relative
    2556 #    # figure coords
    2557 #    bbox = mtransforms.Bbox.union(bboxes)
    2558 #    adjusted=adjust_figure_to_contain_bbox(figure,bbox)
    2559 #   
    2560 #    if adjusted:
    2561 #        figure.canvas.draw()
    2562 #    return False
    2563 #
    2564 #Currently not used - see comment above about
    2565 #figure.canvas.mpl_connect('draw_event', pad_for_tick_labels)
    2566 # TODO - figure out how to use this, add documentation
    2567 #def adjust_figure_to_contain_bbox(fig, bbox,pad=1.1):
    2568 #    """
    2569 #    For each amount we are over (in axes coordinates), we adjust by over*pad
    2570 #    to give ourselves a bit of padding.
    2571 #    """
    2572 #    left=fig.subplotpars.left
    2573 #    bottom=fig.subplotpars.bottom
    2574 #    right=fig.subplotpars.right
    2575 #    top=fig.subplotpars.top
    2576 #
    2577 #    adjusted=False
    2578 #    if bbox.xmin<0:
    2579 #        left-=bbox.xmin*pad
    2580 #        adjusted=True
    2581 #    if bbox.ymin<0:
    2582 #        bottom-=bbox.ymin*pad
    2583 #        adjusted=True
    2584 #    if bbox.xmax>1:
    2585 #        right-=(bbox.xmax-1)*pad
    2586 #        adjusted=True
    2587 #    if bbox.ymax>1:
    2588 #        top-=(bbox.ymax-1)*pad
    2589 #        adjusted=True
    2590 #
    2591 #    if left<right and bottom<top:   
    2592 #        fig.subplots_adjust(left=left, bottom=bottom, right=right, top=top)
    2593 #        return adjusted
    2594 #    else:
    2595 #        return False
    2596 
    2597 _SelectiveFormatterClass = None
    2598 
    2599 def SelectiveFormatter(formatter, skip_values):
    2600     """
    2601     This matplotlib formatter selectively omits some tick values and
    2602     passes the rest on to a specified formatter.
    2603 
    2604     EXAMPLES:
    2605    
    2606     This example is almost straight from a matplotlib example.
    2607    
    2608     ::
    2609 
    2610         sage: from sage.plot.plot import SelectiveFormatter
    2611         sage: import matplotlib.pyplot as plt
    2612         sage: import numpy
    2613         sage: fig=plt.figure()
    2614         sage: ax=fig.add_subplot(111)
    2615         sage: t = numpy.arange(0.0, 2.0, 0.01)
    2616         sage: s = numpy.sin(2*numpy.pi*t)
    2617         sage: p = ax.plot(t, s)
    2618         sage: formatter=SelectiveFormatter(ax.xaxis.get_major_formatter(),skip_values=[0,1])
    2619         sage: ax.xaxis.set_major_formatter(formatter)
    2620         sage: fig.savefig(os.path.join(SAGE_TMP, 'test.png'))
    2621     """
    2622     global _SelectiveFormatterClass
    2623     if _SelectiveFormatterClass is None:
    2624    
    2625         from matplotlib.ticker import Formatter
    2626 
    2627         class _SelectiveFormatterClass(Formatter):
    2628             def __init__(self, formatter,skip_values):
    2629                 """
    2630                 Initialize a SelectiveFormatter object.
    2631 
    2632                 INPUT:
    2633 
    2634                   - formatter -- the formatter object to which we should pass labels
    2635 
    2636                   - skip_values -- a list of values that we should skip when
    2637                     formatting the tick labels
    2638 
    2639                 EXAMPLES::
    2640 
    2641                     sage: from sage.plot.plot import SelectiveFormatter
    2642                     sage: import matplotlib.pyplot as plt
    2643                     sage: import numpy
    2644                     sage: fig=plt.figure()
    2645                     sage: ax=fig.add_subplot(111)
    2646                     sage: t = numpy.arange(0.0, 2.0, 0.01)
    2647                     sage: s = numpy.sin(2*numpy.pi*t)
    2648                     sage: line=ax.plot(t, s)
    2649                     sage: formatter=SelectiveFormatter(ax.xaxis.get_major_formatter(),skip_values=[0,1])
    2650                     sage: ax.xaxis.set_major_formatter(formatter)
    2651                     sage: fig.savefig(os.path.join(SAGE_TMP, 'test.png'))
    2652                 """
    2653                 self.formatter=formatter
    2654                 self.skip_values=skip_values
    2655             def set_locs(self, locs):
    2656                 """
    2657                 Set the locations for the ticks that are not skipped.
    2658                
    2659                 EXAMPLES::
    2660                     sage: from sage.plot.plot import SelectiveFormatter
    2661                     sage: import matplotlib.ticker
    2662                     sage: formatter=SelectiveFormatter(matplotlib.ticker.Formatter(),skip_values=[0,200])
    2663                     sage: formatter.set_locs([i*100 for i in range(10)])
    2664                 """
    2665                 self.formatter.set_locs([l for l in locs if l not in self.skip_values])
    2666             def __call__(self, x, *args, **kwds):
    2667                 """
    2668                 Return the format for tick val *x* at position *pos*
    2669 
    2670                 EXAMPLES::
    2671 
    2672                     sage: from sage.plot.plot import SelectiveFormatter
    2673                     sage: import matplotlib.ticker
    2674                     sage: formatter=SelectiveFormatter(matplotlib.ticker.FixedFormatter(['a','b']),skip_values=[0,2])
    2675                     sage: [formatter(i,1) for i in range(10)]
    2676                     ['', 'b', '', 'b', 'b', 'b', 'b', 'b', 'b', 'b']           
    2677                 """
    2678                 if x in self.skip_values:
    2679                     return ''
    2680                 else:
    2681                     return self.formatter(x, *args, **kwds)
    2682                    
    2683     return _SelectiveFormatterClass(formatter, skip_values)
    2684 
    2685 
    2686 def xydata_from_point_list(points):
    2687     r"""
    2688     Returns two lists (xdata, ydata), each coerced to a list of floats,
    2689     which correspond to the x-coordinates and the y-coordinates of the
    2690     points.
    2691    
    2692     The points parameter can be a list of 2-tuples or some object that
    2693     yields a list of one or two numbers.
    2694    
    2695     This function can potentially be very slow for large point sets.
    2696 
    2697     TESTS::
    2698 
    2699         sage: from sage.plot.plot import xydata_from_point_list
    2700         sage: xydata_from_point_list([CC(0), CC(1)])   # ticket 8082
    2701         ([0.0, 1.0], [0.0, 0.0])
    2702 
    2703     This function should work for anything than can be turned into a
    2704     list, such as iterators and such (see ticket #10478)::
    2705 
    2706         sage: xydata_from_point_list(iter([(0,0), (sqrt(3), 2)]))
    2707         ([0.0, 1.7320508075688772], [0.0, 2.0])
    2708         sage: xydata_from_point_list((x, x^2) for x in range(5))
    2709         ([0.0, 1.0, 2.0, 3.0, 4.0], [0.0, 1.0, 4.0, 9.0, 16.0])
    2710         sage: xydata_from_point_list(enumerate(prime_range(1, 15)))
    2711         ([0.0, 1.0, 2.0, 3.0, 4.0, 5.0], [2.0, 3.0, 5.0, 7.0, 11.0, 13.0])
    2712         sage: from itertools import izip; xydata_from_point_list(izip([2,3,5,7], [11, 13, 17, 19]))
    2713         ([2.0, 3.0, 5.0, 7.0], [11.0, 13.0, 17.0, 19.0])
    2714     """
    2715     from sage.rings.complex_number import ComplexNumber
    2716     if not isinstance(points, (list,tuple)):
    2717         points = list(points)
    2718         try:
    2719             points = [[float(z) for z in points]]
    2720         except TypeError:
    2721             pass
    2722     elif len(points)==2 and not isinstance(points[0],(list,tuple,ComplexNumber)):
    2723         try:
    2724             points = [[float(z) for z in points]]
    2725         except TypeError:
    2726             pass
    2727    
    2728     if len(points)>0 and len(list(points[0]))!=2:
    2729         raise ValueError, "points must have 2 coordinates in a 2d line"
    2730 
    2731    
    2732     xdata = [float(z[0]) for z in points]
    2733     ydata = [float(z[1]) for z in points]           
    2734 
    2735     return xdata, ydata
    2736 
    2737 @rename_keyword(color='rgbcolor')
    2738 @options(alpha=1, thickness=1, fill=False, fillcolor='automatic', fillalpha=0.5, rgbcolor=(0,0,1), plot_points=200,
    2739          adaptive_tolerance=0.01, adaptive_recursion=5, detect_poles = False, exclude = None, legend_label=None,
    2740          __original_opts=True, aspect_ratio='automatic')
    2741 def plot(funcs, *args, **kwds):
    2742     r"""
    2743     Use plot by writing
    2744    
    2745     ``plot(X, ...)``
    2746    
    2747     where `X` is a Sage object (or list of Sage objects) that
    2748     either is callable and returns numbers that can be coerced to
    2749     floats, or has a plot method that returns a
    2750     ``GraphicPrimitive`` object.
    2751    
    2752     There are many other specialized 2D plot commands available
    2753     in Sage, such as ``plot_slope_field``, as well as various
    2754     graphics primitives like Arrow; type ``sage.plot.plot?`` for
    2755     a current list.
    2756 
    2757     Type ``plot.options`` for a dictionary of the default
    2758     options for plots. You can change this to change the defaults for
    2759     all future plots. Use ``plot.reset()`` to reset to the
    2760     default options.
    2761    
    2762     PLOT OPTIONS:
    2763 
    2764     - ``plot_points`` - (default: 200) the minimal number of plot points.
    2765 
    2766     - ``adaptive_recursion`` - (default: 5) how many levels of recursion to go
    2767       before giving up when doing adaptive refinement.  Setting this to 0
    2768       disables adaptive refinement.
    2769 
    2770     - ``adaptive_tolerance`` - (default: 0.01) how large a difference should be
    2771       before the adaptive refinement code considers it significant.  See the
    2772       documentation further below for more information, starting at "the
    2773       algorithm used to insert".
    2774    
    2775     - ``xmin`` - starting x value
    2776 
    2777     - ``xmax`` - ending x value
    2778 
    2779     - ``color`` - an RGB tuple (r,g,b) with each of r,g,b between 0 and 1,
    2780       or a color name as a string (e.g., 'purple'), or an HTML color
    2781       such as '#aaff0b'.
    2782 
    2783     - ``detect_poles`` - (Default: False) If set to True poles are detected.
    2784       If set to "show" vertical asymptotes are drawn.
    2785 
    2786     - ``legend_label`` - the label for this item in the legend
    2787 
    2788     APPEARANCE OPTIONS:
    2789 
    2790     The following options affect the appearance of
    2791     the line through the points on the graph of `X` (these are
    2792     the same as for the line function):
    2793    
    2794     INPUT:
    2795    
    2796     - ``alpha`` - How transparent the line is
    2797 
    2798     - ``thickness`` - How thick the line is
    2799        
    2800     - ``rgbcolor`` - The color as an RGB tuple
    2801        
    2802     - ``hue`` - The color given as a hue
    2803 
    2804     Any MATPLOTLIB line option may also be passed in.  E.g.,
    2805    
    2806     - ``linestyle`` - The style of the line, which is one of
    2807        - ``"-"`` (solid) -- default
    2808        - ``"--"`` (dashed)
    2809        - ``"-."`` (dash dot)
    2810        - ``":"`` (dotted)
    2811        - ``"None"`` or ``" "`` or ``""`` (nothing)
    2812 
    2813        The linestyle can also be prefixed with a drawing style (e.g., ``"steps--"``)
    2814 
    2815        - ``"default"`` (connect the points with straight lines)
    2816        - ``"steps"`` or ``"steps-pre"`` (step function; horizontal
    2817          line is to the left of point)
    2818        - ``"steps-mid"`` (step function; points are in the middle of
    2819          horizontal lines)
    2820        - ``"steps-post"`` (step function; horizontal line is to the
    2821          right of point)
    2822        
    2823     - ``marker``  - The style of the markers, which is one of
    2824        - ``"None"`` or ``" "`` or ``""`` (nothing) -- default
    2825        - ``","`` (pixel), ``"."`` (point)
    2826        - ``"_"`` (horizontal line), ``"|"`` (vertical line)
    2827        - ``"o"`` (circle), ``"p"`` (pentagon), ``"s"`` (square), ``"x"`` (x), ``"+"`` (plus), ``"*"`` (star)
    2828        - ``"D"`` (diamond), ``"d"`` (thin diamond)
    2829        - ``"H"`` (hexagon), ``"h"`` (alternative hexagon)
    2830        - ``"<"`` (triangle left), ``">"`` (triangle right), ``"^"`` (triangle up), ``"v"`` (triangle down)
    2831        - ``"1"`` (tri down), ``"2"`` (tri up), ``"3"`` (tri left), ``"4"`` (tri right)
    2832        - ``0`` (tick left), ``1`` (tick right), ``2`` (tick up), ``3`` (tick down)
    2833        - ``4`` (caret left), ``5`` (caret right), ``6`` (caret up), ``7`` (caret down)
    2834        - ``"$...$"`` (math TeX string)
    2835        
    2836     - ``markersize`` - the size of the marker in points
    2837 
    2838     - ``markeredgecolor`` -- the color of the marker edge
    2839 
    2840     - ``markerfacecolor`` -- the color of the marker face
    2841 
    2842     - ``markeredgewidth`` - the size of the marker edge in points
    2843 
    2844     - ``exclude`` - (Default: None) values which are excluded from the plot range.
    2845       Either a list of real numbers, or an equation in one variable.
    2846 
    2847     FILLING OPTIONS:
    2848 
    2849     - ``fill`` - (Default: False) One of:
    2850                
    2851       - "axis" or True: Fill the area between the function and the x-axis.
    2852                
    2853       - "min": Fill the area between the function and its minimal value.
    2854      
    2855       - "max": Fill the area between the function and its maximal value.
    2856      
    2857       - a number c: Fill the area between the function and the horizontal line y = c.
    2858      
    2859       - a function g: Fill the area between the function that is plotted and g.
    2860      
    2861       - a dictionary d (only if a list of functions are plotted):
    2862         The keys of the dictionary should be integers.
    2863         The value of d[i] specifies the fill options for the i-th function in the list.
    2864         If d[i] == [j]: Fill the area between the i-th and the j-th function in the list.
    2865         (But if d[i] == j: Fill the area between the i-th function in the list and the
    2866         horizontal line y = j.)
    2867 
    2868     - ``fillcolor`` - (default: 'automatic') The color of the fill.
    2869       Either 'automatic' or a color.
    2870        
    2871     - ``fillalpha`` - (default: 0.5) How transparent the fill is.
    2872       A number between 0 and 1.
    2873 
    2874     Note that this function does NOT simply sample equally spaced
    2875     points between xmin and xmax. Instead it computes equally spaced
    2876     points and add small perturbations to them. This reduces the
    2877     possibility of, e.g., sampling sin only at multiples of
    2878     `2\pi`, which would yield a very misleading graph.
    2879    
    2880     EXAMPLES: We plot the sin function::
    2881    
    2882         sage: P = plot(sin, (0,10)); print P
    2883         Graphics object consisting of 1 graphics primitive
    2884         sage: len(P)     # number of graphics primitives
    2885         1
    2886         sage: len(P[0])  # how many points were computed (random)
    2887         225
    2888         sage: P          # render
    2889    
    2890     ::
    2891    
    2892         sage: P = plot(sin, (0,10), plot_points=10); print P
    2893         Graphics object consisting of 1 graphics primitive
    2894         sage: len(P[0])  # random output
    2895         32
    2896         sage: P          # render
    2897    
    2898     We plot with ``randomize=False``, which makes the initial sample points
    2899     evenly spaced (hence always the same). Adaptive plotting might
    2900     insert other points, however, unless ``adaptive_recursion=0``.
    2901    
    2902     ::
    2903    
    2904         sage: p=plot(1, (x,0,3), plot_points=4, randomize=False, adaptive_recursion=0)
    2905         sage: list(p[0])
    2906         [(0.0, 1.0), (1.0, 1.0), (2.0, 1.0), (3.0, 1.0)]
    2907    
    2908     Some colored functions::
    2909    
    2910         sage: plot(sin, 0, 10, color='purple')
    2911         sage: plot(sin, 0, 10, color='#ff00ff')
    2912    
    2913     We plot several functions together by passing a list of functions
    2914     as input::
    2915    
    2916         sage: plot([sin(n*x) for n in [1..4]], (0, pi))
    2917        
    2918     We can also build a plot step by step from an empty plot::
    2919    
    2920         sage: a = plot([]); a       # passing an empty list returns an empty plot (Graphics() object)
    2921         sage: a += plot(x**2); a    # append another plot
    2922         sage: a += plot(x**3); a    # append yet another plot
    2923        
    2924    
    2925     The function `\sin(1/x)` wiggles wildly near `0`.
    2926     Sage adapts to this and plots extra points near the origin.
    2927    
    2928     ::
    2929    
    2930         sage: plot(sin(1/x), (x, -1, 1))
    2931 
    2932     Via the matplotlib library, Sage makes it easy to tell whether
    2933     a graph is on both sides of both axes, as the axes only cross
    2934     if the origin is actually part of the viewing area::
    2935 
    2936         sage: plot(x^3,(x,0,2))  # this one has the origin
    2937         sage: plot(x^3,(x,1,2))  # this one does not
    2938 
    2939     Another thing to be aware of with axis labeling is that when
    2940     the labels have quite different orders of magnitude or are very
    2941     large, scientific notation (the `e` notation for powers of ten) is used::
    2942 
    2943         sage: plot(x^2,(x,480,500))  # this one has no scientific notation
    2944         sage: plot(x^2,(x,300,500))  # this one has scientific notation on y-axis
    2945 
    2946     You can put a legend with ``legend_label`` (the legend is only put
    2947     once in the case of multiple functions)::
    2948 
    2949         sage: plot(exp(x), 0, 2, legend_label='$e^x$')
    2950 
    2951     Sage understands TeX, so these all are slightly different, and you can choose
    2952     one based on your needs::
    2953 
    2954         sage: plot(sin, legend_label='sin')
    2955         sage: plot(sin, legend_label='$sin$')
    2956         sage: plot(sin, legend_label='$\sin$')
    2957 
    2958     Note that the independent variable may be omitted if there is no
    2959     ambiguity::
    2960    
    2961         sage: plot(sin(1/x), (-1, 1))
    2962    
    2963     The algorithm used to insert extra points is actually pretty
    2964     simple. On the picture drawn by the lines below::
    2965    
    2966         sage: p = plot(x^2, (-0.5, 1.4)) + line([(0,0), (1,1)], color='green')
    2967         sage: p += line([(0.5, 0.5), (0.5, 0.5^2)], color='purple')
    2968         sage: p += point(((0, 0), (0.5, 0.5), (0.5, 0.5^2), (1, 1)), color='red', pointsize=20)
    2969         sage: p += text('A', (-0.05, 0.1), color='red')
    2970         sage: p += text('B', (1.01, 1.1), color='red')
    2971         sage: p += text('C', (0.48, 0.57), color='red')
    2972         sage: p += text('D', (0.53, 0.18), color='red')
    2973         sage: p.show(axes=False, xmin=-0.5, xmax=1.4, ymin=0, ymax=2)
    2974    
    2975     You have the function (in blue) and its approximation (in green)
    2976     passing through the points A and B. The algorithm finds the
    2977     midpoint C of AB and computes the distance between C and D. If that
    2978     distance exceeds the ``adaptive_tolerance`` threshold (*relative* to
    2979     the size of the initial plot subintervals), the point D is
    2980     added to the curve.  If D is added to the curve, then the
    2981     algorithm is applied recursively to the points A and D, and D and
    2982     B. It is repeated ``adaptive_recursion`` times (5, by default).
    2983    
    2984     The actual sample points are slightly randomized, so the above
    2985     plots may look slightly different each time you draw them.
    2986    
    2987     We draw the graph of an elliptic curve as the union of graphs of 2
    2988     functions.
    2989    
    2990     ::
    2991    
    2992         sage: def h1(x): return abs(sqrt(x^3  - 1))
    2993         sage: def h2(x): return -abs(sqrt(x^3  - 1))
    2994         sage: P = plot([h1, h2], 1,4)
    2995         sage: P          # show the result
    2996    
    2997     We can also directly plot the elliptic curve::
    2998    
    2999         sage: E = EllipticCurve([0,-1])
    3000         sage: plot(E, (1, 4), color=hue(0.6))
    3001    
    3002     We can change the line style as well::
    3003    
    3004         sage: plot(sin(x), (x, 0, 10), linestyle='-.')
    3005    
    3006     If we have an empty linestyle and specify a marker, we can see the
    3007     points that are actually being plotted::
    3008 
    3009         sage: plot(sin(x), (x,0,10), plot_points=20, linestyle='', marker='.')
    3010 
    3011     The marker can be a TeX symbol as well::
    3012    
    3013         sage: plot(sin(x), (x,0,10), plot_points=20, linestyle='', marker=r'$\checkmark$')
    3014 
    3015     Sage currently ignores points that cannot be evaluated
    3016    
    3017     ::
    3018    
    3019         sage: set_verbose(-1)
    3020         sage: plot(-x*log(x), (x,0,1))  # this works fine since the failed endpoint is just skipped.
    3021         sage: set_verbose(0)
    3022    
    3023     This prints out a warning and plots where it can (we turn off the
    3024     warning by setting the verbose mode temporarily to -1.)
    3025    
    3026     ::
    3027    
    3028         sage: set_verbose(-1)
    3029         sage: plot(x^(1/3), (x,-1,1))
    3030         sage: set_verbose(0)
    3031 
    3032     To plot the negative real cube root, use something like the following::
    3033    
    3034         sage: plot(lambda x : RR(x).nth_root(3), (x,-1, 1))
    3035 
    3036     We can detect the poles of a function::
    3037 
    3038         sage: plot(gamma, (-3, 4), detect_poles = True).show(ymin = -5, ymax = 5)
    3039 
    3040     We draw the Gamma-Function with its poles highlighted::
    3041 
    3042         sage: plot(gamma, (-3, 4), detect_poles = 'show').show(ymin = -5, ymax = 5)
    3043 
    3044     The basic options for filling a plot::
    3045    
    3046         sage: p1 = plot(sin(x), -pi, pi, fill = 'axis')
    3047         sage: p2 = plot(sin(x), -pi, pi, fill = 'min')
    3048         sage: p3 = plot(sin(x), -pi, pi, fill = 'max')
    3049         sage: p4 = plot(sin(x), -pi, pi, fill = 0.5)
    3050         sage: graphics_array([[p1, p2], [p3, p4]]).show(frame=True, axes=False)
    3051 
    3052         sage: plot([sin(x), cos(2*x)*sin(4*x)], -pi, pi, fill = {0: 1}, fillcolor = 'red', fillalpha = 1)
    3053 
    3054     A example about the growth of prime numbers::
    3055    
    3056         sage: plot(1.13*log(x), 1, 100, fill = lambda x: nth_prime(x)/floor(x), fillcolor = 'red')
    3057 
    3058     Fill the area between a function and its asymptote::
    3059    
    3060         sage: f = (2*x^3+2*x-1)/((x-2)*(x+1))
    3061         sage: plot([f, 2*x+2], -7,7, fill = {0: [1]}, fillcolor='#ccc').show(ymin=-20, ymax=20)
    3062 
    3063     Fill the area between a list of functions and the x-axis::
    3064 
    3065         sage: def b(n): return lambda x: bessel_J(n, x)
    3066         sage: plot([b(n) for n in [1..5]], 0, 20, fill = 'axis')
    3067 
    3068     Note that to fill between the ith and jth functions, you
    3069     must use dictionary key-value pairs i:[j]; key-value pairs
    3070     like i:j will fill between the ith function and the line y=j::
    3071 
    3072         sage: def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1)
    3073         sage: plot([b(c) for c in [1..5]], 0, 40, fill = dict([(i, [i+1]) for i in [0..3]]))
    3074         sage: plot([b(c) for c in [1..5]], 0, 40, fill = dict([(i, i+1) for i in [0..3]]))
    3075    
    3076     Extra options will get passed on to show(), as long as they are valid::
    3077 
    3078         sage: plot(sin(x^2), (x, -3, 3), axes_labels=['$x$','$y$']) # These labels will be nicely typeset
    3079         sage: plot(sin(x^2), (x, -3, 3), axes_labels=['x','y']) # These will not
    3080 
    3081     ::
    3082 
    3083         sage: plot(sin(x^2), (x, -3, 3), figsize=[8,2])
    3084         sage: plot(sin(x^2), (x, -3, 3)).show(figsize=[8,2]) # These are equivalent
    3085 
    3086     This includes options for custom ticks and formatting.  See documentation
    3087     for :meth:`show` for more details.
    3088 
    3089     ::
    3090 
    3091         sage: plot(sin(pi*x), (x, -8, 8), ticks=[[-7,-3,0,3,7],[-1/2,0,1/2]])
    3092         sage: plot(2*x+1,(x,0,5),ticks=[[0,1,e,pi,sqrt(20)],2],tick_formatter="latex")
    3093 
    3094     This is particularly useful when setting custom ticks in multiples of `pi`.
    3095 
    3096     ::
    3097 
    3098         sage: plot(sin(x),(x,0,2*pi),ticks=pi/3,tick_formatter=pi)
    3099 
    3100     A example with excluded values::
    3101 
    3102         sage: plot(floor(x), (x, 1, 10), exclude = [1..10])
    3103 
    3104     We exclude all points where prime_pi makes a jump::
    3105 
    3106         sage: jumps = [n for n in [1..100] if prime_pi(n) != prime_pi(n-1)]
    3107         sage: plot(lambda x: prime_pi(x), (x, 1, 100), exclude = jumps)
    3108 
    3109     Excluded points can also be given by an equation::
    3110 
    3111         sage: g(x) = x^2-2*x-2
    3112         sage: plot(1/g(x), (x, -3, 4), exclude = g(x) == 0, ymin = -5, ymax = 5)
    3113 
    3114     ``exclude`` and ``detect_poles`` can be used together::
    3115 
    3116         sage: f(x) = (floor(x)+0.5) / (1-(x-0.5)^2)
    3117         sage: plot(f, (x, -3.5, 3.5), detect_poles = 'show', exclude = [-3..3], ymin = -5, ymax = 5)
    3118 
    3119     TESTS:
    3120    
    3121     We do not randomize the endpoints::
    3122    
    3123         sage: p = plot(x, (x,-1,1))
    3124         sage: p[0].xdata[0] == -1
    3125         True
    3126         sage: p[0].xdata[-1] == 1
    3127         True
    3128    
    3129     We check to make sure that the x/y min/max data get set correctly
    3130     when there are multiple functions.
    3131    
    3132     ::
    3133    
    3134         sage: d = plot([sin(x), cos(x)], 100, 120).get_minmax_data()
    3135         sage: d['xmin']
    3136         100.0
    3137         sage: d['xmax']
    3138         120.0   
    3139    
    3140     We check various combinations of tuples and functions, ending with
    3141     tests that lambda functions work properly with explicit variable
    3142     declaration, without a tuple.
    3143    
    3144     ::
    3145    
    3146         sage: p = plot(lambda x: x,(x,-1,1))
    3147         sage: p = plot(lambda x: x,-1,1)
    3148         sage: p = plot(x,x,-1,1)
    3149         sage: p = plot(x,-1,1)
    3150         sage: p = plot(x^2,x,-1,1)
    3151         sage: p = plot(x^2,xmin=-1,xmax=2)
    3152         sage: p = plot(lambda x: x,x,-1,1)
    3153         sage: p = plot(lambda x: x^2,x,-1,1)
    3154         sage: p = plot(lambda x: 1/x,x,-1,1)
    3155         sage: f(x) = sin(x+3)-.1*x^3
    3156         sage: p = plot(lambda x: f(x),x,-1,1)
    3157    
    3158     We check to handle cases where the function gets evaluated at a
    3159     point which causes an 'inf' or '-inf' result to be produced.
    3160    
    3161     ::
    3162    
    3163         sage: p = plot(1/x, 0, 1)
    3164         sage: p = plot(-1/x, 0, 1)
    3165    
    3166     Bad options now give better errors::
    3167 
    3168         sage: P = plot(sin(1/x), (x,-1,3), foo=10)
    3169         Traceback (most recent call last):
    3170         ...
    3171         RuntimeError: Error in line(): option 'foo' not valid.
    3172         sage: P = plot(x, (x,1,1)) # trac ticket #11753
    3173         Traceback (most recent call last):
    3174         ...
    3175         ValueError: plot start point and end point must be different
    3176 
    3177     We test that we can plot `f(x)=x` (see Trac 10246)::
    3178 
    3179         sage: f(x)=x; f
    3180         x |--> x
    3181         sage: plot(f,(x,-1,1))
    3182     """
    3183     G_kwds = Graphics._extract_kwds_for_show(kwds, ignore=['xmin', 'xmax'])
    3184 
    3185     original_opts = kwds.pop('__original_opts', {})
    3186     do_show = kwds.pop('show',False)
    3187 
    3188     from sage.structure.element import is_Vector
    3189     if kwds.get('parametric',False) and is_Vector(funcs):
    3190         funcs = tuple(funcs)
    3191 
    3192 
    3193     if hasattr(funcs, 'plot'):
    3194         G = funcs.plot(*args, **original_opts)
    3195     # if we are using the generic plotting method
    3196     else:
    3197         n = len(args)
    3198         # if there are no extra args, try to get xmin,xmax from
    3199         # keyword arguments or pick some silly default
    3200         if n == 0:
    3201             xmin = kwds.pop('xmin', -1)
    3202             xmax = kwds.pop('xmax', 1)
    3203             G = _plot(funcs, (xmin, xmax), **kwds)
    3204 
    3205         # if there is one extra arg, then it had better be a tuple
    3206         elif n == 1:
    3207             G = _plot(funcs, *args, **kwds)
    3208         elif n == 2:
    3209         # if there are two extra args, then pull them out and pass them as a tuple
    3210             xmin = args[0]
    3211             xmax = args[1]
    3212             args = args[2:]
    3213             G = _plot(funcs, (xmin, xmax), *args, **kwds)
    3214         elif n == 3:
    3215         # if there are three extra args, then pull them out and pass them as a tuple
    3216             var = args[0]
    3217             xmin = args[1]
    3218             xmax = args[2]
    3219             args = args[3:]
    3220             G = _plot(funcs, (var, xmin, xmax), *args, **kwds)
    3221         elif ('xmin' in kwds) or ('xmax' in kwds):
    3222             xmin = kwds.pop('xmin', -1)
    3223             xmax = kwds.pop('xmax', 1)
    3224             G = _plot(funcs, (xmin, xmax), *args, **kwds)
    3225             pass
    3226         else:
    3227             sage.misc.misc.verbose("there were %s extra arguments (besides %s)" % (n, funcs), level=0)
    3228 
    3229     G._set_extra_kwds(G_kwds)
    3230     if do_show:
    3231         G.show()
    3232     return G
    3233 
    3234 
    3235 def _plot(funcs, xrange, parametric=False,
    3236               polar=False, fill=False, label='', randomize=True, **options):
    3237     """
    3238     Internal function which does the actual plotting.
    3239 
    3240     INPUT:
    3241 
    3242     - ``funcs`` - function or list of functions to be plotted
    3243     - ``xrange`` - two or three tuple of [input variable], min and max
    3244     - ``parametric`` - (default: False) a boolean for whether
    3245       this is a parametric plot
    3246     - ``polar`` - (default: False) a boolean for whether
    3247       this is a polar plot
    3248     - ``fill`` - (default: False) an input for whether
    3249       this plot is filled
    3250     - ``randomize`` - (default: True) a boolean for whether
    3251       to use random plot points
    3252 
    3253     The following option is deprecated in favor of ``legend_label``:
    3254 
    3255     - ``label`` - (default: '') a string for the label
    3256 
    3257     All other usual plot options are also accepted, and a number
    3258     are required (see the example below) which are normally passed
    3259     through the options decorator to :func:`plot`.
    3260 
    3261     OUTPUT:
    3262 
    3263     - A ``Graphics`` object
    3264 
    3265     EXAMPLES::
    3266 
    3267     See :func:`plot` for many, many implicit examples.
    3268     Here is an explicit one::
    3269 
    3270         sage: from sage.plot.plot import _plot
    3271         sage: P = _plot(e^(-x^2),(-3,3),fill=True,color='red',plot_points=50,adaptive_tolerance=2,adaptive_recursion=True,exclude=None)
    3272         sage: P.show(aspect_ratio='automatic')
    3273     """
    3274     from sage.plot.misc import setup_for_eval_on_grid
    3275     if funcs == []:
    3276         return Graphics()
    3277     funcs, ranges = setup_for_eval_on_grid(funcs, [xrange], options['plot_points'])
    3278     xmin, xmax, delta = ranges[0]
    3279     xrange=ranges[0][:2]
    3280     #parametric_plot will be a list or tuple of two functions (f,g)
    3281     #and will plotted as (f(x), g(x)) for all x in the given range
    3282     if parametric:
    3283         f, g = funcs
    3284     #or we have only a single function to be plotted:
    3285     else:
    3286         f = funcs
    3287 
    3288     #check to see if funcs is a list of functions that will
    3289     #be all plotted together.
    3290     if isinstance(funcs, (list, tuple)) and not parametric:
    3291         rainbow_colors = rainbow(len(funcs))
    3292 
    3293         G = Graphics()
    3294         for i, h in enumerate(funcs):
    3295             if isinstance(fill, dict):
    3296                 if i in fill:
    3297                     fill_entry = fill[i]
    3298                     if isinstance(fill_entry, list):
    3299                         if fill_entry[0] < len(funcs):
    3300                             fill_temp = funcs[fill_entry[0]]
    3301                         else:
    3302                             fill_temp = None
    3303                     else:
    3304                         fill_temp = fill_entry
    3305                 else:
    3306                     fill_temp = None
    3307             else:
    3308                 fill_temp = fill
    3309 
    3310             options_temp = options.copy()
    3311             fillcolor_temp = options_temp.pop('fillcolor', 'automatic')
    3312             legend_label=options_temp.pop('legend_label', None) # legend_label popped so the label isn't repeated for nothing
    3313             if fillcolor_temp == 'automatic':
    3314                 fillcolor_temp = rainbow_colors[i]
    3315 
    3316             G += plot(h, xrange, polar = polar, fill = fill_temp, \
    3317                       fillcolor = fillcolor_temp, **options_temp)
    3318         return G
    3319 
    3320     adaptive_tolerance = options.pop('adaptive_tolerance')
    3321     adaptive_recursion = options.pop('adaptive_recursion')
    3322     plot_points = int(options.pop('plot_points'))
    3323 
    3324     exclude = options.pop('exclude')
    3325     if exclude is not None:
    3326         from sage.symbolic.expression import Expression
    3327         if isinstance(exclude, Expression) and exclude.is_relational() == True:
    3328             if len(exclude.variables()) > 1:
    3329                 raise ValueError('exclude has to be an equation of only one variable')
    3330             v = exclude.variables()[0]
    3331             points = [e.right() for e in exclude.solve(v) if e.left() == v and (v not in e.right().variables())]
    3332             # We are only interested in real solutions
    3333             exclude = []
    3334             for x in points:
    3335                 try:
    3336                     exclude.append(float(x))
    3337                 except TypeError:
    3338                     pass
    3339 
    3340         if isinstance(exclude, (list, tuple)):
    3341             exclude = sorted(exclude)
    3342             # We make sure that points plot points close to the excluded points are computed
    3343             epsilon = 0.001*(xmax - xmin)
    3344             initial_points = reduce(lambda a,b: a+b, [[x - epsilon, x + epsilon] for x in exclude], [])
    3345             data = generate_plot_points(f, xrange, plot_points, adaptive_tolerance, adaptive_recursion, randomize, initial_points)
    3346         else:
    3347             raise ValueError('exclude needs to be a list of numbers or an equation')
    3348 
    3349         if exclude == []:
    3350             exclude = None
    3351     else:
    3352         data = generate_plot_points(f, xrange, plot_points, adaptive_tolerance, adaptive_recursion, randomize)
    3353 
    3354     if parametric:
    3355         # We need the original x-values to be able to exclude points in parametric plots
    3356         exclude_data = data
    3357         data = [(fdata, g(x)) for x, fdata in data]
    3358 
    3359     G = Graphics()
    3360 
    3361     fillcolor = options.pop('fillcolor', 'automatic')
    3362     fillalpha = options.pop('fillalpha', 0.5)
    3363 
    3364     # TODO: Use matplotlib's fill and fill_between commands.
    3365     if fill is not False and fill is not None:
    3366         if parametric:
    3367             filldata = data
    3368         else:
    3369             if fill == 'axis' or fill is True:
    3370                 base_level = 0
    3371             elif fill == 'min':
    3372                 base_level = min(t[1] for t in data)
    3373             elif fill == 'max':
    3374                 base_level = max(t[1] for t in data)
    3375             elif hasattr(fill, '__call__'):
    3376                 if fill == max or fill == min:
    3377                     if fill == max:
    3378                         fstr = 'max'
    3379                     else:
    3380                         fstr = 'min'
    3381                     msg = "WARNING: You use the built-in function %s for filling. You probably wanted the string '%s'." % (fstr, fstr)
    3382                     sage.misc.misc.verbose(msg, level=0)
    3383                 if not is_fast_float(fill):
    3384                     fill_f = fast_float(fill, expect_one_var=True)
    3385                 else:
    3386                     fill_f = fill
    3387 
    3388                 filldata = generate_plot_points(fill_f, xrange, plot_points, adaptive_tolerance, \
    3389                                                 adaptive_recursion, randomize)
    3390                 filldata.reverse()
    3391                 filldata += data
    3392             else:
    3393                 try:
    3394                     base_level = float(fill)
    3395                 except TypeError:
    3396                     base_level = 0
    3397 
    3398             if not hasattr(fill, '__call__') and polar:
    3399                 filldata = generate_plot_points(lambda x: base_level, xrange, plot_points, adaptive_tolerance, \
    3400                                                 adaptive_recursion, randomize)
    3401                 filldata.reverse()
    3402                 filldata += data
    3403             if not hasattr(fill, '__call__') and not polar:
    3404                 filldata = [(data[0][0], base_level)] + data + [(data[-1][0], base_level)]
    3405 
    3406         if fillcolor == 'automatic':
    3407             fillcolor = (0.5, 0.5, 0.5)
    3408         fill_options = {}
    3409         fill_options['rgbcolor'] = fillcolor
    3410         fill_options['alpha'] = fillalpha
    3411         fill_options['thickness'] = 0
    3412         if polar:
    3413             filldata = [(y*cos(x), y*sin(x)) for x, y in filldata]
    3414         G += polygon(filldata, **fill_options)
    3415 
    3416     # We need the original data to be able to exclude points in polar plots
    3417     if not parametric:
    3418         exclude_data = data
    3419     if polar:
    3420         data = [(y*cos(x), y*sin(x)) for x, y in data]
    3421 
    3422     from sage.plot.all import line, text
    3423 
    3424     detect_poles = options.pop('detect_poles', False)
    3425     if exclude is not None or detect_poles != False:
    3426         start_index = 0
    3427         # setup for pole detection
    3428         from sage.rings.all import RDF
    3429         epsilon = 0.0001
    3430         pole_options = {}
    3431         pole_options['linestyle'] = '--'
    3432         pole_options['thickness'] = 1
    3433         pole_options['rgbcolor'] = '#ccc'
    3434 
    3435         # setup for exclusion points
    3436         exclusion_point = 0
    3437         if exclude is not None:
    3438             exclude.reverse()
    3439             exclusion_point = exclude.pop()
    3440 
    3441         for i in range(len(data)-1):
    3442             x0, y0 = exclude_data[i]
    3443             x1, y1 = exclude_data[i+1]
    3444             # detect poles
    3445             if (not (polar or parametric)) and detect_poles != False \
    3446                and ((y1 > 0 and y0 < 0) or (y1 < 0 and y0 > 0)):
    3447                 # calculate the slope of the line segment
    3448                 dy = abs(y1-y0)
    3449                 dx = x1 - x0
    3450                 alpha = (RDF(dy)/RDF(dx)).arctan()
    3451                 if alpha >= RDF(pi/2) - epsilon:
    3452                     G += line(data[start_index:i], **options)
    3453                     if detect_poles == 'show':
    3454                         # draw a vertical asymptote
    3455                         G += line([(x0, y0), (x1, y1)], **pole_options)
    3456                     start_index = i+2
    3457 
    3458             # exclude points
    3459             if exclude is not None and (x0 <= exclusion_point <= x1):
    3460                 G += line(data[start_index:i], **options)
    3461                 start_index = i + 2
    3462                 try:
    3463                     exclusion_point = exclude.pop()
    3464                 except IndexError:
    3465                     # all excluded points were considered
    3466                     exclude = None
    3467 
    3468         G += line(data[start_index:], **options)
    3469     else:
    3470         G += line(data, **options)
    3471 
    3472     # Label?
    3473     if label:
    3474         sage.misc.misc.deprecation("Consider using legend_label instead")
    3475         label = '  '+str(label)
    3476         G += text(label, data[-1], horizontal_alignment='left',
    3477                   vertical_alignment='center')
    3478 
    3479     return G
    3480 
    3481 
    3482 
    3483 
    3484 ########## misc functions ###################
    3485 
    3486 @options(aspect_ratio=1.0)
    3487 def parametric_plot(funcs, *args, **kwargs):
    3488     r"""
    3489     Plot a parametric curve or surface in 2d or 3d.
    3490 
    3491     :func:`parametric_plot` takes two or three functions as a
    3492     list or a tuple and makes a plot with the first function giving the
    3493     `x` coordinates, the second function giving the `y`
    3494     coordinates, and the third function (if present) giving the
    3495     `z` coordinates.
    3496 
    3497     In the 2d case, :func:`parametric_plot` is equivalent to the :func:`plot` command
    3498     with the option ``parametric=True``.  In the 3d case, :func:`parametric_plot`
    3499     is equivalent to :func:`~sage.plot.plot3d.parametric_plot3d.parametric_plot3d`.
    3500     See each of these functions for more help and examples.
    3501 
    3502     INPUT:
    3503    
    3504    
    3505     -  ``funcs`` - 2 or 3-tuple of functions, or a vector of dimension 2 or 3.
    3506    
    3507     -  ``other options`` - passed to :func:`plot` or :func:`~sage.plot.plot3d.parametric_plot3d.parametric_plot3d`
    3508    
    3509    
    3510     EXAMPLES: We draw some 2d parametric plots.  Note that the default aspect ratio
    3511     is 1, so that circles look like circles. ::
    3512    
    3513         sage: t = var('t')
    3514         sage: parametric_plot( (cos(t), sin(t)), (t, 0, 2*pi))
    3515 
    3516     ::
    3517 
    3518         sage: parametric_plot( (sin(t), sin(2*t)), (t, 0, 2*pi), color=hue(0.6) )
    3519 
    3520     ::
    3521 
    3522         sage: parametric_plot((1, t), (t, 0, 4))
    3523 
    3524     Note that in parametric_plot, there is only fill or no fill.
    3525    
    3526     ::
    3527    
    3528         sage: parametric_plot((t, t^2), (t, -4, 4), fill = True)
    3529 
    3530     A filled Hypotrochoid::
    3531    
    3532         sage: parametric_plot([cos(x) + 2 * cos(x/4), sin(x) - 2 * sin(x/4)], (x,0, 8*pi), fill = True)
    3533    
    3534         sage: parametric_plot( (5*cos(x), 5*sin(x), x), (x,-12, 12), plot_points=150, color="red")
    3535 
    3536         sage: y=var('y')
    3537         sage: parametric_plot( (5*cos(x), x*y, cos(x*y)), (x, -4,4), (y,-4,4))
    3538        
    3539         sage: t=var('t')
    3540         sage: parametric_plot( vector((sin(t), sin(2*t))), (t, 0, 2*pi), color='green')
    3541         sage: parametric_plot( vector([t, t+1, t^2]), (t, 0, 1))
    3542 
    3543     TESTS::
    3544    
    3545         sage: parametric_plot((x, t^2), (x, -4, 4))
    3546         Traceback (most recent call last):
    3547         ...
    3548         ValueError: there are more variables than variable ranges
    3549    
    3550         sage: parametric_plot((1, x+t), (x, -4, 4))
    3551         Traceback (most recent call last):
    3552         ...
    3553         ValueError: there are more variables than variable ranges
    3554 
    3555         sage: parametric_plot((-t, x+t), (x, -4, 4))
    3556         Traceback (most recent call last):
    3557         ...
    3558         ValueError: there are more variables than variable ranges
    3559 
    3560         sage: parametric_plot((1, x+t, y), (x, -4, 4), (t, -4, 4))
    3561         Traceback (most recent call last):
    3562         ...
    3563         ValueError: there are more variables than variable ranges
    3564 
    3565         sage: parametric_plot((1, x, y), 0, 4)
    3566         Traceback (most recent call last):
    3567         ...
    3568         ValueError: there are more variables than variable ranges
    3569     """
    3570     num_ranges=0
    3571     for i in args:
    3572         if isinstance(i, (list, tuple)):
    3573             num_ranges+=1
    3574         else:
    3575             break
    3576 
    3577     if num_ranges==0 and len(args)>=2:
    3578         from sage.misc.misc import deprecation
    3579         deprecation("variable ranges to parametric_plot must be given as tuples, like (2,4) or (t,2,3)")
    3580         args=tuple(args)
    3581         num_ranges=1
    3582 
    3583     num_funcs = len(funcs)
    3584 
    3585     num_vars=len(sage.plot.misc.unify_arguments(funcs)[0])
    3586     if num_vars>num_ranges:
    3587         raise ValueError, "there are more variables than variable ranges"
    3588 
    3589     if num_funcs == 2 and num_ranges == 1:
    3590         kwargs['parametric'] = True                   
    3591         return plot(funcs, *args, **kwargs)
    3592     elif (num_funcs == 3 and num_ranges <= 2):
    3593         return sage.plot.plot3d.parametric_plot3d.parametric_plot3d(funcs, *args, **kwargs)
    3594     else:
    3595         raise ValueError, "the number of functions and the number of variable ranges is not a supported combination for a 2d or 3d parametric plots"
    3596 
    3597 @options(aspect_ratio=1.0)
    3598 def polar_plot(funcs, *args, **kwds):
    3599     r"""
    3600     ``polar_plot`` takes a single function or a list or
    3601     tuple of functions and plots them with polar coordinates in the given
    3602     domain.
    3603 
    3604     This function is equivalent to the :func:`plot` command with the options
    3605     ``polar=True`` and ``aspect_ratio=1``. For more help on options,
    3606     see the documentation for :func:`plot`.
    3607 
    3608     INPUT:
    3609 
    3610     - ``funcs`` - a function
    3611     - other options are passed to plot
    3612 
    3613     EXAMPLES:
    3614    
    3615     Here is a blue 8-leaved petal::
    3616    
    3617         sage: polar_plot(sin(5*x)^2, (x, 0, 2*pi), color='blue')
    3618    
    3619     A red figure-8::
    3620    
    3621         sage: polar_plot(abs(sqrt(1 - sin(x)^2)), (x, 0, 2*pi), color='red')
    3622    
    3623     A green limacon of Pascal::
    3624    
    3625         sage: polar_plot(2 + 2*cos(x), (x, 0, 2*pi), color=hue(0.3))
    3626 
    3627     Several polar plots::
    3628    
    3629         sage: polar_plot([2*sin(x), 2*cos(x)], (x, 0, 2*pi))
    3630 
    3631     A filled spiral::
    3632    
    3633         sage: polar_plot(sqrt, 0, 2 * pi, fill = True)
    3634 
    3635     Fill the area between two functions::
    3636    
    3637         sage: polar_plot(cos(4*x) + 1.5, 0, 2*pi, fill=0.5 * cos(4*x) + 2.5, fillcolor='orange')
    3638 
    3639     Fill the area between several spirals::
    3640    
    3641         sage: polar_plot([(1.2+k*0.2)*log(x) for k in range(6)], 1, 3 * pi, fill = {0: [1], 2: [3], 4: [5]})
    3642 
    3643     Exclude points at discontinuities::
    3644 
    3645         sage: polar_plot(log(floor(x)), (x, 1, 4*pi), exclude = [1..12])
    3646 
    3647     """
    3648     kwds['polar']=True
    3649     return plot(funcs, *args, **kwds)
    3650 
    3651 @options(aspect_ratio='automatic')
    3652 def list_plot(data, plotjoined=False, **kwargs):
    3653     r"""
    3654     ``list_plot`` takes either a list of numbers, a list of tuples,
    3655     or a dictionary and plots the corresponding points.
    3656 
    3657     If given a list of numbers (that is, not a list of tuples or lists),
    3658     ``list_plot`` forms a list of tuples `(i, x_i)` where `i` goes from
    3659     0 to ``len(data)-1`` and `x_i` is the `i`-th data value, and puts
    3660     points at those tuple values.
    3661    
    3662     ``list_plot`` will plot a list of complex numbers in the obvious
    3663     way; any numbers for which
    3664     :func:`CC()<sage.rings.complex_field.ComplexField>` makes sense will
    3665     work.
    3666 
    3667     ``list_plot`` also takes a list of tuples `(x_i, y_i)` where `x_i`
    3668     and `y_i` are the `i`-th values representing the `x`- and
    3669     `y`-values, respectively.
    3670 
    3671     If given a dictionary, ``list_plot`` interprets the keys as
    3672     `x`-values and the values as `y`-values.
    3673 
    3674     The ``plotjoined=True`` option tells ``list_plot`` to plot a line
    3675     joining all the data.
    3676 
    3677     It is possible to pass empty dictionaries, lists, or tuples to
    3678     list_plot. Doing so will plot nothing (returning an empty plot).
    3679 
    3680     EXAMPLES::
    3681    
    3682         sage: list_plot([i^2 for i in range(5)])
    3683    
    3684     Here are a bunch of random red points::
    3685    
    3686         sage: r = [(random(),random()) for _ in range(20)]
    3687         sage: list_plot(r,color='red')
    3688    
    3689     This gives all the random points joined in a purple line::
    3690    
    3691         sage: list_plot(r, plotjoined=True, color='purple')
    3692 
    3693     Plot a list of complex numbers::
    3694 
    3695         sage: list_plot([1, I, pi + I/2, CC(.25, .25)])
    3696 
    3697         sage: list_plot([exp(I*theta) for theta in [0, .2..pi]])
    3698 
    3699     Note that if your list of complex numbers are all actually real,
    3700     they get plotted as real values, so this
    3701 
    3702     ::
    3703 
    3704         sage: list_plot([CDF(1), CDF(1/2), CDF(1/3)])
    3705 
    3706     is the same as ``list_plot([1, 1/2, 1/3])`` -- it produces a plot of
    3707     the points `(0,1)`, `(1,1/2)`, and `(2,1/3)`.
    3708 
    3709     If you have separate lists of `x` values and `y` values which you
    3710     want to plot against each other, use the ``zip`` command to make a
    3711     single list whose entries are pairs of `(x,y)` values, and feed
    3712     the result into ``list_plot``::
    3713 
    3714         sage: x_coords = [cos(t)^3 for t in srange(0, 2*pi, 0.02)]
    3715         sage: y_coords = [sin(t)^3 for t in srange(0, 2*pi, 0.02)]
    3716         sage: list_plot(zip(x_coords, y_coords))
    3717 
    3718     If instead you try to pass the two lists as separate arguments,
    3719     you will get an error message::
    3720 
    3721         sage: list_plot(x_coords, y_coords)
    3722         Traceback (most recent call last):
    3723         ...
    3724         TypeError: The second argument 'plotjoined' should be boolean (True or False).  If you meant to plot two lists 'x' and 'y' against each other, use 'list_plot(zip(x,y))'.
    3725 
    3726     Dictionaries with numeric keys and values can be plotted::
    3727 
    3728         sage: list_plot({22: 3365, 27: 3295, 37: 3135, 42: 3020, 47: 2880, 52: 2735, 57: 2550})
    3729 
    3730     TESTS:
    3731 
    3732     We check to see that the x/y min/max data are set correctly.
    3733    
    3734     ::
    3735    
    3736         sage: d = list_plot([(100,100), (120, 120)]).get_minmax_data()
    3737         sage: d['xmin']
    3738         100.0
    3739         sage: d['ymin']
    3740         100.0
    3741     """
    3742     from sage.plot.all import line, point
    3743     if data == {} or data == () or data == []:
    3744         return Graphics()
    3745     if isinstance(data, dict):
    3746         if plotjoined:
    3747             list_data = sorted(list(data.iteritems()))
    3748         else:
    3749             list_data = list(data.iteritems())
    3750         return list_plot(list_data, plotjoined=plotjoined, **kwargs)
    3751     if not isinstance(data[0], (list, tuple)):
    3752         data = zip(range(len(data)), data)
    3753     if isinstance(plotjoined, (list, tuple)):
    3754         raise TypeError, "The second argument 'plotjoined' should be boolean (True or False).  If you meant to plot two lists 'x' and 'y' against each other, use 'list_plot(zip(x,y))'."
    3755     try:
    3756         if plotjoined:
    3757             return line(data, **kwargs)
    3758         else:
    3759             return point(data, **kwargs)
    3760     except (TypeError, IndexError):
    3761         # Assume we have complex-valued input and plot real and imaginary parts.
    3762         # Need to catch IndexError because if data is, say, [(0, 1), (1, I)],
    3763         # point3d() throws an IndexError on the (0,1) before it ever
    3764         # gets to (1, I).
    3765         from sage.rings.complex_field import ComplexField
    3766         CC = ComplexField()
    3767         # if we get here, we already did "zip(range(len(data)), data)",
    3768         # so look at z[1] in inner list
    3769         data = [(z.real(), z.imag()) for z in [CC(z[1]) for z in data]]
    3770         if plotjoined:
    3771             return line(data, **kwargs)
    3772         else:
    3773             return point(data, **kwargs)
    3774 
    3775 def to_float_list(v):
    3776     """
    3777     Given a list or tuple or iterable v, coerce each element of v to a
    3778     float and make a list out of the result.
    3779    
    3780     EXAMPLES::
    3781    
    3782         sage: from sage.plot.plot import to_float_list
    3783         sage: to_float_list([1,1/2,3])
    3784         [1.0, 0.5, 3.0]
    3785     """
    3786     return [float(x) for x in v]
    3787 
    3788 
    37892208
    37902209class GraphicsArray(SageObject):
    37912210    """
     
    39832402            sage: H[1] # a circle and some purple points
    39842403        """
    39852404        i = int(i)
    3986         self._glist[i] = g 
     2405        self._glist[i] = g
    39872406       
    39882407    def __set_figsize__(self, ls):
    39892408        """
     
    40002419
    40012420        ::
    40022421
    4003             sage: G.show(figsize=[10,20])  # bigger and tall and thin
     2422            sage: G.show(figsize=[10,20])  # bigger and tall and thin; long time (2s on sage.math, 2012)
    40042423
    40052424        ::
    40062425
     
    40482467
    40492468        TESTS::
    40502469
    4051             sage: from sage.plot.plot import GraphicsArray
     2470            sage: from sage.plot.graphics import GraphicsArray
    40522471            sage: G = GraphicsArray([plot(sin),plot(cos)])
    40532472            sage: G.append(plot(tan))
    40542473            Traceback (most recent call last):
     
    40672486        EXAMPLES::
    40682487
    40692488            sage: graphics_array([[plot(sin), plot(cos)], [plot(tan), plot(sec)]])
    4070         """ 
     2489        """
    40712490        #glist is a list of Graphics objects:
    40722491        glist = self._glist
    40732492        rows = self._rows
     
    41062525            sage: F = sage.misc.misc.tmp_filename()+'.png'
    41072526            sage: L = [plot(sin(k*x),(x,-pi,pi)) for k in [1..3]]
    41082527            sage: G = graphics_array(L)
    4109             sage: G.save(F,500,axes=False)
     2528            sage: G.save(F,500,axes=False)  # long time (6s on sage.math, 2012)
    41102529        """
    4111         if (figsize is not None): self.__set_figsize__(figsize) 
     2530        if (figsize is not None): self.__set_figsize__(figsize)
    41122531        self._render(filename, dpi=dpi, figsize=self._figsize, axes = axes, **args)
    41132532
    41142533    def show(self, filename=None, dpi=DEFAULT_DPI, figsize=None,
     
    41392558            sage: G = graphics_array([[plot(sin), plot(cos)], [plot(tan), plot(sec)]])
    41402559            sage: G.show(axes=False)
    41412560        """
    4142         if (figsize is not None): self.__set_figsize__(figsize) 
    4143         if DOCTEST_MODE:
     2561        if (figsize is not None): self.__set_figsize__(figsize)
     2562        if sage.plot.plot.DOCTEST_MODE:
    41442563            self.save(DOCTEST_MODE_FILE,
    41452564                      dpi=dpi, figsize=self._figsize, axes = axes, **args)
    41462565            return
    4147         if EMBEDDED_MODE:
     2566        if sage.plot.plot.EMBEDDED_MODE:
    41482567            self.save(filename, dpi=dpi, figsize=self._figsize, axes = axes, **args)
    41492568            return
    41502569        if filename is None:
     
    41542573                         sage.misc.viewer.browser(), filename))
    41552574
    41562575
    4157 def reshape(v, n, m):
    4158     """
    4159     Helper function for creating graphics arrays.
    4160 
    4161     The input array is flattened and turned into an `n\times m`
    4162     array, with blank graphics object padded at the end, if
    4163     necessary.
    4164 
    4165     INPUT:
    4166 
    4167     -  ``v`` - a list of lists or tuples
    4168 
    4169     -  ``n, m`` - integers
    4170 
    4171     OUTPUT:
    4172 
    4173     A list of lists of graphics objects
    4174 
    4175     EXAMPLES::
    4176 
    4177         sage: L = [plot(sin(k*x),(x,-pi,pi)) for k in range(10)]
    4178         sage: graphics_array(L,3,4)
    4179 
    4180     ::
    4181 
    4182         sage: M = [[plot(sin(k*x),(x,-pi,pi)) for k in range(3)],[plot(cos(j*x),(x,-pi,pi)) for j in [3..5]]]
    4183         sage: graphics_array(M,6,1)
    4184 
    4185     TESTS::
    4186 
    4187         sage: L = [plot(sin(k*x),(x,-pi,pi)) for k in [1..3]]
    4188         sage: graphics_array(L,0,-1)
    4189         Traceback (most recent call last):
    4190         ...
    4191         AssertionError: array sizes must be positive
    4192     """
    4193     assert n>0 and m>0, 'array sizes must be positive'
    4194     G = Graphics()
    4195     G.axes(False)
    4196     if len(v) == 0:
    4197         return [[G]*m]*n
    4198 
    4199     if not isinstance(v[0], Graphics):
    4200         # a list of lists -- flatten it
    4201         v = sum([list(x) for x in v], [])
    4202 
    4203     # Now v should be a single list.
    4204     # First, make it have the right length.
    4205     for i in xrange(n*m - len(v)):
    4206         v.append(G)
    4207        
    4208     # Next, create a list of lists out of it.
    4209     L = []
    4210     k = 0
    4211     for i in range(n):
    4212         w = []
    4213         for j in range(m):
    4214             w.append(v[k])
    4215             k += 1
    4216         L.append(w)
    4217 
    4218     return L
    4219 
    4220 def graphics_array(array, n=None, m=None):
    4221     r"""
    4222     ``graphics_array`` take a list of lists (or tuples) of
    4223     graphics objects and plots them all on one canvas (single plot).
    4224 
    4225     INPUT:
    4226 
    4227     -  ``array`` - a list of lists or tuples
    4228 
    4229     -  ``n, m`` - (optional) integers - if n and m are
    4230        given then the input array is flattened and turned into an n x m
    4231        array, with blank graphics objects padded at the end, if
    4232        necessary.
    4233 
    4234 
    4235     EXAMPLE: Make some plots of `\sin` functions::
    4236 
    4237         sage: f(x) = sin(x)
    4238         sage: g(x) = sin(2*x)
    4239         sage: h(x) = sin(4*x)
    4240         sage: p1 = plot(f,(-2*pi,2*pi),color=hue(0.5))
    4241         sage: p2 = plot(g,(-2*pi,2*pi),color=hue(0.9))
    4242         sage: p3 = parametric_plot((f,g),(0,2*pi),color=hue(0.6))
    4243         sage: p4 = parametric_plot((f,h),(0,2*pi),color=hue(1.0))
    4244 
    4245     Now make a graphics array out of the plots::
    4246 
    4247         sage: graphics_array(((p1,p2),(p3,p4)))
    4248 
    4249     One can also name the array, and then use :meth:`~GraphicsArray.show`
    4250     or :meth:`~GraphicsArray.save`::
    4251 
    4252         sage: ga = graphics_array(((p1,p2),(p3,p4)))
    4253         sage: ga.show()
    4254 
    4255     Here we give only one row::
    4256 
    4257         sage: p1 = plot(sin,(-4,4))
    4258         sage: p2 = plot(cos,(-4,4))
    4259         sage: g = graphics_array([p1, p2]); print g
    4260         Graphics Array of size 1 x 2
    4261         sage: g.show()
    4262 
    4263     It is possible to use ``figsize`` to change the size of the plot
    4264     as a whole::
    4265 
    4266         sage: L = [plot(sin(k*x),(x,-pi,pi)) for k in [1..3]]
    4267         sage: G = graphics_array(L)
    4268         sage: G.show(figsize=[5,3])  # smallish and compact
    4269 
    4270     ::
    4271 
    4272         sage: G.show(figsize=[10,20])  # bigger and tall and thin
    4273 
    4274     ::
    4275 
    4276         sage: G.show(figsize=8)  # figure as a whole is a square
    4277     """
    4278     if not n is None:
    4279         # Flatten then reshape input
    4280         n = int(n)
    4281         m = int(m)
    4282         array = reshape(array, n, m)
    4283     return GraphicsArray(array)
    4284 
    4285 def var_and_list_of_values(v, plot_points):
    4286     """
    4287     INPUT:
    4288    
    4289    
    4290     -  ``v`` - (v0, v1) or (var, v0, v1); if the former
    4291        return the range of values between v0 and v1 taking plot_points
    4292        steps; if var is given, also return var.
    4293    
    4294     -  ``plot_points`` - integer = 2 (the endpoints)
    4295    
    4296    
    4297     OUTPUT:
    4298    
    4299    
    4300     -  ``var`` - a variable or None
    4301    
    4302     -  ``list`` - a list of floats
    4303    
    4304    
    4305     EXAMPLES::
    4306    
    4307         sage: from sage.plot.plot import var_and_list_of_values
    4308         sage: var_and_list_of_values((var('theta'), 2, 5),  5)
    4309         doctest:...: DeprecationWarning: var_and_list_of_values is deprecated.  Please use sage.plot.misc.setup_for_eval_on_grid; note that that function has slightly different calling and return conventions which make it more generally applicable
    4310         (theta, [2.0, 2.75, 3.5, 4.25, 5.0])
    4311         sage: var_and_list_of_values((2, 5),  5)
    4312         (None, [2.0, 2.75, 3.5, 4.25, 5.0])
    4313         sage: var_and_list_of_values((var('theta'), 2, 5),  2)
    4314         (theta, [2.0, 5.0])
    4315         sage: var_and_list_of_values((2, 5),  2)
    4316         (None, [2.0, 5.0])
    4317     """
    4318     from sage.misc.misc import deprecation
    4319     deprecation("var_and_list_of_values is deprecated.  Please use sage.plot.misc.setup_for_eval_on_grid; note that that function has slightly different calling and return conventions which make it more generally applicable")
    4320     plot_points = int(plot_points)
    4321     if plot_points < 2:
    4322         raise ValueError, "plot_points must be greater than 1"
    4323     if not isinstance(v, (tuple, list)):
    4324         raise TypeError, "v must be a tuple or list"
    4325     if len(v) == 3:
    4326         var = v[0]
    4327         a, b = v[1], v[2]
    4328     elif len(v) == 2:
    4329         var = None
    4330         a, b = v
    4331     else:
    4332         raise ValueError, "parametric value range must be a list or tuple of length 2 or 3."
    4333 
    4334     a = float(a)
    4335     b = float(b)
    4336     if plot_points == 2:
    4337         return var, [a, b]
    4338     else:
    4339         step = (b-a)/float(plot_points-1)
    4340         values = [a + step*i for i in xrange(plot_points)]
    4341         return var, values
    4342 
    4343 
    4344 
    4345 def setup_for_eval_on_grid(v, xrange, yrange, plot_points):
    4346     """
    4347     This function is deprecated.  Please use
    4348     sage.plot.misc.setup_for_eval_on_grid instead.  Please note that
    4349     that function has slightly different calling and return
    4350     conventions which make it more generally applicable.
    4351 
    4352     INPUT:
    4353    
    4354    
    4355     -  ``v`` - a list of functions
    4356    
    4357     -  ``xrange`` - 2 or 3 tuple (if 3, first is a
    4358        variable)
    4359    
    4360     -  ``yrange`` - 2 or 3 tuple
    4361    
    4362     -  ``plot_points`` - a positive integer
    4363    
    4364    
    4365     OUTPUT:
    4366    
    4367    
    4368     -  ``g`` - tuple of fast callable functions
    4369    
    4370     -  ``xstep`` - step size in xdirection
    4371    
    4372     -  ``ystep`` - step size in ydirection
    4373    
    4374     -  ``xrange`` - tuple of 2 floats
    4375    
    4376     -  ``yrange`` - tuple of 2 floats
    4377    
    4378    
    4379     EXAMPLES::
    4380    
    4381         sage: x,y = var('x,y')
    4382         sage: sage.plot.plot.setup_for_eval_on_grid([x^2 + y^2], (x,0,5), (y,0,pi), 11)
    4383         doctest:...: DeprecationWarning: sage.plot.plot.setup_for_eval_on_grid is deprecated.  Please use sage.plot.misc.setup_for_eval_on_grid; note that that function has slightly different calling and return conventions which make it more generally applicable
    4384         ([<sage.ext... object at ...>],
    4385          0.5,
    4386          0.3141592653589793,
    4387          (0.0, 5.0),
    4388          (0.0, 3.141592653589793))
    4389 
    4390     We always plot at least two points; one at the beginning and one at the end of the ranges.
    4391 
    4392     ::
    4393    
    4394         sage: sage.plot.plot.setup_for_eval_on_grid([x^2+y^2], (x,0,1), (y,-1,1), 1)
    4395         ([<sage.ext... object at ...>],
    4396         1.0,
    4397         2.0,
    4398         (0.0, 1.0),
    4399         (-1.0, 1.0))
    4400 
    4401        
    4402     """
    4403     from sage.misc.misc import deprecation
    4404     deprecation("sage.plot.plot.setup_for_eval_on_grid is deprecated.  Please use sage.plot.misc.setup_for_eval_on_grid; note that that function has slightly different calling and return conventions which make it more generally applicable")
    4405 
    4406     from sage.plot.misc import setup_for_eval_on_grid as setup
    4407     g, ranges=setup(v, [xrange, yrange], plot_points)
    4408     return list(g), ranges[0][2], ranges[1][2], ranges[0][:2], ranges[1][:2]
    4409 
    4410 
    4411 def minmax_data(xdata, ydata, dict=False):
    4412     """
    4413     Returns the minimums and maximums of xdata and ydata.
    4414    
    4415     If dict is False, then minmax_data returns the tuple (xmin, xmax,
    4416     ymin, ymax); otherwise, it returns a dictionary whose keys are
    4417     'xmin', 'xmax', 'ymin', and 'ymax' and whose values are the
    4418     corresponding values.
    4419    
    4420     EXAMPLES::
    4421    
    4422         sage: from sage.plot.plot import minmax_data
    4423         sage: minmax_data([], [])
    4424         (-1, 1, -1, 1)
    4425         sage: minmax_data([-1, 2], [4, -3])
    4426         (-1, 2, -3, 4)
    4427         sage: d = minmax_data([-1, 2], [4, -3], dict=True)
    4428         sage: list(sorted(d.items()))
    4429         [('xmax', 2), ('xmin', -1), ('ymax', 4), ('ymin', -3)]
    4430     """
    4431     xmin = min(xdata) if len(xdata) > 0 else -1
    4432     xmax = max(xdata) if len(xdata) > 0 else 1
    4433     ymin = min(ydata) if len(ydata) > 0 else -1
    4434     ymax = max(ydata) if len(ydata) > 0 else 1
    4435     if dict:
    4436         return {'xmin':xmin, 'xmax':xmax,
    4437                 'ymin':ymin, 'ymax':ymax}
    4438     else:
    4439         return xmin, xmax, ymin, ymax
    4440 
    4441 def adaptive_refinement(f, p1, p2, adaptive_tolerance=0.01, adaptive_recursion=5, level=0):
    4442     r"""
    4443     The adaptive refinement algorithm for plotting a function f. See
    4444     the docstring for plot for a description of the algorithm.
    4445    
    4446     INPUT:
    4447    
    4448    
    4449     -  ``f`` - a function of one variable
    4450    
    4451     -  ``p1, p2`` - two points to refine between
    4452    
    4453     -  ``adaptive_recursion`` - (default: 5) how many
    4454        levels of recursion to go before giving up when doing adaptive
    4455        refinement. Setting this to 0 disables adaptive refinement.
    4456    
    4457     -  ``adaptive_tolerance`` - (default: 0.01) how large
    4458        a relative difference should be before the adaptive refinement
    4459        code considers it significant; see documentation for generate_plot_points
    4460        for more information.  See the documentation for plot() for more
    4461        information on how the adaptive refinement algorithm works.
    4462    
    4463     OUTPUT:
    4464    
    4465    
    4466     -  ``list`` - a list of points to insert between p1 and
    4467        p2 to get a better linear approximation between them
    4468    
    4469    
    4470     TESTS::
    4471    
    4472         sage: from sage.plot.plot import adaptive_refinement
    4473         sage: adaptive_refinement(sin, (0,0), (pi,0), adaptive_tolerance=0.01, adaptive_recursion=0)
    4474         []
    4475         sage: adaptive_refinement(sin, (0,0), (pi,0), adaptive_tolerance=0.01)
    4476         [(0.125*pi, 0.3826834323650898), (0.1875*pi, 0.5555702330196022), (0.25*pi, 0.7071067811865475), (0.3125*pi, 0.8314696123025452), (0.375*pi, 0.9238795325112867), (0.4375*pi, 0.9807852804032304), (0.5*pi, 1.0), (0.5625*pi, 0.9807852804032304), (0.625*pi, 0.9238795325112867), (0.6875*pi, 0.8314696123025455), (0.75*pi, 0.7071067811865476), (0.8125*pi, 0.5555702330196022), (0.875*pi, 0.3826834323650899)]
    4477 
    4478     This shows that lowering adaptive_tolerance and raising
    4479     adaptive_recursion both increase the number of subdivision
    4480     points, though which one creates more points is heavily
    4481     dependent upon the function being plotted.
    4482 
    4483     ::
    4484    
    4485         sage: x = var('x')
    4486         sage: f(x) = sin(1/x)
    4487         sage: n1 = len(adaptive_refinement(f, (0,0), (pi,0), adaptive_tolerance=0.01)); n1
    4488         15
    4489         sage: n2 = len(adaptive_refinement(f, (0,0), (pi,0), adaptive_recursion=10, adaptive_tolerance=0.01)); n2
    4490         79
    4491         sage: n3 = len(adaptive_refinement(f, (0,0), (pi,0), adaptive_tolerance=0.001)); n3
    4492         26
    4493     """
    4494     if level >= adaptive_recursion:
    4495         return []
    4496 
    4497     x = (p1[0] + p2[0])/2.0
    4498     msg = ''
    4499 
    4500     try:
    4501         y = float(f(x))
    4502         if str(y) in ['nan', 'NaN', 'inf', '-inf']:
    4503             sage.misc.misc.verbose("%s\nUnable to compute f(%s)"%(msg, x),1)
    4504             # give up for this branch
    4505             return []
    4506 
    4507     except (ZeroDivisionError, TypeError, ValueError, OverflowError), msg:
    4508         sage.misc.misc.verbose("%s\nUnable to compute f(%s)"%(msg, x), 1)
    4509         # give up for this branch
    4510         return []
    4511 
    4512     # this distance calculation is not perfect.
    4513     if abs((p1[1] + p2[1])/2.0 - y) > adaptive_tolerance:
    4514         return adaptive_refinement(f, p1, (x, y),
    4515                     adaptive_tolerance=adaptive_tolerance,
    4516                     adaptive_recursion=adaptive_recursion,
    4517                     level=level+1) \
    4518                     + [(x, y)] + \
    4519             adaptive_refinement(f, (x, y), p2,
    4520                     adaptive_tolerance=adaptive_tolerance,
    4521                     adaptive_recursion=adaptive_recursion,
    4522                     level=level+1)
    4523     else:
    4524         return []
    4525 
    4526 def generate_plot_points(f, xrange, plot_points=5, adaptive_tolerance=0.01, adaptive_recursion=5, randomize = True, initial_points = None):
    4527     r"""
    4528     Calculate plot points for a function f in the interval xrange.  The
    4529     adaptive refinement algorithm is also automatically invoked with a
    4530     *relative* adaptive tolerance of adaptive_tolerance; see below.
    4531 
    4532     INPUT:
    4533        
    4534     - ``f`` - a function of one variable
    4535        
    4536     - ``p1, p2`` - two points to refine between
    4537        
    4538     - ``plot_points`` - (default: 5) the minimal number of plot points. (Note
    4539       however that in any actual plot a number is passed to this, with default
    4540       value 200.)
    4541 
    4542     - ``adaptive_recursion`` - (default: 5) how many levels of recursion to go
    4543       before giving up when doing adaptive refinement.  Setting this to 0
    4544       disables adaptive refinement.
    4545 
    4546     - ``adaptive_tolerance`` - (default: 0.01) how large the relative difference
    4547       should be before the adaptive refinement code considers it significant.  If
    4548       the actual difference is greater than adaptive_tolerance*delta, where delta
    4549       is the initial subinterval size for the given xrange and plot_points, then
    4550       the algorithm will consider it significant.
    4551 
    4552     - ``initial_points`` - (default: None) a list of points that should be evaluated.
    4553 
    4554     OUTPUT:
    4555        
    4556     - a list of points (x, f(x)) in the interval xrange, which approximate
    4557       the function f.
    4558 
    4559     TESTS::
    4560 
    4561         sage: from sage.plot.plot import generate_plot_points
    4562         sage: generate_plot_points(sin, (0, pi), plot_points=2, adaptive_recursion=0)
    4563         [(0.0, 0.0), (3.141592653589793, 1.2246...e-16)]
    4564 
    4565         sage: from sage.plot.plot import generate_plot_points
    4566         sage: generate_plot_points(lambda x: x^2, (0, 6), plot_points=2, adaptive_recursion=0, initial_points = [1,2,3])
    4567         [(0.0, 0.0), (1.0, 1.0), (2.0, 4.0), (3.0, 9.0), (6.0, 36.0)]
    4568 
    4569         sage: generate_plot_points(sin(x).function(x), (-pi, pi), randomize=False)
    4570         [(-3.141592653589793, -1.2246...e-16), (-2.748893571891069,
    4571         -0.3826834323650899), (-2.356194490192345, -0.707106781186547...),
    4572         (-2.1598449493429825, -0.831469612302545...), (-1.9634954084936207,
    4573         -0.9238795325112867), (-1.7671458676442586, -0.9807852804032304),
    4574         (-1.5707963267948966, -1.0), (-1.3744467859455345,
    4575         -0.9807852804032304), (-1.1780972450961724, -0.9238795325112867),
    4576         (-0.9817477042468103, -0.831469612302545...), (-0.7853981633974483,
    4577         -0.707106781186547...), (-0.39269908169872414, -0.3826834323650898),
    4578         (0.0, 0.0), (0.39269908169872414, 0.3826834323650898),
    4579         (0.7853981633974483, 0.707106781186547...), (0.9817477042468103,
    4580         0.831469612302545...), (1.1780972450961724, 0.9238795325112867),
    4581         (1.3744467859455345, 0.9807852804032304), (1.5707963267948966, 1.0),
    4582         (1.7671458676442586, 0.9807852804032304), (1.9634954084936207,
    4583         0.9238795325112867), (2.1598449493429825, 0.831469612302545...),
    4584         (2.356194490192345, 0.707106781186547...), (2.748893571891069,
    4585         0.3826834323650899), (3.141592653589793, 1.2246...e-16)]
    4586 
    4587     This shows that lowering adaptive_tolerance and raising
    4588     adaptive_recursion both increase the number of subdivision points.
    4589     (Note that which creates more points is heavily dependent on the
    4590     particular function plotted.)
    4591 
    4592     ::
    4593 
    4594         sage: x = var('x')
    4595         sage: f(x) = sin(1/x)
    4596         sage: [len(generate_plot_points(f, (-pi, pi), plot_points=16, adaptive_tolerance=i, randomize=False)) for i in [0.01, 0.001, 0.0001]]
    4597         [97, 161, 275]
    4598 
    4599         sage: [len(generate_plot_points(f, (-pi, pi), plot_points=16, adaptive_recursion=i, randomize=False)) for i in [5, 10, 15]]
    4600         [97, 499, 2681]
    4601     """
    4602     from sage.plot.misc import setup_for_eval_on_grid
    4603     ignore, ranges = setup_for_eval_on_grid([], [xrange], plot_points)
    4604     xmin, xmax, delta = ranges[0]
    4605     data = srange(*ranges[0], include_endpoint=True)
    4606 
    4607     random = current_randstate().python_random().random
    4608 
    4609     for i in range(len(data)):
    4610         xi = data[i]
    4611         # Slightly randomize the interior sample points if
    4612         # randomize is true
    4613         if randomize and i > 0 and i < plot_points-1:
    4614             xi += delta*(random() - 0.5)
    4615             data[i] = xi
    4616 
    4617     # add initial points
    4618     if isinstance(initial_points, list):
    4619         data = sorted(data + initial_points)
    4620 
    4621     exceptions = 0; msg=''
    4622     exception_indices = []
    4623     for i in range(len(data)):
    4624         xi = data[i]
    4625 
    4626         try:
    4627             data[i] = (float(xi), float(f(xi)))
    4628             if str(data[i][1]) in ['nan', 'NaN', 'inf', '-inf']:
    4629                 sage.misc.misc.verbose("%s\nUnable to compute f(%s)"%(msg, xi),1)
    4630                 exceptions += 1
    4631                 exception_indices.append(i)
    4632 
    4633         except (ArithmeticError, TypeError, ValueError), msg:
    4634             sage.misc.misc.verbose("%s\nUnable to compute f(%s)"%(msg, xi),1)
    4635 
    4636             if i == 0: # Given an error for left endpoint, try to move it in slightly
    4637                 for j in range(1, 99):
    4638                     xj = xi + delta*j/100.0
    4639                     try:
    4640                         data[i] = (float(xj), float(f(xj)))
    4641                         # nan != nan
    4642                         if data[i][1] != data[i][1]:
    4643                             continue
    4644                         break
    4645                     except (ArithmeticError, TypeError, ValueError), msg:
    4646                         pass
    4647                 else:
    4648                     exceptions += 1
    4649                     exception_indices.append(i)
    4650 
    4651             elif i == plot_points-1: # Given an error for right endpoint, try to move it in slightly
    4652                 for j in range(1, 99):
    4653                     xj = xi - delta*j/100.0
    4654                     try:
    4655                         data[i] = (float(xj), float(f(xj)))
    4656                         # nan != nan
    4657                         if data[i][1] != data[i][1]:
    4658                             continue
    4659                         break
    4660                     except (ArithmeticError, TypeError, ValueError), msg:
    4661                         pass
    4662                 else:
    4663                     exceptions += 1
    4664                     exception_indices.append(i)
    4665             else:
    4666                 exceptions += 1
    4667                 exception_indices.append(i)
    4668 
    4669     data = [data[i] for i in range(len(data)) if i not in exception_indices]
    4670 
    4671     # calls adaptive refinement
    4672     i, j = 0, 0
    4673     adaptive_tolerance = delta * float(adaptive_tolerance)
    4674     adaptive_recursion = int(adaptive_recursion)
    4675 
    4676     while i < len(data) - 1:
    4677        for p in adaptive_refinement(f, data[i], data[i+1],
    4678                                      adaptive_tolerance=adaptive_tolerance,
    4679                                      adaptive_recursion=adaptive_recursion):
    4680             data.insert(i+1, p)
    4681             i += 1
    4682        i += 1
    4683 
    4684     if (len(data) == 0 and exceptions > 0) or exceptions > 10:
    4685         sage.misc.misc.verbose("WARNING: When plotting, failed to evaluate function at %s points."%exceptions, level=0)
    4686         sage.misc.misc.verbose("Last error message: '%s'"%msg, level=0)
    4687 
    4688     return data
    4689 
    4690 #Lovely cruft to keep the pickle jar working
    4691 from line import line, line2d, Line as GraphicPrimitive_Line
    4692 from arrow import arrow, Arrow as GraphicPrimitive_Arrow
    4693 from bar_chart import bar_chart, BarChart as GraphicPrimitive_BarChart
    4694 from disk import disk, Disk as GraphicPrimitive_Disk
    4695 from point import point, points, point2d, Point as GraphicPrimitive_Point
    4696 from matrix_plot import matrix_plot, MatrixPlot as GraphicPrimitive_MatrixPlot
    4697 from plot_field import plot_vector_field, plot_slope_field, PlotField as GraphicPrimitive_PlotField
    4698 from text import text, Text as GraphicPrimitive_Text
    4699 from polygon import polygon, Polygon as GraphicPrimitive_Polygon
    4700 from circle import circle, Circle as GraphicPrimtive_Circle
    4701 from contour_plot import contour_plot, implicit_plot, ContourPlot as GraphicPrimitive_ContourPlot
    4702 
  • sage/plot/hyperbolic_arc.py

    diff --git a/sage/plot/hyperbolic_arc.py b/sage/plot/hyperbolic_arc.py
    a b  
    128128   
    129129         sage: hyperbolic_arc(I, 2*I, linestyle='dashed')
    130130    """
    131     from sage.plot.plot import Graphics
     131    from sage.plot.all import Graphics
    132132    g = Graphics()
    133133    g._set_extra_kwds(g._extract_kwds_for_show(options))
    134134    g.add_primitive(HyperbolicArc(a, b, options))
  • sage/plot/hyperbolic_triangle.py

    diff --git a/sage/plot/hyperbolic_triangle.py b/sage/plot/hyperbolic_triangle.py
    a b  
    138138   
    139139         sage: hyperbolic_triangle(0, 1, 2+i, fill=true, rgbcolor='red')
    140140    """
    141     from sage.plot.plot import Graphics
     141    from sage.plot.all import Graphics
    142142    g = Graphics()
    143143    g._set_extra_kwds(g._extract_kwds_for_show(options))
    144144    g.add_primitive(HyperbolicTriangle(a, b, c, options))
  • sage/plot/line.py

    diff --git a/sage/plot/line.py b/sage/plot/line.py
    a b  
    430430        sage: line([(0,1), (3,4)], figsize=[10, 2])
    431431        sage: line([(0,1), (3,4)]).show(figsize=[10, 2]) # These are equivalent
    432432    """
    433     from sage.plot.plot import Graphics, xydata_from_point_list
     433    from sage.plot.all import Graphics
     434    from sage.plot.plot import xydata_from_point_list
    434435    if points == []:
    435436        return Graphics()
    436437    xdata, ydata = xydata_from_point_list(points)
  • sage/plot/matrix_plot.py

    diff --git a/sage/plot/matrix_plot.py b/sage/plot/matrix_plot.py
    a b  
    5555        sage: M.options()
    5656        {'cmap': 'winter'}
    5757
    58     Extra options will get passed on to :meth:`~sage.plot.plot.Graphics.show`, as long as they are valid::
     58    Extra options will get passed on to :meth:`~Graphics.show`, as long as they are valid::
    5959
    6060        sage: matrix_plot([[1, 0], [0, 1]], fontsize=10)
    6161        sage: matrix_plot([[1, 0], [0, 1]]).show(fontsize=10) # These are equivalent
     
    446446    """
    447447    import numpy as np
    448448    import scipy.sparse as scipysparse
    449     from sage.plot.plot import Graphics
     449    from sage.plot.all import Graphics
    450450    from sage.matrix.all import is_Matrix
    451451    from sage.rings.all import RDF
    452452    orig_mat=mat
  • sage/plot/plot.py

    diff --git a/sage/plot/plot.py b/sage/plot/plot.py
    a b  
    144144    sage: print H
    145145    Graphics object consisting of 3 graphics primitives
    146146    sage: type(H)
    147     <class 'sage.plot.plot.Graphics'>
     147    <class 'sage.plot.graphics.Graphics'>
    148148    sage: H[1]
    149149    Polygon defined by 3 points
    150150    sage: list(H[1])
     
    310310
    311311- Jason Grout (2010-10): rewrote aspect ratio portions of the code
    312312
     313- Jeroen Demeyer (2012-04-19): move parts of this file to graphics.py (:trac:`12857`)
     314
    313315"""
     316#*****************************************************************************
     317#       Copyright (C) 2006 Alex Clemesha <clemesha@gmail.com>
     318#       Copyright (C) 2006-2008 William Stein <wstein@gmail.com>
     319#       Copyright (C) 2010 Jason Grout
     320#
     321#  Distributed under the terms of the GNU General Public License (GPL)
     322#  as published by the Free Software Foundation; either version 2 of
     323#  the License, or (at your option) any later version.
     324#                  http://www.gnu.org/licenses/
     325#*****************************************************************************
    314326
    315 ############################################################################
    316 #  Copyright (C) 2006 Alex Clemesha <clemesha@gmail.com> and William Stein <wstein@gmail.com>
    317 #  Distributed under the terms of the GNU General Public License (GPL)
    318 #                  http://www.gnu.org/licenses/
    319 ############################################################################
    320327
    321 import os, types
    322 
    323 from sage.structure.sage_object import SageObject
     328import os
    324329
    325330## IMPORTANT: Do *not* import matplotlib at module scope.  It takes a
    326331## surprisingly long time to initialize itself.  It's better if it is
    327332## imported in functions, so it only gets started if it is actually
    328333## going to be used.
    329334
    330 ALLOWED_EXTENSIONS = ['.eps', '.pdf', '.png', '.ps', '.sobj', '.svg']
    331335#DEFAULT_FIGSIZE=(6, 3.70820393249937)
    332 DEFAULT_DPI = 100
    333336EMBEDDED_MODE = False
    334337DOCTEST_MODE = False
    335338import sage.misc.misc
    336339from sage.misc.misc import srange
    337 DOCTEST_MODE_FILE = os.path.join(sage.misc.misc.SAGE_TMP, 'test.png')
    338 SHOW_DEFAULT = True
    339 
    340 def show_default(default=None):
    341     r"""
    342     Set the default for showing plots using any plot commands. If
    343     called with no arguments, returns the current default.
    344    
    345     If this is ``True`` (the default) then any plot object
    346     when displayed will be displayed as an actual plot instead of text,
    347     i.e., the show command is not needed.
    348    
    349     EXAMPLES: The default starts out as ``True``::
    350    
    351         sage: show_default()
    352         True
    353    
    354     We set it to ``False``.
    355    
    356     ::
    357    
    358         sage: show_default(False)
    359    
    360     We see that it is ``False``.
    361    
    362     ::
    363    
    364         sage: show_default()
    365         False
    366    
    367     Now plot commands will not display their plots by default.
    368    
    369     Turn back on default display.
    370    
    371     ::
    372    
    373         sage: show_default(True)
    374     """
    375     global SHOW_DEFAULT
    376     if default is None:
    377         return SHOW_DEFAULT
    378     SHOW_DEFAULT = bool(default)
    379 
    380 # If do_verify is True, options are checked when drawing a
    381 # GraphicsPrimitive.  See primitive.py
    382 do_verify = True
    383340
    384341from sage.misc.randstate import current_randstate #for plot adaptive refinement
    385 import os #for viewing and writing images
    386342from math import sin, cos, pi #for polar_plot
    387 from sage.structure.sage_object import SageObject
    388343
    389344from sage.ext.fast_eval import fast_float, fast_float_constant, is_fast_float
    390345
    391 from sage.misc.html import html
     346from sage.misc.decorators import options, rename_keyword
    392347
    393 from sage.misc.decorators import options, suboptions, rename_keyword
    394 
    395 from colors import hue, rainbow, rgbcolor, Color, to_mpl_color
    396 
    397 import operator
    398 
    399 ############### WARNING ###
    400 # Try not to import any matplotlib stuff here -- matplotlib is
    401 # slow to import.  (I did benchmarking and found that by not
    402 # importing here, and instead importing when needed below, that
    403 # Sage startup times are much improved.)  - William
    404 ###############
    405 
    406 def is_Graphics(x):
    407     """
    408     Return True if `x` is a Graphics object.
    409    
    410     EXAMPLES::
    411    
    412         sage: from sage.plot.plot import is_Graphics
    413         sage: is_Graphics(1)
    414         False
    415         sage: is_Graphics(disk((0.0, 0.0), 1, (0, pi/2)))
    416         True
    417     """
    418     return isinstance(x, Graphics)
    419 
    420 class Graphics(SageObject):
    421     """
    422     The Graphics object is an empty list of graphics objects It is
    423     useful to use this object when initializing a for loop where
    424     different graphics object will be added to the empty object.
    425    
    426     EXAMPLES::
    427    
    428         sage: G = Graphics(); print G
    429         Graphics object consisting of 0 graphics primitives
    430         sage: c = circle((1,1), 1)
    431         sage: G+=c; print G
    432         Graphics object consisting of 1 graphics primitive
    433    
    434     Here we make a graphic of embedded isosceles triangles, coloring
    435     each one with a different color as we go::
    436    
    437         sage: h=10; c=0.4; p=0.5;
    438         sage: G = Graphics()
    439         sage: for x in srange(1,h+1):
    440         ...        l = [[0,x*sqrt(3)],[-x/2,-x*sqrt(3)/2],[x/2,-x*sqrt(3)/2],[0,x*sqrt(3)]]
    441         ...        G+=line(l,color=hue(c + p*(x/h)))
    442         sage: G.show(figsize=[5,5])
    443 
    444     TESTS:
    445 
    446     From trac #4604, ensure Graphics can handle 3d objects::
    447 
    448         sage: g = Graphics()
    449         sage: g += sphere((1, 1, 1), 2)
    450         sage: g.show()
    451     """
    452 
    453     def __init__(self):
    454         """
    455         Create a new empty Graphics objects with all the defaults.
    456        
    457         EXAMPLES::
    458        
    459             sage: G = Graphics()
    460         """
    461         self.__fontsize = 10
    462         self.__show_axes = True
    463         self.__show_legend = False
    464         self.__legend_opts = {}
    465         self.__axes_color = (0, 0, 0)
    466         self.__axes_label_color = (0, 0, 0)
    467         self.__tick_label_color = (0, 0, 0)
    468         self.__axes_width = 0.8
    469         self.__objects = []
    470         self._extra_kwds = {}
    471         self.__bbox_extra_artists = []
    472 
    473     def set_aspect_ratio(self, ratio):
    474         """
    475         Set the aspect ratio, which is the ratio of height and width
    476         of a unit square (i.e., height/width of a unit square), or
    477         'automatic' (expand to fill the figure).
    478        
    479         INPUT:
    480        
    481        
    482         -  ``ratio`` - a positive real number or 'automatic'
    483        
    484        
    485         EXAMPLES: We create a plot of the upper half of a circle, but it
    486         doesn't look round because the aspect ratio is off::
    487        
    488             sage: P = plot(sqrt(1-x^2),(x,-1,1)); P
    489        
    490         So we set the aspect ratio and now it is round::
    491        
    492             sage: P.set_aspect_ratio(1)
    493             sage: P.aspect_ratio()
    494             1.0
    495             sage: P
    496        
    497         Note that the aspect ratio is inherited upon addition (which takes
    498         the max of aspect ratios of objects whose aspect ratio has been
    499         set)::
    500        
    501             sage: P + plot(sqrt(4-x^2),(x,-2,2))
    502        
    503         In the following example, both plots produce a circle that looks
    504         twice as tall as wide::
    505        
    506             sage: Q = circle((0,0), 0.5); Q.set_aspect_ratio(2)
    507             sage: (P + Q).aspect_ratio(); P+Q
    508             2.0
    509             sage: (Q + P).aspect_ratio(); Q+P
    510             2.0
    511         """
    512         if ratio != 'auto' and ratio != 'automatic':
    513             ratio = float(ratio)
    514             if ratio <= 0:
    515                 raise ValueError, "the aspect ratio must be positive or 'automatic'"
    516         else:
    517             ratio = 'automatic'
    518         self._extra_kwds['aspect_ratio'] = ratio
    519 
    520     def aspect_ratio(self):
    521         """
    522         Get the current aspect ratio, which is the ratio of height to
    523         width of a unit square, or 'automatic'.
    524        
    525         OUTPUT: a positive float (height/width of a unit square), or 'automatic'
    526         (expand to fill the figure).
    527        
    528         EXAMPLES:
    529        
    530         The default aspect ratio for a new blank Graphics object is 'automatic'::
    531 
    532             sage: P = Graphics()
    533             sage: P.aspect_ratio()
    534             'automatic'
    535 
    536         The aspect ratio can be explicitly set different than the object's default::
    537 
    538             sage: P = circle((1,1), 1)
    539             sage: P.aspect_ratio()
    540             1.0
    541             sage: P.set_aspect_ratio(2)
    542             sage: P.aspect_ratio()
    543             2.0
    544             sage: P.set_aspect_ratio('automatic')
    545             sage: P.aspect_ratio()
    546             'automatic'
    547         """
    548         return self._extra_kwds.get('aspect_ratio', 'automatic')
    549 
    550     def legend(self, show=None):
    551         r"""
    552         Set whether or not the legend is shown by default.
    553        
    554         INPUT:
    555 
    556         -  ``show`` - (default: None) a boolean
    557        
    558         If called with no input, return the current legend setting.
    559        
    560         EXAMPLES:
    561 
    562         By default no legend is displayed::
    563 
    564             sage: P = plot(sin)
    565             sage: P.legend()
    566             False
    567            
    568         But if we put a label then the legend is shown::
    569 
    570             sage: P = plot(sin, legend_label='sin')
    571             sage: P.legend()
    572             True
    573 
    574         We can turn it on or off::
    575 
    576             sage: P.legend(False)
    577             sage: P.legend()
    578             False
    579             sage: P.legend(True)
    580             sage: P # show with the legend
    581         """
    582         if show is None:
    583             return self.__show_legend
    584         else:
    585             self.__show_legend = bool(show)
    586 
    587     def set_legend_options(self, **kwds):
    588         r"""
    589         Set various legend options.
    590        
    591         INPUT:
    592 
    593         - ``title`` - (default: None) string, the legend title
    594 
    595         - ``ncol`` - (default: 1) positive integer, the number of columns
    596 
    597         - ``columnspacing`` - (default: None) the spacing between columns
    598 
    599         - ``borderaxespad`` - (default: None) float, length between the axes and the legend
    600 
    601         - ``back_color`` - (default: (0.9, 0.9, 0.9)) This parameter can be a string
    602           denoting a color or an RGB tuple. The string can be a color name
    603           as in ('red', 'green', 'yellow', ...) or a floating point number
    604           like '0.8' which gets expanded to (0.8, 0.8, 0.8). The
    605           tuple form is just a floating point RGB tuple with all values ranging
    606           from 0 to 1.
    607 
    608         - ``handlelength`` - (default: 0.05) float, the length of the legend handles
    609 
    610         - ``handletextpad`` - (default: 0.5) float, the pad between the legend handle and text
    611 
    612         - ``labelspacing`` - (default: 0.02) float, vertical space between legend entries
    613 
    614         - ``loc`` - (default: 'best') May be a string, an integer or a tuple. String or
    615               integer inputs must be one of the following:
    616 
    617           - 0, 'best'
    618 
    619           - 1, 'upper right'
    620 
    621           - 2, 'upper left'
    622 
    623           - 3, 'lower left'
    624 
    625           - 4, 'lower right'
    626 
    627           - 5, 'right'
    628 
    629           - 6, 'center left'
    630 
    631           - 7, 'center right'
    632 
    633           - 8, 'lower center'
    634 
    635           - 9, 'upper center'
    636 
    637           - 10, 'center'
    638 
    639           - Tuple arguments represent an absolute (x, y) position on the plot
    640             in axes coordinates (meaning from 0 to 1 in each direction).
    641 
    642         - ``markerscale`` - (default: 0.6) float, how much to scale the markers in the legend.
    643 
    644         - ``numpoints`` - (default: 2) integer, the number of points in the legend for line
    645 
    646         - ``borderpad`` - (default: 0.6) float, the fractional whitespace inside the legend border
    647           (between 0 and 1)
    648 
    649         - ``font_family`` - (default: 'sans-serif') string, one of 'serif', 'sans-serif',
    650           'cursive', 'fantasy', 'monospace'
    651 
    652         - ``font_style`` - (default: 'normal') string, one of 'normal', 'italic', 'oblique'
    653 
    654         - ``font_variant`` - (default: 'normal') string, one of 'normal', 'small-caps'
    655 
    656         - ``font_weight`` - (default: 'medium') string, one of 'black', 'extra bold', 'bold',
    657           'semibold', 'medium', 'normal', 'light'
    658 
    659         - ``font_size`` - (default: 'medium') string, one of 'xx-small', 'x-small', 'small',
    660           'medium', 'large', 'x-large', 'xx-large' or an absolute font size (e.g. 12)
    661 
    662         -  ``shadow`` - (default: False) boolean - draw a shadow behind the legend
    663 
    664         - ``fancybox`` - (default: False) a boolean.  If True, draws a frame with a round
    665           fancybox.
    666 
    667         These are all keyword arguments.
    668        
    669         OUTPUT: a dictionary of all current legend options
    670            
    671         EXAMPLES:
    672 
    673         By default, no options are set::
    674 
    675             sage: p = plot(tan, legend_label='tan')
    676             sage: p.set_legend_options()
    677             {}
    678        
    679         We build a legend with a shadow::
    680 
    681             sage: p.set_legend_options(shadow=True)
    682             sage: p.set_legend_options()['shadow']
    683             True
    684        
    685         To set the legend position to the center of the plot, all these
    686         methods are roughly equivalent::
    687 
    688             sage: p.set_legend_options(loc='center'); p
    689 
    690         ::
    691 
    692             sage: p.set_legend_options(loc=10); p
    693 
    694         ::
    695 
    696             sage: p.set_legend_options(loc=(0.5,0.5)); p # aligns the bottom of the box to the center
    697         """
    698         if len(kwds) == 0:
    699             return self.__legend_opts
    700         else:
    701             self.__legend_opts.update(kwds)
    702    
    703 
    704     def get_axes_range(self):
    705         """
    706         Returns a dictionary of the range of the axes for this graphics
    707         object.  This is fall back to the ranges in get_minmax_data() for
    708         any value which the user has not explicitly set.
    709 
    710         .. warning::
    711 
    712            Changing the dictionary returned by this function does not
    713            change the axes range for this object.  To do that, use the
    714            :meth:`set_axes_range` method.
    715 
    716         EXAMPLES::
    717 
    718             sage: L = line([(1,2), (3,-4), (2, 5), (1,2)])
    719             sage: list(sorted(L.get_axes_range().items()))
    720             [('xmax', 3.0), ('xmin', 1.0), ('ymax', 5.0), ('ymin', -4.0)]
    721             sage: L.set_axes_range(xmin=-1)
    722             sage: list(sorted(L.get_axes_range().items()))
    723             [('xmax', 3.0), ('xmin', -1.0), ('ymax', 5.0), ('ymin', -4.0)]
    724         """
    725         axes_range = self.get_minmax_data()
    726         axes_range.update(self._get_axes_range_dict())
    727         return axes_range
    728 
    729     def set_axes_range(self, xmin=None, xmax=None, ymin=None, ymax=None):
    730         """
    731         Set the ranges of the `x` and `y` axes.
    732        
    733         INPUT:
    734        
    735        
    736         -  ``xmin, xmax, ymin, ymax`` - floats
    737        
    738        
    739         EXAMPLES::
    740        
    741             sage: L = line([(1,2), (3,-4), (2, 5), (1,2)])
    742             sage: L.set_axes_range(-1, 20, 0, 2)
    743             sage: d = L.get_axes_range()
    744             sage: d['xmin'], d['xmax'], d['ymin'], d['ymax']
    745             (-1.0, 20.0, 0.0, 2.0)
    746         """
    747         l = locals()
    748         axes_range = self._get_axes_range_dict()
    749         for name in ['xmin', 'xmax', 'ymin', 'ymax']:
    750             if l[name] is not None:
    751                 axes_range[name] = float(l[name])
    752 
    753     axes_range = set_axes_range
    754 
    755     def _get_axes_range_dict(self):
    756         """
    757         Returns the underlying dictionary used to store the user's
    758         custom ranges for the axes on this object.
    759 
    760         EXAMPLES::
    761 
    762             sage: L = line([(1,2), (3,-4), (2, 5), (1,2)])
    763             sage: L._get_axes_range_dict()
    764             {}
    765             sage: L.set_axes_range(xmin=-1)
    766             sage: L._get_axes_range_dict()
    767             {'xmin': -1.0}
    768         """
    769         try:
    770             return self.__axes_range
    771         except AttributeError:
    772             self.__axes_range = {}
    773             return self.__axes_range
    774 
    775     def fontsize(self, s=None):
    776         """
    777         Set the font size of axes labels and tick marks.
    778        
    779         INPUT:
    780        
    781        
    782         -  ``s`` - integer, a font size in points.
    783        
    784        
    785         If called with no input, return the current fontsize.
    786        
    787         EXAMPLES::
    788        
    789             sage: L = line([(1,2), (3,-4), (2, 5), (1,2)])
    790             sage: L.fontsize()
    791             10
    792             sage: L.fontsize(20)
    793             sage: L.fontsize()
    794             20
    795        
    796         All the numbers on the axes will be very large in this plot::
    797        
    798             sage: L
    799         """
    800         if s is None:
    801             try:
    802                 return self.__fontsize
    803             except AttributeError:
    804                 self.__fontsize = 10
    805                 return self.__fontsize
    806         self.__fontsize = int(s)
    807 
    808     def axes(self, show=None):
    809         """
    810         Set whether or not the `x` and `y` axes are shown
    811         by default.
    812        
    813         INPUT:
    814        
    815        
    816         -  ``show`` - bool
    817        
    818        
    819         If called with no input, return the current axes setting.
    820        
    821         EXAMPLES::
    822        
    823             sage: L = line([(1,2), (3,-4), (2, 5), (1,2)])
    824        
    825         By default the axes are displayed.
    826        
    827         ::
    828        
    829             sage: L.axes()
    830             True
    831        
    832         But we turn them off, and verify that they are off
    833        
    834         ::
    835        
    836             sage: L.axes(False)
    837             sage: L.axes()
    838             False
    839        
    840         Displaying L now shows a triangle but no axes.
    841        
    842         ::
    843        
    844             sage: L
    845         """
    846         if show is None:
    847             try:
    848                 return self.__show_axes
    849             except AttributeError:
    850                 self.__show_axes = True
    851                 return self.__show_axes
    852         self.__show_axes = bool(show)
    853 
    854     def axes_color(self, c=None):
    855         """
    856         Set the axes color.
    857        
    858         If called with no input, return the current axes_color setting.
    859        
    860         INPUT:
    861        
    862        
    863         -  ``c`` - an RGB color 3-tuple, where each tuple entry
    864            is a float between 0 and 1
    865        
    866        
    867         EXAMPLES: We create a line, which has like everything a default
    868         axes color of black.
    869        
    870         ::
    871        
    872             sage: L = line([(1,2), (3,-4), (2, 5), (1,2)])
    873             sage: L.axes_color()
    874             (0, 0, 0)
    875        
    876         We change the axes color to red and verify the change.
    877        
    878         ::
    879        
    880             sage: L.axes_color((1,0,0))
    881             sage: L.axes_color()
    882             (1.0, 0.0, 0.0)
    883        
    884         When we display the plot, we'll see a blue triangle and bright red
    885         axes.
    886        
    887         ::
    888        
    889             sage: L
    890         """
    891         if c is None:
    892             try:
    893                 return self.__axes_color
    894            
    895             except AttributeError:
    896                 self.__axes_color = (0.0, 0.0, 0.0)
    897                 return self.__axes_color
    898         self.__axes_color = rgbcolor(c)
    899 
    900     def axes_labels(self, l=None):
    901         """
    902         Set the axes labels.
    903        
    904         INPUT:
    905        
    906        
    907         -  ``l`` - (default: None) a list of two strings or
    908            None
    909        
    910        
    911         OUTPUT: a 2-tuple of strings
    912        
    913         If l is None, returns the current ``axes_labels``,
    914         which is itself by default None. The default labels are both
    915         empty.
    916        
    917         EXAMPLES: We create a plot and put x and y axes labels on it.
    918        
    919         ::
    920        
    921             sage: p = plot(sin(x), (x, 0, 10))
    922             sage: p.axes_labels(['$x$','$y$'])
    923             sage: p.axes_labels()
    924             ('$x$', '$y$')
    925        
    926         Now when you plot p, you see x and y axes labels::
    927        
    928             sage: p
    929 
    930         Notice that some may prefer axes labels which are not
    931         typeset::
    932 
    933             sage: plot(sin(x), (x, 0, 10), axes_labels=['x','y'])
    934         """
    935         if l is None:
    936             try:
    937                 return self.__axes_labels
    938             except AttributeError:
    939                 self.__axes_labels = None
    940                 return self.__axes_labels
    941         if not isinstance(l, (list, tuple)):
    942             raise TypeError, "l must be a list or tuple"
    943         if len(l) != 2:
    944             raise ValueError, "l must have length 2"
    945         self.__axes_labels = (str(l[0]), str(l[1]))
    946 
    947     def axes_label_color(self, c=None):
    948         r"""
    949         Set the color of the axes labels.
    950        
    951         The axes labels are placed at the edge of the x and y axes, and are
    952         not on by default (use the ``axes_labels`` command to
    953         set them; see the example below). This function just changes their
    954         color.
    955        
    956         INPUT:
    957        
    958        
    959         -  ``c`` - an RGB 3-tuple of numbers between 0 and 1
    960        
    961        
    962         If called with no input, return the current axes_label_color
    963         setting.
    964        
    965         EXAMPLES: We create a plot, which by default has axes label color
    966         black.
    967        
    968         ::
    969        
    970             sage: p = plot(sin, (-1,1))
    971             sage: p.axes_label_color()
    972             (0, 0, 0)
    973        
    974         We change the labels to be red, and confirm this::
    975        
    976             sage: p.axes_label_color((1,0,0))
    977             sage: p.axes_label_color()
    978             (1.0, 0.0, 0.0)
    979        
    980         We set labels, since otherwise we won't see anything.
    981        
    982         ::
    983        
    984             sage: p.axes_labels(['$x$ axis', '$y$ axis'])
    985        
    986         In the plot below, notice that the labels are red::
    987        
    988             sage: p
    989         """
    990         if c is None:
    991             try:
    992                 return self.__axes_label_color
    993             except AttributeError:
    994                 self.__axes_label_color = (0, 0, 0)
    995                 return self.__axes_label_color
    996         self.__axes_label_color = rgbcolor(c)
    997 
    998 
    999     def axes_width(self, w=None):
    1000         r"""
    1001         Set the axes width. Use this to draw a plot with really fat or
    1002         really thin axes.
    1003        
    1004         INPUT:
    1005        
    1006        
    1007         -  ``w`` - a float
    1008        
    1009        
    1010         If called with no input, return the current
    1011         ``axes_width`` setting.
    1012        
    1013         EXAMPLE: We create a plot, see the default axes width (with funny
    1014         Python float rounding), then reset the width to 10 (very fat).
    1015        
    1016         ::
    1017        
    1018             sage: p = plot(cos, (-3,3))
    1019             sage: p.axes_width()
    1020             0.8
    1021             sage: p.axes_width(10)
    1022             sage: p.axes_width()
    1023             10.0
    1024        
    1025         Finally we plot the result, which is a graph with very fat axes.
    1026        
    1027         ::
    1028        
    1029             sage: p
    1030         """
    1031         if w is None:
    1032             try:
    1033                 return self.__axes_width
    1034             except AttributeError:
    1035                 self.__axes_width = True
    1036                 return self.__axes_width
    1037         self.__axes_width = float(w)
    1038 
    1039     def tick_label_color(self, c=None):
    1040         """
    1041         Set the color of the axes tick labels.
    1042        
    1043         INPUT:
    1044        
    1045        
    1046         -  ``c`` - an RGB 3-tuple of numbers between 0 and 1
    1047        
    1048        
    1049         If called with no input, return the current tick_label_color
    1050         setting.
    1051        
    1052         EXAMPLES::
    1053        
    1054             sage: p = plot(cos, (-3,3))
    1055             sage: p.tick_label_color()
    1056             (0, 0, 0)
    1057             sage: p.tick_label_color((1,0,0))
    1058             sage: p.tick_label_color()
    1059             (1.0, 0.0, 0.0)
    1060             sage: p
    1061         """
    1062         if c is None:
    1063             try:
    1064                 return self.__tick_label_color
    1065             except AttributeError:
    1066                 self.__tick_label_color = (0, 0, 0)
    1067                 return self.__tick_label_color
    1068         self.__tick_label_color = rgbcolor(c)
    1069 
    1070     def _repr_(self):
    1071         r"""
    1072         Show this graphics objects.
    1073        
    1074         If the ``show_default`` function has been called with
    1075         True (the default), then you'll see this graphics object displayed.
    1076         Otherwise you'll see a text representation of it.
    1077        
    1078         EXAMPLES: We create a plot and call ``_repr_`` on it,
    1079         which causes it to be displayed as a plot::
    1080        
    1081             sage: P = plot(cos, (-1,1))
    1082             sage: P._repr_()
    1083             ''
    1084        
    1085         Just doing this also displays the plot::
    1086        
    1087             sage: P
    1088        
    1089         Note that printing P with the ``print`` statement does
    1090         not display the plot::
    1091        
    1092             sage: print P
    1093             Graphics object consisting of 1 graphics primitive
    1094        
    1095         Now we turn off showing plots by default::
    1096        
    1097             sage: show_default(False)
    1098        
    1099         Now we just get a string. To show P you would have to do
    1100         ``show(P)``.
    1101        
    1102         ::
    1103        
    1104             sage: P._repr_()
    1105             'Graphics object consisting of 1 graphics primitive'
    1106             sage: P
    1107             Graphics object consisting of 1 graphics primitive
    1108        
    1109         Finally, we turn ``show_default`` back on::
    1110        
    1111             sage: show_default(True)
    1112         """
    1113         if SHOW_DEFAULT:
    1114             self.show()
    1115             return ''
    1116         else:
    1117             return self.__str__()
    1118 
    1119     def __str__(self):
    1120         r"""
    1121         Return string representation of this plot.
    1122        
    1123         EXAMPLES::
    1124        
    1125             sage: S = circle((0,0), 2); S.__str__()
    1126             'Graphics object consisting of 1 graphics primitive'
    1127             sage: print S
    1128             Graphics object consisting of 1 graphics primitive
    1129        
    1130         .. warning::
    1131 
    1132            ``__str__`` is not called when printing lists of graphics
    1133            objects, which can be confusing, since they will all pop
    1134            up. One workaround is to call ``show_default``:
    1135        
    1136         For example, below when we do ``print v`` two plots are
    1137         displayed::
    1138        
    1139             sage: v = [circle((0,0), 2), circle((2,3), 1)]
    1140             sage: print v
    1141             [, ]
    1142        
    1143         However, if we call ``show_default`` then we see the
    1144         text representations of the graphics::
    1145        
    1146             sage: show_default(False)
    1147             sage: print v
    1148             [Graphics object consisting of 1 graphics primitive, Graphics object consisting of 1 graphics primitive]
    1149             sage: v
    1150             [Graphics object consisting of 1 graphics primitive,
    1151              Graphics object consisting of 1 graphics primitive]
    1152        
    1153         ::
    1154        
    1155             sage: show_default(True)
    1156         """
    1157         pr, i = '', 0
    1158         for x in self:
    1159             pr += '\n\t%s -- %s'%(i, x)
    1160             i += 1
    1161         s = "Graphics object consisting of %s graphics primitives"%(len(self))
    1162         if len(self) == 1:
    1163             s = s[:-1]
    1164         return s
    1165 
    1166     def __getitem__(self, i):
    1167         """
    1168         Returns the ith graphics primitive object:
    1169        
    1170         EXAMPLE::
    1171        
    1172             sage: G = circle((1,1),2) + circle((2,2),5); print G
    1173             Graphics object consisting of 2 graphics primitives
    1174             sage: G[1]
    1175             Circle defined by (2.0,2.0) with r=5.0
    1176         """
    1177         return self.__objects[i]
    1178 
    1179     def __len__(self):
    1180         """
    1181         If G is of type Graphics, then len(G) gives the number of distinct
    1182         graphics primitives making up that object.
    1183        
    1184         EXAMPLES::
    1185        
    1186             sage: G = circle((1,1),1) + circle((1,2),1) + circle((1,2),5); print G
    1187             Graphics object consisting of 3 graphics primitives
    1188             sage: len(G)
    1189             3
    1190         """
    1191         return len(self.__objects)
    1192 
    1193     def __delitem__(self, i):
    1194         """
    1195         If G is of type Graphics, then del(G[i]) removes the ith distinct
    1196         graphic primitive making up that object.
    1197        
    1198         EXAMPLES::
    1199        
    1200             sage: G = circle((1,1),1) + circle((1,2),1) + circle((1,2),5); print G
    1201             Graphics object consisting of 3 graphics primitives
    1202             sage: len(G)
    1203             3
    1204             sage: del(G[2])
    1205             sage: print G
    1206             Graphics object consisting of 2 graphics primitives
    1207             sage: len(G)
    1208             2
    1209         """
    1210         del self.__objects[int(i)]
    1211 
    1212     def __setitem__(self, i, x):
    1213         """
    1214         You can replace a GraphicPrimitive (point, line, circle, etc...) in
    1215         a Graphics object G with any other GraphicPrimitive
    1216        
    1217         EXAMPLES::
    1218        
    1219             sage: G = circle((1,1),1) + circle((1,2),1) + circle((1,2),5); print G
    1220             Graphics object consisting of 3 graphics primitives
    1221        
    1222         ::
    1223        
    1224             sage: p = polygon([[1,3],[2,-2],[1,1],[1,3]]); print p
    1225             Graphics object consisting of 1 graphics primitive
    1226        
    1227         ::
    1228        
    1229             sage: G[1] = p[0]
    1230             sage: G    # show the plot
    1231         """
    1232         from sage.plot.primitive import GraphicPrimitive
    1233         if not isinstance(x, GraphicPrimitive):
    1234             raise TypeError, "x must be a GraphicPrimitive"
    1235         self.__objects[int(i)] = x
    1236 
    1237     def __radd__(self, other):
    1238         """
    1239         Compute and return other + this graphics object.
    1240        
    1241         This only works when other is a Python int equal to 0. In all other
    1242         cases a TypeError is raised. The main reason for this function is
    1243         to make summing a list of graphics objects easier.
    1244        
    1245         EXAMPLES::
    1246        
    1247             sage: S = circle((0,0), 2)
    1248             sage: print int(0) + S
    1249             Graphics object consisting of 1 graphics primitive
    1250             sage: print S + int(0)
    1251             Graphics object consisting of 1 graphics primitive
    1252        
    1253         The following would fail were it not for this function::
    1254        
    1255             sage: v = [circle((0,0), 2), circle((2,3), 1)]
    1256             sage: print sum(v)
    1257             Graphics object consisting of 2 graphics primitives
    1258         """
    1259         if isinstance(other, (int, long)) and other == 0:
    1260             return self
    1261         raise TypeError
    1262 
    1263     def __add__(self, other):
    1264         """
    1265         If you have any Graphics object G1, you can always add any other
    1266         amount of Graphics objects G2,G3,... to form a new Graphics object:
    1267         G4 = G1 + G2 + G3.
    1268        
    1269         The xmin, xmax, ymin, and ymax properties of the graphics objects
    1270         are expanded to include all objects in both scenes. If the aspect
    1271         ratio property of either or both objects are set, then the larger
    1272         aspect ratio is chosen, with 'automatic' being overridden by a
    1273         numeric aspect ratio.
    1274 
    1275         If one of the graphics object is set to show a legend, then the
    1276         resulting object will also be set to show a legend.  None of the
    1277         legend options are carried over.
    1278 
    1279         EXAMPLES::
    1280        
    1281             sage: g1 = plot(abs(sqrt(x^3-1)), (x,1,5), frame=True)
    1282             sage: g2 = plot(-abs(sqrt(x^3-1)), (x,1,5), color='red')
    1283             sage: g1 + g2  # displays the plot
    1284 
    1285         TESTS:
    1286 
    1287         Extra keywords to show are propagated::
    1288 
    1289             sage: (g1 + g2)._extra_kwds=={'aspect_ratio': 'automatic', 'frame': True}
    1290             True
    1291             sage: g1.set_aspect_ratio(2)
    1292             sage: (g1+g2).aspect_ratio()
    1293             2.0
    1294             sage: g2.set_aspect_ratio(3)
    1295             sage: (g1+g2).aspect_ratio()
    1296             3.0
    1297         """
    1298         if isinstance(other, int) and other == 0:
    1299             return self
    1300         if not isinstance(other, Graphics):
    1301             from sage.plot.plot3d.base import Graphics3d
    1302             if isinstance(other, Graphics3d):
    1303                 return self.plot3d() + other
    1304             raise TypeError, "other (=%s) must be a Graphics objects"%other
    1305         g = Graphics()
    1306         g.__objects = self.__objects + other.__objects
    1307         g.__show_legend = self.__show_legend or other.__show_legend
    1308         g._extra_kwds.update(self._extra_kwds)
    1309         g._extra_kwds.update(other._extra_kwds)
    1310         if self.aspect_ratio()=='automatic':
    1311             g.set_aspect_ratio(other.aspect_ratio())
    1312         elif other.aspect_ratio()=='automatic':
    1313             g.set_aspect_ratio(self.aspect_ratio())
    1314         else:
    1315             g.set_aspect_ratio( max(self.aspect_ratio(), other.aspect_ratio()))
    1316         return g
    1317  
    1318     def add_primitive(self, primitive):
    1319         """
    1320         Adds a primitive to this graphics object.
    1321 
    1322         EXAMPLES:
    1323 
    1324         We give a very explicit example::
    1325 
    1326             sage: G = Graphics()
    1327             sage: from sage.plot.line import Line
    1328             sage: from sage.plot.arrow import Arrow
    1329             sage: L = Line([3,4,2,7,-2],[1,2,e,4,5.],{'alpha':1,'thickness':2,'rgbcolor':(0,1,1),'legend_label':''})
    1330             sage: A = Arrow(2,-5,.1,.2,{'width':3,'head':0,'rgbcolor':(1,0,0),'linestyle':'dashed','zorder':8,'legend_label':''})
    1331             sage: G.add_primitive(L)
    1332             sage: G.add_primitive(A)
    1333             sage: G
    1334         """
    1335         self.__objects.append(primitive)
    1336 
    1337     def plot(self, *args, **kwds):
    1338         """
    1339         Draw a 2D plot of this graphics object, which just returns this
    1340         object since this is already a 2D graphics object.
    1341        
    1342         EXAMPLES::
    1343        
    1344             sage: S = circle((0,0), 2)
    1345             sage: S.plot() is S
    1346             True
    1347         """
    1348         return self
    1349        
    1350     def plot3d(self, z=0, **kwds):
    1351         """
    1352         Returns an embedding of this 2D plot into the xy-plane of 3D space,
    1353         as a 3D plot object. An optional parameter z can be given to
    1354         specify the z-coordinate.
    1355        
    1356         EXAMPLES::
    1357        
    1358             sage: sum([plot(z*sin(x), 0, 10).plot3d(z) for z in range(6)]) # long time
    1359         """
    1360         from sage.plot.plot3d.base import Graphics3dGroup
    1361         g = Graphics3dGroup([g.plot3d(**kwds) for g in self.__objects])
    1362         if z:
    1363             g = g.translate(0,0,z)
    1364         return g
    1365        
    1366     @classmethod
    1367     def _extract_kwds_for_show(cls, kwds, ignore=[]):
    1368         """
    1369         Extract keywords relevant to show() from the provided dictionary.
    1370 
    1371         EXAMPLES::
    1372 
    1373             sage: kwds = {'f': lambda x: x, 'xmin': 0, 'figsize': [1,1], 'plot_points': (40, 40)}
    1374             sage: G_kwds = Graphics._extract_kwds_for_show(kwds, ignore='xmin')
    1375             sage: kwds # Note how this action modifies the passed dictionary
    1376             {'xmin': 0, 'plot_points': (40, 40), 'f': <function <lambda> at ...>}
    1377             sage: G_kwds
    1378             {'figsize': [1, 1]}
    1379 
    1380         This method is intended to be used with _set_extra_kwds(). Here is an
    1381         idiom to ensure the correct keywords will get passed on to show()::
    1382 
    1383             sage: options = {} # Usually this will come from an argument
    1384             sage: g = Graphics()
    1385             sage: g._set_extra_kwds(Graphics._extract_kwds_for_show(options))
    1386         """
    1387         result = {}
    1388         for option in cls.SHOW_OPTIONS:
    1389             if option not in ignore:
    1390                 try:
    1391                     result[option] = kwds.pop(option)
    1392                 except KeyError:
    1393                     pass
    1394         return result
    1395 
    1396     def _set_extra_kwds(self, kwds):
    1397         """
    1398         Set a dictionary of keywords that will get passed on to show().
    1399 
    1400         TESTS::
    1401 
    1402             sage: g = Graphics()
    1403             sage: g._extra_kwds
    1404             {}
    1405             sage: g._set_extra_kwds({'figsize': [10,10]})
    1406             sage: g._extra_kwds
    1407             {'figsize': [10, 10]}
    1408             sage: g.show() # Now the (blank) plot will be extra large
    1409         """
    1410         self._extra_kwds = kwds
    1411 
    1412     # This dictionary has the default values for the keywords to show(). When
    1413     # show is invoked with keyword arguments, those arguments are merged with
    1414     # this dictionary to create a set of keywords with the defaults filled in.
    1415     # Then, those keywords are passed on to save().
    1416 
    1417     # NOTE: If you intend to use a new parameter in show(), you should update
    1418     # this dictionary to contain the default value for that parameter.
    1419 
    1420     SHOW_OPTIONS = dict(xmin=None, xmax=None, ymin=None, ymax=None,
    1421                         figsize=None, fig_tight=True,
    1422                         filename=None,
    1423                         dpi=DEFAULT_DPI, axes=None, axes_labels=None,frame=False,
    1424                         fontsize=None,
    1425                         aspect_ratio=None,
    1426                         gridlines=None, gridlinesstyle=None,
    1427                         vgridlinesstyle=None, hgridlinesstyle=None,transparent=False,
    1428                         show_legend=None, legend_options={},
    1429                         axes_pad=.02, ticks_integer=False,
    1430                         ticks=None, tick_formatter=None)
    1431 
    1432     @suboptions('legend', numpoints=2, borderpad=0.6, markerscale=0.6, shadow=False,
    1433                 labelspacing=0.02, handlelength=0.05, handletextpad=0.5, borderaxespad=None,
    1434                 loc='best', font_size='medium', font_family='sans-serif', font_style='normal',
    1435                 font_weight='medium', font_variant='normal', back_color=(0.9, 0.9, 0.9),
    1436                 title=None, ncol=1, columnspacing=None, fancybox=False)
    1437     def show(self, **kwds):
    1438         """
    1439         Show this graphics image with the default image viewer.
    1440 
    1441         OPTIONAL INPUT:
    1442 
    1443         - ``filename`` - (default: None) string
    1444 
    1445         - ``dpi`` - dots per inch
    1446 
    1447         - ``figsize`` - [width, height]
    1448 
    1449         - ``fig_tight`` - (default: True) whether to clip the drawing
    1450           tightly around drawn objects.  If True, then the resulting
    1451           image will usually not have dimensions corresponding to
    1452           ``figsize``.  If False, the resulting image will have
    1453           dimensions corresponding to ``figsize``.
    1454 
    1455         - ``aspect_ratio`` - the perceived height divided by the
    1456           perceived width. For example, if the aspect ratio is set to ``1``, circles
    1457           will look round and a unit square will appear to have sides
    1458           of equal length, and if the aspect ratio is set ``2``, vertical units will be
    1459           twice as long as horizontal units, so a unit square will be twice as
    1460           high as it is wide.  If set to ``'automatic'``, the aspect ratio
    1461           is determined by ``figsize`` and the picture fills the figure.
    1462 
    1463         - ``axes`` - (default: True)
    1464        
    1465         - ``axes_labels`` - (default: None) list (or tuple) of two
    1466           strings; the first is used as the label for the horizontal
    1467           axis, and the second for the vertical axis.
    1468                            
    1469         - ``fontsize`` - (default: current setting -- 10) positive
    1470           integer; used for axes labels; if you make this very large,
    1471           you may have to increase figsize to see all labels.
    1472 
    1473         - ``frame`` - (default: False) draw a frame around the image
    1474 
    1475         - ``gridlines`` - (default: None) can be any of the following:
    1476 
    1477           - None, False: do not add grid lines.
    1478 
    1479           - True, "automatic", "major": add grid lines at major ticks of the axes.
    1480 
    1481           - "minor": add grid at major and minor ticks.
    1482 
    1483           - [xlist,ylist]: a tuple or list containing
    1484             two elements, where xlist (or ylist) can be
    1485             any of the following.
    1486 
    1487 
    1488             - None, False: don't add horizontal (or vertical) lines.
    1489 
    1490             - True, "automatic", "major": add horizontal (or vertical) grid lines at
    1491               the major ticks of the axes.
    1492 
    1493             - "minor": add horizontal (or vertical) grid lines at major and minor ticks of
    1494               axes.
    1495 
    1496             - an iterable yielding numbers n or pairs (n,opts), where n
    1497               is the coordinate of the line and opt is a dictionary of
    1498               MATPLOTLIB options for rendering the line.
    1499 
    1500 
    1501         - ``gridlinesstyle, hgridlinesstyle, vgridlinesstyle`` -
    1502           (default: None) a dictionary of MATPLOTLIB options for the
    1503           rendering of the grid lines, the horizontal grid lines or the
    1504           vertical grid lines, respectively.
    1505 
    1506         - ``linkmode`` - (default: False) If True a string containing a link
    1507             to the produced file is returned.
    1508 
    1509         - ``transparent`` - (default: False) If True, make the background transparent.
    1510 
    1511         - ``axes_pad`` - (default: 0.02) The percentage of the axis
    1512           range that is added to each end of each axis.  This helps
    1513           avoid problems like clipping lines because of line-width,
    1514           etc.  To get axes that are exactly the specified limits, set
    1515           ``axes_pad`` to zero.
    1516 
    1517         - ``ticks_integer`` - (default: False) guarantee that the ticks
    1518           are integers (the ``ticks`` option, if specified, will
    1519           override this)
    1520 
    1521         - ``ticks`` - A matplotlib locator for the major ticks, or
    1522           a number. There are several options.  For more information about
    1523           locators, type ``from matplotlib import ticker`` and then
    1524           ``ticker?``.
    1525 
    1526           - If this is a locator object, then it is the locator for
    1527             the horizontal axis.  A value of None means use the default
    1528             locator.
    1529 
    1530           - If it is a list of two locators, then the first is for the
    1531             horizontal axis and one for the vertical axis.  A value of
    1532             None means use the default locator (so a value of
    1533             [None, my_locator] uses my_locator for the vertical axis and
    1534             the default for the horizontal axis).
    1535 
    1536           - If in either case above one of the entries is a number `m`
    1537             (something which can be coerced to a float), it will be
    1538             replaced by a MultipleLocator which places major ticks at
    1539             integer multiples of `m`.  See examples.
    1540 
    1541           - If in either case above one of the entries is a list of
    1542             numbers, it will be replaced by a FixedLocator which places
    1543             ticks at the locations specified.  This includes the case of
    1544             of the empty list, which will give no ticks.  See examples.
    1545 
    1546         - ``tick_formatter`` - A matplotlib formatter for the major
    1547           ticks. There are several options.  For more information about
    1548           formatters, type ``from matplotlib import ticker`` and then
    1549           ``ticker?``.
    1550 
    1551           If the value of this keyword is a single item, then this will
    1552           give the formatting for the horizontal axis *only* (except for
    1553           the ``"latex"`` option).  If it is a list or tuple, the first
    1554           is for the horizontal axis, the second for the vertical axis.
    1555           The options are below:
    1556 
    1557           - If one of the entries is a formatter object, then it used.
    1558             A value of None means to use the default locator (so using
    1559             ``tick_formatter=[None, my_formatter]`` uses my_formatter
    1560             for the vertical axis and the default for the horizontal axis).
    1561 
    1562           - If one of the entries is a symbolic constant such as `\pi`,
    1563             `e`, or `sqrt(2)`, ticks will be formatted nicely at rational
    1564             multiples of this constant.
    1565 
    1566           .. warning:: This should only be used with the ``ticks`` option
    1567              using nice rational multiples of that constant!
    1568 
    1569           - If one of the entries is the string ``"latex"``, then the
    1570             formatting will be nice typesetting of the ticks.  This is
    1571             intended to be used when the tick locator for at least one of
    1572             the axes is a list including some symbolic elements.  See examples.
    1573 
    1574         - ``show_legend`` - (default: None) If True, show the legend
    1575 
    1576         - ``legend_*`` - all the options valid for :meth:`set_legend_options` prefixed with ``legend_``
    1577 
    1578         EXAMPLES::
    1579        
    1580             sage: c = circle((1,1), 1, color='red')
    1581             sage: c.show(xmin=-1, xmax=3, ymin=-1, ymax=3)
    1582        
    1583         You could also just make the picture larger by changing ``figsize``::
    1584 
    1585             sage: c.show(figsize=8, xmin=-1, xmax=3, ymin=-1, ymax=3)       
    1586        
    1587         You can turn off the drawing of the axes::
    1588        
    1589             sage: show(plot(sin,-4,4), axes=False)
    1590        
    1591         You can also label the axes.  Putting something in dollar
    1592         signs formats it as a mathematical expression::
    1593        
    1594             sage: show(plot(sin,-4,4), axes_labels=('$x$','$y$'))
    1595        
    1596         You can turn on the drawing of a frame around the plots::
    1597        
    1598             sage: show(plot(sin,-4,4), frame=True)
    1599        
    1600         You can make the background transparent::
    1601 
    1602             sage: plot(sin(x), (x, -4, 4), transparent=True)
    1603 
    1604         Add grid lines at the major ticks of the axes.
    1605        
    1606         ::
    1607        
    1608             sage: c = circle((0,0), 1)
    1609             sage: c.show(gridlines=True)
    1610             sage: c.show(gridlines="automatic")
    1611             sage: c.show(gridlines="major")
    1612        
    1613         Add grid lines at the major and minor ticks of the axes.
    1614        
    1615         ::
    1616        
    1617             sage: u,v = var('u v')
    1618             sage: f = exp(-(u^2+v^2))
    1619             sage: p = plot_vector_field(f.gradient(), (u,-2,2), (v,-2,2))
    1620             sage: p.show(gridlines="minor")
    1621        
    1622         Add only horizontal or vertical grid lines.
    1623        
    1624         ::
    1625        
    1626             sage: p = plot(sin,-10,20)
    1627             sage: p.show(gridlines=[None, "automatic"])
    1628             sage: p.show(gridlines=["minor", False])
    1629        
    1630         Add grid lines at specific positions (using lists/tuples).
    1631        
    1632         ::
    1633        
    1634             sage: x, y = var('x, y')
    1635             sage: p = implicit_plot((y^2-x^2)*(x-1)*(2*x-3)-4*(x^2+y^2-2*x)^2, \
    1636             ...             (x,-2,2), (y,-2,2), plot_points=1000)
    1637             sage: p.show(gridlines=[[1,0],[-1,0,1]])
    1638        
    1639         Add grid lines at specific positions (using iterators).
    1640        
    1641         ::
    1642        
    1643             sage: def maple_leaf(t):
    1644             ...     return (100/(100+(t-pi/2)^8))*(2-sin(7*t)-cos(30*t)/2)
    1645             sage: p = polar_plot(maple_leaf, -pi/4, 3*pi/2, color="red",plot_points=1000) # long time
    1646             sage: p.show(gridlines=( [-3,-2.75,..,3], xrange(-1,5,2) )) # long time
    1647        
    1648         Add grid lines at specific positions (using functions).
    1649        
    1650         ::
    1651        
    1652             sage: y = x^5 + 4*x^4 - 10*x^3 - 40*x^2 + 9*x + 36
    1653             sage: p = plot(y, -4.1, 1.1)
    1654             sage: xlines = lambda a,b: [z for z,m in y.roots()]
    1655             sage: p.show(gridlines=[xlines, [0]], frame=True, axes=False)
    1656        
    1657         Change the style of all the grid lines.
    1658        
    1659         ::
    1660        
    1661             sage: b = bar_chart([-3,5,-6,11], color='red')
    1662             sage: b.show(gridlines=([-1,-0.5,..,4],True),
    1663             ...     gridlinesstyle=dict(color="blue", linestyle=":"))
    1664        
    1665         Change the style of the horizontal or vertical grid lines
    1666         separately.
    1667        
    1668         ::
    1669        
    1670             sage: p = polar_plot(2 + 2*cos(x), 0, 2*pi, color=hue(0.3))
    1671             sage: p.show(gridlines=True,
    1672             ...     hgridlinesstyle=dict(color="orange", linewidth=1.0),
    1673             ...     vgridlinesstyle=dict(color="blue", linestyle=":"))
    1674        
    1675         Change the style of each grid line individually.
    1676        
    1677         ::
    1678        
    1679             sage: x, y = var('x, y')
    1680             sage: p = implicit_plot((y^2-x^2)*(x-1)*(2*x-3)-4*(x^2+y^2-2*x)^2,
    1681             ...             (x,-2,2), (y,-2,2), plot_points=1000)
    1682             sage: p.show(gridlines=(
    1683             ...    [
    1684             ...     (1,{"color":"red","linestyle":":"}),
    1685             ...     (0,{"color":"blue","linestyle":"--"})
    1686             ...    ],
    1687             ...    [
    1688             ...     (-1,{"color":"red","linestyle":":"}),
    1689             ...     (0,{"color":"blue","linestyle":"--"}),
    1690             ...     (1,{"color":"red","linestyle":":"}),
    1691             ...    ]
    1692             ...    ),
    1693             ...    gridlinesstyle=dict(marker='x',color="black"))
    1694        
    1695         Grid lines can be added to contour plots.
    1696        
    1697         ::
    1698        
    1699             sage: f = sin(x^2 + y^2)*cos(x)*sin(y)
    1700             sage: c = contour_plot(f, (x, -4, 4), (y, -4, 4), plot_points=100)
    1701             sage: c.show(gridlines=True, gridlinesstyle={'linestyle':':','linewidth':1, 'color':'red'})
    1702        
    1703         Grid lines can be added to matrix plots.
    1704        
    1705         ::
    1706        
    1707             sage: M = MatrixSpace(QQ,10).random_element()
    1708             sage: matrix_plot(M).show(gridlines=True)
    1709 
    1710         By default, Sage increases the horizontal and vertical axes
    1711         limits by a certain percentage in all directions.  This is
    1712         controlled by the ``axes_pad`` parameter.  Increasing the range
    1713         of the axes helps avoid problems with lines and dots being
    1714         clipped because the linewidth extends beyond the axes.  To get
    1715         axes limits that are exactly what is specified, set
    1716         ``axes_pad`` to zero.  Compare the following two examples
    1717 
    1718         ::
    1719        
    1720             sage: plot(sin(x), (x, -pi, pi),thickness=2)+point((pi, -1), pointsize=15)
    1721             sage: plot(sin(x), (x, -pi, pi),thickness=2,axes_pad=0)+point((pi, -1), pointsize=15)
    1722        
    1723         Via matplotlib, Sage allows setting of custom ticks.  See above
    1724         for more details.
    1725 
    1726         ::
    1727 
    1728             sage: plot(sin(pi*x), (x, -8, 8)) # Labels not so helpful
    1729             sage: plot(sin(pi*x), (x, -8, 8), ticks=2) # Multiples of 2
    1730             sage: plot(sin(pi*x), (x, -8, 8), ticks=[[-7,-3,0,3,7],[-1/2,0,1/2]]) # Your choices
    1731             sage: plot(sin(pi*x), (x, -8, 8), ticks=[[],[]]) # No ticks at all!
    1732 
    1733         This can be very helpful in showing certain features of plots. ::
    1734 
    1735             sage: plot(1.5/(1+e^(-x)), (x, -10, 10)) # doesn't quite show value of inflection point
    1736 
    1737         ::
    1738 
    1739             sage: plot(1.5/(1+e^(-x)), (x, -10, 10), ticks=[None, 1.5/4]) # It's right at f(x)=0.75!
    1740 
    1741         But be careful to leave enough room for at least two major ticks, so that
    1742         the user can tell what the scale is.
    1743 
    1744         ::
    1745 
    1746             sage: plot(x^2,(x,1,8),ticks=6)
    1747             Traceback (most recent call last):
    1748             ...
    1749             ValueError: Expand the range of the independent variable to allow two multiples of your tick locator (option `ticks`).
    1750 
    1751         We can also do custom formatting if you need it.  See above for full
    1752         details.
    1753 
    1754         ::
    1755 
    1756             sage: plot(2*x+1,(x,0,5),ticks=[[0,1,e,pi,sqrt(20)],2],tick_formatter="latex")
    1757 
    1758         This is particularly useful when setting custom ticks in multiples
    1759         of `\pi`.
    1760 
    1761         ::
    1762 
    1763             sage: plot(sin(x),(x,0,2*pi),ticks=pi/3,tick_formatter=pi)
    1764 
    1765         But keep in mind that you will get exactly the formatting you asked
    1766         for if you specify both formatters.  The first syntax is recommended
    1767         for best style in that case. ::
    1768 
    1769             sage: plot(arcsin(x),(x,-1,1),ticks=[None,pi/6],tick_formatter=["latex",pi]) # Nice-looking!
    1770 
    1771         ::
    1772 
    1773             sage: plot(arcsin(x),(x,-1,1),ticks=[None,pi/6],tick_formatter=[None,pi]) # Not so nice-looking
    1774 
    1775         """
    1776 
    1777         # This option should not be passed on to save().
    1778         linkmode = kwds.pop('linkmode', False)
    1779 
    1780         if DOCTEST_MODE:
    1781             kwds.pop('filename', None)
    1782             self.save(DOCTEST_MODE_FILE, **kwds)
    1783         elif EMBEDDED_MODE:
    1784             kwds.setdefault('filename', sage.misc.misc.graphics_filename())
    1785             self.save(**kwds)
    1786             if linkmode == True:
    1787                 return "<img src='cell://%s'>" % kwds['filename']
    1788             else:
    1789                 html("<img src='cell://%s'>" % kwds['filename'])
    1790         else:
    1791             kwds.setdefault('filename', sage.misc.misc.tmp_filename() + '.png')
    1792             self.save(**kwds)
    1793             os.system('%s %s 2>/dev/null 1>/dev/null &'
    1794                       % (sage.misc.viewer.browser(), kwds['filename']))
    1795 
    1796     def xmin(self, xmin=None):
    1797         """
    1798         EXAMPLES::
    1799 
    1800             sage: g = line([(-1,1), (3,2)])
    1801             sage: g.xmin()
    1802             -1.0
    1803             sage: g.xmin(-3)
    1804             sage: g.xmin()
    1805             -3.0
    1806         """
    1807         if xmin is None:
    1808             return self.get_axes_range()['xmin']
    1809         else:
    1810             self.set_axes_range(xmin=xmin)
    1811 
    1812     def xmax(self, xmax=None):
    1813         """
    1814         EXAMPLES::
    1815 
    1816             sage: g = line([(-1,1), (3,2)])
    1817             sage: g.xmax()
    1818             3.0
    1819             sage: g.xmax(10)
    1820             sage: g.xmax()
    1821             10.0
    1822         """
    1823         if xmax is None:
    1824             return self.get_axes_range()['xmax']
    1825         else:
    1826             self.set_axes_range(xmax=xmax)
    1827 
    1828     def ymin(self, ymin=None):
    1829         """
    1830         EXAMPLES::
    1831 
    1832             sage: g = line([(-1,1), (3,2)])
    1833             sage: g.ymin()
    1834             1.0
    1835             sage: g.ymin(-3)
    1836             sage: g.ymin()
    1837             -3.0
    1838         """
    1839         if ymin is None:
    1840             return self.get_axes_range()['ymin']
    1841         else:
    1842             self.set_axes_range(ymin=ymin)
    1843 
    1844     def ymax(self, ymax=None):
    1845         """
    1846         EXAMPLES::
    1847 
    1848             sage: g = line([(-1,1), (3,2)])
    1849             sage: g.ymax()
    1850             2.0
    1851             sage: g.ymax(10)
    1852             sage: g.ymax()
    1853             10.0
    1854         """
    1855         if ymax is None:
    1856             return self.get_axes_range()['ymax']
    1857         else:
    1858             self.set_axes_range(ymax=ymax)
    1859 
    1860 
    1861     def get_minmax_data(self):
    1862         """
    1863         Return a dictionary whose keys give the xmin, xmax, ymin, and ymax
    1864         data for this graphic.
    1865        
    1866         .. warning::
    1867 
    1868            The returned dictionary is mutable, but changing it does
    1869            not change the xmin/xmax/ymin/ymax data.  The minmax data is a function
    1870            of the primitives which make up this Graphics object.  To change the
    1871            range of the axes, call methods :meth:`xmin`, :meth:`xmax`,
    1872            :meth:`ymin`, :meth:`ymax`, or :meth:`set_axes_range`. 
    1873 
    1874         EXAMPLES::
    1875 
    1876             sage: g = line([(-1,1), (3,2)])
    1877             sage: list(sorted(g.get_minmax_data().items()))
    1878             [('xmax', 3.0), ('xmin', -1.0), ('ymax', 2.0), ('ymin', 1.0)]
    1879 
    1880         Note that changing ymax doesn't change the output of get_minmax_data::
    1881 
    1882             sage: g.ymax(10)
    1883             sage: list(sorted(g.get_minmax_data().items()))
    1884             [('xmax', 3.0), ('xmin', -1.0), ('ymax', 2.0), ('ymin', 1.0)]
    1885         """
    1886         objects = self.__objects
    1887         if objects:
    1888             minmax_data = [o.get_minmax_data() for o in objects]
    1889             xmin = min(d['xmin'] for d in minmax_data)
    1890             xmax = max(d['xmax'] for d in minmax_data)
    1891             ymin = min(d['ymin'] for d in minmax_data)
    1892             ymax = max(d['ymax'] for d in minmax_data)
    1893             # check for NaN's: weird thing -- only way I know to check if a float
    1894             # is a NaN is to check if it is not equal to itself.
    1895             if xmin!=xmin:
    1896                 xmin=0; sage.misc.misc.verbose("xmin was NaN (setting to 0)", level=0)
    1897             if xmax!=xmax:
    1898                 xmax=0; sage.misc.misc.verbose("xmax was NaN (setting to 0)", level=0)
    1899             if ymin!=ymin:
    1900                 ymin=0; sage.misc.misc.verbose("ymin was NaN (setting to 0)", level=0)
    1901             if ymax!=ymax:
    1902                 ymax=0; sage.misc.misc.verbose("ymax was NaN (setting to 0)", level=0)
    1903         else:
    1904             xmin = xmax = ymin = ymax = 0
    1905 
    1906         if xmin == xmax:
    1907             xmin -= 1
    1908             xmax += 1
    1909         if ymin == ymax:
    1910             ymin -= 1
    1911             ymax += 1
    1912         return {'xmin':xmin, 'xmax':xmax, 'ymin':ymin, 'ymax':ymax}
    1913        
    1914     def matplotlib(self, filename=None,
    1915                    xmin=None, xmax=None, ymin=None, ymax=None,
    1916                    figsize=None, figure=None, sub=None,
    1917                    axes=None, axes_labels=None, fontsize=None,
    1918                    frame=False, verify=True,
    1919                    aspect_ratio = None,
    1920                    gridlines=None, gridlinesstyle=None,
    1921                    vgridlinesstyle=None, hgridlinesstyle=None,
    1922                    show_legend=None, legend_options={},
    1923                    axes_pad=0.02, ticks_integer=None,
    1924                    tick_formatter=None, ticks=None):
    1925         r"""
    1926         Return a matplotlib figure object representing the graphic
    1927 
    1928         EXAMPLES::
    1929        
    1930             sage: c = circle((1,1),1)
    1931             sage: print c.matplotlib()
    1932             Figure(640x480)
    1933 
    1934         To obtain the first matplotlib axes object inside of the
    1935         figure, you can do something like the following.
    1936 
    1937         ::
    1938 
    1939             sage: p=plot(sin(x), (x, -2*pi, 2*pi))
    1940             sage: figure=p.matplotlib()
    1941             sage: axes=figure.axes[0]
    1942 
    1943         For input parameters, see the documentation for the
    1944         :meth:`show` method (this function accepts all except the
    1945         transparent argument).
    1946 
    1947         TESTS:
    1948 
    1949         We verify that #10291 is fixed::
    1950 
    1951           sage: p = plot(sin(x), (x, -2*pi, 2*pi))
    1952           sage: figure = p.matplotlib()
    1953           sage: axes_range = p.get_axes_range()
    1954           sage: figure = p.matplotlib()
    1955           sage: axes_range2 = p.get_axes_range()
    1956           sage: axes_range == axes_range2
    1957           True
    1958         """
    1959         if not isinstance(ticks, (list, tuple)):
    1960             ticks = (ticks, None)
    1961 
    1962         from sage.symbolic.ring import SR
    1963         if not isinstance(tick_formatter, (list, tuple)):  # make sure both formatters typeset or both don't
    1964             if tick_formatter == "latex" or tick_formatter in SR:
    1965                 tick_formatter = (tick_formatter, "latex")
    1966             else:
    1967                 tick_formatter = (tick_formatter, None)
    1968            
    1969         self.set_axes_range(xmin, xmax, ymin, ymax)
    1970         d = self.get_axes_range()
    1971         xmin = d['xmin']
    1972         xmax = d['xmax']
    1973         ymin = d['ymin']
    1974         ymax = d['ymax']
    1975        
    1976         x_pad=(xmax-xmin)*float(axes_pad)
    1977         y_pad=(ymax-ymin)*float(axes_pad)
    1978 
    1979         xmin-=x_pad
    1980         xmax+=x_pad
    1981         ymin-=y_pad
    1982         ymax+=y_pad
    1983                
    1984         global do_verify
    1985         do_verify = verify
    1986 
    1987         if axes is None:
    1988             axes = self.__show_axes
    1989 
    1990         from matplotlib.figure import Figure
    1991         from matplotlib import rcParams
    1992         self.fontsize(fontsize)
    1993         self.axes_labels(l=axes_labels)
    1994 
    1995         if figsize is not None and not isinstance(figsize, (list, tuple)):
    1996             default_width, default_height=rcParams['figure.figsize']
    1997             figsize=(figsize, default_height*figsize/default_width)
    1998 
    1999         if figure is None:
    2000             figure=Figure(figsize=figsize)
    2001        
    2002         #the incoming subplot instance
    2003         subplot = sub
    2004         if not subplot:
    2005             subplot = figure.add_subplot(111)
    2006         if aspect_ratio is None:
    2007             aspect_ratio=self.aspect_ratio()
    2008         if aspect_ratio == 'automatic':
    2009             subplot.set_aspect('auto', adjustable='box')
    2010         else:
    2011             subplot.set_aspect(aspect_ratio, adjustable='box')
    2012         #add all the primitives to the subplot
    2013         for g in self.__objects:
    2014             g._render_on_subplot(subplot)
    2015             if hasattr(g, '_bbox_extra_artists'):
    2016                 self.__bbox_extra_artists.extend(g._bbox_extra_artists)
    2017        
    2018         #add the legend if requested
    2019         if show_legend is None:
    2020             show_legend = self.__show_legend
    2021        
    2022         if show_legend:
    2023             from matplotlib.font_manager import FontProperties
    2024             lopts = dict()
    2025             lopts.update(legend_options)
    2026             lopts.update(self.__legend_opts)
    2027             prop = FontProperties(family=lopts.pop('font_family'), weight=lopts.pop('font_weight'), \
    2028                     size=lopts.pop('font_size'), style=lopts.pop('font_style'), variant=lopts.pop('font_variant'))
    2029             color = lopts.pop('back_color')
    2030             leg = subplot.legend(prop=prop, **lopts)
    2031             if leg is None:
    2032                 sage.misc.misc.warn("legend requested but no items are labeled")
    2033             else:
    2034                 # color
    2035                 lframe = leg.get_frame()
    2036                 lframe.set_facecolor(color)
    2037        
    2038            
    2039         subplot.set_xlim([xmin, xmax])
    2040         subplot.set_ylim([ymin,ymax])
    2041 
    2042         locator_options=dict(nbins=9,steps=[1,2,5,10],integer=ticks_integer)
    2043 
    2044 
    2045         if axes is None:
    2046             axes = self.__show_axes
    2047 
    2048         for spine in subplot.spines.values():
    2049             spine.set_color(self.__axes_color)
    2050             spine.set_linewidth(self.__axes_width)
    2051        
    2052 
    2053         if frame:
    2054             # For now, set the formatter to the old one, since that is
    2055             # sort of what we are used to.  We should eventually look at
    2056             # the default one to see if we like it better.
    2057 
    2058             from matplotlib.ticker import OldScalarFormatter, MaxNLocator, MultipleLocator, FixedLocator, NullLocator, Locator
    2059             x_locator, y_locator = ticks
    2060             if x_locator is None:
    2061                 x_locator = MaxNLocator(**locator_options)
    2062             elif isinstance(x_locator,Locator):
    2063                 pass
    2064             elif x_locator == []:
    2065                 x_locator = NullLocator()
    2066             elif isinstance(x_locator,list):
    2067                 x_locator = FixedLocator(x_locator)
    2068             else: # x_locator is a number which can be made a float
    2069                 from sage.functions.other import ceil, floor
    2070                 if floor(xmax/x_locator)-ceil(xmin/x_locator)>1:
    2071                     x_locator=MultipleLocator(float(x_locator))
    2072                 else: # not enough room for two major ticks
    2073                     raise ValueError('Expand the range of the independent variable to allow two multiples of your tick locator (option `ticks`).')
    2074             if y_locator is None:
    2075                 y_locator = MaxNLocator(**locator_options)
    2076             elif isinstance(y_locator,Locator):
    2077                 pass
    2078             elif y_locator == []:
    2079                 y_locator = NullLocator()
    2080             elif isinstance(y_locator,list):
    2081                 y_locator = FixedLocator(y_locator)
    2082             else: # y_locator is a number which can be made a float
    2083                 from sage.functions.other import ceil, floor
    2084                 if floor(ymax/y_locator)-ceil(ymin/y_locator)>1:
    2085                     y_locator=MultipleLocator(float(y_locator))
    2086                 else: # not enough room for two major ticks
    2087                     raise ValueError('Expand the range of the dependent variable to allow two multiples of your tick locator (option `ticks`).')
    2088 
    2089             x_formatter, y_formatter = tick_formatter
    2090             from matplotlib.ticker import FuncFormatter
    2091             from sage.misc.latex import latex
    2092             if x_formatter is None:
    2093                 x_formatter = OldScalarFormatter()
    2094             elif x_formatter in SR:
    2095                 from misc import _multiple_of_constant
    2096                 x_const = x_formatter
    2097                 x_formatter = FuncFormatter(lambda n,pos: _multiple_of_constant(n,pos,x_const))
    2098             elif x_formatter == "latex":
    2099                 x_formatter = FuncFormatter(lambda n,pos: '$%s$'%latex(n))
    2100             if y_formatter is None:
    2101                 y_formatter = OldScalarFormatter()
    2102             elif y_formatter in SR:
    2103                 from misc import _multiple_of_constant
    2104                 y_const = y_formatter
    2105                 y_formatter = FuncFormatter(lambda n,pos: _multiple_of_constant(n,pos,y_const))
    2106             elif y_formatter == "latex":
    2107                 y_formatter = FuncFormatter(lambda n,pos: '$%s$'%latex(n))
    2108 
    2109             subplot.xaxis.set_major_locator(x_locator)
    2110             subplot.yaxis.set_major_locator(y_locator)
    2111             subplot.xaxis.set_major_formatter(x_formatter)
    2112             subplot.yaxis.set_major_formatter(y_formatter)
    2113            
    2114             subplot.set_frame_on(True)
    2115             if axes:
    2116                 if ymin<=0 and ymax>=0:
    2117                     subplot.axhline(color=self.__axes_color,
    2118                                     linewidth=self.__axes_width)
    2119                 if xmin<=0 and xmax>=0:
    2120                     subplot.axvline(color=self.__axes_color,
    2121                                     linewidth=self.__axes_width)
    2122            
    2123         elif axes:
    2124             ymiddle=False
    2125             xmiddle=False
    2126             if xmin>0:
    2127                 subplot.spines['right'].set_visible(False)
    2128                 subplot.spines['left'].set_position(('outward',10))
    2129                 subplot.yaxis.set_ticks_position('left')
    2130                 subplot.yaxis.set_label_position('left')
    2131                 yaxis='left'
    2132             elif xmax<0:
    2133                 subplot.spines['left'].set_visible(False)
    2134                 subplot.spines['right'].set_position(('outward',10))
    2135                 subplot.yaxis.set_ticks_position('right')
    2136                 subplot.yaxis.set_label_position('right')
    2137                 yaxis='right'
    2138             else:
    2139                 subplot.spines['left'].set_position('zero')
    2140                 subplot.yaxis.set_ticks_position('left')
    2141                 subplot.yaxis.set_label_position('left')
    2142                 subplot.spines['right'].set_visible(False)
    2143                 ymiddle=True
    2144                 yaxis='left'
    2145 
    2146             if ymin>0:
    2147                 subplot.spines['top'].set_visible(False)
    2148                 subplot.spines['bottom'].set_position(('outward',10))
    2149                 subplot.xaxis.set_ticks_position('bottom')
    2150                 subplot.xaxis.set_label_position('bottom')
    2151                 xaxis='bottom'
    2152             elif ymax<0:
    2153                 subplot.spines['bottom'].set_visible(False)
    2154                 subplot.spines['top'].set_position(('outward',10))
    2155                 subplot.xaxis.set_ticks_position('top')
    2156                 subplot.xaxis.set_label_position('top')
    2157                 xaxis='top'
    2158             else:
    2159                 subplot.spines['bottom'].set_position('zero')
    2160                 subplot.xaxis.set_ticks_position('bottom')
    2161                 subplot.xaxis.set_label_position('bottom')
    2162                 subplot.spines['top'].set_visible(False)
    2163                 xmiddle=True
    2164                 xaxis='bottom'
    2165            
    2166             # For now, set the formatter to the old one, since that is
    2167             # sort of what we are used to.  We should eventually look at
    2168             # the default one to see if we like it better.
    2169            
    2170             from matplotlib.ticker import OldScalarFormatter, MaxNLocator, MultipleLocator, FixedLocator, NullLocator, Locator
    2171             x_locator, y_locator = ticks
    2172             if x_locator is None:
    2173                 x_locator = MaxNLocator(**locator_options)
    2174             elif isinstance(x_locator,Locator):
    2175                 pass
    2176             elif x_locator == []:
    2177                 x_locator = NullLocator()
    2178             elif isinstance(x_locator,list):
    2179                 x_locator = FixedLocator(x_locator)
    2180             else: # x_locator is a number which can be made a float
    2181                 from sage.functions.other import ceil, floor
    2182                 if floor(xmax/x_locator)-ceil(xmin/x_locator)>1:
    2183                     x_locator=MultipleLocator(float(x_locator))
    2184                 else: # not enough room for two major ticks
    2185                     raise ValueError('Expand the range of the independent variable to allow two multiples of your tick locator (option `ticks`).')
    2186             if y_locator is None:
    2187                 y_locator = MaxNLocator(**locator_options)
    2188             elif isinstance(y_locator,Locator):
    2189                 pass
    2190             elif y_locator == []:
    2191                 y_locator = NullLocator()
    2192             elif isinstance(y_locator,list):
    2193                 y_locator = FixedLocator(y_locator)
    2194             else: # y_locator is a number which can be made a float
    2195                 from sage.functions.other import ceil, floor
    2196                 if floor(ymax/y_locator)-ceil(ymin/y_locator)>1:
    2197                     y_locator=MultipleLocator(float(y_locator))
    2198                 else: # not enough room for two major ticks
    2199                     raise ValueError('Expand the range of the dependent variable to allow two multiples of your tick locator (option `ticks`).')
    2200 
    2201             x_formatter, y_formatter = tick_formatter
    2202             from matplotlib.ticker import FuncFormatter
    2203             from sage.misc.latex import latex
    2204             from sage.symbolic.ring import SR
    2205             if x_formatter is None:
    2206                 x_formatter = OldScalarFormatter()
    2207             elif x_formatter in SR:
    2208                 from misc import _multiple_of_constant
    2209                 x_const = x_formatter
    2210                 x_formatter = FuncFormatter(lambda n,pos: _multiple_of_constant(n,pos,x_const))
    2211             elif x_formatter == "latex":
    2212                 x_formatter = FuncFormatter(lambda n,pos: '$%s$'%latex(n))
    2213             if y_formatter is None:
    2214                 y_formatter = OldScalarFormatter()
    2215             elif y_formatter in SR:
    2216                 from misc import _multiple_of_constant
    2217                 y_const = y_formatter
    2218                 y_formatter = FuncFormatter(lambda n,pos: _multiple_of_constant(n,pos,y_const))
    2219             elif y_formatter == "latex":
    2220                 y_formatter = FuncFormatter(lambda n,pos: '$%s$'%latex(n))
    2221 
    2222             subplot.xaxis.set_major_locator(x_locator)
    2223             subplot.yaxis.set_major_locator(y_locator)
    2224             subplot.xaxis.set_major_formatter(x_formatter)
    2225             subplot.yaxis.set_major_formatter(y_formatter)
    2226 
    2227             # Make ticklines go on both sides of the axes
    2228             #             if xmiddle:
    2229             #                 for t in subplot.xaxis.get_majorticklines():
    2230             #                     t.set_marker("|")
    2231             #                     t.set_markersize(8)
    2232             #                 for t in subplot.xaxis.get_minorticklines():
    2233             #                     t.set_marker("|")
    2234             #                     t.set_markersize(4)
    2235            
    2236             #             if ymiddle:
    2237             #                 for t in subplot.yaxis.get_majorticklines():
    2238             #                     t.set_marker("|")
    2239             #                     t.set_markersize(8)
    2240             #                 for t in subplot.yaxis.get_minorticklines():
    2241             #                     t.set_marker("|")
    2242             #                     t.set_markersize(4)
    2243            
    2244             # Make the zero tick labels disappear if the axes cross
    2245             # inside the picture
    2246             if xmiddle and ymiddle:
    2247                 subplot.yaxis.set_major_formatter(SelectiveFormatter(subplot.yaxis.get_major_formatter(),skip_values=[0]))
    2248                 subplot.xaxis.set_major_formatter(SelectiveFormatter(subplot.xaxis.get_major_formatter(),skip_values=[0]))
    2249 
    2250         else:
    2251             for spine in subplot.spines.values():
    2252                 spine.set_visible(False)
    2253             from matplotlib.ticker import NullFormatter, NullLocator
    2254             subplot.xaxis.set_major_formatter(NullFormatter())
    2255             subplot.yaxis.set_major_formatter(NullFormatter())
    2256             subplot.xaxis.set_major_locator(NullLocator())
    2257             subplot.yaxis.set_major_locator(NullLocator())
    2258 
    2259         if frame or axes:
    2260             # Make minor tickmarks, unless we specify fixed ticks or no ticks
    2261             from matplotlib.ticker import AutoMinorLocator, FixedLocator, NullLocator
    2262             if isinstance(x_locator, (NullLocator, FixedLocator)):
    2263                 subplot.xaxis.set_minor_locator(NullLocator())
    2264             else:
    2265                 subplot.xaxis.set_minor_locator(AutoMinorLocator())
    2266             if isinstance(y_locator, (NullLocator, FixedLocator)):
    2267                 subplot.yaxis.set_minor_locator(NullLocator())
    2268             else:
    2269                 subplot.yaxis.set_minor_locator(AutoMinorLocator())
    2270 
    2271             ticklabels=subplot.xaxis.get_majorticklabels() + \
    2272                 subplot.xaxis.get_minorticklabels() + \
    2273                 subplot.yaxis.get_majorticklabels() + \
    2274                 subplot.yaxis.get_minorticklabels()
    2275             for ticklabel in ticklabels:
    2276                 ticklabel.set_fontsize(self.__fontsize)
    2277                 ticklabel.set_color(self.__tick_label_color)
    2278 
    2279             ticklines=subplot.xaxis.get_majorticklines() + \
    2280                 subplot.xaxis.get_minorticklines() + \
    2281                 subplot.yaxis.get_majorticklines() + \
    2282                 subplot.yaxis.get_minorticklines()
    2283             for tickline in ticklines:
    2284                 tickline.set_color(self.__axes_color)
    2285                
    2286            
    2287         if gridlines is not None:
    2288             if isinstance(gridlines, (list, tuple)):
    2289                 vgridlines,hgridlines=gridlines
    2290             else:
    2291                 hgridlines=gridlines
    2292                 vgridlines=gridlines
    2293 
    2294             if gridlinesstyle is None:
    2295                 # Set up the default grid style
    2296                 gridlinesstyle=dict(color='black',linestyle=':',linewidth=0.5)
    2297 
    2298             vgridstyle=gridlinesstyle.copy()
    2299             if vgridlinesstyle is not None:
    2300                 vgridstyle.update(vgridlinesstyle)
    2301 
    2302             hgridstyle=gridlinesstyle.copy()
    2303             if hgridlinesstyle is not None:
    2304                 hgridstyle.update(hgridlinesstyle)
    2305 
    2306             if hgridlines=='minor':
    2307                 hgridstyle['which']='both'
    2308             if vgridlines=='minor':
    2309                 vgridstyle['which']='both'
    2310                
    2311             if hasattr(hgridlines, '__iter__'):
    2312                 hlines=iter(hgridlines)
    2313                 hgridstyle.pop("minor",None)
    2314                 for hline in hlines:
    2315                     if isinstance(hline, (list, tuple)):
    2316                         hl, style=hline
    2317                         st=hgridstyle.copy()
    2318                         st.update(style)
    2319                     else:
    2320                         hl=hline
    2321                         st=hgridstyle
    2322                     subplot.axhline(hl,**st)
    2323             else:
    2324                 if hgridlines not in (None, False):
    2325                     subplot.yaxis.grid(True, **hgridstyle)
    2326 
    2327             if hasattr(vgridlines, '__iter__'):
    2328                 vlines=iter(vgridlines)
    2329                 vgridstyle.pop("minor",None)
    2330                 for vline in vlines:
    2331                     if isinstance(vline, (list, tuple)):
    2332                         vl, style=vline
    2333                         st=vgridstyle.copy()
    2334                         st.update(style)
    2335                     else:
    2336                         vl=vline
    2337                         st=vgridstyle
    2338                     subplot.axvline(vl,**st)
    2339             else:
    2340                 if vgridlines not in (None, False):
    2341                     subplot.xaxis.grid(True, **vgridstyle)
    2342 
    2343 
    2344 
    2345         if self.__axes_labels is not None:
    2346             label_options={}
    2347             label_options['color']=self.__axes_label_color
    2348             label_options['size']=self.__fontsize
    2349             subplot.set_xlabel(self.__axes_labels[0], **label_options)
    2350             subplot.set_ylabel(self.__axes_labels[1], **label_options)
    2351                
    2352 
    2353             if axes is True and frame is False:
    2354                 # We set the label positions according to where we are
    2355                 # drawing the axes.
    2356                 if xaxis=='bottom':
    2357                     yaxis_labely=subplot.get_ylim()[1]
    2358                     yaxis_labeloffset=8
    2359                     yaxis_vert='bottom'
    2360                     xaxis_labely=0
    2361                     xaxis_vert='baseline'
    2362                 else:
    2363                     yaxis_labely=subplot.get_ylim()[0]
    2364                     yaxis_labeloffset=-8
    2365                     yaxis_vert='top'
    2366                     xaxis_labely=1
    2367                     xaxis_vert='top'
    2368 
    2369                 if yaxis=='left':
    2370                     xaxis_labelx=subplot.get_xlim()[1]
    2371                     xaxis_labeloffset=8
    2372                     xaxis_horiz='left'
    2373                     yaxis_labelx=0
    2374                 else:
    2375                     xaxis_labelx=subplot.get_xlim()[0]
    2376                     xaxis_labeloffset=-8
    2377                     xaxis_horiz='right'
    2378                     yaxis_labelx=1
    2379 
    2380                 from matplotlib.transforms import offset_copy
    2381                 xlabel=subplot.xaxis.get_label()
    2382                 xlabel.set_horizontalalignment(xaxis_horiz)
    2383                 xlabel.set_verticalalignment(xaxis_vert)
    2384                 trans=subplot.spines[xaxis].get_transform()
    2385                 labeltrans=offset_copy(trans, figure, x=xaxis_labeloffset, y=0, units='points')
    2386                 subplot.xaxis.set_label_coords(x=xaxis_labelx,y=xaxis_labely,transform=labeltrans)
    2387 
    2388                 ylabel=subplot.yaxis.get_label()
    2389                 ylabel.set_horizontalalignment('center')
    2390                 ylabel.set_verticalalignment(yaxis_vert)
    2391                 ylabel.set_rotation('horizontal')
    2392                 trans=subplot.spines[yaxis].get_transform()
    2393                 labeltrans=offset_copy(trans, figure, x=0, y=yaxis_labeloffset, units='points')
    2394                 subplot.yaxis.set_label_coords(x=yaxis_labelx,y=yaxis_labely,transform=labeltrans)
    2395 
    2396         # This option makes the xlim and ylim limits not take effect
    2397         # todo: figure out which limits were specified, and let the
    2398         # free limits autoscale
    2399         #subplot.autoscale_view(tight=True)
    2400         return figure
    2401        
    2402     # ALLOWED_EXTENSIONS is the list of recognized formats.
    2403     # filename argument is written explicitly so that it can be used as a
    2404     # positional one, which is a very likely usage for this function.
    2405     @suboptions('legend', numpoints=2, borderpad=0.6, markerscale=0.6, shadow=False,
    2406                 labelspacing=0.02, handlelength=0.05, handletextpad=0.5, borderaxespad=None,
    2407                 loc='best', font_size='medium', font_family='sans-serif', font_style='normal',
    2408                 font_weight='medium', font_variant='normal', back_color=(0.9, 0.9, 0.9),
    2409                 title=None, ncol=1, columnspacing=None, fancybox=False)
    2410     def save(self, filename=None, **kwds):
    2411         r"""
    2412         Save the graphics to an image file.
    2413        
    2414         INPUT:
    2415        
    2416         - ``filename`` -- a string (default: autogenerated), the filename and
    2417           the image format given by the extension, which can be one of the
    2418           following:
    2419          
    2420             * ``.eps``,
    2421            
    2422             * ``.pdf``,
    2423            
    2424             * ``.png``,
    2425            
    2426             * ``.ps``,
    2427            
    2428             * ``.sobj`` (for a Sage object you can load later),
    2429            
    2430             * ``.svg``,
    2431            
    2432             * empty extension will be treated as ``.sobj``.
    2433            
    2434         All other keyword arguments will be passed to the plotter.
    2435        
    2436         OUTPUT:
    2437        
    2438         - none.       
    2439 
    2440         EXAMPLES::
    2441        
    2442             sage: c = circle((1,1), 1, color='red')
    2443             sage: filename = os.path.join(SAGE_TMP, 'test.png')
    2444             sage: c.save(filename, xmin=-1, xmax=3, ymin=-1, ymax=3)
    2445 
    2446         To make a figure bigger or smaller, use ``figsize``::
    2447 
    2448             sage: c.save(filename, figsize=5, xmin=-1, xmax=3, ymin=-1, ymax=3)       
    2449 
    2450         By default, the figure grows to include all of the graphics and text,
    2451         so the final image may not be exactly the figure size you specified.
    2452         If you want a figure to be exactly a certain size, specify the keyword
    2453         ``fig_tight=False``::
    2454 
    2455             sage: c.save(filename, figsize=[8,4], fig_tight=False,
    2456             ...       xmin=-1, xmax=3, ymin=-1, ymax=3)       
    2457        
    2458         You can also pass extra options to the plot command instead of this
    2459         method, e.g. ::
    2460        
    2461             sage: plot(x^2 - 5, (x, 0, 5), ymin=0).save(
    2462             ...       sage.misc.misc.tmp_filename() + '.png')
    2463            
    2464         will save the same plot as the one shown by this command::
    2465        
    2466             sage: plot(x^2 - 5, (x, 0, 5), ymin=0)
    2467            
    2468         (This test verifies that Trac #8632 is fixed.)
    2469 
    2470         TESTS:
    2471 
    2472         Legend labels should save correctly::
    2473 
    2474             sage: P = plot(x,(x,0,1),legend_label='$xyz$')
    2475             sage: P.set_legend_options(back_color=(1,0,0))
    2476             sage: P.set_legend_options(loc=7)
    2477             sage: filename=os.path.join(SAGE_TMP, 'test.png')
    2478             sage: P.save(filename)
    2479 
    2480         This plot should save with the frame shown, showing Trac #7524
    2481         is fixed (same issue as #7981 and #8632)::
    2482 
    2483             sage: var('x,y')               
    2484             (x, y)
    2485             sage: a = plot_vector_field((x,-y),(x,-1,1),(y,-1,1))
    2486             sage: filename=os.path.join(SAGE_TMP, 'test2.png')
    2487             sage: a.save(filename)
    2488         """
    2489         options = dict()
    2490         options.update(self.SHOW_OPTIONS)
    2491         options.update(self._extra_kwds)
    2492         options.update(kwds)
    2493         dpi = options.pop('dpi')
    2494         transparent = options.pop('transparent')
    2495         fig_tight = options.pop('fig_tight')
    2496        
    2497         if filename is None:
    2498             filename = options.pop('filename')
    2499         if filename is None:
    2500             filename = sage.misc.misc.graphics_filename()
    2501         ext = os.path.splitext(filename)[1].lower()
    2502        
    2503         if ext not in ALLOWED_EXTENSIONS:
    2504             raise ValueError("allowed file extensions for images are '"
    2505                              + "', '".join(ALLOWED_EXTENSIONS) + "'!")
    2506         elif ext in ['', '.sobj']:
    2507             SageObject.save(self, filename)
    2508         else:
    2509             figure = self.matplotlib(**options)
    2510             # You can output in PNG, PS, EPS, PDF, or SVG format, depending on the file extension.
    2511             # matplotlib looks at the file extension to see what the renderer should be.
    2512             # The default is FigureCanvasAgg for PNG's because this is by far the most
    2513             # common type of files rendered, like in the notebook, for example.
    2514             # if the file extension is not '.png', then matplotlib will handle it.
    2515             from matplotlib.backends.backend_agg import FigureCanvasAgg
    2516             figure.set_canvas(FigureCanvasAgg(figure))
    2517             # this messes up the aspect ratio!
    2518             #figure.canvas.mpl_connect('draw_event', pad_for_tick_labels)
    2519            
    2520             # tight_layout adjusts the *subplot* parameters so ticks aren't cut off, etc.
    2521             figure.tight_layout()
    2522 
    2523             if fig_tight is True:
    2524                 figure.savefig(filename, dpi=dpi, bbox_inches='tight',
    2525                     bbox_extra_artists=self.__bbox_extra_artists,
    2526                     transparent=transparent)
    2527             else:
    2528                 figure.savefig(filename, dpi=dpi,
    2529                            transparent=transparent)
     348from graphics import Graphics, GraphicsArray
    2530349
    2531350#Currently not used - see comment immediately above about
    2532351#figure.canvas.mpl_connect('draw_event', pad_for_tick_labels)
     
    32881107    #check to see if funcs is a list of functions that will
    32891108    #be all plotted together.
    32901109    if isinstance(funcs, (list, tuple)) and not parametric:
     1110        from sage.plot.colors import rainbow
    32911111        rainbow_colors = rainbow(len(funcs))
    32921112
    32931113        G = Graphics()
     
    37861606    return [float(x) for x in v]
    37871607
    37881608
    3789 
    3790 class GraphicsArray(SageObject):
    3791     """
    3792     GraphicsArray takes a (`m` x `n`) list of lists of
    3793     graphics objects and plots them all on one canvas.
    3794     """
    3795     def __init__(self, array):
    3796         """
    3797         Constructor for ``GraphicsArray`` class.  Normally used only
    3798         via :func:`graphics_array` function.
    3799 
    3800         INPUT: a list or list of lists/tuples, all of which are graphics objects
    3801 
    3802         EXAMPLES::
    3803 
    3804             sage: L = [plot(sin(k*x),(x,-pi,pi)) for k in range(10)]
    3805             sage: G = graphics_array(L)
    3806             sage: G.ncols()
    3807             10
    3808             sage: M = [[plot(x^2)],[plot(x^3)]]
    3809             sage: H = graphics_array(M)
    3810             sage: str(H[1])
    3811             'Graphics object consisting of 1 graphics primitive'
    3812 
    3813         TESTS::
    3814 
    3815             sage: L = [[plot(sin),plot(cos)],[plot(tan)]]
    3816             sage: graphics_array(L)
    3817             Traceback (most recent call last):
    3818             ...
    3819             TypeError: array (=[[, ], []]) must be a list of lists of Graphics objects
    3820             sage: G = plot(x,(x,0,1))
    3821             sage: graphics_array(G)
    3822             Traceback (most recent call last):
    3823             ...
    3824             TypeError: array (=Graphics object consisting of 1 graphics primitive) must be a list of lists of Graphics objects
    3825             sage: G = [[plot(x,(x,0,1)),x]]
    3826             sage: graphics_array(G)
    3827             Traceback (most recent call last):
    3828             ...
    3829             TypeError: every element of array must be a Graphics object
    3830         """
    3831         if not isinstance(array, (list, tuple)):
    3832             raise TypeError,"array (=%s) must be a list of lists of Graphics objects"%(array)
    3833         array = list(array)
    3834         self._glist = []
    3835         self._rows = len(array)
    3836         if self._rows > 0:
    3837             if not isinstance(array[0], (list, tuple)):
    3838                 array = [array]
    3839                 self._rows = 1
    3840             self._cols = len(array[0])
    3841         else:
    3842             self._cols = 0
    3843         self._dims = self._rows*self._cols
    3844         for row in array: #basically flatten the list
    3845             if not isinstance(row, (list, tuple)) or len(row) != self._cols:
    3846                 raise TypeError,"array (=%s) must be a list of lists of Graphics objects"%(array)
    3847             for g in row:
    3848                 if not isinstance(g, Graphics):
    3849                     raise TypeError, "every element of array must be a Graphics object"
    3850                 self._glist.append(g)
    3851         self._figsize = None
    3852 
    3853     def _repr_(self):
    3854         """
    3855         Representation of the graphics array.
    3856 
    3857         EXAMPLES::
    3858 
    3859             sage: R = rainbow(6)
    3860             sage: L = [plot(x^n,(x,0,1),color=R[n]) for n in range(6)]
    3861             sage: G = graphics_array(L,2,3)
    3862             sage: G # plot shown is default
    3863 
    3864         We can make commands not display their plots by default. ::
    3865 
    3866             sage: show_default(False)
    3867             sage: graphics_array(L)
    3868             Graphics Array of size 1 x 6
    3869             sage: show_default(True)
    3870         """
    3871         if SHOW_DEFAULT:
    3872             self.show()
    3873             return ''
    3874         else:
    3875             return self.__str__()
    3876 
    3877     def __str__(self):
    3878         """
    3879         String representation of the graphics array.
    3880 
    3881         EXAMPLES::
    3882 
    3883             sage: R = rainbow(6)
    3884             sage: L = [plot(x^n,(x,0,1),color=R[n]) for n in range(6)]
    3885             sage: G = graphics_array(L,2,3)
    3886             sage: str(G)
    3887             'Graphics Array of size 2 x 3'
    3888 
    3889         We can make commands not display their plots by default. ::
    3890 
    3891             sage: show_default(False)
    3892             sage: graphics_array(L)
    3893             Graphics Array of size 1 x 6
    3894             sage: show_default(True)
    3895         """
    3896         return "Graphics Array of size %s x %s"%(self._rows, self._cols)
    3897 
    3898     def nrows(self):
    3899         """
    3900         Number of rows of the graphics array.
    3901 
    3902         EXAMPLES::
    3903 
    3904             sage: R = rainbow(6)
    3905             sage: L = [plot(x^n,(x,0,1),color=R[n]) for n in range(6)]
    3906             sage: G = graphics_array(L,2,3)
    3907             sage: G.nrows()
    3908             2
    3909             sage: graphics_array(L).nrows()
    3910             1
    3911         """
    3912         return self._rows
    3913 
    3914     def ncols(self):
    3915         """
    3916         Number of columns of the graphics array.
    3917 
    3918         EXAMPLES::
    3919 
    3920             sage: R = rainbow(6)
    3921             sage: L = [plot(x^n,(x,0,1),color=R[n]) for n in range(6)]
    3922             sage: G = graphics_array(L,2,3)
    3923             sage: G.ncols()
    3924             3
    3925             sage: graphics_array(L).ncols()
    3926             6
    3927         """
    3928         return self._cols
    3929    
    3930     def __getitem__(self, i):
    3931         """
    3932         Return the ``i``th element of the list of graphics
    3933         in the (flattened) array.
    3934 
    3935         EXAMPLES:
    3936 
    3937         We can access and view individual plots::
    3938 
    3939             sage: M = [[plot(x^2)],[plot(x^3)]]
    3940             sage: H = graphics_array(M)
    3941             sage: H[1]
    3942 
    3943         They can also be represented::
    3944 
    3945             sage: str(H[1])
    3946             'Graphics object consisting of 1 graphics primitive'
    3947 
    3948         Another example::
    3949 
    3950             sage: L = [plot(sin(k*x),(x,-pi,pi))+circle((k,k),1,color='red') for k in range(10)]
    3951             sage: G = graphics_array(L,5,2)
    3952             sage: str(G[3])
    3953             'Graphics object consisting of 2 graphics primitives'
    3954             sage: G[3]
    3955         """
    3956         i = int(i)
    3957         return self._glist[i]
    3958 
    3959     def __setitem__(self, i, g):
    3960         """
    3961         Set the ``i``th element of the list of graphics
    3962         in the (flattened) array.
    3963 
    3964         EXAMPLES::
    3965 
    3966             sage: M = [[plot(x^2)],[plot(x^3)]]
    3967             sage: H = graphics_array(M)
    3968             sage: str(H[1])
    3969             'Graphics object consisting of 1 graphics primitive'
    3970 
    3971         We can check this is one primitive::
    3972 
    3973             sage: H[1] # the plot of x^3
    3974 
    3975         Now we change it::
    3976 
    3977             sage: H[1] = circle((1,1),2)+points([(1,2),(3,2),(5,5)],color='purple')
    3978             sage: str(H[1])
    3979             'Graphics object consisting of 2 graphics primitives'
    3980 
    3981         And we visually check that it's different::
    3982 
    3983             sage: H[1] # a circle and some purple points
    3984         """
    3985         i = int(i)
    3986         self._glist[i] = g
    3987        
    3988     def __set_figsize__(self, ls):
    3989         """
    3990         Set the figsize of all plots in the array.
    3991 
    3992         This is normally only used via the ``figsize`` keyword in
    3993         :meth:`save` or :meth:`show`.
    3994 
    3995         EXAMPLES::
    3996 
    3997             sage: L = [plot(sin(k*x),(x,-pi,pi)) for k in [1..3]]
    3998             sage: G = graphics_array(L)
    3999             sage: G.show(figsize=[5,3])  # smallish and compact
    4000 
    4001         ::
    4002 
    4003             sage: G.show(figsize=[10,20])  # bigger and tall and thin
    4004 
    4005         ::
    4006 
    4007             sage: G.show(figsize=8)  # figure as a whole is a square
    4008         """
    4009         # if just one number is passed in for figsize, as documented
    4010         if not isinstance(ls,list):
    4011             ls = [ls,ls]
    4012         # now the list is a list
    4013         m = int(ls[0])
    4014         n = int(ls[1])
    4015         self._figsize = [m,n]
    4016 
    4017     def __len__(self):
    4018         """
    4019         Total number of elements of the graphics array.
    4020 
    4021         EXAMPLES::
    4022 
    4023             sage: R = rainbow(6)
    4024             sage: L = [plot(x^n,(x,0,1),color=R[n]) for n in range(6)]
    4025             sage: G = graphics_array(L,2,3)
    4026             sage: G.ncols()
    4027             3
    4028             sage: graphics_array(L).ncols()
    4029             6
    4030         """
    4031         return len(self._glist)
    4032 
    4033 # This does not work, and can never have worked!
    4034 # To make this work, one would also change the
    4035 # dimensions of the array, but it's not clear there
    4036 # is a canonical way to do this.
    4037 #
    4038 #    def append(self, g):
    4039 #        """
    4040 #        Appends a graphic to the array.
    4041 #        """
    4042 #        self._glist.append(g)
    4043 
    4044     def append(self, g):
    4045         """
    4046         Appends a graphic to the array.  Currently
    4047         not implemented.
    4048 
    4049         TESTS::
    4050 
    4051             sage: from sage.plot.plot import GraphicsArray
    4052             sage: G = GraphicsArray([plot(sin),plot(cos)])
    4053             sage: G.append(plot(tan))
    4054             Traceback (most recent call last):
    4055             ...
    4056             NotImplementedError: Appending to a graphics array is not yet implemented
    4057         """
    4058         raise NotImplementedError('Appending to a graphics array is not yet implemented')
    4059 
    4060 
    4061     def _render(self, filename, dpi=None, figsize=None, axes=None, **args):
    4062         r"""
    4063         ``_render`` loops over all graphics objects in the array
    4064         and adds them to the subplot.  This is only used internally
    4065         when the plot is actually saved or shown.
    4066 
    4067         EXAMPLES::
    4068 
    4069             sage: graphics_array([[plot(sin), plot(cos)], [plot(tan), plot(sec)]])
    4070         """
    4071         #glist is a list of Graphics objects:
    4072         glist = self._glist
    4073         rows = self._rows
    4074         cols = self._cols
    4075         dims = self._dims
    4076         #make a blank matplotlib Figure:
    4077         from matplotlib.figure import Figure
    4078         figure = Figure(figsize)
    4079         global do_verify
    4080         do_verify = True
    4081         for i,g in zip(range(1, dims+1), glist):
    4082             subplot = figure.add_subplot(rows, cols, i)
    4083             g.matplotlib(filename, figure=figure, sub=subplot,
    4084                          verify=do_verify, axes = axes, **args)
    4085         g.save(filename, dpi=dpi, figure=figure, sub=subplot,
    4086                verify=do_verify, axes = axes, **args)