def hier_part(graph, pop_col, pop_target, epsilon): h=graph.copy() clusters = {x:[{x},graph.nodes[x][pop_col]] for x in graph.nodes()} #removed=[] while len(clusters)>2: chosen_e = random.choice(list(h.edges())) #print(chosen_e) cpop = clusters[chosen_e[0]][1] + clusters[chosen_e[1]][1] print(cpop) if cpop < pop_target + epsilon*pop_target: k=h.copy() k.remove_node(chosen_e[1]) if nx.is_connected(k): print(True,True) #print(clusters[chosen_e[0]]) #print(clusters[chosen_e[1]]) clusters[chosen_e[0]][1] = cpop clusters[chosen_e[0]][0]=clusters[chosen_e[0]][0].union(clusters[chosen_e[1]][0]) clusters.pop(chosen_e[1]) #removed.append(chosen_e[1]) h = nx.contracted_edge(h,chosen_e,self_loops = False) else: print(True,False) cc=list(nx.connected_components(k)) tsums=[] for l in cc: tsums.append(0) for n in l: #print(removed) tsums[-1]=tsums[-1]+clusters[n][1] val, idx = min((val, idx) for (idx, val) in enumerate(tsums)) l=cc[idx] for n in l: #print(n) clusters[chosen_e[1]][1]=clusters[chosen_e[1]][1] + clusters[n][1] clusters[chosen_e[1]][0]=clusters[chosen_e[1]][0].union(clusters[n][0]) clusters.pop(n) h.add_edge(chosen_e[1],n) h = nx.contracted_edge(h,(chosen_e[1],n),self_loops = False) else: print(False) print(len(clusters)) return clusters
def kirkoff_inverse_sampler(graph): size = len(graph) - 1 T = [] edge_list = list(graph.edges()) edge = edge_list[0] shuffle(edge_list) while len(T) <= size - 1: print("T currently", len(T)) edge = choice(list(graph.edges())) total_inverse = 0 for edge in list(graph.edges()): H = nx.contracted_edge(graph, edge) p = np.exp(log_number_trees(H)) / np.exp(log_number_trees(graph)) #Replace this with a computation of effective resistance! #You also don't need to compute this so many times! total_inverse += 1/p edge = choice(list(graph.edges())) H = nx.contracted_edge(graph, edge) q = np.exp(log_number_trees(H)) / np.exp(log_number_trees(graph)) p = (1 / q) / total_inverse print(p, q, total_inverse) c = uniform(0,1) if c <= p: T.append(edge) graph = nx.contracted_edge(graph, edge, self_loops=False) else: if q < .999999: graph.remove_edge(edge[0], edge[1]) tree = nx.Graph() tree.add_edges_from(T) edge = T[0] return (tree, edge)
def test_nonexistent_edge(self): """Tests that attempting to contract a non-existent edge raises an exception. """ G = nx.cycle_graph(4) nx.contracted_edge(G, (0, 2))
def test_nonexistent_edge(self): """TestData that attempting to contract a non-existent edge raises an exception. """ with pytest.raises(ValueError): G = nx.cycle_graph(4) nx.contracted_edge(G, (0, 2))
def simplify_network(network): """Simplify all linear sections of network by removing nodes containing 2 degrees""" new_network = network.copy() edge_list = get_edge_list(new_network, max_degree=2) while edge_list.size > 0: for edge in edge_list: try: new_network = nx.contracted_edge( new_network, edge, self_loops=False) except (ValueError, KeyError): pass edge_list = get_edge_list(new_network, max_degree=2) new_network = nx.convert_node_labels_to_integers(new_network) node_coord = get_node_coord_array(new_network) d_coord, r2_coord = distance_matrix(node_coord) r_coord = np.sqrt(r2_coord) for edge in new_network.edges: new_network[edge[0]][edge[1]]['r'] = r_coord[edge[0]][edge[1]] return new_network
def test_undirected_edge_contraction(self): """Tests for edge contraction in an undirected graph.""" G = nx.cycle_graph(4) actual = nx.contracted_edge(G, (0, 1)) expected = nx.complete_graph(3) expected.add_edge(0, 0) assert nx.is_isomorphic(actual, expected)
def contract_edge_once(graph, edge, reg_param=0): """ Function to contract a given edge `edge` in the graph `graph`. Covariates of the node resulting from the contraction is given by the sum of covariates at the nodes composing `edge`. The edge weight is recalculated after this re-assignment. Arguments: - graph: networkx.Graph object - edge: edge in `graph` to be contracted - reg_param: parameter for variance based regularization """ node1, node2 = edge new_node = generate_node_after_contraction(node1, node2) # Contract nodes, and relabel the contracted node with a tuple indicating the cluster new_graph = nx.relabel_nodes( nx.contracted_edge(graph, (node1, node2), self_loops=False), {node1: new_node} ) new_graph.nodes[new_node]["cov"] = ( new_graph.nodes[new_node].pop("cov") + new_graph.nodes[new_node].pop("contraction")[node2]["cov"] ) # Re-compute the edge weights setattr(new_graph, "complete_target", graph.complete_target) for edge in new_graph.edges(new_node): # Just for the edges which originate at new_node new_graph.edges[edge]["weight"] = multiple_regression_error_weight( new_graph, edge[0], edge[1], reg_param ) return new_graph
def test_undirected_edge_contraction(self): """Tests for edge contraction in an undirected graph.""" G = nx.cycle_graph(4) actual = nx.contracted_edge(G, (0, 1)) expected = nx.complete_graph(3) expected.add_edge(0, 0) assert_true(nx.is_isomorphic(actual, expected))
def contract_edge(graph, edge, edge_weight_assign): """ Function to contract an edge in the graph. Attributes of the nodes of edge being contracted are appended to form one longer array and is assigned to the new node resulting from the contraction. The edge weight is recalculated after this re-assignment. Arguments: - graph: networkx.Graph object - edge: edge in `graph` to be contracted - edge_weight_assign: string representing the weighting function. """ node1, node2 = edge new_node = generate_node_after_contraction(node1, node2) # Contract nodes, and relabel the contracted node with a tuple indicating the cluster new_graph = nx.relabel_nodes( nx.contracted_edge(graph, (node1, node2), self_loops=False), {node1: new_node} ) # Re-assign the anomaly attribute; this is simply a concatenation of existing anomalies new_graph.nodes[new_node]["cov"] = ( new_graph.nodes[new_node].pop("cov") + new_graph.nodes[new_node].pop("contraction")[node2]["cov"] ) # Re-compute the edge weights edge_weight_func = get_edge_weight_func(edge_weight_assign) for edge in new_graph.edges(new_node): new_graph.edges[edge]["weight"] = edge_weight_func(new_graph, edge[0], edge[1]) return new_graph
def part2path3(graph, pop_col, pop_target, epsilon): h = graph.copy() start = random.choice(list(h.nodes())) clusters = {x: [{x}, graph.nodes[x][pop_col]] for x in graph.nodes()} while clusters[start][1] < pop_target - epsilon * pop_target: print(clusters[start][1] / pop_target) end = start while end == start: end = random.choice(list(h.nodes())) path = nx.shortest_path(graph, source=start, target=end) psum = 0 for p in path: if p not in clusters[start][0]: psum += clusters[p][1] if psum + clusters[start][0] < pop_target + epsilon * pop_target: print(True) cpop = psum if cpop < pop_target + epsilon * pop_target: k = h.copy() k.remove_nodes_from(path) print(len(k.nodes())) if nx.is_connected(k): path.remove(start) print(True, True) for p in path: h.add_edge(start, p) h = nx.contracted_edge(h, (start, p), self_loops=False) if p not in clusters[start][0]: clusters[start][0] = clusters[start][0].union( clusters[p][0]) clusters[start][1] += clusters[p][1] #clusters.pop(p) else: print(True, False) #else: # print(False,False) # h.remove_edge(start,neighbor) cd2 = {} cd2[start] = clusters[start][0] cd2[-1] = [] for node in graph.nodes(): if node not in cd2[start]: cd2[-1].append(node) cd2[-1] = set(cd2[-1]) return cd2
def contract_dag(input_spec, latency_spec): G = ScheduleDAG() G.create_dag(input_spec.nodes, input_spec.edges, latency_spec) action_nodes = G.nodes(select='action') match_nodes = G.nodes(select='match') tables = [] found_table = dict() for m in match_nodes: for a in action_nodes: if (a.startswith("_condition")): continue assert (m.endswith('MATCH')) assert (a.endswith('ACTION')) m_table = m.strip('MATCH') a_table = a.strip('ACTION') if (m_table == a_table): tables.append((m, a)) found_table[m] = True found_table[a] = True for m in match_nodes: if m not in found_table: print("Unpaired match, ERROR!!!") exit(1) for a in action_nodes: if a not in found_table: pass # print ("Unpaired action or condition: ", a, file=sys.stderr) # Contract table edges for table in tables: match = table[0] action = table[1] table_name = match.strip('MATCH') + 'TABLE' key_width = G.node[match]['key_width'] num_fields = G.node[action]['num_fields'] G = nx.contracted_edge(G, table, self_loops=False) nx.relabel_nodes(G, {match: table_name}, False) G.node[table_name]['type'] = 'table' G.node[table_name]['key_width'] = key_width G.node[table_name]['num_fields'] = num_fields # Create dummy tables for the rest for v in G.nodes(): if (G.node[v]['type'] != 'table'): G.node[v]['type'] = 'table' G.node[v]['key_width'] = 0 assert (G.node[v]['num_fields'] >= 0) # leave num_fields unchanged return G
def kirkoff_sampler(graph): size = len(graph) - 1 T = [] edge_list = list(graph.edges()) edge = edge_list[0] shuffle(edge_list) while len(T) <= size - 1: edge = choice(list(graph.edges())) H = nx.contracted_edge(graph, edge) p = np.exp(log_number_trees(H)) / np.exp(log_number_trees(graph)) print(p) c = uniform(0,1) if c <= p: T.append(edge) graph = nx.contracted_edge(graph, edge, self_loops=False) else: graph.remove_edge(edge[0], edge[1]) tree = nx.Graph() tree.add_edges_from(T) return tree
def edge_contract(self, u, v, self_loop=False): """ Contract the edge (u,v) and relabel u using the concatenation of the labels at u and v """ try: ulabel = self.g.node[u]['label'] vlabel = self.g.node[v]['label'] self.g = nx.contracted_edge(self.g, (u, v), self_loop) self.g.node[u]['label'] = ulabel + vlabel except ValueError as err: print(err)
def minor(graph): g = nx.Graph(graph) while True: has_contracted = False for u, v in g.edges(): if g.nodes[u]['label'] == g.nodes[v]['label']: g = nx.contracted_edge(g, (u, v), self_loops=False) has_contracted = True break if has_contracted is False: break return g
def contract(self, G, c): # Contract edges uv as long as d(u)+d(v)\leq c. while True: try: u, v = next( ifilter( lambda x: x[0] != x[1] and G.degree(x[0]) + G.degree(x[ 1]) <= c, G.edges_iter())) G = nx.contracted_edge(G, (u, v), self_loops=False) except StopIteration: break return G
def merge(G,edge): """Returns a new graph with edge merged, and the new node containing the information lost in the merge. The weights from common neighbors are added together, a la Stoer-Wagner algorithm.""" if G.node[edge[1]]['type'] == 'login' or G.node[edge[1]]['type'] == 'email': edge = edge[::-1] # If login/email is on the right, flip the order, so it's always on the left nx.set_node_attributes(G,'list',{edge[0]:G.node[edge[0]]['list']+[edge[1]]}) J = nx.contracted_edge(G,(edge[0],edge[1]),self_loops = False) #Contract edge without self-loop # Weight stuff N = nx.common_neighbors(G,edge[0],edge[1]) #find common nodes for i in N: J[i][edge[0]]['weight'] = G[edge[0]][i]['weight'] + G[edge[1]][i]['weight'] #modify the weight after contraction return J
def contract_tree(tree): G_tree = nx.from_edgelist(get_edge_list(tree)) for u in G_tree: if u not in G_tree: continue G = list(G_tree[u]) while len(G) == 2: mx = max(G) G_temp = nx.contracted_edge(G_tree, (u, mx)) G_temp.remove_edges_from(G_temp.selfloop_edges()) G = list(G_temp[u]) '''if len(G) >= 3: break''' G_tree = G_temp return G_tree
def minor_lbound_num(self, k, timeout, l=1): for u, v in self.G.edges_iter(): G1 = nx.convert_node_labels_to_integers( nx.contracted_edge(self.G, (u, v), self_loops=False)) # sanity check # G1 = self.hypergraph.copy() lbound_solver = GraphSatTw(G1, timeout=timeout) print('u = %s, v = %s' % (u, v)) ret = lbound_solver.solve(k) print('ret = %s' % ret) if not ret: return False return True
def contract(self): to_contract = {"id", "connect"} graph = self.graph.copy() # none_nodes = [n for n in graph.nodes() if str(n) == "none"] # graph.remove_nodes_from(none_nodes) def left_to_contract(graph): node_names = set([str(n) for n in graph.nodes()]) return len(node_names.intersection(to_contract)) > 0 while left_to_contract(graph): for e_1, e_2 in graph.edges(): if str(e_2) in to_contract: graph = nx.contracted_edge(graph, (e_1, e_2), self_loops=False) break return graph
def lower_bound(graph): """Minor-min-width""" graph = graph.copy() dmax = 0 while len(graph) > 0: # pick node of minimum degree d, u = min((len(graph[u]), u) for u in graph) dmax = max(dmax, d) # Gogate and Dechter: minor-min-width nb = set(graph[u]) - {u} if len(nb) > 0: _, v = min((len(set(graph[v]) & nb), v) for v in nb) graph = networkx.contracted_edge(graph, (u, v), self_loops=False) else: graph.remove_node(u) return dmax
def __contracted_edges(self, G, node_from, node_to): ''' contract edges (u,v) in a Graph G :param G: NetworkX Graph :param node_from: node u of an edge (u,v) :param node_to: node v of an edge (u,v) :return: A network graph where node v will be merge into u ''' u = self.__get_node(node_from) v = self.__get_node(node_to) M = nx.contracted_edge(G, (u, v)) # since the node v is merged with u, we save the reference in case that there an edges that needs to be # contracted which includes node v. self.__set_node(v, u) return M
def contract_edges_matching(G, num_iters=2): """Given a graph G and a desired number of edges to be contracted, contracts edges uniformly at random (non-mutating of the original graph). Edges are contracted such that the two endpoints are now "identified" with one another. This mapping is returned as a dictionary If more edges are provided than can be contracted, an error is thrown. Returns (1) contracted graph (NetworkX Graph); (2) identified nodes dictionary (NetworkX node -> NetworkX node) """ identified_nodes = {} for _ in range(num_iters): edges = list(G.edges) matching = nx.maximal_matching(G) for vertex_pair in matching: identified_nodes[vertex_pair[0]] = vertex_pair[ 0] # right gets contracted into left G = nx.contracted_edge(G, vertex_pair, self_loops=False) return G, identified_nodes
def contract_edges(G, num_edges): """Given a graph G and a desired number of edges to be contracted, contracts edges uniformly at random (non-mutating of the original graph). Edges are contracted such that the two endpoints are now "identified" with one another. This mapping is returned as a dictionary If more edges are provided than can be contracted, an error is thrown. Returns (1) contracted graph (NetworkX Graph); (2) identified nodes dictionary (NetworkX node -> NetworkX node) """ identified_nodes = {} for _ in range(num_edges): edges = list(G.edges) random_edge = edges[random.randint(0, len(edges) - 1)] node_to_contract = random_edge[1] identified_nodes[node_to_contract] = random_edge[ 0] # right gets contracted into left G = nx.contracted_edge(G, random_edge, self_loops=False) return G, identified_nodes
def draw_contraction(T): t = T.copy() stack = [v for v in t.nodes() if len(eval(v)) == 1] pos = nx.spring_layout(t) draw_snapshot(t, stack, pos) i = 1 while stack: v = stack.pop() for w in t[v]: if len(eval(w)) > 1: t = nx.contracted_edge(t, (v, w), self_loops=False) # stack.append(v) stack = [v] + stack draw_snapshot(t, stack, pos, i) i += 1 break for u, v in t.edges(): t[u][v]['weight'] *= 4 draw_snapshot(t, stack, pos, i) return t
def mmw(g): lb = 0 iter = 0 while True: iter += 1 nodes = list(g.nodes()) if len(nodes) < 2: return lb # todo: huge room for optimization here #---- Find min degree vertex vertex, degree = min_degreeV(g, nodes) #---- Find min degree v from his neighbors neig = list(g.neighbors(vertex)) neig = [v for v in neig if v != vertex] vertex2, _ = min_degreeV(g, neig) #print(lb,iter,vertex,vertex2) # Self loops=False costed me 1.5 hours! g = nx.contracted_edge(g, (vertex, vertex2), self_loops=False) #data._save_graph(g,'gt%i.png'%iter) nodes = list(g.nodes()) lb = max(lb, degree)
def mincut(g): # check that g is a graph with > 2 vertices assert isinstance(g, nx.MultiGraph) and nx.is_connected(g) # check base cases of vertices if g.number_of_nodes() < 2: return 0 elif g.number_of_nodes() == 2: return g.size() # while more than two nodes remain remove an edge while (g.number_of_nodes() > 2): # pick and edge at random idx = np.random.choice(len(g.edges())) random_edge = g.edges()[idx] # contract the edge in the graph #nx.draw(g) g = nx.contracted_edge(g, random_edge, self_loops=False) # return the number of edges remaining in g print(g) return g.size()
def expand_graph(G, n): print "G has:", len(G.nodes()), "nodes" # number of times to expand for expand in range(n): nextEdges = G.edges(1) print "Root Neighbors:", nextEdges # print G.edges() print "expanding" # merges with all neighboring nodes for edge in nextEdges: G = nx.contracted_edge(G, edge, self_loops=False) print "G has:", len(G.nodes()), "nodes" # print G.edges() return G
def make_random_homomorphism(G): H = nx.Graph(G) r = randint(1, int(max(5, len(list(G.nodes())) / 5))) phi = list(range(len(G.nodes()))) for i in range(randint(1, r)): u = choice(list(G.nodes())) v = [ v for v in list(G.nodes()) if v != u and (u, v) not in list(G.edges()) ] v = choice(v) H.add_edge(v, u) edge = (v, u) H = nx.contracted_edge(H, edge, self_loops=False) phi[u] = v for i in range(randint(1, r)): u = choice(list(G.nodes())) v = [ v for v in list(G.nodes()) if v != u and (u, v) not in list(G.edges()) ] v = choice(v) H.add_edge(u, v) return H, phi
def _recursive(G): # If the graph is not connected, then it has a rel poly of 0 if not nx.is_connected(G): return sympy.Poly(0, p) # Check if the graph is multigraph complete # and has no parallel edges if is_multigraph_complete_no_parallel(G): return _complete(G) # if # edges > 0, then we perform the two subcases of the # Factoring theorem. if len(G.edges()) > 0: e = random.choice(G.edges()) contracted = nx.contracted_edge(G, e, self_loops=False) G.remove_edge(*e) rec_deleted = _recursive(G) rec_contracted = _recursive(contracted) s = sympy.Poly(p)*(rec_contracted) + sympy.Poly(1-p)*(rec_deleted) return s # Otherwise, we only have 0 edges and 1 vertex, which is connected, # so we return 1. return sympy.Poly(1, p)
def part2blob(graph, pop_col, pop_target, epsilon): h=graph.copy() start = random.choice(list(h.nodes())) clusters={x:[{x},graph.nodes[x][pop_col]] for x in graph.nodes()} neighbors = list(h.neighbors(start)) while clusters[start][1] < pop_target - epsilon*pop_target: print(clusters[start][1]/pop_target) if neighbors==[]: neighbors=list(h.neighbors(start)) for neighbor in neighbors: cpop = clusters[start][1] + clusters[neighbor][1] if cpop < pop_target + epsilon*pop_target: k=h.copy() k.remove_node(start) k.remove_node(neighbor) print(len(k.nodes())) if nx.is_connected(k): print(True,True) h = nx.contracted_edge(h,(start,neighbor),self_loops = False) clusters[start][0] = clusters[start][0].union(clusters[neighbor][0]) clusters[start][1] = cpop clusters.pop(neighbor) else: print(True,False) cc=list(nx.connected_components(k)) tsums=[] for l in cc: tsums.append(0) for n in l: #print(removed) tsums[-1]=tsums[-1]+graph.nodes[n][pop_col] val, idx = min((val, idx) for (idx, val) in enumerate(tsums)) l=cc[idx] for n in l: #print(n) h.add_edge(neighbor,n) #h.nodes[neighbor][pop_col]+=h.nodes[n][pop_col] clusters[neighbor][1] = clusters[neighbor][1]+ clusters[n][1] h = nx.contracted_edge(h,(neighbor,n),self_loops = False) clusters[neighbor][0]=clusters[neighbor][0].union(clusters[n][0]) clusters.pop(n) if n in neighbors: neighbors.remove(n) else: print(False,False) h.remove_edge(start,neighbor) neighbors.remove(neighbor) cd2={} cd2[start]=clusters[start][0] cd2[-1]=[] for node in graph.nodes(): if node not in cd2[start]: cd2[-1].append(node) cd2[-1]=set(cd2[-1]) cs=dict() cs[1]=cd2[start] print(cs) print(cs[1]) return cs
k=h.copy() k.remove_node(chosen_e[1]) if nx.is_connected(k): print(True,True) h #print(clusters[chosen_e[0]]) #print(clusters[chosen_e[1]]) clusters[chosen_e[0]][1] = cpop clusters[chosen_e[0]][0]=clusters[chosen_e[0]][0].union(clusters[chosen_e[1]][0]) clusters.pop(chosen_e[1]) #removed.append(chosen_e[1]) h = nx.contracted_edge(h,chosen_e,self_loops = False) else: print(True,False) cc=list(nx.connected_components(k)) tsums=[] for l in cc: tsums.append(0) for n in l: #print(removed) tsums[-1]=tsums[-1]+clusters[n][1] val, idx = min((val, idx) for (idx, val) in enumerate(tsums)) l=cc[idx] for n in l:
def populate_graph(data): # noqa: C901 Graph = namedtuple('Graph', 'G source regions') G = nx.Graph( ) # We can't trust directions of edges, so graph should be not-directional # MG = nx.Graph() # converted graph to modules.tf schema # @todo: convert from graph (G) to modules.tf graph (MG), which can be dumped to json and passed to generator function regions = [] connectors = [] # We don't care about these keys in json: images, icons data_id = data["id"] data = data.get("data", {}) data_nodes = data.get("nodes", []) data_edges = data.get("edges", []) data_groups = data.get("groups", []) data_connectors = data.get("connectors", []) data_text = data.get("text", []) data_name = data.get("name", "unnamed") ######## # NODES ######## for node in data_nodes: G.add_node(node["id"], data=node) ######## # EDGES ######## for edge in data_edges: if "from" in edge and "to" in edge: G.add_edge(edge["from"], edge["to"]) ##################### # AUTOSCALING GROUPS, SECURITY GROUPS AND VPCS ##################### for group in data_groups: group_type = group.get("type") if group_type in ["asg", "sg", "vpc"]: group_id = group.get("id") group_nodes = group.get("nodes") group_region = group.get("region") group_name = group.get("name") regions.append(group_region) G.add_node(group_id, data={ "type": group_type, "group_nodes": group_nodes, "group_region": group_region, "group_name": group_name, }) if group_type == "sg": G.nodes[group_id]["data"]["inbound_rules"] = group.get( "inboundRules") G.nodes[group_id]["data"]["outbound_rules"] = group.get( "outboundRules") elif group_type == "vpc": G.nodes[group_id]["data"]["peering_connections"] = group.get( "peeringConnections") for group_node in group_nodes: # some items (like "text") may belong to groups, but are not in "nodes" if group_node not in G.nodes: continue # nodes type "icon" does not have "data", so we skip them if "data" not in G.nodes[group_node]: continue if group_type == "asg": G.nodes[group_node]["data"]["asg_id"] = group_id elif group_type == "sg": G.nodes[group_node]["data"]["sg_id"] = group_id elif group_type == "vpc": G.nodes[group_node]["data"]["vpc_id"] = group_id ############# # CONNECTORS ############# for connector in data_connectors: G.add_node(connector["id"], type="connector") connectors.append(connector["id"]) # Merge connectors by contracting edges edge = [] while True: # Find first edge which contains connector for edge in G.edges.data(): edge = list(edge) if edge[0] == edge[1]: edge = [] # maybe continue elif edge[0] in connectors or edge[1] in connectors: break else: edge = [] # Skip edges without connectors and edges which does not have nodes on one any side if len(edge) == 0 or edge[0] not in G or edge[1] not in G: break G = nx.contracted_edge(G, (edge[0], edge[1]), self_loops=False) ######## # TEXTS ######## for text in data_text: mapPos = text.get("mapPos", {}) if isinstance(mapPos, dict): relTo = mapPos.get("relTo") if relTo in G.nodes: G.nodes[relTo]["text"] = text["text"].strip() ########### # REGION ########### regions = list(set(regions)) ######## # SOURCE ######## source = { "name": data_name, "id": data_id, } # Debug - draw into file # import matplotlib.pyplot as plt # plt.rcParams["figure.figsize"] = (10, 10) # nx.draw(G, pos=nx.spring_layout(G), with_labels=True) # plt.savefig("graph.png") # pprint(G.edges["0820fb86-ee74-49ce-9fe5-03f610ca5e75"]) pprint("NODES===") pprint(G.nodes.data()) # print("EDGES===") # print(G.edges.data()) # pprint(regions) # pprint(regions.keys()) # pprint(nodes) # pprint(texts) # pprint(edges, indent=2) # pprint(edges_rev) # nx.drawing.nx_agraph.write_dot(G, "graph.dot") return Graph(G, source, regions)