# 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
diff --git a/sage/graphs/generic_graph.py b/sage/graphs/generic_graph.py
 a Every graph carries a dictionary of options, which is set here to None.  Some options are added to the global :data:sage.misc.latex.latex instance which will insure that if \mbox{\rm\LaTeX} is used to render the graph, that if LaTeX is used to render the graph, then the right packages are loaded and MathJax reacts properly. return s def _latex_(self): r""" Returns a string to render the graph using \mbox{\rm{\LaTeX}}. r""" Returns a string to render the graph using LaTeX. To adjust the string, use the :meth:set_latex_options method to set options, Returns an instance of :class:~sage.graphs.graph_latex.GraphLatex for the graph. Changes to this object will affect the \mbox{\rm\LaTeX} version of the graph.    For a full explanation of how to use LaTeX to render graphs, see the introduction to the :mod:~sage.graphs.graph_latex module. Changes to this object will affect the LaTeX version of the graph.  For a full explanation of how to use LaTeX to render graphs, see the introduction to the :mod:~sage.graphs.graph_latex module. EXAMPLES:: return [xmin, xmax, ymin, ymax] @options(vertex_size=200, vertex_labels=True, layout=None, edge_style='solid', edge_color='black',edge_colors=None, edge_labels=False, iterations=50, tree_orientation='down', heights=None, graph_border=False, talk=False, color_by_label=False, partition=None, dist = .075, max_dist=1.5, loop_size=.075) def graphplot(self, **options): """ Returns a GraphPlot object. EXAMPLES: Creating a graphplot object uses the same options as graph.plot():: sage: g = Graph({}, loops=True, multiedges=True, sparse=True) sage: g.add_edges([(0,0,'a'),(0,0,'b'),(0,1,'c'),(0,1,'d'), ...     (0,1,'e'),(0,1,'f'),(0,1,'f'),(2,1,'g'),(2,2,'h')]) sage: GP.plot() We can modify the graphplot object.  Notice that the changes are cumulative:: sage: GP.set_edges(edge_style='solid') sage: GP.plot() sage: GP.set_vertices(talk=True) from sage.graphs.graph_plot import GraphPlot return GraphPlot(graph=self, options=options) @options(vertex_size=200, vertex_labels=True, layout=None, edge_style='solid', edge_color = 'black', edge_colors=None, edge_labels=False, iterations=50, tree_orientation='down', heights=None, graph_border=False, talk=False, color_by_label=False, partition=None, dist = .075, max_dist=1.5, loop_size=.075) @options() def plot(self, **options): r""" Returns a graphics object representing the (di)graph. See also the :mod:sage.graphs.graph_latex module for ways to use  \mbox{\rm\LaTeX} to produce an image of a graph. INPUT: INPUT: - pos - an optional positioning dictionary - layout - what kind of layout to use, takes precedence over pos - 'circular' -- plots the graph with vertices evenly distributed on a circle - 'spring' - uses the traditional spring layout, using the graph's current positions as initial positions - 'tree' - the (di)graph must be a tree. One can specify the root of the tree using the keyword tree_root, otherwise a root will be selected at random. Then the tree will be plotted in levels, depending on minimum distance for the root. - vertex_labels - whether to print vertex labels - edge_labels - whether to print edge labels. By default, False, but if True, the result of str(l) is printed on the edge for each label l. Labels equal to None are not printed (to set edge labels, see set_edge_label). - vertex_size - size of vertices displayed - vertex_shape - the shape to draw the vertices (Not available for multiedge digraphs.) - graph_border - whether to include a box around the graph - vertex_colors - optional dictionary to specify vertex each corresponding entry is a list of vertices. If a vertex is not listed, it looks invisible on the resulting plot (it doesn't get drawn). - edge_colors - a dictionary specifying edge colors: each key is a color recognized by matplotlib, and each entry is a list of edges. - heights - if specified, this is a dictionary from a set of floating point heights to a set of vertices - edge_style - keyword arguments passed into the edge-drawing routine.  This currently only works for directed graphs, since we pass off the undirected graph to - tree_root - a vertex of the tree to be used as the root for the layout="tree" option. If no root is specified, then one is chosen at random. Ignored unless layout='tree'. - tree_orientation - "up" or "down" (default is "down"). is chosen at random. Ignored unless layout='tree'. - tree_orientation - "up" or "down" (default is "down"). If "up" (resp., "down"), then the root of the tree will appear on the bottom (resp., top) and the tree will grow upwards (resp. downwards). Ignored unless layout='tree'. - save_pos - save position computed during plotting EXAMPLES:: .. NOTE:: - See the documentation of the :mod:sage.graphs.graph_plot module for information on default arguments of this method. - Default parameters for this method can also be set through the :class:~sage.misc.decorators.options mechanism. - See also the :mod:sage.graphs.graph_latex module for ways to use LaTeX to produce an image of a graph. EXAMPLES:: sage: from sage.graphs.graph_plot import graphplot_options sage: list(sorted(graphplot_options.iteritems())) [...] def show(self, **kwds): """ Shows the (di)graph. For syntax and lengthy documentation, see G.plot?. Any options not used by plot will be passed on to the Graphics.show method. EXAMPLES:: .. NOTE:: See the documentation of the :mod:sage.graphs.graph_plot module for information on default arguments of this method. EXAMPLES:: sage: C = graphs.CubeGraph(8) sage: P = C.plot(vertex_labels=False, vertex_size=0, graph_border=True) sage: P.show()  # long time (3s on sage.math, 2011) """ kwds.setdefault('figsize', [4,4]) from sage.graphs.graph_plot import GraphPlot from graph_plot import graphplot_options vars = graphplot_options.keys() plot_kwds = {} for kwd in vars: if kwds.has_key(kwd): plot_kwds[kwd] = kwds.pop(kwd) self.plot(**plot_kwds).show(**kwds) # This dictinary only contains the options that graphplot # understands. These options are removed from kwds at the same # time. plot_kwds = {k:kwds.pop(k) for k in graphplot_options if k in kwds} return GraphPlot(graph=self, options=plot_kwds).show(**kwds) def plot3d(self, bgcolor=(1,1,1), vertex_colors=None, vertex_size=0.06, edge_colors=None, edge_size=0.02, edge_size2=0.0325, pos3d=None, color_by_label=False, engine='jmol', **kwds): r""" Plot a graph in three dimensions.    See also the :mod:sage.graphs.graph_latex module for ways to use \mbox{\rm\LaTeX} to produce an image of a graph. Plot a graph in three dimensions. See also the :mod:sage.graphs.graph_latex module for ways to use LaTeX to produce an image of a graph. INPUT:
diff --git a/sage/graphs/graph_plot.py b/sage/graphs/graph_plot.py
 a """ Graph Plotting *(For LaTeX drawings of graphs, see the* :mod:~sage.graphs.graph_latex *module.)* All graphs have an associated Sage graphics object, which you can display:: sage: G = graphs.WheelGraph(15) random and empty graphs), the position dictionary is filled in, instead of using the spring-layout algorithm. Functions and methods --------------------- **Default options** This module defines two dictionaries containing default options for the :meth:~GraphPlot.plot and :meth:~GraphPlot.show methods. Obviously, these values are overruled when arguments are given explicitely. Here is how to define the default size of a graph drawing to be [4,4]. The first call to :meth:~sage.graphs.generic_graph.show uses this option, while the second one does not (a value for figsize is explicitely given):: sage: sage.graphs.graph_plot.DEFAULT_SHOW_OPTIONS['figsize'] = [4,4] sage: g = graphs.PetersenGraph() sage: g.show() # long time sage: g.show(figsize=[7,7]) These two dictionaries are sage.graphs.graph_plot.DEFAULT_SHOW_OPTIONS and sage.graphs.graph_plot.DEFAULT_PLOT_OPTIONS. .. NOTE:: In order to define a default value permanently, you can add a couple of lines to :doc:Sage's startup scripts <../../startup>. Example :: sage: import sage.graphs.graph_plot sage: sage.graphs.graph_plot.DEFAULT_SHOW_OPTIONS['figsize'] = [4,4] **Index of methods and functions** .. csv-table:: :class: contentstable :widths: 30, 70 :delim: | :meth:GraphPlot.set_pos | Sets the position plotting parameters for this GraphPlot. :meth:GraphPlot.set_vertices | Sets the vertex plotting parameters for this GraphPlot. :meth:GraphPlot.set_edges | Sets the edge (or arrow) plotting parameters for the GraphPlot object. :meth:GraphPlot.show | Shows the (Di)Graph associated with this GraphPlot object. :meth:GraphPlot.plot | Returns a graphics object representing the (di)graph. :meth:GraphPlot.layout_tree | Compute a nice layout of a tree. :meth:~sage.graphs.graph_plot._circle_embedding | Sets some vertices on a circle in the embedding of a graph G. :meth:~sage.graphs.graph_plot._line_embedding | Sets some vertices on a line in the embedding of a graph G. Methods and classes ------------------- .. autofunction:: _circle_embedding .. autofunction:: _line_embedding """ #***************************************************************************** } graphplot_options = layout_options.copy() graphplot_options.update( {'pos': 'The position dictionary of vertices', 'vertex_labels': 'Whether or not to draw vertex labels.', 'talk': 'Whether to display the vertices in talk mode (larger and white)', 'graph_border': 'Whether or not to draw a frame around the graph.'}) DEFAULT_SHOW_OPTIONS = { "figsize"             : [4,4] } DEFAULT_PLOT_OPTIONS = { "vertex_size"         : 200, "vertex_labels"       : True, "layout"              : None, "edge_style"          : 'solid', "edge_color"          : 'black', "edge_colors"         : None, "edge_labels"         : False, "iterations"          : 50, "tree_orientation"    : 'down', "heights"             : None, "graph_border"        : False, "talk"                : False, "color_by_label"      : False, "partition"           : None, "dist"                : .075, "max_dist"            : 1.5, "loop_size"           : .075 } class GraphPlot(SageObject): def __init__(self, graph, options): """ sage: g = graphs.CompleteGraph(2); g.show() """ # Setting the default values if needed for k,value in DEFAULT_PLOT_OPTIONS.iteritems(): if k not in options: options[k] = value self._plot_components = {} self._nodelist = graph.vertices() self._graph = graph self._arcdigraph = True else: self._arcdigraph = False self.set_vertices() self.set_edges() def _repr_(self): """ Returns a string representation of a GraphPlot object. for v in self._nodelist: self._plot_components['vertex_labels'].append(text(str(v), self._pos[v], rgbcolor=(0,0,0), zorder=8)) def set_edges(self, **edge_options): """ Sets the edge (or arrow) plotting parameters for the GraphPlot object. This function is called by the constructor but can also be called to make updates to the vertex options of an existing GraphPlot object.  Note that the changes are cumulative. EXAMPLES:: sage: g = Graph({}, loops=True, multiedges=True, sparse=True) sage: GP.plot() sage: GP.set_edges(edge_color='black') sage: GP.plot() sage: d = DiGraph({}, loops=True, multiedges=True, sparse=True) sage: d.add_edges([(0,0,'a'),(0,0,'b'),(0,1,'c'),(0,1,'d'), ...     (0,1,'e'),(0,1,'f'),(0,1,'f'),(2,1,'g'),(2,2,'h')]) sage: GP.plot() TESTS:: sage: G = Graph("Fooba") sage: G.show(edge_colors={'red':[(3,6),(2,5)]}) for arg in edge_options: self._options[arg] = edge_options[arg] if 'edge_colors' in edge_options: self._options['color_by_label'] = False # Handle base edge options: thickness, linestyle eoptions={} if 'edge_style' in self._options: eoptions['linestyle'] = self._options['edge_style'] if 'thickness' in self._options: eoptions['thickness'] = self._options['thickness'] # Set labels param to add labels on the fly labels = False if self._options['edge_labels']: labels = True self._plot_components['edge_labels'] = [] # Make dict collection of all edges (keep label and edge color) # Make dict collection of all edges (keep label and edge color) edges_to_draw = {} if self._options['color_by_label'] or isinstance(self._options['edge_colors'], dict): if self._options['color_by_label']: edge_colors = self._graph._color_by_label() for edge in edge_colors[color]: key = tuple(sorted([edge[0],edge[1]])) if key == (edge[0],edge[1]): head = 1 else: head = 0 else: head = 0 if len(edge) < 3: label = self._graph.edge_label(edge[0],edge[1]) if isinstance(label, list): edges_to_draw[key].append((label[-1], color, head)) else: label = edge[2] if key in edges_to_draw: edges_to_draw[key].append((label, color, head)) else: break if not specified: if key == (edge[0],edge[1]): head = 1 else: head = 0 else: head = 0 edges_to_draw[key] = [(label, 'black', head)] else: for edge in self._graph.edges(sort=True): key = tuple(sorted([edge[0],edge[1]])) if key == (edge[0],edge[1]): head = 1 else: head = 0 else: head = 0 if key in edges_to_draw: edges_to_draw[key].append((edge[2], self._options['edge_color'], head)) else: edges_to_draw[key] = [(edge[2], self._options['edge_color'], head)] if edges_to_draw: self._plot_components['edges'] = [] else: return # Check for multi-edges or loops if self._arcs or self._loops: tmp = edges_to_draw.copy() from sage.functions.all import sqrt for (a,b) in tmp: if a == b: # Loops # Loops distance = dist local_labels = edges_to_draw.pop((a,b)) if len(local_labels)*dist > max_dist: elif D[1] > 0: theta = pi/2 return ([VR*cos(theta)+A[0], VR*sin(theta)+A[1]], [(R-VR)*cos(theta)+A[0], (R-VR)*sin(theta)+A[1]]) def show(self, **kwds): """ Shows the (Di)Graph associated with this GraphPlot object. For syntax and lengthy documentation, see :meth:GraphPlot.plot. Any options not used by plot will be passed on to the :meth:~sage.plot.plot.Graphics.show method. .. NOTE:: - See :mod:the module's documentation  for information on default values of this method. - Any options not used by plot will be passed on to the :meth:~sage.plot.plot.Graphics.show method. EXAMPLE:: sage: P = C.graphplot(vertex_labels=False, vertex_size=0, graph_border=True) sage: P.show() """ # Setting the default values if needed for k,value in DEFAULT_SHOW_OPTIONS.iteritems(): if k not in kwds: kwds[k] = value self.plot().show(**kwds) def plot(self, **kwds): """ Returns a graphics object representing the (di)graph. INPUT: - pos -- an optional positioning dictionar - save_pos -- save position computed during plotting .. NOTE:: See :mod:the module's documentation  for information on default values of this method. EXAMPLES: Let's list all possible options:: ('vertex_shape', 'The shape to draw the vertices, Currently unavailable for Multi-edged DiGraphs.'), ('vertex_size', 'The size to draw the vertices.')] We can specify some pretty precise plotting of familiar graphs:: sage: from math import sin, cos, pi def _circle_embedding(g, vertices, center=(0, 0), radius=1, shift=0): r""" Set some vertices on a circle in the embedding of a graph G. Sets some vertices on a circle in the embedding of a graph G. This method modifies the graph's embedding so that the vertices listed in vertices appear in this ordering on a circle of given
diff --git a/sage/modular/arithgroup/arithgroup_perm.py b/sage/modular/arithgroup/arithgroup_perm.py