def create_graph(N, E): G = nx.Graph() G.add_nodes_from(np.arange(N)) G_nodes = list(G.nodes()) mu, sigma = 40., 1.5 # mean and standard deviation link_lengths = np.random.lognormal(mu, sigma, E) for i in range(E): G.add_edge(random.choice(G_nodes), random.choice(G_nodes), len=link_lengths[i]) b = False while not b: G = modification(G, mu, delete=True) b, f = nx.check_planarity(G) G.remove_nodes_from(list(nx.isolates(G))) # Delete non-edges b = False for i in range(len(G.nodes)): G = modification(G, mu, delete=False) nx.draw(G, with_labels=True, font_weight='bold') print("Is planar - ", nx.check_planarity(G)) return G
def nodesToRemoveToPlanarizeGraph_greedy(G): nodesToRemove = set() H = G.copy() (isHPlanar, K) = nx.check_planarity(H, counterexample=True) while not isHPlanar: nodeToRemove = random.choice(list(K.nodes())) nodesToRemove.add(nodeToRemove) H.remove_node(nodeToRemove) (isHPlanar, K) = nx.check_planarity(H, counterexample=True) return nodesToRemove
def __init__(self, G: Graph, pos: POSITIONS = None): if nx.number_of_selfloops(G) != 0: raise OrthogonalException( 'There can be no self loops in the graph') if nx.is_connected(G) is False: raise OrthogonalException( 'The graph or parts of it are not connected.') self.logger: Logger = getLogger(__name__) if pos is None: is_planar, self.embedding = nx.check_planarity(G) assert is_planar pos = nx.combinatorial_embedding_to_pos(self.embedding) else: if self.numberOfCrossings(G, pos) != 0: raise OrthogonalException( 'The graph has edges that cross each other') self.embedding: nx.PlanarEmbedding = self.convert_pos_to_embedding( G, pos) self.G: Graph = G.copy() self.pos = pos # is only used to find the ext_face now. self.dcel: Dcel = Dcel(G, self.embedding) self.ext_face = self.get_external_face()
def actions_to_graph(initial_vertices: int, actions: List[Tuple[int, int]]): i = 0 is_planar = True embedding = None path_grouping = [] # Initialize graph graph = nx.MultiGraph() graph.add_nodes_from([i for i in range(0, initial_vertices)]) while i < len(actions) and is_planar: # Find points "clicked on" start = actions[i][0] end = actions[i][1] new_vertex_id = initial_vertices + i edge_0 = (start - 1, new_vertex_id) edge_1 = (new_vertex_id, end - 1) graph.add_edge(*edge_0) graph.add_edge(*edge_1) path_grouping.append((edge_0, edge_1, new_vertex_id)) i += 1 is_planar, embedding = nx.check_planarity(graph) if is_planar: return graph, embedding, path_grouping else: raise LoadException("Graph became non-planar at when adding edge (" + str(actions[i - 1][0]) + "," + str(actions[i - 1][1]) + ").")
def check_graph(G, is_planar=None): """Raises an exception if the lr_planarity check returns a wrong result Parameters ---------- G : NetworkX graph is_planar : bool The expected result of the planarity check. If set to None only counter example or embedding are verified. """ # obtain results of planarity check is_planar_lr, result = nx.check_planarity(G, True) is_planar_lr_rec, result_rec = check_planarity_recursive(G, True) if is_planar is not None: # set a message for the assert if is_planar: msg = "Wrong planarity check result. Should be planar." else: msg = "Wrong planarity check result. Should be non-planar." # check if the result is as expected assert_equals(is_planar, is_planar_lr, msg) assert_equals(is_planar, is_planar_lr_rec, msg) if is_planar_lr: # check embedding check_embedding(G, result) check_embedding(G, result_rec) else: # check counter example check_counterexample(G, result) check_counterexample(G, result_rec)
def obtainRandomValidInputForJS(numNodes, soddiLength, swapEdgeCreationChance=0.4, interactionEdgeCreationChance=0.1): G_swaps = None connected = False planar = False while not (connected and planar): G_swaps = nx.erdos_renyi_graph(numNodes, swapEdgeCreationChance, directed=False) connected = nx.is_connected(G_swaps) planar = nx.check_planarity(G_swaps) G_interactions = nx.DiGraph() gSwapsNodes = list(G_swaps.nodes) for e in itertools.permutations(gSwapsNodes, 2): if random.uniform(0, 1) < interactionEdgeCreationChance: G_interactions.add_edge(e[0], e[1]) soddi = [] while len(soddi) < soddiLength: firstNum = random.randint(0, len(G_swaps.nodes) - 1) secondNum = random.randint(0, len(G_swaps.nodes) - 1) if firstNum != secondNum: soddi.append((firstNum, secondNum)) return { "gSwaps": str(list(G_swaps.edges)), "gInteractions": str(list(G_interactions.edges)), "soddi": str(soddi) }
def sample_planar(n): while True: #m = random.randint(0, n * (n - 1) / 2) G = nx.gnp_random_graph(n, 0.6) is_planar, emb = nx.check_planarity(G) if is_planar and nx.is_connected(G): return G, emb
def pmfg(corr): """ Constructs a PMFG from the correlation matrix specified Parameters ----------- corr : array_like p x p matrix - correlation matrix Returns ------- networkx graph The Planar Maximally Filtered Graph """ vals = np.argsort(corr.flatten(), axis=None)[::-1] pmfg = nx.Graph() p = corr.shape[0] pmfg.add_nodes_from(range(p)) for v in vals: idx_i, idx_j = np.unravel_index(v, (p, p)) if idx_i == idx_j: continue pmfg.add_edge(idx_i, idx_j, weight=corr[idx_i, idx_j]) if not nx.check_planarity(pmfg)[0]: pmfg.remove_edge(idx_i, idx_j) if len(pmfg.edges()) == 3 * (p - 2): break return pmfg
def check_graph(G, is_planar=None): """Raises an exception if the lr_planarity check returns a wrong result Parameters ---------- G : NetworkX graph is_planar : bool The expected result of the planarity check. If set to None only counter example or embedding are verified. """ # obtain results of planarity check is_planar_lr, result = nx.check_planarity(G, True) is_planar_lr_rec, result_rec = check_planarity_recursive(G, True) if is_planar is not None: # set a message for the assert if is_planar: msg = "Wrong planarity check result. Should be planar." else: msg = "Wrong planarity check result. Should be non-planar." # check if the result is as expected assert is_planar == is_planar_lr, msg assert is_planar == is_planar_lr_rec, msg if is_planar_lr: # check embedding check_embedding(G, result) check_embedding(G, result_rec) else: # check counter example check_counterexample(G, result) check_counterexample(G, result_rec)
def construct_planar_er(self, n, m, max_number_of_iterations=1000): ''' Constructs random er-graphs until a planar graph is found. Note that for m < 3n, the probability that G is planar converges to 1 if n is large (citation needed) ''' #logging.info("=== construct_planar_er ===") if m > 3 * n - 6: # number of edges is too large: no planar graph possible raise TooManyEdgesException( "Number of edges too large. No planar graph with these parameters can exist." ) p = (2.0 * m) / (n * (n - 1)) planar_graph_constructed = False G = None iterations = 0 while iterations < max_number_of_iterations and not planar_graph_constructed: iterations += 1 G = nx.erdos_renyi_graph(n, p) try: is_planar = nx.check_planarity(G)[0] except AttributeError: raise WrongNetworkxVersion( "Old version of networkx does not support planarity check") if is_planar: planar_graph_constructed = True if not planar_graph_constructed: raise TooManyIterationsException( "Exceeded maximum number of iterations (" + str(max_number_of_iterations) + ").") return self.ensure_connectivity(G)
def main(): # Cycle graph _, embedding = nx.check_planarity(nx.cycle_graph(20)) embedding_fully, _ = nx.triangulate_embedding(embedding, True) diff_fully = nx.Graph(list(embedding_fully.edges - embedding.edges)) embedding_internal, _ = nx.triangulate_embedding(embedding, False) diff_internal = nx.Graph(list(embedding_internal.edges - embedding.edges)) pos = nx.combinatorial_embedding_to_pos(embedding_fully) nx.draw(diff_fully, pos, alpha=0.5, width=1, style="dotted", node_size=30) nx.draw(embedding, pos, width=2 , node_size=30) plt.savefig("drawing_cycle_fully_triangulated.png", format="PNG") plt.show() pos = nx.combinatorial_embedding_to_pos(embedding_internal) nx.draw(diff_internal, pos, alpha=0.5, width=1, style="dotted", node_size=30) nx.draw(embedding, pos, width=2, node_size=30) plt.savefig("drawing_cycle_internally_triangulated.png", format="PNG") plt.show() # Other graph G = nx.Graph([(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (1, 4), (4, 3)]) is_planar, embedding = nx.check_planarity(G) print(is_planar) embedding_fully, _ = nx.triangulate_embedding(embedding, True) diff_fully = nx.Graph(list(embedding_fully.edges - embedding.edges)) embedding_internal, _ = nx.triangulate_embedding(embedding, False) diff_internal = nx.Graph(list(embedding_internal.edges - embedding.edges)) pos = nx.combinatorial_embedding_to_pos(embedding_fully) nx.draw(diff_fully, pos, alpha=0.5, width=1, style="dotted", node_size=30) nx.draw(embedding, pos, width=2, node_size=30) plt.savefig("drawing_other_fully_triangulated.png", format="PNG") plt.show() pos = nx.combinatorial_embedding_to_pos(embedding_internal) nx.draw(diff_internal, pos, alpha=0.5, width=1, style="dotted", node_size=30) nx.draw(embedding, pos, width=2, node_size=30) plt.savefig("drawing_other_internally_triangulated.png", format="PNG") plt.show() embedding_data = {0: [36, 42], 1: [], 2: [23, 16], 3: [19], 4: [23, 17], 5: [45, 18], 6: [42, 29, 40], 7: [48, 26, 32], 8: [15, 44, 23], 9: [11, 27], 10: [39, 11, 32, 47, 26, 15], 11: [10, 9], 12: [41, 34, 35], 13: [48], 14: [28, 45], 15: [34, 8, 10], 16: [2, 39, 21], 17: [4], 18: [5], 19: [22, 3], 20: [], 21: [16, 49], 22: [26, 47, 19], 23: [8, 2, 4], 24: [46], 25: [], 26: [7, 34, 10, 22, 38], 27: [9, 48], 28: [36, 41, 14], 29: [6], 30: [48], 31: [], 32: [7, 10, 46], 33: [48], 34: [12, 15, 26], 35: [12, 41], 36: [0, 28, 43], 37: [47], 38: [26], 39: [16, 10], 40: [6], 41: [28, 12, 35], 42: [44, 0, 6], 43: [36], 44: [8, 42], 45: [14, 5], 46: [32, 24], 47: [22, 10, 37], 48: [27, 7, 13, 30, 33], 49: [21]} embedding = nx.PlanarEmbedding() embedding.set_data(embedding_data) pos = nx.combinatorial_embedding_to_pos(embedding, fully_triangulate=False) nx.draw(embedding, pos, node_size=30) plt.savefig("drawing_large_graph_internally_triangulated.png", format="PNG") plt.show()
def createLayout(G, layout=None): pos = nx.spring_layout(G, seed=36) if layout == 'Planar' and nx.check_planarity(G)[0]: print(nx.check_planarity(G)) pos = nx.planar_layout(G) elif layout == 'Circular': pos = nx.circular_layout(G) elif layout == 'Kamada-Kawai': pos = nx.kamada_kawai_layout(G) elif layout == 'Random': pos = nx.random_layout(G) elif layout == 'Spectral': pos = nx.spectral_layout(G) elif layout == 'Spiral': pos = nx.spiral_layout(G, resolution=1.0) return pos
def planar(input_struct): G = nx.Graph() G.add_nodes_from(input_struct.get("nodes")) G.add_weighted_edges_from(input_struct.get("edges")) G_first_set = nx.Graph() G.add_nodes_from(input_struct.get("first_set_nodes")) G.add_weighted_edges_from(input_struct.get("first_set_edges")) choice = input_struct.get("choice") # check if graph is planar is_planar, _ = nx.check_planarity(G) # user choice if choice: if is_planar == True: # if choice is true and graph was planar display(Markdown("Corretto !")) #print("Corretto il grafo è planare, fornire un planar embedding") else: # if choice is true and graph was not planar display(Markdown("Soluzione errata")) #print("Soluzione errata") else: if is_planar == False: # if choice is flase and graph was not planar if G_first_set.number_of_nodes() == 6: # check k_33 graph with bipartition bip_first_set = bipartite.is_bipartite(G_first_set) if bip_first_set: display(Markdown("Controesempio corretto")) #print("Controesempio corretto") else: display(Markdown("Non è un K 3 3")) #print("Non è un K 3 3") elif G_first_set.number_of_nodes() == 5: # check k 5 with clique clique = nx.find_cliques(G_first_set) sorted_list = sorted(clique, key=len) if len(sorted_list[len(sorted_list) - 1]) == 5: display(Markdown("Controesempio corretto")) #print("Controesempio corretto") else: display(Markdown("Non è un K 5")) #print("Non è un K 5") else: # wrong counterexample display(Markdown("Controesempio non valido")) #print("Controesempio non valido") else: # if choice is flase and graph was planar display(Markdown("Soluzione errata"))
def test_get_circuit_connectivity(): a, b, c, d = cirq.LineQubit.range(4) circuit = cirq.Circuit(cirq.CZ(a, b), cirq.CZ(b, c), cirq.CZ(c, d), cirq.CZ(d, a)) graph = ccr.get_circuit_connectivity(circuit) assert graph.number_of_nodes() == 4 assert graph.number_of_edges() == 4 is_planar, _ = nx.check_planarity(graph) assert is_planar
def random_planar_graph(n, m): while True: G = nx.gnm_random_graph(n, m) if nx.check_planarity(G)[0]: # if nx.is_connected(G): break return G
def isPlanar(graph): ''' description: - given a graph, return if it is planar params: - graph: networkx DiGraph object returns: - boolean True if graph is planar, False otherwise ''' return nx.check_planarity(graph)
def check_test_graph(given_graph): # Planarity Check if not nx.check_planarity(given_graph)[0]: return 0 # Subgraph is K4 if GraphMatcher(given_graph, nx.complete_graph(4)).subgraph_is_isomorphic(): return 0 # Some other random checks! return 1
def planar_layout(G, scale=1, center=None, dim=2): """Position nodes without edge intersections. Parameters ---------- G : NetworkX graph or list of nodes A position will be assigned to every node in G. If G is of type nx.PlanarEmbedding, the positions are selected accordingly. scale : number (default: 1) Scale factor for positions. center : array-like or None Coordinate pair around which to center the layout. dim : int Dimension of layout. Returns ------- pos : dict A dictionary of positions keyed by node Raises ------ NetworkXException If G is not planar Examples -------- >>> G = nx.path_graph(4) >>> pos = nx.planar_layout(G) """ import numpy as np if dim != 2: raise ValueError("can only handle 2 dimensions") G, center = _process_params(G, center, dim) if len(G) == 0: return {} if isinstance(G, nx.PlanarEmbedding): embedding = G else: is_planar, embedding = nx.check_planarity(G) if not is_planar: raise nx.NetworkXException("G is not planar.") pos = nx.combinatorial_embedding_to_pos(embedding) node_list = list(embedding) pos = np.row_stack([pos[x] for x in node_list]) pos = pos.astype(np.float64) pos = rescale_layout(pos, scale=scale) + center return dict(zip(node_list, pos))
def create_pmfg(self, input_matrix): """ Creates the PMFG matrix from the input matrix of all edges. :param input_matrix: (pd.Dataframe) Input matrix with all edges :return: (nx.Graph) Output PMFG matrix """ nodes = list(input_matrix.columns) # Heap to store ordered edges heap = [] cnt = count() # Generate pairwise combination between nodes pairwise_combinations = list( itertools.combinations(range(len(nodes)), 2)) # For cluster 1 and cluster 2 in the pairwise combination lists for i, j in pairwise_combinations: node_i = nodes[i] node_j = nodes[j] weight = input_matrix[node_i][node_j] # If the matrix type is correlation, order the edge list by largest to smallest if self.matrix_type == "correlation": heapq.heappush(heap, (weight * -1.0, next(cnt), { 'node_i': node_i, 'node_j': node_j })) else: heapq.heappush(heap, (weight, next(cnt), { 'node_i': node_i, 'node_j': node_j })) # Add the nodes with no edges to the PMFG graph pmfg_graph = nx.Graph() for node in nodes: pmfg_graph.add_node(node) # Starting with the smallest, keep adding edges while len(pmfg_graph.edges()) != 3 * (len(nodes) - 2): _, _, edge = heapq.heappop(heap) node_i = edge['node_i'] node_j = edge['node_j'] weight = input_matrix.at[node_i, node_j] pmfg_graph.add_weighted_edges_from([(node_i, node_j, weight)]) if not nx.check_planarity(pmfg_graph)[0]: pmfg_graph.remove_edge(node_i, node_j) # Store the MST edges as an attribute, so we can style those edges differently. self.mst_edges = nx.minimum_spanning_tree(pmfg_graph).edges() return pmfg_graph
def __init__(self, G, pos=None): if pos is None: is_planar, embedding = nx.check_planarity(G) pos = nx.combinatorial_embedding_to_pos(embedding) else: embedding = convert_pos_to_embedding(G, pos) self.G = G.copy() self.dcel = Dcel(G, embedding) self.dcel.ext_face = self.get_external_face(pos) self.dcel.ext_face.is_external = True
def drawGraph(diG): if nx.check_planarity(diG)[0]: pos = nx.planar_layout(diG) else: pos = nx.spring_layout(diG) nx.draw_networkx_nodes(diG, pos) nx.draw_networkx_labels(diG, pos) nx.draw_networkx_edges(diG, pos) lables = nx.get_edge_attributes(diG, 'current') nx.draw_networkx_edge_labels(diG, pos, edge_labels = lables) plt.show()
def is_planar(self) -> bool: """ Whether this qubit topology is a planar graph. """ try: # pylint: disable = import-outside-toplevel import networkx as nx # type: ignore except ModuleNotFoundError as e: # pylint: disable = unused-variable raise ModuleNotFoundError("You must install the 'networkx' library.") G = self.to_nx is_planar, _ = nx.check_planarity(G) return is_planar
def make_graph_visual(G, num_tasks): ''' Visualize graph G ''' if nx.check_planarity(G)[0]: pos = nx.planar_layout(G) else: pos = nx.shell_layout(G) nx.draw(G, pos, node_color='k', node_size=500) nx.draw_networkx_labels(G, pos, font_size=20, font_color='y') plt.axis('off') plt.show()
def compile(self): times = {"sa": 0, "opts": 0, "target": 0, "tc": 0} start = timer() ir = self.translate(self.config.input) times['sa'] = timer() - start start = timer() prog = self.optimizations(self.program) times['opts'] = timer() - start start = timer() target = self.target(prog) times['target'] = timer() - start if self.config.target == TargetSelector.INKWELL and self.config.validate_schema: for root in self.program.functions: planar = nx.check_planarity( self.program.functions[root]['graph'], True) if planar[0]: self.log.debug( f"{self.config.input}'s {root} function is planar.") else: self.log.warning( f"{self.config.input}'s {root} is not planar.") times['write'] = 0 if self.config.write_out: start = timer() for key, writable in self.program.write.items(): writable.write() times['write'] = timer() - start else: self.log.warning("Not writing any output to disk.") if self.log.debug: for key, writable in self.program.write.items(): # self.log.info('{}: \n{}'.format(key, writable.content)) pass if self.config.print_stats: stats = "\n" stats += "Semantic Analysis:\t{}\n".format(round(times['sa'], 4)) stats += "Optimizations:\t\t{}\n".format(round(times['opts']), 4) stats += "Target Gen:\t\t\t{}\n".format(round(times['target'], 4)) stats += "Writing to disk:\t{}\n".format(round(times['write'], 4)) stats += "Total:\t\t\t\t{}".format(round(sum(times.values()), 4)) self.log.debug(stats) if not target: self.log.critical( "You aren't doing anything with the results of the compile function." )
def embed_graph_lst(graph_list: List[nx.Graph]) -> List[nx.PlanarEmbedding]: """Return a list of the planar embeddings of the graphs of the given list. Non-planar graphs and graphs whose size is smaller than 3 are ignored. :param graph_list: A list of graphs. :return: The list of the planar embeddings. """ lst = [] for graph in graph_list: planar, embedding = nx.check_planarity(graph) if len(graph) > 2 and planar: lst.append(embedding) return lst
def reinsert(sub, edgelist): print("reinserting...") for i in range(0, edgelist.__len__()): e = edgelist[i] next = edgelist[i+1] if e not in sub.edges(): sub.add_edge(e[0], e[1]) # if sub.number_of_edges() > 500: # return sub sub.add_edge(next[0], next[1]) p, _ = nx.check_planarity(sub) sub.remove_edge(next[0], next[1]) if not p: return sub return sub
def __init__(self, G, pos=None): assert nx.number_of_selfloops(G) == 0 assert nx.is_connected(G) if pos is None: is_planar, self.embedding = nx.check_planarity(G) assert is_planar pos = nx.combinatorial_embedding_to_pos(self.embedding) else: assert number_of_cross(G, pos) == 0 self.embedding = convert_pos_to_embdeding(G, pos) self.G = G.copy() self.pos = pos # is only used to find the ext_face now. self.dcel = DCEL.Dcel(G, self.embedding) self.ext_face = self.get_external_face()
def modification(graph, leng, delete=True): if delete: edges = list(graph.edges) chosen_edge = random.choice(edges) graph.remove_edge(chosen_edge[0], chosen_edge[1]) else: nonedges = list(nx.non_edges(graph)) chosen_nonedge = random.choice(nonedges) graph.add_edge(chosen_nonedge[0], chosen_nonedge[1], len=leng) b, f = nx.check_planarity(graph) if not b: graph.remove_edge(chosen_nonedge[0], chosen_nonedge[1]) return graph
def test_random(): while True: n = 50 p = 1.0 is_planar = False while not is_planar: G = nx.fast_gnp_random_graph(n, p) is_planar, embedding = nx.check_planarity(G) p *= 0.9 pos = nx.combinatorial_embedding_to_pos(embedding, fully_triangulate=False) assert_true(planar_drawing_conforms_to_embedding(embedding, pos), "Planar drawing does not conform to the embedding") assert_true(is_planar_drawing_correct(G, pos), "Planar drawing is not correct") print("Graph correct")
def get_planarity(self, start, end, file_name, remove_planar_nodes=10): """ This function returns if the network is planar or not, from the start till the end index. It prints out the time instant, meshedness and the number of edges of all the graphs which are planar :param remove_planar_nodes: If the analysis is to be done by removing all the upper floor nodes then pass value 1. If the analysis is to be done by removing all the lower floor nodes then pass value 0. If the analysis is to be done by NOT removing any nodes then pass any value greater than 1. :param start: start index of the analysis :param end: end index of the analysis :param file_name: The list of filename :return: It returns a dictionary whose keys are the file names and the value is if the graph is planar or not. """ i = start planarity = dict() vertices = len(list(self.node_loc.keys())) graph_copy = self.topology_graphs.copy() upper_nodes = ['30', '31', '32', '60', '61', '62', '63', '90', '91', '92'] lower_nodes = ['10', '11', '12', '20', '21', '22', '40', '41', '42', '50', '51', '52', '54', '70', '71', '72', '80', '81', '82', '100', '101', '102', '5', '110'] if remove_planar_nodes is 1: remove_nodes = upper_nodes vertices = vertices - len(upper_nodes) print("Removing upper nodes") elif remove_planar_nodes is 0: remove_nodes = lower_nodes vertices = vertices - len(lower_nodes) print("Removing lower nodes") else: remove_nodes = [] print("Not removing any nodes") while i < end + 1: fn = file_name[i] for up in remove_nodes: graph_copy[i].remove_node(up) planarity[fn] = dict() planarity[fn]['planarity'] = int(nx.check_planarity(graph_copy[i])[0]) if planarity[fn]['planarity']: edges = self.topology_graphs[i].number_of_edges() meshedness = (edges - vertices + 1)/(2*vertices - 5) planarity[fn]['meshedness'] = meshedness else: planarity[fn]['meshedness'] = -1 i += 1 return planarity
def autogenerate_coordinates(n, assign=False, layouter=None): """ Automatically generate bus coordinates for the network graph according to a layouting function from `networkx <https://networkx.github.io/>`_. Parameters ---------- n : pypsa.Network assign : bool, default False Assign generated coordinates to the network bus coordinates at ``n.buses[['x','y']]``. layouter : networkx.drawing.layout function, default None Layouting function from `networkx <https://networkx.github.io/>`_. See `list <https://networkx.github.io/documentation/stable/reference/drawing.html#module-networkx.drawing.layout>`_ of available options. By default coordinates are determined for a `planar layout <https://networkx.github.io/documentation/stable/reference/generated/networkx.drawing.layout.planar_layout.html#networkx.drawing.layout.planar_layout>`_ if the network graph is planar, otherwise for a `Kamada-Kawai layout <https://networkx.github.io/documentation/stable/reference/generated/networkx.drawing.layout.kamada_kawai_layout.html#networkx.drawing.layout.kamada_kawai_layout>`_. Returns ------- coordinates : pd.DataFrame DataFrame containing the generated coordinates with buses as index and ['x', 'y'] as columns. Examples -------- >>> autogenerate_coordinates(network) >>> autogenerate_coordinates(network, assign=True, layouter=nx.circle_layout) """ G = n.graph() if layouter is None: is_planar = nx.check_planarity(G)[0] if is_planar: layouter = nx.planar_layout else: layouter = nx.kamada_kawai_layout coordinates = pd.DataFrame(layouter(G)).T.rename({0: 'x', 1: 'y'}, axis=1) if assign: n.buses[['x', 'y']] = coordinates return coordinates