@@ -21663,13 +21663,14 @@ def layout_tutte(self, external_face=None, external_face_pos=None, **options):
2166321663 OUTPUT: a dictionary mapping vertices to positions
2166421664
2166521665 EXAMPLES::
21666+
2166621667 sage: g = graphs.WheelGraph(n=7)
2166721668 sage: g.plot(layout='tutte', external_face=[0,1,2]) # needs sage.plot
2166821669 Graphics object consisting of 20 graphics primitives
2166921670 sage: g = graphs.CubeGraph(n=3, embedding=2)
2167021671 sage: g.plot(layout='tutte', external_face=['101','111','001',
2167121672 ....: '011'], external_face_pos={'101':(1,0), '111':(0,0),
21672- ....: '001':(2,1), '011':(-1,1)}) # needs sage.plot
21673+ ....: '001':(2,1), '011':(-1,1)}) # needs sage.plot
2167321674 Graphics object consisting of 21 graphics primitives
2167421675 sage: g = graphs.CompleteGraph(n=5)
2167521676 sage: g.plot(layout='tutte', external_face=[0,1,2])
@@ -21688,32 +21689,27 @@ def layout_tutte(self, external_face=None, external_face_pos=None, **options):
2168821689 if (external_face is not None) and (len(external_face) < 3):
2168921690 raise ValueError("external face must have at least 3 vertices")
2169021691
21691- if not self.is_planar():
21692+ if not self.is_planar(set_embedding=True ):
2169221693 raise ValueError("graph must be planar")
2169321694
2169421695 if not self.vertex_connectivity(k=3):
2169521696 raise ValueError("graph must be 3-connected")
2169621697
21698+ faces_edges = self.faces()
21699+ faces_vertices = [[edge[0] for edge in face] for face in faces_edges]
2169721700 if external_face is None:
21698- from sage.graphs.graph import Graph
21699- H = Graph(self) # take a (undirected) copy H of the graph
21700- u, v = next(H.edge_iterator(labels=False)) # take any edge (u, v) of H
21701- H.delete_edge(u, v) # remove edge (u, v) from H
21702- external_face = H.shortest_path(v, u)
21703- # Compute a shortest path from v to u in H minus (u, v)H = G.
21704- # Cycle existence is guaranteed since G is 3-connected.
21701+ external_face = faces_vertices[0]
2170521702 else:
21706- C = self.subgraph(vertices=external_face)
21707- if (not C.is_cycle(directed_cycle=False)):
21708- raise ValueError("external face must be a cycle")
21709- external_face = C.depth_first_search(start=external_face[0], ignore_direction=False)
21703+ # Check that external_face is a face and order it correctly
21704+ matching_face = next((f for f in faces_vertices if sorted(external_face) == sorted(f)), None)
21705+ if matching_face is None:
21706+ raise ValueError("external face must be a face of the graph")
21707+ external_face = matching_face
2171021708
21711- pos = dict()
2171221709 if external_face_pos is None:
2171321710 pos = self._circle_embedding(external_face, return_dict=True)
2171421711 else:
21715- for v, p in external_face_pos.items():
21716- pos[v] = p
21712+ pos = external_face_pos.copy()
2171721713
2171821714 n = self.order()
2171921715 M = zero_matrix(RR, n, n)
@@ -22123,7 +22119,7 @@ def plot(self, **options):
2212322119 appear on the bottom (resp., top) and the tree will grow upwards
2212422120 (resp. downwards). Ignored unless ``layout='tree'``.
2212522121
22126- - ``external_face`` -- list of vertices; the external face to be made a
22122+ - ``external_face`` -- list of vertices (default: ``None``) ; the external face to be made a
2212722123 in the Tutte layout. Ignored unless ``layout='tutte''``.
2212822124
2212922125 - ``external_face_pos`` -- dictionary (default: ``None``). If specified,
0 commit comments