passagemath-graphs 10.5.10__cp39-cp39-macosx_14_0_arm64.whl → 10.5.43__cp39-cp39-macosx_14_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {passagemath_graphs-10.5.10.dist-info → passagemath_graphs-10.5.43.dist-info}/METADATA +126 -30
- passagemath_graphs-10.5.43.dist-info/RECORD +256 -0
- {passagemath_graphs-10.5.10.dist-info → passagemath_graphs-10.5.43.dist-info}/WHEEL +2 -1
- passagemath_graphs.dylibs/libgmp.10.dylib +0 -0
- sage/all__sagemath_graphs.py +5 -0
- sage/combinat/abstract_tree.py +1 -1
- sage/combinat/binary_tree.py +1 -1
- sage/combinat/cluster_algebra_quiver/all.py +1 -1
- sage/combinat/cluster_algebra_quiver/cluster_seed.py +28 -24
- sage/combinat/cluster_algebra_quiver/interact.py +4 -0
- sage/combinat/designs/MOLS_handbook_data.py +5 -5
- sage/combinat/designs/bibd.py +10 -9
- sage/combinat/designs/covering_array.py +3 -3
- sage/combinat/designs/covering_design.py +2 -1
- sage/combinat/designs/database.py +11 -10
- sage/combinat/designs/designs_pyx.cpython-39-darwin.so +0 -0
- sage/combinat/designs/designs_pyx.pyx +13 -45
- sage/combinat/designs/difference_family.py +6 -6
- sage/combinat/designs/difference_matrices.py +1 -1
- sage/combinat/designs/evenly_distributed_sets.cpython-39-darwin.so +0 -0
- sage/combinat/designs/evenly_distributed_sets.pyx +15 -22
- sage/combinat/designs/ext_rep.py +9 -14
- sage/combinat/designs/gen_quadrangles_with_spread.cpython-39-darwin.so +0 -0
- sage/combinat/designs/gen_quadrangles_with_spread.pyx +1 -1
- sage/combinat/designs/group_divisible_designs.py +1 -1
- sage/combinat/designs/incidence_structures.py +8 -8
- sage/combinat/designs/latin_squares.py +1 -1
- sage/combinat/designs/orthogonal_arrays_build_recursive.py +8 -7
- sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-39-darwin.so +0 -0
- sage/combinat/designs/resolvable_bibd.py +1 -1
- sage/combinat/designs/steiner_quadruple_systems.py +1 -1
- sage/combinat/designs/subhypergraph_search.cpython-39-darwin.so +0 -0
- sage/combinat/designs/subhypergraph_search.pyx +9 -9
- sage/combinat/finite_state_machine_generators.py +2 -2
- sage/combinat/graph_path.py +3 -3
- sage/combinat/interval_posets.py +10 -10
- sage/combinat/ordered_tree.py +1 -1
- sage/combinat/posets/cartesian_product.py +1 -1
- sage/combinat/posets/d_complete.py +1 -1
- sage/combinat/posets/forest.py +1 -1
- sage/combinat/posets/hasse_cython.cpython-39-darwin.so +0 -0
- sage/combinat/posets/hasse_diagram.py +8 -6
- sage/combinat/posets/incidence_algebras.py +8 -8
- sage/combinat/posets/lattices.py +28 -4
- sage/combinat/posets/linear_extension_iterator.cpython-39-darwin.so +0 -0
- sage/combinat/posets/linear_extension_iterator.pyx +2 -0
- sage/combinat/posets/linear_extensions.py +7 -16
- sage/combinat/posets/moebius_algebra.py +1 -1
- sage/combinat/posets/poset_examples.py +1 -1
- sage/combinat/posets/posets.py +54 -56
- sage/combinat/rooted_tree.py +3 -3
- sage/combinat/tamari_lattices.py +1 -1
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/graphs/asteroidal_triples.cpython-39-darwin.so +0 -0
- sage/graphs/base/boost_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/boost_graph.pxd +1 -1
- sage/graphs/base/boost_graph.pyx +1 -1
- sage/graphs/base/c_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/c_graph.pxd +4 -4
- sage/graphs/base/c_graph.pyx +270 -184
- sage/graphs/base/dense_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/graph_backends.cpython-39-darwin.so +0 -0
- sage/graphs/base/sparse_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/static_dense_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/static_sparse_backend.cpython-39-darwin.so +0 -0
- sage/graphs/base/static_sparse_backend.pyx +93 -6
- sage/graphs/base/static_sparse_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/static_sparse_graph.pyx +1 -1
- sage/graphs/bipartite_graph.py +0 -1
- sage/graphs/centrality.cpython-39-darwin.so +0 -0
- sage/graphs/centrality.pyx +0 -0
- sage/graphs/comparability.cpython-39-darwin.so +0 -0
- sage/graphs/comparability.pyx +172 -138
- sage/graphs/connectivity.cpython-39-darwin.so +0 -0
- sage/graphs/connectivity.pyx +194 -18
- sage/graphs/convexity_properties.cpython-39-darwin.so +0 -0
- sage/graphs/digraph_generators.py +118 -74
- sage/graphs/distances_all_pairs.cpython-39-darwin.so +0 -0
- sage/graphs/distances_all_pairs.pyx +145 -27
- sage/graphs/edge_connectivity.cpython-39-darwin.so +0 -0
- sage/graphs/generators/basic.py +471 -130
- sage/graphs/generators/distance_regular.cpython-39-darwin.so +0 -0
- sage/graphs/generators/distance_regular.pyx +12 -12
- sage/graphs/generators/families.py +2 -2
- sage/graphs/generators/random.py +8 -13
- sage/graphs/generators/smallgraphs.py +12 -11
- sage/graphs/generic_graph.py +687 -265
- sage/graphs/generic_graph_pyx.cpython-39-darwin.so +0 -0
- sage/graphs/genus.cpython-39-darwin.so +0 -0
- sage/graphs/graph.py +12 -46
- sage/graphs/graph_coloring.cpython-39-darwin.so +0 -0
- sage/graphs/graph_database.py +1 -1
- sage/graphs/graph_decompositions/bandwidth.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/cutwidth.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/fast_digraph.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/graph_products.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/modular_decomposition.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/tree_decomposition.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/vertex_separation.cpython-39-darwin.so +0 -0
- sage/graphs/graph_generators.py +110 -55
- sage/graphs/graph_generators_pyx.cpython-39-darwin.so +0 -0
- sage/graphs/graph_latex.py +1 -1
- sage/graphs/graph_list.py +2 -3
- sage/graphs/graph_plot.py +225 -30
- sage/graphs/hyperbolicity.cpython-39-darwin.so +0 -0
- sage/graphs/independent_sets.cpython-39-darwin.so +0 -0
- sage/graphs/isgci.py +3 -8
- sage/graphs/isoperimetric_inequalities.cpython-39-darwin.so +0 -0
- sage/graphs/line_graph.cpython-39-darwin.so +0 -0
- sage/graphs/matching.py +14 -25
- sage/graphs/matching_covered_graph.py +871 -60
- sage/graphs/orientations.py +190 -134
- sage/graphs/path_enumeration.cpython-39-darwin.so +0 -0
- sage/graphs/path_enumeration.pyx +25 -25
- sage/graphs/spanning_tree.cpython-39-darwin.so +0 -0
- sage/graphs/strongly_regular_db.cpython-39-darwin.so +0 -0
- sage/graphs/strongly_regular_db.pyx +54 -52
- sage/graphs/traversals.cpython-39-darwin.so +0 -0
- sage/graphs/traversals.pyx +114 -46
- sage/graphs/trees.cpython-39-darwin.so +0 -0
- sage/graphs/views.cpython-39-darwin.so +0 -0
- sage/graphs/weakly_chordal.cpython-39-darwin.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-39-darwin.so +0 -0
- sage/knots/free_knotinfo_monoid.py +2 -3
- sage/knots/knot.py +1 -1
- sage/knots/knotinfo.py +4 -4
- sage/knots/link.py +58 -57
- sage/sandpiles/sandpile.py +2 -3
- sage/topology/cell_complex.py +1 -1
- sage/topology/cubical_complex.py +7 -7
- sage/topology/delta_complex.py +4 -4
- sage/topology/simplicial_complex.py +7 -22
- passagemath_graphs-10.5.10.dist-info/RECORD +0 -251
- {passagemath_graphs-10.5.10.dist-info → passagemath_graphs-10.5.43.dist-info}/top_level.txt +0 -0
sage/graphs/graph_plot.py
CHANGED
@@ -182,6 +182,9 @@ graphplot_options.update({
|
|
182
182
|
'a dictionary keyed by vertices and associating to each vertex '
|
183
183
|
'a label string, or a function taking as input a vertex and returning '
|
184
184
|
'a label string.',
|
185
|
+
'vertex_label_shift':
|
186
|
+
'If layout is circular and we have vertex labels, will shift vertices '
|
187
|
+
'away from center of circle in coordinate fashion `(x, y)`.',
|
185
188
|
'vertex_color':
|
186
189
|
'Default color for vertices not listed '
|
187
190
|
'in vertex_colors dictionary.',
|
@@ -198,10 +201,19 @@ graphplot_options.update({
|
|
198
201
|
'Whether or not to draw edge labels.',
|
199
202
|
'edge_style':
|
200
203
|
'The linestyle of the edges. It should be '
|
201
|
-
'one of "solid", "dashed", "dotted", dashdot", '
|
204
|
+
'one of "solid", "dashed", "dotted", "dashdot", '
|
202
205
|
'or "-", "--", ":", "-.", respectively. ',
|
206
|
+
'edge_styles':
|
207
|
+
'A dictionary specifying edge styles: '
|
208
|
+
'each key is an edge or a label (all same) and value is the linestyle '
|
209
|
+
'of the edge. It should be one of "solid", "dashed", "dotted", '
|
210
|
+
'"dashdot", or "-", "--", ":", "-.", respectively.',
|
203
211
|
'edge_thickness':
|
204
212
|
'The thickness of the edges.',
|
213
|
+
'edge_thicknesses':
|
214
|
+
'A dictionary specifying edge thicknesses: '
|
215
|
+
'each key is an edge or a label (all same) and thickness of the '
|
216
|
+
'corresponding edge.',
|
205
217
|
'edge_color':
|
206
218
|
'The default color for edges not listed in edge_colors.',
|
207
219
|
'edge_colors':
|
@@ -216,12 +228,16 @@ graphplot_options.update({
|
|
216
228
|
'cell in a different color; vertex_colors takes precedence.',
|
217
229
|
'loop_size':
|
218
230
|
'The radius of the smallest loop.',
|
231
|
+
'arrowsize':
|
232
|
+
'Size of arrows.',
|
219
233
|
'dist':
|
220
234
|
'The distance between multiedges.',
|
221
235
|
'max_dist':
|
222
236
|
'The max distance range to allow multiedges.',
|
223
237
|
'talk':
|
224
238
|
'Whether to display the vertices in talk mode (larger and white).',
|
239
|
+
'label_fontsize':
|
240
|
+
'font size of all labels',
|
225
241
|
'graph_border':
|
226
242
|
'Whether or not to draw a frame around the graph.',
|
227
243
|
'edge_labels_background':
|
@@ -239,9 +255,12 @@ DEFAULT_SHOW_OPTIONS = {'figsize': (4, 4)}
|
|
239
255
|
DEFAULT_PLOT_OPTIONS = {
|
240
256
|
'vertex_size' : 200,
|
241
257
|
'vertex_labels' : True,
|
258
|
+
'vertex_label_shift' : None,
|
242
259
|
'layout' : None,
|
243
260
|
'edge_style' : 'solid',
|
261
|
+
'edge_styles' : None,
|
244
262
|
'edge_thickness' : 1,
|
263
|
+
'edge_thicknesses' : None,
|
245
264
|
'edge_color' : 'black',
|
246
265
|
'edge_colors' : None,
|
247
266
|
'edge_labels' : False,
|
@@ -254,6 +273,7 @@ DEFAULT_PLOT_OPTIONS = {
|
|
254
273
|
'partition' : None,
|
255
274
|
'dist' : .075,
|
256
275
|
'max_dist' : 1.5,
|
276
|
+
'label_fontsize' : 10,
|
257
277
|
'loop_size' : .075,
|
258
278
|
'edge_labels_background' : 'white'}
|
259
279
|
|
@@ -569,9 +589,26 @@ class GraphPlot(SageObject):
|
|
569
589
|
return vlabels.get(x, "")
|
570
590
|
else:
|
571
591
|
vfun = vlabels
|
592
|
+
|
572
593
|
# TODO: allow text options
|
573
|
-
self.
|
574
|
-
|
594
|
+
if self._options['layout'] == 'circular' and self._options['vertex_label_shift'] is not None:
|
595
|
+
def pos_shift(v, shift):
|
596
|
+
return (v[0] + (v[0] * shift[0])/100, v[1] + (v[1] * shift[1])/100)
|
597
|
+
self._plot_components['vertex_labels'] = [
|
598
|
+
text(
|
599
|
+
vfun(v),
|
600
|
+
pos_shift(self._pos[v], self._options['vertex_label_shift']),
|
601
|
+
fontsize=self._options['label_fontsize'],
|
602
|
+
color='black',
|
603
|
+
zorder=8
|
604
|
+
)
|
605
|
+
for v in self._nodelist
|
606
|
+
]
|
607
|
+
else:
|
608
|
+
self._plot_components['vertex_labels'] = [
|
609
|
+
text(vfun(v), self._pos[v], color='black', zorder=8, fontsize=self._options['label_fontsize'])
|
610
|
+
for v in self._nodelist
|
611
|
+
]
|
575
612
|
|
576
613
|
def set_edges(self, **edge_options):
|
577
614
|
"""
|
@@ -710,15 +747,20 @@ class GraphPlot(SageObject):
|
|
710
747
|
if self._options['edge_labels_background'] == "transparent":
|
711
748
|
self._options['edge_labels_background'] = "None"
|
712
749
|
|
713
|
-
#
|
750
|
+
# Whether a key is an edge or not:
|
751
|
+
# None => edge_x is not set
|
752
|
+
# True => keys are edges
|
753
|
+
# False => keys are labels
|
754
|
+
style_key_edges = None
|
755
|
+
thickness_key_edges = None
|
756
|
+
if isinstance(self._options['edge_styles'], dict):
|
757
|
+
style_key_edges = next(iter(self._options['edge_styles'])) in self._graph.edges()
|
758
|
+
if isinstance(self._options['edge_thicknesses'], dict):
|
759
|
+
thickness_key_edges = next(iter(self._options['edge_thicknesses'])) in self._graph.edges()
|
760
|
+
|
714
761
|
eoptions = {}
|
715
|
-
if '
|
716
|
-
|
717
|
-
eoptions['linestyle'] = get_matplotlib_linestyle(
|
718
|
-
self._options['edge_style'],
|
719
|
-
return_type='long')
|
720
|
-
if 'edge_thickness' in self._options:
|
721
|
-
eoptions['thickness'] = self._options['edge_thickness']
|
762
|
+
if 'arrowsize' in self._options:
|
763
|
+
eoptions['arrowsize'] = self._options['arrowsize']
|
722
764
|
|
723
765
|
# Set labels param to add labels on the fly
|
724
766
|
labels = False
|
@@ -813,12 +855,24 @@ class GraphPlot(SageObject):
|
|
813
855
|
# Now add all the loops at this vertex, varying their size
|
814
856
|
for lab, col, _ in local_labels:
|
815
857
|
x, y = self._pos[a][0], self._pos[a][1] - loop_size
|
816
|
-
|
858
|
+
|
859
|
+
estyle = self._options['edge_style']
|
860
|
+
ethickness = self._options['edge_thickness']
|
861
|
+
if (style_key_edges is not None
|
862
|
+
and ((style_key_edges and (x, y) in self._options['edge_styles'])
|
863
|
+
or (not style_key_edges and lab in self._options['edge_styles']))):
|
864
|
+
estyle = style_key_edges and self._options['edge_styles'][(x, y)] or self._options['edge_styles'][lab]
|
865
|
+
if (thickness_key_edges is not None
|
866
|
+
and ((thickness_key_edges and (x, y) in self._options['edge_thicknesses'])
|
867
|
+
or (not thickness_key_edges and lab in self._options['edge_thicknesses']))):
|
868
|
+
ethickness = thickness_key_edges and self._options['edge_thicknesses'][(x, y)] or self._options['edge_thicknesses'][lab]
|
869
|
+
|
870
|
+
c = circle((x, y), loop_size, rgbcolor=col, linestyle=estyle, thickness=ethickness)
|
817
871
|
self._plot_components['edges'].append(c)
|
818
872
|
if labels:
|
819
873
|
bg = self._options['edge_labels_background']
|
820
874
|
y -= loop_size # place label at bottom of loop
|
821
|
-
t = text(lab, (x, y), background_color=bg)
|
875
|
+
t = text(lab, (x, y), background_color=bg, fontsize=self._options['label_fontsize'])
|
822
876
|
self._plot_components['edge_labels'].append(t)
|
823
877
|
loop_size += loop_size_increment
|
824
878
|
elif len(edges_to_draw[a, b]) > 1:
|
@@ -884,6 +938,9 @@ class GraphPlot(SageObject):
|
|
884
938
|
distance = float(max_dist) / len_local_labels
|
885
939
|
for i in range(len_local_labels // 2):
|
886
940
|
k = (i + 1.0) * distance
|
941
|
+
estyle = self._options['edge_style']
|
942
|
+
ethickness = self._options['edge_thickness']
|
943
|
+
|
887
944
|
if self._arcdigraph:
|
888
945
|
vr = self._vertex_radius
|
889
946
|
ph = self._polar_hack_for_multidigraph
|
@@ -891,73 +948,112 @@ class GraphPlot(SageObject):
|
|
891
948
|
odd_end = ph(odd_xy(k), p2, vr)[1]
|
892
949
|
even_start = ph(p1, even_xy(k), vr)[0]
|
893
950
|
even_end = ph(even_xy(k), p2, vr)[1]
|
951
|
+
|
894
952
|
self._plot_components['edges'].append(
|
895
953
|
arrow(path=[[odd_start, odd_xy(k), odd_end]],
|
896
954
|
head=local_labels[2 * i][2], zorder=1,
|
897
955
|
rgbcolor=local_labels[2 * i][1],
|
898
|
-
|
956
|
+
linestyle=estyle,
|
957
|
+
width=ethickness,
|
958
|
+
**eoptions
|
959
|
+
))
|
899
960
|
self._plot_components['edges'].append(
|
900
961
|
arrow(path=[[even_start, even_xy(k), even_end]],
|
901
962
|
head=local_labels[2 * i + 1][2], zorder=1,
|
902
963
|
rgbcolor=local_labels[2 * i + 1][1],
|
903
|
-
|
964
|
+
linestyle=estyle,
|
965
|
+
width=ethickness,
|
966
|
+
**eoptions
|
967
|
+
))
|
904
968
|
else:
|
905
969
|
self._plot_components['edges'].append(
|
906
970
|
bezier_path([[p1, odd_xy(k), p2]], zorder=1,
|
907
971
|
rgbcolor=local_labels[2 * i][1],
|
908
|
-
|
972
|
+
linestyle=estyle,
|
973
|
+
thickness=ethickness
|
974
|
+
))
|
909
975
|
self._plot_components['edges'].append(
|
910
976
|
bezier_path([[p1, even_xy(k), p2]], zorder=1,
|
911
977
|
rgbcolor=local_labels[2 * i + 1][1],
|
912
|
-
|
978
|
+
linestyle=estyle,
|
979
|
+
thickness=ethickness
|
980
|
+
))
|
913
981
|
if labels:
|
914
982
|
j = k / 2.0
|
915
983
|
bg = self._options['edge_labels_background']
|
916
984
|
self._plot_components['edge_labels'].append(
|
917
985
|
text(local_labels[2 * i][0], odd_xy(j),
|
918
|
-
background_color=bg))
|
986
|
+
background_color=bg, fontsize=self._options['label_fontsize']))
|
919
987
|
self._plot_components['edge_labels'].append(
|
920
988
|
text(local_labels[2 * i + 1][0], even_xy(j),
|
921
|
-
background_color=bg))
|
989
|
+
background_color=bg, fontsize=self._options['label_fontsize']))
|
922
990
|
if len_local_labels % 2:
|
923
991
|
# draw line for last odd
|
924
992
|
edges_to_draw[a, b] = [local_labels[-1]]
|
925
993
|
|
926
994
|
is_directed = self._graph.is_directed()
|
927
995
|
for a, b in edges_to_draw:
|
996
|
+
elabel = edges_to_draw[a, b][0][0]
|
997
|
+
ecolor = edges_to_draw[a, b][0][1]
|
998
|
+
ehead = edges_to_draw[a, b][0][2]
|
999
|
+
e = (a, b, elabel)
|
1000
|
+
|
1001
|
+
estyle = self._options['edge_style']
|
1002
|
+
ethickness = self._options['edge_thickness']
|
1003
|
+
if (style_key_edges is not None
|
1004
|
+
and ((style_key_edges and e in self._options['edge_styles'])
|
1005
|
+
or (not style_key_edges and elabel in self._options['edge_styles']))):
|
1006
|
+
estyle = style_key_edges and self._options['edge_styles'][e] or self._options['edge_styles'][elabel]
|
1007
|
+
if (thickness_key_edges is not None
|
1008
|
+
and ((thickness_key_edges and e in self._options['edge_thicknesses'])
|
1009
|
+
or (not thickness_key_edges and elabel in self._options['edge_thicknesses']))):
|
1010
|
+
ethickness = thickness_key_edges and self._options['edge_thicknesses'][e] or self._options['edge_thicknesses'][elabel]
|
1011
|
+
|
928
1012
|
if self._arcdigraph:
|
929
1013
|
ph = self._polar_hack_for_multidigraph
|
930
1014
|
C, D = ph(self._pos[a], self._pos[b], self._vertex_radius)
|
931
1015
|
self._plot_components['edges'].append(
|
932
1016
|
arrow(C, D,
|
933
|
-
rgbcolor=
|
934
|
-
head=
|
935
|
-
|
1017
|
+
rgbcolor=ecolor,
|
1018
|
+
head=ehead,
|
1019
|
+
linestyle=estyle,
|
1020
|
+
width=ethickness,
|
1021
|
+
**eoptions
|
1022
|
+
))
|
936
1023
|
if labels:
|
937
1024
|
bg = self._options['edge_labels_background']
|
938
1025
|
self._plot_components['edge_labels'].append(
|
939
|
-
text(str(
|
1026
|
+
text(str(elabel),
|
940
1027
|
[(C[0] + D[0]) / 2., (C[1] + D[1]) / 2.],
|
941
|
-
background_color=bg
|
1028
|
+
background_color=bg,
|
1029
|
+
fontsize=self._options['label_fontsize']
|
1030
|
+
))
|
942
1031
|
elif is_directed:
|
943
1032
|
self._plot_components['edges'].append(
|
944
1033
|
arrow(self._pos[a], self._pos[b],
|
945
|
-
rgbcolor=
|
1034
|
+
rgbcolor=ecolor,
|
946
1035
|
arrowshorten=self._arrowshorten,
|
947
|
-
head=
|
948
|
-
|
1036
|
+
head=ehead,
|
1037
|
+
linestyle=estyle,
|
1038
|
+
width=ethickness,
|
1039
|
+
**eoptions
|
1040
|
+
))
|
949
1041
|
else:
|
950
1042
|
self._plot_components['edges'].append(
|
951
1043
|
line([self._pos[a], self._pos[b]],
|
952
|
-
rgbcolor=
|
953
|
-
|
1044
|
+
rgbcolor=ecolor,
|
1045
|
+
linestyle=estyle,
|
1046
|
+
thickness=ethickness
|
1047
|
+
))
|
954
1048
|
if labels and not self._arcdigraph:
|
955
1049
|
bg = self._options['edge_labels_background']
|
956
1050
|
self._plot_components['edge_labels'].append(
|
957
1051
|
text(str(edges_to_draw[a, b][0][0]),
|
958
1052
|
[(self._pos[a][0] + self._pos[b][0]) / 2.,
|
959
1053
|
(self._pos[a][1] + self._pos[b][1]) / 2.],
|
960
|
-
background_color=bg
|
1054
|
+
background_color=bg,
|
1055
|
+
fontsize=self._options['label_fontsize']
|
1056
|
+
))
|
961
1057
|
|
962
1058
|
def _polar_hack_for_multidigraph(self, A, B, VR):
|
963
1059
|
"""
|
@@ -1149,6 +1245,31 @@ class GraphPlot(SageObject):
|
|
1149
1245
|
D.set_edge_label(u, v, f'({u},{v})')
|
1150
1246
|
sphinx_plot(D.graphplot(edge_labels=True, layout='circular'))
|
1151
1247
|
|
1248
|
+
For graphs with ``circular`` layouts, one may shift the vertex labels by
|
1249
|
+
specifying coordinates to shift by::
|
1250
|
+
|
1251
|
+
sage: D = DiGraph({
|
1252
|
+
....: 0: [1, 10, 19], 1: [8, 2], 2: [3, 6], 3: [19, 4],
|
1253
|
+
....: 4: [17, 5], 5: [6, 15], 6: [7], 7: [8, 14], 8: [9],
|
1254
|
+
....: 9: [10, 13], 10: [11], 11: [12, 18], 12: [16, 13],
|
1255
|
+
....: 13: [14], 14: [15], 15: [16], 16: [17], 17: [18],
|
1256
|
+
....: 18: [19], 19: []})
|
1257
|
+
sage: for u, v, l in D.edges(sort=True):
|
1258
|
+
....: D.set_edge_label(u, v, f'({u},{v})')
|
1259
|
+
sage: D.graphplot(edge_labels=True, layout='circular', vertex_label_shift=(15,10)).show()
|
1260
|
+
|
1261
|
+
.. PLOT::
|
1262
|
+
|
1263
|
+
D = DiGraph({
|
1264
|
+
0: [1, 10, 19], 1: [8, 2], 2: [3, 6], 3: [19, 4],
|
1265
|
+
4: [17, 5], 5: [6, 15], 6: [7], 7: [8, 14], 8: [9],
|
1266
|
+
9: [10, 13], 10: [11], 11: [12, 18], 12: [16, 13],
|
1267
|
+
13: [14], 14: [15], 15: [16], 16: [17], 17: [18],
|
1268
|
+
18: [19], 19: []})
|
1269
|
+
for u, v, l in D.edges(sort=True):
|
1270
|
+
D.set_edge_label(u, v, f'({u},{v})')
|
1271
|
+
sphinx_plot(D.graphplot(edge_labels=True, layout='circular', vertex_label_shift=(15,10)))
|
1272
|
+
|
1152
1273
|
This example shows off the coloring of edges::
|
1153
1274
|
|
1154
1275
|
sage: from sage.plot.colors import rainbow
|
@@ -1238,6 +1359,17 @@ class GraphPlot(SageObject):
|
|
1238
1359
|
P = g.graphplot(pos=pos, layout='spring', iterations=0).plot()
|
1239
1360
|
sphinx_plot(P)
|
1240
1361
|
|
1362
|
+
::
|
1363
|
+
|
1364
|
+
sage: D = graphs.CubeGraph(3)
|
1365
|
+
sage: D.graphplot(layout='planar').plot() # needs planarity
|
1366
|
+
Graphics object consisting of 21 graphics primitives
|
1367
|
+
|
1368
|
+
.. PLOT::
|
1369
|
+
|
1370
|
+
D = graphs.CubeGraph(3)
|
1371
|
+
sphinx_plot(D.graphplot(layout='planar'))
|
1372
|
+
|
1241
1373
|
::
|
1242
1374
|
|
1243
1375
|
sage: G = Graph()
|
@@ -1346,6 +1478,17 @@ class GraphPlot(SageObject):
|
|
1346
1478
|
D = DiGraph({0:[1,2,3], 2:[1,4], 3:[0]})
|
1347
1479
|
sphinx_plot(D.graphplot())
|
1348
1480
|
|
1481
|
+
::
|
1482
|
+
|
1483
|
+
sage: D = DiGraph({0:[1,2,3], 2:[1,4], 3:[0]})
|
1484
|
+
sage: D.graphplot(label_fontsize=20, arrowsize=10).show()
|
1485
|
+
|
1486
|
+
.. PLOT::
|
1487
|
+
|
1488
|
+
D = DiGraph({0:[1,2,3], 2:[1,4], 3:[0]})
|
1489
|
+
sphinx_plot(D.graphplot(label_fontsize=20, arrowsize=10))
|
1490
|
+
|
1491
|
+
|
1349
1492
|
::
|
1350
1493
|
|
1351
1494
|
sage: D = DiGraph(multiedges=True, sparse=True)
|
@@ -1390,12 +1533,64 @@ class GraphPlot(SageObject):
|
|
1390
1533
|
|
1391
1534
|
The ``edge_style`` option may be provided in the short format too::
|
1392
1535
|
|
1536
|
+
|
1393
1537
|
sage: g.graphplot(edge_labels=True,
|
1394
1538
|
....: color_by_label=True,
|
1395
1539
|
....: edge_style='--'
|
1396
1540
|
....: ).plot()
|
1397
1541
|
Graphics object consisting of 22 graphics primitives
|
1398
1542
|
|
1543
|
+
The ``edge_styles`` option may be provided if you need only certain edges
|
1544
|
+
to have certain styles::
|
1545
|
+
|
1546
|
+
sage: g = Graph(loops=True, multiedges=True, sparse=True)
|
1547
|
+
sage: g.add_edges([(0, 0, 'a'), (0, 0, 'b'), (0, 1, 'c'),
|
1548
|
+
....: (0, 1, 'd'), (0, 1, 'e'), (0, 1, 'f'),
|
1549
|
+
....: (0, 1, 'f'), (2, 1, 'g'), (2, 2, 'h')])
|
1550
|
+
sage: GP = g.graphplot(vertex_size=100, edge_labels=True,
|
1551
|
+
....: color_by_label=True, edge_style='dashed')
|
1552
|
+
sage: GP.set_edges(edge_styles={'a':'dashed', 'g':'dotted'})
|
1553
|
+
sage: GP.plot()
|
1554
|
+
Graphics object consisting of 22 graphics primitives
|
1555
|
+
|
1556
|
+
.. PLOT::
|
1557
|
+
|
1558
|
+
g = Graph(loops=True, multiedges=True, sparse=True)
|
1559
|
+
g.add_edges([(0, 0, 'a'), (0, 0, 'b'), (0, 1, 'c'),
|
1560
|
+
(0, 1, 'd'), (0, 1, 'e'), (0, 1, 'f'),
|
1561
|
+
(0, 1, 'f'), (2, 1, 'g'), (2, 2, 'h')])
|
1562
|
+
GP = g.graphplot(vertex_size=100, edge_labels=True,
|
1563
|
+
color_by_label=True, edge_style='dashed')
|
1564
|
+
GP.set_edges(edge_style='solid')
|
1565
|
+
GP.set_edges(edge_color='black')
|
1566
|
+
GP.set_edges(edge_styles={'a':'dashed', 'g':'dotted'})
|
1567
|
+
sphinx_plot(GP)
|
1568
|
+
|
1569
|
+
::
|
1570
|
+
|
1571
|
+
sage: g = Graph(loops=True, multiedges=True, sparse=True)
|
1572
|
+
sage: g.add_edges([(0, 0, 'a'), (0, 0, 'b'), (0, 1, 'c'),
|
1573
|
+
....: (0, 1, 'd'), (0, 1, 'e'), (0, 1, 'f'),
|
1574
|
+
....: (0, 1, 'f'), (2, 1, 'g'), (2, 2, 'h')])
|
1575
|
+
sage: GP = g.graphplot(vertex_size=100, edge_labels=True,
|
1576
|
+
....: color_by_label=True, edge_thickness=3)
|
1577
|
+
sage: GP.set_edges(edge_thicknesses={'a':1, 'g':5})
|
1578
|
+
sage: GP.plot()
|
1579
|
+
Graphics object consisting of 22 graphics primitives
|
1580
|
+
|
1581
|
+
.. PLOT::
|
1582
|
+
|
1583
|
+
g = Graph(loops=True, multiedges=True, sparse=True)
|
1584
|
+
g.add_edges([(0, 0, 'a'), (0, 0, 'b'), (0, 1, 'c'),
|
1585
|
+
(0, 1, 'd'), (0, 1, 'e'), (0, 1, 'f'),
|
1586
|
+
(0, 1, 'f'), (2, 1, 'g'), (2, 2, 'h')])
|
1587
|
+
GP = g.graphplot(vertex_size=100, edge_labels=True,
|
1588
|
+
color_by_label=True, edge_thickness=3)
|
1589
|
+
GP.set_edges(edge_style='solid')
|
1590
|
+
GP.set_edges(edge_color='black')
|
1591
|
+
GP.set_edges(edge_thicknesses={'a':1, 'g':5})
|
1592
|
+
sphinx_plot(GP)
|
1593
|
+
|
1399
1594
|
TESTS:
|
1400
1595
|
|
1401
1596
|
Make sure that show options work with plot also::
|
Binary file
|
Binary file
|
sage/graphs/isgci.py
CHANGED
@@ -502,7 +502,7 @@ class GraphClass(SageObject, CachedRepresentation):
|
|
502
502
|
sage: graph_classes.Chordal == graph_classes.Tree
|
503
503
|
Unknown
|
504
504
|
"""
|
505
|
-
return self >= other
|
505
|
+
return self >= other >= self
|
506
506
|
|
507
507
|
def __lt__(self, other):
|
508
508
|
r"""
|
@@ -854,13 +854,8 @@ class GraphClasses(UniqueRepresentation):
|
|
854
854
|
|
855
855
|
This method downloads the ISGCI database from the website
|
856
856
|
`GraphClasses.org <http://www.graphclasses.org/>`_. It then extracts the
|
857
|
-
zip file and parses its XML content.
|
858
|
-
|
859
|
-
Depending on the credentials of the user running Sage when this command
|
860
|
-
is run, one attempt is made at saving the result in Sage's directory so
|
861
|
-
that all users can benefit from it. If the credentials are not
|
862
|
-
sufficient, the XML file are saved instead in the user's directory (in
|
863
|
-
the SAGE_DB folder).
|
857
|
+
zip file and parses its XML content. The XML file is saved in the directory
|
858
|
+
controlled by the :class:`DatabaseGraphs` class (usually, ``$HOME/.sage/db``).
|
864
859
|
|
865
860
|
EXAMPLES::
|
866
861
|
|
Binary file
|
Binary file
|
sage/graphs/matching.py
CHANGED
@@ -880,7 +880,7 @@ def is_matching_covered(G, matching=None, algorithm='Edmonds', coNP_certificate=
|
|
880
880
|
sage: H = graphs.PathGraph(20)
|
881
881
|
sage: M = H.matching()
|
882
882
|
sage: H.is_matching_covered(matching=M, coNP_certificate=True)
|
883
|
-
(False, (
|
883
|
+
(False, (2, 1, None))
|
884
884
|
|
885
885
|
TESTS:
|
886
886
|
|
@@ -1023,44 +1023,33 @@ def is_matching_covered(G, matching=None, algorithm='Edmonds', coNP_certificate=
|
|
1023
1023
|
if color[u]:
|
1024
1024
|
u, v = v, u
|
1025
1025
|
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
H.add_edge(v, u)
|
1026
|
+
H.add_edge((u, v))
|
1027
|
+
if next(M.neighbor_iterator(u)) == v:
|
1028
|
+
H.add_edge((v, u))
|
1030
1029
|
|
1031
1030
|
# Check if H is strongly connected using Kosaraju's algorithm
|
1032
|
-
def dfs(
|
1031
|
+
def dfs(v, visited, neighbor_iterator):
|
1033
1032
|
stack = [v] # a stack of vertices
|
1034
1033
|
|
1035
1034
|
while stack:
|
1036
1035
|
v = stack.pop()
|
1036
|
+
visited.add(v)
|
1037
1037
|
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
if orientation == 'in':
|
1042
|
-
for u in J.neighbors_out(v):
|
1043
|
-
if u not in visited:
|
1044
|
-
stack.append(u)
|
1045
|
-
|
1046
|
-
elif orientation == 'out':
|
1047
|
-
for u in J.neighbors_in(v):
|
1048
|
-
if u not in visited:
|
1049
|
-
stack.append(u)
|
1050
|
-
else:
|
1051
|
-
raise ValueError('Unknown orientation')
|
1038
|
+
for u in neighbor_iterator(v):
|
1039
|
+
if u not in visited:
|
1040
|
+
stack.append(u)
|
1052
1041
|
|
1053
1042
|
root = next(H.vertex_iterator())
|
1054
1043
|
|
1055
|
-
visited_in =
|
1056
|
-
dfs(
|
1044
|
+
visited_in = set()
|
1045
|
+
dfs(root, visited_in, H.neighbor_in_iterator)
|
1057
1046
|
|
1058
|
-
visited_out =
|
1059
|
-
dfs(
|
1047
|
+
visited_out = set()
|
1048
|
+
dfs(root, visited_out, H.neighbor_out_iterator)
|
1060
1049
|
|
1061
1050
|
for edge in H.edge_iterator():
|
1062
1051
|
u, v, _ = edge
|
1063
|
-
if (u not in
|
1052
|
+
if (u not in visited_out) or (v not in visited_in):
|
1064
1053
|
if not M.has_edge(edge):
|
1065
1054
|
return (False, edge) if coNP_certificate else False
|
1066
1055
|
|