def make_planar(G): if planarity.is_planar(G.edges()): return G all_kuratowski_edges = [] next_G = G.copy() while planarity.is_planar(G.edges()) == False: edge_list = planarity.kuratowski_edges(G) print(len(edge_list)) G.remove_edges_from(edge_list) for edge in edge_list: all_kuratowski_edges.append(edge) itr = 0 replaced = [] for edge in all_kuratowski_edges: neighbors = nx.neighbors(G, edge[1]) if itr < len(neighbors) and edge not in replaced: G.add_edge(edge[0], neighbors[itr]) elif itr >= len(neighbors) and edge not in replaced: global neighbors neighbors = nx.neighbors(G, edge[0]) itr = 0 itr = itr + 1 print(planarity.is_planar(G), nx.number_of_edges(G)) print(planarity.is_planar(next_G), nx.number_of_edges(next_G))
def round_robin_thickness_graphs(g): """ Generate round robin thickness graphs Take best known solution (naive) Allocate n-1 graphs (if > 1 in naive solution) Sort Edges Round robin edge assignment (i.e. try to spread out the edges for each node across the graphs) :param g: :return: """ naive_best = naive_thickness_graphs(g) if len(naive_best) == 1: return naive_best gs = [nx.Graph() for _ in range(len(naive_best) - 1)] gedges = [e for e in g.edges()] gedges.sort() vs = set() for e in g.edges(): vs.add(e[0]) vs.add(e[1]) for v in vs: for cur in gs: cur.add_node(v) not_added = [] for i, edge in enumerate(gedges): gi = i % len(gs) gs[gi].add_edge(edge[0], edge[1]) if not is_planar(gs[gi]): not_added.append(edge) gs[gi].remove_edge(edge[0], edge[1]) not_added_again = [] for e in not_added: added = False for gcur in gs: gcur.add_edge(e[0], e[1]) if is_planar(gcur): added = True break else: gcur.remove_edge(e[0], e[1]) if not added: not_added_again.append(e) if len(not_added_again) > 0: return naive_best return gs
def thickness(G): # Complete Graphs # # The thickness of an arbitrary complete graph is given by # floor((n+7)/6) (except for where n=9,10 where thickness is 3) # # Alekseev, V. B.; Goncakov, V. S. # https://mathscinet.ams.org/mathscinet-getitem?mr=0460162 if G.number_of_edges() == edge_count_of_complete_graph( G.number_of_nodes()): if G.number_of_nodes() == 9 or G.number_of_nodes() == 10: return 3 else: return int(floor((G.number_of_nodes() + 7) / 6)) # Planar Graphs # # The thickness of any planar graph is 1 if is_planar(G): return 1 # Small Graphs # # If a graph is pretty small, we can run a brute-force-search if G.number_of_edges() < 8: return brute_force_thickness(G) # All other graphs # # since we couldn't find a characterization that helps with this graph, we check using # Alex's brute-force-like search algorithm # # note: this is not guaranteed to yield the actual thickness; only a number greater than or equal to it return round_robin_thickness(G)
def naive_thickness_graphs(g): """ Generate the thickness graphs themselves :param g: :return: """ vs = set() gs = [nx.Graph()] for e in g.edges(): vs.add(e[0]) vs.add(e[1]) added = False for current in gs: current.add_edge(e[0], e[1]) if is_planar(current): added = True break else: current.remove_edge(e[0], e[1]) if not added: ng = nx.Graph() ng.add_edge(e[0], e[1]) gs.append(ng) for g in gs: for v in vs: g.add_node(v) return gs
def pmfg(df): n = len(df) A = np.zeros([n,n]) rho = df.as_matrix() rholist = [] for i in range(0, n): for j in range(i+1, n): rholist.append([rho[i][j], i, j]) rholist = np.array(rholist) rholist = rholist[rholist[:,0].argsort()].tolist() rholist = [rholist[len(rholist)-i-1] for i in range(len(rholist))] control = 0 edgelist = [] for t in range(0, len(rholist)): if control <= 3*(n-2)-1: i, j = rholist[t][1], rholist[t][2] A[i][j], A[j][i] = 1, 1 edgelist.append((str(i),str(j))) if is_planar(edgelist) == False: A[i][j], A[j][i] = 0, 0 edgelist = edgelist[:-1] else: control += 1 return pd.DataFrame(data=A, columns=df.columns, index=df.index)
def construct_pmfg(self, df_distance, matrix_panel, inv=False, threshold=0.0): """Trim the provided adjacency matrix to create a Planary Maximum Filtered Graph matrix inserting all the node and edge metrics into the graph """ if inv: dist_matrix = 1.0 / df_distance.values else: dist_matrix = df_distance.values index_upper_triangular = np.triu_indices(dist_matrix.shape[0], 1) isort = np.argsort(dist_matrix[index_upper_triangular]) G = nx.Graph() names = df_distance.columns.unique() for k in np.arange(0, len(isort)): u = index_upper_triangular[0][isort[k]] v = index_upper_triangular[1][isort[k]] if np.abs( dist_matrix[u, v] ) > threshold / len(names): # optional bonferroni correction edgedict = {'weight': float(dist_matrix[u, v])} for item in matrix_panel.items: edgedict[item] = float(matrix_panel.ix[item, u, v]) G.add_edge(u, v, edgedict) if not planarity.is_planar(G): G.remove_edge(u, v) labels = {} for i, n in enumerate(names): name = names[i] labels[i] = name G = nx.relabel_nodes(G, labels) return G
def construct_pmfg(self, df_distance, matrix_panel, inv=False, threshold=0.0): """Trim the provided adjacency matrix to create a Planary Maximum Filtered Graph matrix inserting all the node and edge metrics into the graph """ if inv: dist_matrix = 1.0/df_distance.values else: dist_matrix = df_distance.values index_upper_triangular = np.triu_indices(dist_matrix.shape[0], 1) isort = np.argsort(dist_matrix[index_upper_triangular]) G = nx.Graph() names = df_distance.columns.unique() for k in np.arange(0, len(isort)): u = index_upper_triangular[0][isort[k]] v = index_upper_triangular[1][isort[k]] if np.abs(dist_matrix[u, v]) > threshold / len(names): # optional bonferroni correction edgedict = {'weight': float(dist_matrix[u, v])} for item in matrix_panel.items: edgedict[item] = float(matrix_panel.ix[item, u, v]) G.add_edge(u, v, edgedict) if not planarity.is_planar(G): G.remove_edge(u, v) labels = {} for i, n in enumerate(names): name = names[i] labels[i] = name G = nx.relabel_nodes(G, labels) return G
def network_is_planar(network): """Check if the network is planar. A network is planar if it can be drawn in the plane without crossing edges. If a network is planar, it can be shown that an embedding of the network in the plane exists, and, furthermore, that straight-line embedding in the plane exists. Warning: This function uses the python binding of the *edge addition planarity suite* in the background. The package is available on GitHub: https://github.com/hagberg/planarity. Parameters: network (compas.datastructures.network.Network): The network object. Returns: bool: ``True`` if the network is planar. ``False`` otherwise. Raises: ImportError: If the planarity package is not installed. Example: .. plot:: :include-source: import compas from compas.datastructures.network import Network from compas.visualization.plotters import NetworkPlotter from compas.datastructures.network.algorithms import network_is_planar from compas.datastructures.network.algorithms import network_find_crossings network = Network.from_obj(compas.get_data('lines.obj')) network.add_edge(21, 29) network.add_edge(17, 28) if not network_is_planar(network): crossings = network_find_crossings(network) else: crossings = [] plotter = NetworkPlotter(network) plotter.draw_vertices(radius=0.15, text={key: key for key in network.vertices()}) plotter.draw_edges(color={edge: '#ff0000' for edges in crossings for edge in edges}) plotter.show() """ try: import planarity except ImportError: print( "Planarity is not installed. Get Planarity at https://github.com/hagberg/planarity." ) raise return planarity.is_planar(network.edges())
def graphFactoryPlanarErdosRenyiGenration(nb_graph,size_graph,graphtype,edgeProba,section='all'): cpt=0 while cpt <= nb_graph: G = nx.gnp_random_graph(size_graph,edgeProba) if graphToCSV(G,graphtype,section,pl.is_planar(G)): cpt+=1 if cpt%10 == 0: print(str(cpt)+'/'+str(nb_graph)+' '+str(100*cpt/nb_graph)+'%')
def test_is_planar_unions(self): try: from itertools import combinations,product except ImportError: raise SkipTest('itertools.combinations not found') for (G1,G2) in combinations(self.planar,2): G=nx.disjoint_union(G1,G2) assert_true(planarity.is_planar(G)) for (G1,G2) in combinations(self.non_planar,2): G=nx.disjoint_union(G1,G2) assert_false(planarity.is_planar(G)) for (G1,G2) in product(self.planar,self.non_planar): G=nx.disjoint_union(G1,G2) assert_false(planarity.is_planar(G))
def test_is_planar_unions(self): try: from itertools import combinations, product except ImportError: raise SkipTest('itertools.combinations not found') for (G1, G2) in combinations(self.planar, 2): G = nx.disjoint_union(G1, G2) assert_true(planarity.is_planar(G)) for (G1, G2) in combinations(self.non_planar, 2): G = nx.disjoint_union(G1, G2) assert_false(planarity.is_planar(G)) for (G1, G2) in product(self.planar, self.non_planar): G = nx.disjoint_union(G1, G2) assert_false(planarity.is_planar(G))
def graphFactoryPlanar(nb_graph, size_graph, graphtype, section='all'): cpt = 0 while cpt <= nb_graph: m = np.random.random_sample(1) G = nx.gnm_random_graph(size_graph,edgeForDensity(size_graph,m)) if graphToCSV(G,graphtype,section,pl.is_planar(G)): cpt+=1 if cpt%10 == 0: print(str(cpt)+'/'+str(nb_graph)+' '+str(100*cpt/nb_graph)+'%')
def graphFactoryPlanarNormalDistribution(nb_graph,size_graph,graphtype,location,spread,section='all'): cpt=0 while cpt <= nb_graph: rdm_density = np.random.normal(location,spread) G = nx.gnm_random_graph(size_graph,edgeForDensity(size_graph,rdm_density)) if graphToCSV(G,graphtype,section,pl.is_planar(G)): cpt+=1 if cpt%10 == 0: print(str(cpt)+'/'+str(nb_graph)+' '+str(100*cpt/nb_graph)+'%')
def get_network_PMFG(corr_matrix): """ This function creates a filtered network starting from a correlation matrix using PMFG algorithm :param corr_matrix (numpy 2D-array) :return: returns filtered network (networkx Graph) """ # get the list of links in decreasing order of weight rholist = [] n = len(corr_matrix) for i in range(n): for j in range(n): if i > j: # matrix is symmetric if corr_matrix[i][j] != 0: rholist.append([abs(float(corr_matrix[i, j])), i, j]) # weight, node1, node2 # sort the list in decreasing order rholist.sort(key=lambda x: x[0]) rholist.reverse() # initialize filtered matrix m = len(rholist) filtered_matrix = np.zeros((n, n)) control = 0 # filtered graph G = nx.Graph() # get the filtered adjacency matrix using the PMFG algorithm # iterate over ordered edges for t in range(m): # stopping condition if control <= 3 * (n - 2) - 1: # get the current edge i = rholist[t][1] j = rholist[t][2] filtered_matrix[i, j] = rholist[t][0] # add the edge to the Graph G.add_edge(int(i), int(j), weight=filtered_matrix[i, j]) # if the obtained G is not planarity we remove the edge if planarity.is_planar(G) == False: # remove edge filtered_matrix[i, j] = 0 control = control + 1 G.remove_edge(int(i), int(j)) else: break return filtered_matrix, G
def test_goldner_harary(self): # goldner-harary graph # http://en.wikipedia.org/wiki/Goldner%E2%80%93Harary_graph # a maximal planar graph e= [(1,2 ),( 1,3 ),( 1,4 ),( 1,5 ),( 1,7 ),( 1,8 ),( 1,10 ), ( 1,11 ),( 2,3 ),( 2,4 ),( 2,6 ),( 2,7 ),( 2,9 ),( 2,10 ), ( 2,11 ),( 3,4 ),( 4,5 ),( 4,6 ),( 4,7 ),( 5,7 ),( 6,7 ), ( 7,8 ),( 7,9 ),( 7,10 ),( 8,10 ),( 9,10 ),( 10,11)] G=nx.Graph(e) assert_true(planarity.is_planar(G))
def test_goldner_harary(self): # goldner-harary graph # http://en.wikipedia.org/wiki/Goldner%E2%80%93Harary_graph # a maximal planar graph e = [(1, 2), (1, 3), (1, 4), (1, 5), (1, 7), (1, 8), (1, 10), (1, 11), (2, 3), (2, 4), (2, 6), (2, 7), (2, 9), (2, 10), (2, 11), (3, 4), (4, 5), (4, 6), (4, 7), (5, 7), (6, 7), (7, 8), (7, 9), (7, 10), (8, 10), (9, 10), (10, 11)] G = nx.Graph(e) assert_true(planarity.is_planar(G))
def compute_PMFG(sorted_edges, nb_nodes): PMFG = nx.Graph() for edge in sorted_edges: PMFG.add_edge(edge[0], edge[1], metric=edge[2]) if not planarity.is_planar(PMFG): PMFG.remove_edge(edge[0], edge[1]) if len(PMFG.edges()) == 3 * (nb_nodes - 2): break return PMFG
def compute_PMFG(sorted_edges, nb_nodes): PMFG = nx.Graph() for edge in sorted_edges: PMFG.add_edge(edge['source'], edge['dest']) if not planarity.is_planar(PMFG): PMFG.remove_edge(edge['source'], edge['dest']) if len(PMFG.edges()) == 3 * (nb_nodes - 2): break return PMFG
def is_planar(self): """Verify that the graph has a planar embedding. Returns ------- bool """ if compas.IPY: from compas.rpc import Proxy planarity = Proxy('planarity') else: import planarity return planarity.is_planar(list(self.edges()))
def construct_pmfg(df_corr_matrix): df_distance = compute_distance(df_corr_matrix) dist_matrix = df_distance.values index_upper_triangular = np.triu_indices(dist_matrix.shape[0], 1) isort = np.argsort(dist_matrix[index_upper_triangular]) G = nx.Graph() for k in range(len(isort)): u = index_upper_triangular[0][isort[k]] v = index_upper_triangular[1][isort[k]] if dist_matrix[u, v] > .0: # remove perfect correlation because of diagonal FIXME G.add_edge(u, v, {'weight': float(dist_matrix[u, v])}) if not planarity.is_planar(G): G.remove_edge(u, v) return G
def construct_pmfg(df_corr_matrix): # TW: Is this required? What's the difference to graph.algos.construct_pmfg? df_distance = np.sqrt( 2 * np.clip( 1. - df_corr_matrix, 0., 2.) ) dist_matrix = df_distance.values index_upper_triangular = np.triu_indices(dist_matrix.shape[0],1) isort = np.argsort( dist_matrix[index_upper_triangular] ) G = nx.Graph() for k in xrange(0,len(isort)): u = index_upper_triangular[0][isort[k]] v = index_upper_triangular[1][isort[k]] if dist_matrix[u,v] > 0: # remove perfect correlation because of diagonal FIXME G.add_edge(u, v, {'weight': float(dist_matrix[u,v])}) if not planarity.is_planar(G): G.remove_edge(u,v) return G
def brute_force_thickness(g): smallest_thickness = 500 for thickness_guess in range(2, 4): for edge_arrangement in algorithm_u(g.edges(), thickness_guess): all_planar = True for layer in edge_arrangement: if not is_planar(_from_edge_list(layer)): all_planar = False break if all_planar and len(edge_arrangement) < smallest_thickness: smallest_thickness = len(edge_arrangement) break if smallest_thickness <= thickness_guess: break return smallest_thickness
def check_planar(dataset): with open("generated_smiles_%s" % dataset, 'rb') as f: all_smiles = set(pickle.load(f)) total_non_planar = 0 for smiles in all_smiles: try: nodes, edges = to_graph(smiles, dataset) except: continue edges = [(src, dst) for src, e, dst in edges] if edges == []: continue if not planarity.is_planar(edges): total_non_planar += 1 return len(all_smiles), total_non_planar
def simplify_using_PMFG(corr_matrix): #get the list of decreasing weighted links rholist = [] n = len(corr_matrix) for i in range(n): for j in range(n): if i < j: if corr_matrix[i][j] != 0: rholist.append([abs(float(corr_matrix[i][j])), i, j]) rholist.sort(key=lambda x: x[0]) rholist.reverse() m = len(rholist) filtered_matr = np.zeros((n, n)) control = 0 with progressbar.ProgressBar(max_value=m) as bar: #get the filtered adjacency matrix using PMFG algorithm for t in range(m): if control <= 3 * (n - 2) - 1: i = rholist[t][1] j = rholist[t][2] filtered_matr[i][j] = rholist[t][0] #check planarity here G = nx.Graph() for i in range(0, n): for j in range(0, n): if filtered_matr[i][j] != 0: G.add_edge(int(i), int(j), weight=filtered_matr[i][j]) if planarity.is_planar(G) == False: filtered_matr[i][j] = 0 control = control + 1 bar.update(t) #build the network PMFG = nx.Graph() for i in range(0, n): for j in range(0, n): if filtered_matr[i][j] != 0: PMFG.add_edge(int(i), int(j), weight=filtered_matr[i][j]) return PMFG
def construct_pmfg(df_corr_matrix): # TW: Is this required? What's the difference to graph.algos.construct_pmfg? df_distance = np.sqrt(2 * np.clip(1. - df_corr_matrix, 0., 2.)) dist_matrix = df_distance.values index_upper_triangular = np.triu_indices(dist_matrix.shape[0], 1) isort = np.argsort(dist_matrix[index_upper_triangular]) G = nx.Graph() for k in xrange(0, len(isort)): u = index_upper_triangular[0][isort[k]] v = index_upper_triangular[1][isort[k]] if dist_matrix[ u, v] > 0: # remove perfect correlation because of diagonal FIXME G.add_edge(u, v, {'weight': float(dist_matrix[u, v])}) if not planarity.is_planar(G): G.remove_edge(u, v) return G
def is_planar(location, adj_list, is_dense=False): if is_dense: new_adj_list = defaultdict(list) for x in range(len(adj_list)): for y in range(len(adj_list)): if adj_list[x][y] == 1: new_adj_list[x].append((y, 1)) adj_list = new_adj_list edges = [] seen = set() for src, l in adj_list.items(): for dst, e in l: if (dst, src) not in seen: edges.append((src, dst)) seen.add((src, dst)) edges += [location, (location[1], location[0])] return planarity.is_planar(edges)
def network_is_planar(network): """Check if the network is planar. Parameters ---------- network : Network A network object. Returns ------- bool True if the network is planar. False otherwise. Raises ------ ImportError If the planarity package is not installed. Notes ----- A network is planar if it can be drawn in the plane without crossing edges. If a network is planar, it can be shown that an embedding of the network in the plane exists, and, furthermore, that straight-line embedding in the plane exists. Warnings -------- This function uses the python binding of the *edge addition planarity suite*. It is available on Anaconda: https://anaconda.org/conda-forge/python-planarity. Examples -------- >>> """ try: import planarity except ImportError: print("Planarity is not installed.") raise return planarity.is_planar(list(network.edges()))
def compute_PMFG(sorted_edges, nb_nodes): # remove weakest links ''' References Tumminello, M., Aste, T., Di Matteo, T., & Mantegna, R. N. (2005). A tool for filtering information in complex systems. Proceedings of the National Academy of Sciences of the United States of America, 102(30), 10421-10426. https://gmarti.gitlab.io/networks/2018/06/03/pmfg-algorithm.html https://github.com/hagberg/planarity http://jgaa.info/accepted/2004/BoyerMyrvold2004.8.3.pdf https://networkx.github.io/documentation/stable/index.html ''' PMFG = nx.Graph() for edge in sorted_edges: PMFG.add_edge(edge['source'], edge['dest'], weight=edge['weight']) if not planarity.is_planar(PMFG): PMFG.remove_edge(edge['source'], edge['dest']) if len(PMFG.edges()) == 3 * (nb_nodes - 2): break return PMFG
def compute_PMFG(G): PMFG = nx.Graph() # initialize ne_total = G.number_of_edges() nb_nodes = len(G.nodes) ne_pmfg = 3 * (nb_nodes - 2) sorted_edges = sort_graph_edges_corr(G) t0 = time.time() for i, edge in enumerate(sorted_edges): PMFG.add_edge(edge['source'], edge['dest'], weight=edge['weight']) if not planarity.is_planar(PMFG): PMFG.remove_edge(edge['source'], edge['dest']) ne = PMFG.number_of_edges() print( "Generating PMFG... added edges in PMFG %d/%d (%.2f%%) lookup edges in G %d/%d (%.2f%%) Elapsed TIme %.2f [sec]" % (ne, ne_pmfg, (ne / ne_pmfg) * 100, i, ne_total, (i + 1 / ne_total) * 100, time.time() - t0), end="\r") if ne == ne_pmfg: break return PMFG
def exportRandomGraph(name, path=''): G = nx.newman_watts_strogatz_graph(6,2,0.5) nx.draw(G) plt.savefig('img_rdm_generate_graph_'+name+'.png') plt.clf() print(pl.is_planar(G))
def test_is_planar(self): for G in self.planar: assert_true(planarity.is_planar(G)) for G in self.non_planar: assert_false(planarity.is_planar(G))
import planarity import networkx as nx # Example of the complete graph of 5 nodes, K5 G=nx.complete_graph(5) # K5 is not planar print(planarity.is_planar(G)) # False # find forbidden Kuratowski subgraph K=planarity.kuratowski_subgraph(G) print(K.edges()) # K5 edges
def is_planar(edge_list): return planarity.is_planar(edge_list)
import planarity n = 6 m = n * (n - 1) / 2 out = "1" for x in xrange(1, pow(2, m)): edgelist = [] u, v = 1, 1 for y in xrange(m): u += 1 if u >= v: v += 1 u = 1 if x & (1<<(m-y-1)): edgelist.append((u, v)) out += "1" if planarity.is_planar(edgelist) else "0" print(out)
import planarity # Example of the complete graph of 5 nodes, K5 # K5 is not planar # use text strings as labels edgelist = [('a', 'b'), ('a', 'c'), ('a', 'd'), ('a', 'e'), ('b', 'c'),('b', 'd'),('b', 'e'), ('c', 'd'), ('c', 'e'), ('d', 'e')] print planarity.is_planar(edgelist) # False # print forbidden Kuratowski subgraph (K5) print planarity.kuratowski_edges(edgelist) # remove an edge edgelist.remove(('a','b')) # graph is now planar print planarity.is_planar(edgelist) # True # no forbidden subgraph, empty list returned print planarity.kuratowski_edges(edgelist)
import planarity edgelist = [ ('a', 'b'), ('a', 'c'), ('a', 'd'), ('a', 'e'), ('b', 'c'),('b', 'd'),('b', 'e'), ('c', 'd'), ('c', 'e'), ('d', 'e') ] print(planarity.is_planar(edgelist))
nx.write_adjlist(new_G, output_path_adj) if write_graph: if verbose: print('Saving graph: %s' % output_path) sys.stdout.flush() graphutils.write_graph(new_G, output_path) image_path = output_path + '.pdf' stderr_path = output_path + '.err.txt' if init_options['compare_replica']: if verbose: print('Generator Report') print('Comparing replica') sys.stdout.flush() graphutils.compare_nets(G, new_G, params=params) print(planarity.is_planar(new_G.edges())) pos = nx.graphviz_layout(new_G) nx.draw(new_G, pos, with_labels=False, node_size=1) plt.show() benchmarks.find_differences(G, new_G) #0.03 is too small for Linux #sfdp_default_cmd = 'sfdp -Goverlap="prism100" -Goverlap_scaling=-100 -Nlabel="" -Nwidth=0.01 -Nfixedsize=true -Nheight=0.01' sfdp_default_cmd = 'sfdp -Nlabel="" -Nwidth=0.06 -Nfixedsize=true -Nheight=0.06 -Nstyle=filled' if write_graph and visualizer == 'sfdp' and output_path[-3:] == 'dot': visualizer_cmdl = sfdp_default_cmd + ' -Tpdf %s > %s 2> %s ' % ( output_path, image_path, stderr_path) if verbose: print('Writing graph image: %s ..' % image_path) sys.stdout.flush() retCode = os.system(visualizer_cmdl)
if __name__ == '__main__': arguments = docopt(__doc__) M = int(arguments['M']) N = int(arguments['N']) output = arguments['OUTPUT'] # G = nx.complete_multipartite_graph(M, N) # G = nx.complete_graph(M) G = nx.gnm_random_graph(M, N) if planarity_test.is_planar(G): print("Graph is planar") try: draw(G, output) print("Planar graph drawn!") except: print("Could not draw a planar graph...") nx.draw_random(G) plt.axis('off') plt.savefig(output) else: if planarity.is_planar(G): draw(G, output) print("Graph is unexpectedly planar...") else: nx.draw_random(G) plt.axis('off') plt.savefig(output) print("Graph is not planar!")
def exportGraph(G, name, path=''): nx.draw(G) plt.savefig('img_'+name+'.png') plt.clf() print(pl.is_planar(G))
def network_is_planar(network): """Check if the network is planar. Parameters ---------- network : Network A network object. Returns ------- bool True if the network is planar. False otherwise. Raises ------ ImportError If the planarity package is not installed. Notes ----- A network is planar if it can be drawn in the plane without crossing edges. If a network is planar, it can be shown that an embedding of the network in the plane exists, and, furthermore, that straight-line embedding in the plane exists. Warning ------- This function uses the python binding of the *edge addition planarity suite*. It is available on GitHub: https://github.com/hagberg/planarity. Examples -------- .. plot:: :include-source: import compas from compas.datastructures import Network from compas.topology import network_is_planar from compas.topology import network_find_crossings from compas.plotters import NetworkPlotter network = Network.from_obj(compas.get('lines.obj')) network.add_edge(21, 29) network.add_edge(17, 28) if not network_is_planar(network): crossings = network_find_crossings(network) else: crossings = [] plotter = NetworkPlotter(network) plotter.draw_vertices(radius=0.15, text={key: key for key in network.vertices()}) plotter.draw_edges(color={edge: '#ff0000' for edges in crossings for edge in edges}) plotter.show() """ try: import planarity except ImportError: print( "Planarity is not installed. Get Planarity at https://github.com/hagberg/planarity." ) raise return planarity.is_planar(network.edges())
# K5 is not planar # any of the following formats can bed used for representing the graph edgelist = [(0, 1), (0, 2), (0, 3), (0, 4), (1, 2),(1, 3),(1, 4), (2, 3), (2, 4), (3, 4)] dictofdicts = {0: {1: {}, 2: {}, 3: {}, 4: {}}, 1: {2: {}, 3: {}, 4: {}}, 2: {3: {}, 4: {}}, 3: {4: {}}, 4: {}} dictofsets = {0: set([1,2,3,4]), 1: set([2,3,4]), 2: set([3,4]), 3: set([4]), 4: set([])} dictoflists = {0: list([1,2,3,4]), 1: list([2,3,4]), 2: list([3,4]), 3: list([4]), 4: list([])} print planarity.is_planar(edgelist) # False print planarity.is_planar(dictofdicts) # False print planarity.is_planar(dictofsets) # False print planarity.is_planar(dictoflists) # False
def test_is_planar_adj_input_function(self): assert_false(planarity.is_planar(self.k5_adj))
def network_is_planar(network): """Check if the network is planar. Parameters ---------- network : Network A network object. Returns ------- bool True if the network is planar. False otherwise. Raises ------ ImportError If the planarity package is not installed. Notes ----- A network is planar if it can be drawn in the plane without crossing edges. If a network is planar, it can be shown that an embedding of the network in the plane exists, and, furthermore, that straight-line embedding in the plane exists. Warning ------- This function uses the python binding of the *edge addition planarity suite*. It is available on Anaconda: https://anaconda.org/conda-forge/python-planarity. Examples -------- .. plot:: :include-source: import compas from compas.datastructures import Network from compas.datastructures import network_is_planar from compas.datastructures import network_find_crossings from compas_plotters import NetworkPlotter network = Network.from_obj(compas.get('lines.obj')) network.add_edge(6, 15) if not network_is_planar(network): print('here') crossings = network_find_crossings(network) else: crossings = [] print(crossings) plotter = NetworkPlotter(network) plotter.draw_vertices(radius=0.15, text={key: key for key in network.vertices()}) plotter.draw_edges(color={edge: '#ff0000' for edges in crossings for edge in edges}) plotter.show() """ return planarity.is_planar(list(network.edges()))
import planarity import networkx as nx G8 = nx.complete_graph(8) G8.nodes G8.edges planarity.is_planar(G8) K = planarity.kuratowski_subgraph(G8) K.edges K.nodes nx.draw(G8)
def test_is_planar_edgelist_input_function(self): assert_false(planarity.is_planar(self.k5_edgelist))