Ticket #13891: trac_13891.patch

File trac_13891.patch, 20.8 KB (added by ncohen, 6 years ago)
  • sage/graphs/generic_graph.py

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1356905040 -3600
    # Node ID 87d536b860599458340e6b66c614c5fbdddbac2d
    # Parent  5f40efadebd6c04b618e24538c9013e8bea1d637
    Default parameters for Graph.plot() and Graph.show()
    
    diff --git a/sage/graphs/generic_graph.py b/sage/graphs/generic_graph.py
    a b  
    324324        Every graph carries a dictionary of options, which is set
    325325        here to ``None``.  Some options are added to the global
    326326        :data:`sage.misc.latex.latex` instance which will insure
    327         that if `\mbox{\rm\LaTeX}` is used to render the graph,
     327        that if LaTeX is used to render the graph,
    328328        then the right packages are loaded and MathJax reacts
    329329        properly.
    330330
     
    593593        return s
    594594
    595595    def _latex_(self):
    596         r""" Returns a string to render the graph using
    597         `\mbox{\rm{\LaTeX}}`.
     596        r"""
     597
     598        Returns a string to render the graph using LaTeX.
    598599
    599600        To adjust the string, use the
    600601        :meth:`set_latex_options` method to set options,
     
    1370113702        Returns an instance of
    1370213703        :class:`~sage.graphs.graph_latex.GraphLatex` for the graph.
    1370313704
    13704         Changes to this object will affect the `\mbox{\rm\LaTeX}`
    13705         version of the graph.    For a full explanation of
    13706         how to use LaTeX to render graphs, see the introduction to the
    13707         :mod:`~sage.graphs.graph_latex` module.
     13705        Changes to this object will affect the LaTeX version of the graph.  For
     13706        a full explanation of how to use LaTeX to render graphs, see the
     13707        introduction to the :mod:`~sage.graphs.graph_latex` module.
    1370813708
    1370913709        EXAMPLES::
    1371013710
     
    1418914189
    1419014190        return [xmin, xmax, ymin, ymax]
    1419114191
    14192 
    14193 
    14194     @options(vertex_size=200, vertex_labels=True, layout=None,
    14195             edge_style='solid', edge_color='black',edge_colors=None, edge_labels=False,
    14196             iterations=50, tree_orientation='down', heights=None, graph_border=False,
    14197             talk=False, color_by_label=False, partition=None,
    14198             dist = .075, max_dist=1.5, loop_size=.075)
    1419914192    def graphplot(self, **options):
    1420014193        """
    1420114194        Returns a GraphPlot object.
    14202        
    14203        
     14195
    1420414196        EXAMPLES:
    14205        
     14197
    1420614198        Creating a graphplot object uses the same options as graph.plot()::
    14207        
     14199
    1420814200            sage: g = Graph({}, loops=True, multiedges=True, sparse=True)
    1420914201            sage: g.add_edges([(0,0,'a'),(0,0,'b'),(0,1,'c'),(0,1,'d'),
    1421014202            ...     (0,1,'e'),(0,1,'f'),(0,1,'f'),(2,1,'g'),(2,2,'h')])
     
    1421314205            sage: GP.plot()
    1421414206
    1421514207        We can modify the graphplot object.  Notice that the changes are cumulative::
    14216        
     14208
    1421714209            sage: GP.set_edges(edge_style='solid')
    1421814210            sage: GP.plot()
    1421914211            sage: GP.set_vertices(talk=True)
     
    1422214214        from sage.graphs.graph_plot import GraphPlot
    1422314215        return GraphPlot(graph=self, options=options)
    1422414216
    14225     @options(vertex_size=200, vertex_labels=True, layout=None,
    14226             edge_style='solid', edge_color = 'black', edge_colors=None, edge_labels=False,
    14227             iterations=50, tree_orientation='down', heights=None, graph_border=False,
    14228             talk=False, color_by_label=False, partition=None,
    14229             dist = .075, max_dist=1.5, loop_size=.075)
     14217    @options()
    1423014218    def plot(self, **options):
    1423114219        r"""
    1423214220        Returns a graphics object representing the (di)graph.
    14233         See also the :mod:`sage.graphs.graph_latex` module for ways
    14234         to use  `\mbox{\rm\LaTeX}` to produce an image of a graph.
    14235        
    14236         INPUT:
    14237            
     14221
     14222        INPUT:
     14223
    1423814224        - ``pos`` - an optional positioning dictionary
    14239            
     14225
    1424014226        - ``layout`` - what kind of layout to use, takes precedence
    1424114227          over pos
    14242                
     14228
    1424314229           - 'circular' -- plots the graph with vertices evenly
    1424414230             distributed on a circle
    14245              
     14231
    1424614232           - 'spring' - uses the traditional spring layout, using the
    1424714233             graph's current positions as initial positions
    14248                
     14234
    1424914235           - 'tree' - the (di)graph must be a tree. One can specify
    1425014236             the root of the tree using the keyword tree_root,
    1425114237             otherwise a root will be selected at random. Then the
    1425214238             tree will be plotted in levels, depending on minimum
    1425314239             distance for the root.
    14254            
     14240
    1425514241        - ``vertex_labels`` - whether to print vertex labels
    1425614242
    1425714243        - ``edge_labels`` - whether to print edge labels. By default,
    1425814244          False, but if True, the result of str(l) is printed on the
    1425914245          edge for each label l. Labels equal to None are not printed
    1426014246          (to set edge labels, see set_edge_label).
    14261            
     14247
    1426214248        - ``vertex_size`` - size of vertices displayed
    1426314249
    1426414250        - ``vertex_shape`` - the shape to draw the vertices (Not
    1426514251          available for multiedge digraphs.)
    14266                
     14252
    1426714253        - ``graph_border`` - whether to include a box around the graph
    1426814254
    1426914255        - ``vertex_colors`` - optional dictionary to specify vertex
     
    1427114257          each corresponding entry is a list of vertices. If a vertex
    1427214258          is not listed, it looks invisible on the resulting plot (it
    1427314259          doesn't get drawn).
    14274                
     14260
    1427514261        - ``edge_colors`` - a dictionary specifying edge colors: each
    1427614262          key is a color recognized by matplotlib, and each entry is a
    1427714263          list of edges.
     
    1429014276
    1429114277        - ``heights`` - if specified, this is a dictionary from a set
    1429214278          of floating point heights to a set of vertices
    14293                
     14279
    1429414280        - ``edge_style`` - keyword arguments passed into the
    1429514281          edge-drawing routine.  This currently only works for
    1429614282          directed graphs, since we pass off the undirected graph to
     
    1429814284
    1429914285        - ``tree_root`` - a vertex of the tree to be used as the root
    1430014286          for the layout="tree" option. If no root is specified, then one
    14301           is chosen at random. Ignored unless layout='tree'. 
    14302 
    14303         - ``tree_orientation`` - "up" or "down" (default is "down"). 
     14287          is chosen at random. Ignored unless layout='tree'.
     14288
     14289        - ``tree_orientation`` - "up" or "down" (default is "down").
    1430414290          If "up" (resp., "down"), then the root of the tree will
    1430514291          appear on the bottom (resp., top) and the tree will grow
    1430614292          upwards (resp. downwards). Ignored unless layout='tree'.
    1430714293
    1430814294        - ``save_pos`` - save position computed during plotting
    14309            
    14310         EXAMPLES::
    14311        
     14295
     14296        .. NOTE::
     14297
     14298            - See the documentation of the :mod:`sage.graphs.graph_plot` module
     14299              for information on default arguments of this method.
     14300
     14301            - Default parameters for this method can also be set through the
     14302              :class:`~sage.misc.decorators.options` mechanism.
     14303
     14304            - See also the :mod:`sage.graphs.graph_latex` module for ways to use
     14305              LaTeX to produce an image of a graph.
     14306
     14307        EXAMPLES::
     14308
    1431214309            sage: from sage.graphs.graph_plot import graphplot_options
    1431314310            sage: list(sorted(graphplot_options.iteritems()))
    1431414311            [...]
     
    1449314490    def show(self, **kwds):
    1449414491        """
    1449514492        Shows the (di)graph.
    14496        
     14493
    1449714494        For syntax and lengthy documentation, see G.plot?. Any options not
    1449814495        used by plot will be passed on to the Graphics.show method.
    14499        
    14500         EXAMPLES::
    14501        
     14496
     14497        .. NOTE::
     14498
     14499            See the documentation of the :mod:`sage.graphs.graph_plot` module
     14500            for information on default arguments of this method.
     14501
     14502        EXAMPLES::
     14503
    1450214504            sage: C = graphs.CubeGraph(8)
    1450314505            sage: P = C.plot(vertex_labels=False, vertex_size=0, graph_border=True)
    1450414506            sage: P.show()  # long time (3s on sage.math, 2011)
    1450514507        """
    14506         kwds.setdefault('figsize', [4,4])
     14508        from sage.graphs.graph_plot import GraphPlot
    1450714509        from graph_plot import graphplot_options
    14508         vars = graphplot_options.keys()
    14509         plot_kwds = {}
    14510         for kwd in vars:
    14511             if kwds.has_key(kwd):
    14512                 plot_kwds[kwd] = kwds.pop(kwd)
    14513         self.plot(**plot_kwds).show(**kwds)
     14510
     14511        # This dictinary only contains the options that graphplot
     14512        # understands. These options are removed from kwds at the same
     14513        # time.
     14514        plot_kwds = {k:kwds.pop(k) for k in graphplot_options if k in kwds}
     14515
     14516        return GraphPlot(graph=self, options=plot_kwds).show(**kwds)
    1451414517
    1451514518    def plot3d(self, bgcolor=(1,1,1), vertex_colors=None, vertex_size=0.06,
    1451614519                     edge_colors=None, edge_size=0.02, edge_size2=0.0325,
    1451714520                     pos3d=None, color_by_label=False,
    1451814521                     engine='jmol', **kwds):
    1451914522        r"""
    14520         Plot a graph in three dimensions.    See also the
    14521         :mod:`sage.graphs.graph_latex` module for ways to use
    14522         `\mbox{\rm\LaTeX}` to produce an image of a graph.
     14523        Plot a graph in three dimensions.
     14524
     14525        See also the :mod:`sage.graphs.graph_latex` module for ways to use LaTeX
     14526        to produce an image of a graph.
    1452314527       
    1452414528        INPUT:
    1452514529       
  • sage/graphs/graph_plot.py

    diff --git a/sage/graphs/graph_plot.py b/sage/graphs/graph_plot.py
    a b  
    11"""
    22Graph Plotting
    33
     4*(For LaTeX drawings of graphs, see the* :mod:`~sage.graphs.graph_latex` *module.)*
     5
    46All graphs have an associated Sage graphics object, which you can display::
    57
    68    sage: G = graphs.WheelGraph(15)
     
    2224random and empty graphs), the position dictionary is filled in, instead of using
    2325the spring-layout algorithm.
    2426
    25 Functions and methods
    26 ---------------------
     27**Default options**
     28
     29This module defines two dictionaries containing default options for the
     30:meth:`~GraphPlot.plot` and :meth:`~GraphPlot.show` methods. Obviously, these
     31values are overruled when arguments are given explicitely.
     32
     33Here is how to define the default size of a graph drawing to be ``[4,4]``. The
     34first call to :meth:`~sage.graphs.generic_graph.show` uses this option, while
     35the second one does not (a value for ``figsize`` is explicitely given)::
     36
     37    sage: sage.graphs.graph_plot.DEFAULT_SHOW_OPTIONS['figsize'] = [4,4]
     38    sage: g = graphs.PetersenGraph()
     39    sage: g.show() # long time
     40    sage: g.show(figsize=[7,7])
     41
     42These two dictionaries are ``sage.graphs.graph_plot.DEFAULT_SHOW_OPTIONS`` and
     43``sage.graphs.graph_plot.DEFAULT_PLOT_OPTIONS``.
     44
     45.. NOTE::
     46
     47   In order to define a default value permanently, you can add a couple of lines to
     48   :doc:`Sage's startup scripts <../../startup>`. Example ::
     49
     50       sage: import sage.graphs.graph_plot
     51       sage: sage.graphs.graph_plot.DEFAULT_SHOW_OPTIONS['figsize'] = [4,4]
     52
     53**Index of methods and functions**
     54
     55.. csv-table::
     56    :class: contentstable
     57    :widths: 30, 70
     58    :delim: |
     59
     60    :meth:`GraphPlot.set_pos` | Sets the position plotting parameters for this GraphPlot.
     61    :meth:`GraphPlot.set_vertices` | Sets the vertex plotting parameters for this GraphPlot.
     62    :meth:`GraphPlot.set_edges` | Sets the edge (or arrow) plotting parameters for the GraphPlot object.
     63    :meth:`GraphPlot.show` | Shows the (Di)Graph associated with this GraphPlot object.
     64    :meth:`GraphPlot.plot` | Returns a graphics object representing the (di)graph.
     65    :meth:`GraphPlot.layout_tree` | Compute a nice layout of a tree.
     66    :meth:`~sage.graphs.graph_plot._circle_embedding` | Sets some vertices on a circle in the embedding of a graph G.
     67    :meth:`~sage.graphs.graph_plot._line_embedding` | Sets some vertices on a line in the embedding of a graph G.
     68
     69Methods and classes
     70-------------------
     71.. autofunction:: _circle_embedding
     72.. autofunction:: _line_embedding
    2773"""
    2874
    2975#*****************************************************************************
     
    60106                    }
    61107
    62108graphplot_options = layout_options.copy()
     109
    63110graphplot_options.update(
    64111                   {'pos': 'The position dictionary of vertices',
    65112                    'vertex_labels': 'Whether or not to draw vertex labels.',
     
    78125                    'talk': 'Whether to display the vertices in talk mode (larger and white)',
    79126                    'graph_border': 'Whether or not to draw a frame around the graph.'})
    80127
     128DEFAULT_SHOW_OPTIONS = {
     129    "figsize"             : [4,4]
     130    }
     131
     132DEFAULT_PLOT_OPTIONS = {
     133    "vertex_size"         : 200,
     134    "vertex_labels"       : True,
     135    "layout"              : None,
     136    "edge_style"          : 'solid',
     137    "edge_color"          : 'black',
     138    "edge_colors"         : None,
     139    "edge_labels"         : False,
     140    "iterations"          : 50,
     141    "tree_orientation"    : 'down',
     142    "heights"             : None,
     143    "graph_border"        : False,
     144    "talk"                : False,
     145    "color_by_label"      : False,
     146    "partition"           : None,
     147    "dist"                : .075,
     148    "max_dist"            : 1.5,
     149    "loop_size"           : .075
     150    }
     151
     152
    81153class GraphPlot(SageObject):
    82154    def __init__(self, graph, options):
    83155        """
     
    115187            sage: g = graphs.CompleteGraph(2); g.show()
    116188
    117189        """
     190        # Setting the default values if needed
     191        for k,value in DEFAULT_PLOT_OPTIONS.iteritems():
     192            if k not in options:
     193                options[k] = value
     194
    118195        self._plot_components = {}
    119196        self._nodelist = graph.vertices()
    120197        self._graph = graph
     
    126203            self._arcdigraph = True
    127204        else:
    128205            self._arcdigraph = False
     206
    129207        self.set_vertices()
    130208        self.set_edges()
    131        
     209
    132210    def _repr_(self):
    133211        """
    134212        Returns a string representation of a ``GraphPlot`` object.
     
    303381            for v in self._nodelist:
    304382                self._plot_components['vertex_labels'].append(text(str(v),
    305383                    self._pos[v], rgbcolor=(0,0,0), zorder=8))
    306    
     384
    307385    def set_edges(self, **edge_options):
    308386        """
    309387        Sets the edge (or arrow) plotting parameters for the ``GraphPlot`` object.
     388
    310389        This function is called by the constructor but can also be called to make
    311390        updates to the vertex options of an existing ``GraphPlot`` object.  Note
    312391        that the changes are cumulative.
    313        
     392
    314393        EXAMPLES::
    315394
    316395            sage: g = Graph({}, loops=True, multiedges=True, sparse=True)
     
    321400            sage: GP.plot()
    322401            sage: GP.set_edges(edge_color='black')
    323402            sage: GP.plot()
    324            
     403
    325404            sage: d = DiGraph({}, loops=True, multiedges=True, sparse=True)
    326405            sage: d.add_edges([(0,0,'a'),(0,0,'b'),(0,1,'c'),(0,1,'d'),
    327406            ...     (0,1,'e'),(0,1,'f'),(0,1,'f'),(2,1,'g'),(2,2,'h')])
     
    332411            sage: GP.plot()
    333412
    334413        TESTS::
    335        
     414
    336415            sage: G = Graph("Fooba")
    337416            sage: G.show(edge_colors={'red':[(3,6),(2,5)]})
    338417
     
    360439        for arg in edge_options:
    361440            self._options[arg] = edge_options[arg]
    362441        if 'edge_colors' in edge_options: self._options['color_by_label'] = False
    363        
     442
    364443        # Handle base edge options: thickness, linestyle
    365444        eoptions={}
    366445        if 'edge_style' in self._options:
    367446            eoptions['linestyle'] = self._options['edge_style']
    368447        if 'thickness' in self._options:
    369448            eoptions['thickness'] = self._options['thickness']
    370            
     449
    371450        # Set labels param to add labels on the fly
    372451        labels = False
    373452        if self._options['edge_labels']:
    374453            labels = True
    375454            self._plot_components['edge_labels'] = []
    376455
    377         # Make dict collection of all edges (keep label and edge color)           
     456        # Make dict collection of all edges (keep label and edge color)
    378457        edges_to_draw = {}
    379458        if self._options['color_by_label'] or isinstance(self._options['edge_colors'], dict):
    380459            if self._options['color_by_label']: edge_colors = self._graph._color_by_label()
     
    383462                for edge in edge_colors[color]:
    384463                    key = tuple(sorted([edge[0],edge[1]]))
    385464                    if key == (edge[0],edge[1]): head = 1
    386                     else: head = 0 
    387                    
     465                    else: head = 0
     466
    388467                    if len(edge) < 3:
    389468                        label = self._graph.edge_label(edge[0],edge[1])
    390469                        if isinstance(label, list):
     
    396475                                edges_to_draw[key].append((label[-1], color, head))
    397476                    else:
    398477                        label = edge[2]
    399                        
     478
    400479                    if key in edges_to_draw:
    401480                        edges_to_draw[key].append((label, color, head))
    402481                    else:
     
    413492                            break
    414493                if not specified:
    415494                    if key == (edge[0],edge[1]): head = 1
    416                     else: head = 0 
     495                    else: head = 0
    417496                    edges_to_draw[key] = [(label, 'black', head)]
    418497        else:
    419498            for edge in self._graph.edges(sort=True):
    420499                key = tuple(sorted([edge[0],edge[1]]))
    421500                if key == (edge[0],edge[1]): head = 1
    422                 else: head = 0 
     501                else: head = 0
    423502                if key in edges_to_draw:
    424503                    edges_to_draw[key].append((edge[2], self._options['edge_color'], head))
    425504                else:
    426505                    edges_to_draw[key] = [(edge[2], self._options['edge_color'], head)]
    427                
     506
    428507        if edges_to_draw:
    429508            self._plot_components['edges'] = []
    430509        else:
    431510            return
    432                        
     511
    433512        # Check for multi-edges or loops
    434513        if self._arcs or self._loops:
    435514            tmp = edges_to_draw.copy()
     
    439518            from sage.functions.all import sqrt
    440519            for (a,b) in tmp:
    441520                if a == b:
    442                     # Loops 
     521                    # Loops
    443522                    distance = dist
    444523                    local_labels = edges_to_draw.pop((a,b))
    445524                    if len(local_labels)*dist > max_dist:
     
    559638        elif D[1] > 0:
    560639            theta = pi/2
    561640        return ([VR*cos(theta)+A[0], VR*sin(theta)+A[1]], [(R-VR)*cos(theta)+A[0], (R-VR)*sin(theta)+A[1]])
    562        
     641
    563642    def show(self, **kwds):
    564643        """
    565644        Shows the (Di)Graph associated with this ``GraphPlot`` object.
    566        
     645
    567646        For syntax and lengthy documentation, see :meth:`GraphPlot.plot`.
    568         Any options not used by plot will be passed on to the
    569         :meth:`~sage.plot.plot.Graphics.show` method.
     647
     648        .. NOTE::
     649
     650            - See :mod:`the module's documentation <sage.graphs.graph_plot>` for
     651              information on default values of this method.
     652
     653            - Any options not used by plot will be passed on to the
     654              :meth:`~sage.plot.plot.Graphics.show` method.
    570655
    571656        EXAMPLE::
    572657
     
    574659            sage: P = C.graphplot(vertex_labels=False, vertex_size=0, graph_border=True)
    575660            sage: P.show()
    576661        """
     662        # Setting the default values if needed
     663        for k,value in DEFAULT_SHOW_OPTIONS.iteritems():
     664            if k not in kwds:
     665                kwds[k] = value
     666
    577667        self.plot().show(**kwds)
    578        
     668
    579669    def plot(self, **kwds):
    580670        """
    581671        Returns a graphics object representing the (di)graph.
    582        
     672
    583673        INPUT:
    584674
    585675        - ``pos`` -- an optional positioning dictionar
     
    649739
    650740        - ``save_pos`` -- save position computed during plotting
    651741
     742        .. NOTE::
     743
     744            See :mod:`the module's documentation <sage.graphs.graph_plot>` for
     745            information on default values of this method.
     746
    652747        EXAMPLES:
    653748
    654749        Let's list all possible options::
     
    682777             ('vertex_shape', 'The shape to draw the vertices, Currently unavailable for Multi-edged DiGraphs.'),
    683778             ('vertex_size', 'The size to draw the vertices.')]
    684779
    685 
    686780        We can specify some pretty precise plotting of familiar graphs::
    687781
    688782            sage: from math import sin, cos, pi
     
    9501044
    9511045def _circle_embedding(g, vertices, center=(0, 0), radius=1, shift=0):
    9521046    r"""
    953     Set some vertices on a circle in the embedding of a graph G.
     1047    Sets some vertices on a circle in the embedding of a graph G.
    9541048
    9551049    This method modifies the graph's embedding so that the vertices
    9561050    listed in ``vertices`` appear in this ordering on a circle of given
  • sage/modular/arithgroup/arithgroup_perm.py

    diff --git a/sage/modular/arithgroup/arithgroup_perm.py b/sage/modular/arithgroup/arithgroup_perm.py
    a b  
    12901290            res.plot.options['edge_labels'] = True
    12911291
    12921292        return res
    1293      
     1293
    12941294    def generalised_level(self):
    12951295        r"""
    12961296        Return the generalised level of this subgroup.