def inter_community_edges(G, partition): """Returns the number of inter-community edges according to the given partition of the nodes of `G`. `G` must be a NetworkX graph. `partition` must be a partition of the nodes of `G`. The *inter-community edges* are those edges joining a pair of nodes in different blocks of the partition. Implementation note: this function creates an intermediate graph that may require the same amount of memory as required to store `G`. """ # Alternate implementation that does not require constructing a new # graph object (but does require constructing an affiliation # dictionary): # # aff = dict(chain.from_iterable(((v, block) for v in block) # for block in partition)) # return sum(1 for u, v in G.edges() if aff[u] != aff[v]) # if G.is_directed(): return nx.quotient_graph(G, partition, create_using=nx.MultiDiGraph()).size() else: return nx.quotient_graph(G, partition, create_using=nx.MultiGraph()).size()
def blockmodel(G, partition, multigraph=False): """Returns a reduced graph constructed using the generalized block modeling technique. The blockmodel technique collapses nodes into blocks based on a given partitioning of the node set. Each partition of nodes (block) is represented as a single node in the reduced graph. Edges between nodes in the block graph are added according to the edges in the original graph. If the parameter multigraph is False (the default) a single edge is added with a weight equal to the sum of the edge weights between nodes in the original graph The default is a weight of 1 if weights are not specified. If the parameter multigraph is True then multiple edges are added each with the edge data from the original graph. Parameters ---------- G : graph A networkx Graph or DiGraph partition : list of lists, or list of sets The partition of the nodes. Must be non-overlapping. multigraph : bool, optional If True return a MultiGraph with the edge data of the original graph applied to each corresponding edge in the new graph. If False return a Graph with the sum of the edge weights, or a count of the edges if the original graph is unweighted. Returns ------- blockmodel : a Networkx graph object Examples -------- >>> G = nx.path_graph(6) >>> partition = [[0,1],[2,3],[4,5]] >>> M = nx.blockmodel(G,partition) References ---------- .. [1] Patrick Doreian, Vladimir Batagelj, and Anuska Ferligoj "Generalized Blockmodeling",Cambridge University Press, 2004. .. note:: Deprecated in NetworkX v1.11 `blockmodel` will be removed in NetworkX 2.0. Instead use `quotient_graph` with keyword argument `relabel=True`, and `create_using=nx.MultiGraph()` for multigraphs. """ if multigraph: return nx.quotient_graph(G, partition, create_using=nx.MultiGraph(), relabel=True) else: return nx.quotient_graph(G, partition, relabel=True)
def blockmodel(G, partition, multigraph=False): """Returns a reduced graph constructed using the generalized block modeling technique. The blockmodel technique collapses nodes into blocks based on a given partitioning of the node set. Each partition of nodes (block) is represented as a single node in the reduced graph. Edges between nodes in the block graph are added according to the edges in the original graph. If the parameter multigraph is False (the default) a single edge is added with a weight equal to the sum of the edge weights between nodes in the original graph The default is a weight of 1 if weights are not specified. If the parameter multigraph is True then multiple edges are added each with the edge data from the original graph. Parameters ---------- G : graph A networkx Graph or DiGraph partition : list of lists, or list of sets The partition of the nodes. Must be non-overlapping. multigraph : bool, optional If True return a MultiGraph with the edge data of the original graph applied to each corresponding edge in the new graph. If False return a Graph with the sum of the edge weights, or a count of the edges if the original graph is unweighted. Returns ------- blockmodel : a Networkx graph object Examples -------- >>> G = nx.path_graph(6) >>> partition = [[0,1],[2,3],[4,5]] >>> M = nx.blockmodel(G,partition) References ---------- .. [1] Patrick Doreian, Vladimir Batagelj, and Anuska Ferligoj "Generalized Blockmodeling",Cambridge University Press, 2004. .. note:: Deprecated in NetworkX v1.11 ``blockmodel`` will be removed in NetworkX 2.0. Instead use ``quotient_graph`` with keyword argument ``relabel=True``, and ``create_using=nx.MultiGraph()`` for multigraphs. """ if multigraph: return nx.quotient_graph(G, partition, create_using=nx.MultiGraph(), relabel=True) else: return nx.quotient_graph(G, partition, relabel=True)
def test_quotient_graph_incomplete_partition(self): G = nx.path_graph(6) partition = [] H = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(H.nodes(), []) assert_edges_equal(H.edges(), []) partition = [[0, 1], [2, 3], [5]] H = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(H.nodes(), [0, 1, 2]) assert_edges_equal(H.edges(), [(0, 1)])
def computeQuotientGraph_fromFunction(graph, function): """ Computes the quotient graph: graph/function :param graph: usual graph :param function: a function from the nodes somewhere :return: The quotient graph. The labels are the values of f """ # Create a partition for the nodes based on f partition = {} for node in graph.nodes(): node_converted = [int(bit) for bit in node] key = str(tuple(function(node_converted))) if key not in partition: partition[key] = [] partition[key] += [node] def relation(s, t): s = [int(bit) for bit in s] t = [int(bit) for bit in t] for fs, ft in zip(function(s), function(t)): if fs != ft: return False return True quotient_graph = nx.quotient_graph(graph, relation) return nx.relabel_nodes(quotient_graph, invert_dict(partition))
def community_blocks(graph, communities): """ Extract block graph of communities. This graph just highlights the relationships of communities. :param graph: :param communities: :return: """ # This generates the block graph partition_keys = communities.keys() partition_values = communities.values() block = nx.quotient_graph(graph, partition_values) # Re-map the block nodes to communities block_nodes_map = {} for k, v in zip(partition_keys, partition_values): for n in block.nodes: if frozenset(v) == frozenset(n): block_nodes_map[n] = k break block = nx.relabel_nodes(block, block_nodes_map) # Remove graph from block data (otherwise we can't save it) for node, data in block.nodes(data=True): del data['graph'] return block
def export_draw_agents_network(p_coupled_network): """ export agents network by quotient_graph """ all_edges_df = pd.read_csv(BaseConfig.OUT_PATH + 'Coupled_Network\\AllLinks.csv') id_sou = all_edges_df['Source'].map(str) id_tar = all_edges_df['Target'].map(str) all_ver_list = list(id_sou) + list(id_tar) # set the unique of the agents ver_list_unique = list(set(all_ver_list)) # group of nodes partitions = [] for a_id in ver_list_unique: partitions.append([ n for n, d in p_coupled_network.nodes(data=True) if d['ga_id'] == a_id ]) block_net = nx.quotient_graph(p_coupled_network, partitions, relabel=False) name_mapping = {} for b_node in block_net.nodes: name_mapping[b_node] = list(b_node)[0].split('_')[0] block_net.nodes[b_node]['ga_id'] = list(b_node)[0].split('_')[0] block_net.nodes[b_node]['color'] = 'r' block_net.nodes[b_node]['var_name'] = list(b_node)[0].split('_')[1] for e in block_net.edges: block_net.edges[e]['weight'] = 1 nx.relabel_nodes(block_net, name_mapping) draw_net_on_map(block_net, 'Agents_Net')
def export_draw_vars_network(p_coupled_network): """ export vars network by quotient_graph """ # group of nodes partitions = [] for var in VARS_LIST: partitions.append([ n for n, d in p_coupled_network.nodes(data=True) if d['var_name'] == var ]) block_net = nx.quotient_graph(p_coupled_network, partitions, relabel=False) for n, d in block_net.nodes(data=True): var_label = list(n)[0].split('_')[1] block_net.nodes[n]['label'] = var_label fig = plt.figure(figsize=(10, 10), dpi=300) ax = plt.gca() pos = nx.circular_layout(block_net) for e in block_net.edges: ax.annotate("", xy=pos[e[0]], xycoords='data', xytext=pos[e[1]], textcoords='data', arrowprops=dict(arrowstyle="->", color=VAR_COLOR_DICT[list( e[0])[0].split('_')[1]], shrinkA=3, shrinkB=3, patchA=None, patchB=None, connectionstyle="arc3,rad=rrr".replace( 'rrr', str(0.005 * e[2])))) nx.draw_networkx_nodes(block_net, pos, node_size=[ block_net.nodes[n]['nedges'] * 30 for n, d in block_net.nodes(data=True) ], node_color=[ VAR_COLOR_DICT[list(n)[0].split('_')[1]] for n, d in block_net.nodes(data=True) ], label=[ block_net.nodes[n]['label'] for n, d in block_net.nodes(data=True) ]) nx.draw_networkx_labels(block_net, pos, labels={ n: block_net.nodes[n]['label'] for n, d in block_net.nodes(data=True) }, font_size=14, font_color='#0007DA') plt.savefig(BaseConfig.OUT_PATH + 'Coupled_Network//vars_network.pdf')
def test_multigraph_blockmodel(self): G = nx.MultiGraph(nx.path_graph(6)) partition = [[0, 1], [2, 3], [4, 5]] M = nx.quotient_graph(G, partition, create_using=nx.MultiGraph(), relabel=True) assert_nodes_equal(M.nodes(), [0, 1, 2]) assert_edges_equal(M.edges(), [(0, 1), (1, 2)]) for n in M.nodes(): assert M.nodes[n]["nedges"] == 1 assert M.nodes[n]["nnodes"] == 2 assert M.nodes[n]["density"] == 1.0
def test_multigraph_path(self): G = nx.MultiGraph(nx.path_graph(6)) partition = [{0, 1}, {2, 3}, {4, 5}] M = nx.quotient_graph(G, partition, relabel=True) assert_equal(sorted(M), [0, 1, 2]) assert_equal(sorted(M.edges()), [(0, 1), (1, 2)]) for n in M: assert_equal(M.node[n]['nedges'], 1) assert_equal(M.node[n]['nnodes'], 2) assert_equal(M.node[n]['density'], 1)
def test_path__partition_provided_as_dict_of_tuples(self): G = nx.path_graph(6) partition = {0: (0, 1), 2: (2, 3), 4: (4, 5)} M = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(M, [0, 1, 2]) assert_edges_equal(M.edges(), [(0, 1), (1, 2)]) for n in M: assert M.nodes[n]["nedges"] == 1 assert M.nodes[n]["nnodes"] == 2 assert M.nodes[n]["density"] == 1
def test_blockmodel(self): G = nx.path_graph(6) partition = [[0, 1], [2, 3], [4, 5]] M = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(M.nodes(), [0, 1, 2]) assert_edges_equal(M.edges(), [(0, 1), (1, 2)]) for n in M.nodes(): assert_equal(M.nodes[n]['nedges'], 1) assert_equal(M.nodes[n]['nnodes'], 2) assert_equal(M.nodes[n]['density'], 1.0)
def test_barbell(self): G = nx.barbell_graph(3, 0) partition = [set([0, 1, 2]), set([3, 4, 5])] M = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(M, [0, 1]) assert_edges_equal(M.edges(), [(0, 1)]) for n in M: assert_equal(M.nodes[n]['nedges'], 3) assert_equal(M.nodes[n]['nnodes'], 3) assert_equal(M.nodes[n]['density'], 1)
def test_path__partition_provided_as_dict_of_sets(self): G = nx.path_graph(6) partition = {0: {0, 1}, 2: {2, 3}, 4: {4, 5}} M = nx.quotient_graph(G, partition, relabel=True) assert nodes_equal(M, [0, 1, 2]) assert edges_equal(M.edges(), [(0, 1), (1, 2)]) for n in M: assert M.nodes[n]["nedges"] == 1 assert M.nodes[n]["nnodes"] == 2 assert M.nodes[n]["density"] == 1
def test_blockmodel(self): G = nx.path_graph(6) partition = [[0, 1], [2, 3], [4, 5]] M = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(M.nodes(), [0, 1, 2]) assert_edges_equal(M.edges(), [(0, 1), (1, 2)]) for n in M.nodes(): assert M.nodes[n]['nedges'] == 1 assert M.nodes[n]['nnodes'] == 2 assert M.nodes[n]['density'] == 1.0
def test_multigraph_path(self): G = nx.MultiGraph(nx.path_graph(6)) partition = [set([0, 1]), set([2, 3]), set([4, 5])] M = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(M, [0, 1, 2]) assert_edges_equal(M.edges(), [(0, 1), (1, 2)]) for n in M: assert_equal(M.nodes[n]['nedges'], 1) assert_equal(M.nodes[n]['nnodes'], 2) assert_equal(M.nodes[n]['density'], 1)
def test_barbell(self): G = nx.barbell_graph(3, 0) partition = [{0, 1, 2}, {3, 4, 5}] M = nx.quotient_graph(G, partition, relabel=True) assert_equal(sorted(M), [0, 1]) assert_equal(sorted(M.edges()), [(0, 1)]) for n in M: assert_equal(M.node[n]['nedges'], 3) assert_equal(M.node[n]['nnodes'], 3) assert_equal(M.node[n]['density'], 1)
def test_multigraph_path(self): G = nx.MultiGraph(nx.path_graph(6)) partition = [{0, 1}, {2, 3}, {4, 5}] M = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(M, [0, 1, 2]) assert_edges_equal(M.edges(), [(0, 1), (1, 2)]) for n in M: assert M.nodes[n]["nedges"] == 1 assert M.nodes[n]["nnodes"] == 2 assert M.nodes[n]["density"] == 1
def test_barbell(self): G = nx.barbell_graph(3, 0) partition = [{0, 1, 2}, {3, 4, 5}] M = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(M, [0, 1]) assert_edges_equal(M.edges(), [(0, 1)]) for n in M: assert M.nodes[n]["nedges"] == 3 assert M.nodes[n]["nnodes"] == 3 assert M.nodes[n]["density"] == 1
def test_path(self): G = nx.path_graph(6) partition = [{0, 1}, {2, 3}, {4, 5}] M = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(M, [0, 1, 2]) assert_edges_equal(M.edges(), [(0, 1), (1, 2)]) for n in M: assert_equal(M.nodes[n]['nedges'], 1) assert_equal(M.nodes[n]['nnodes'], 2) assert_equal(M.nodes[n]['density'], 1)
def test_directed_path(self): G = nx.DiGraph() nx.add_path(G, range(6)) partition = [{0, 1}, {2, 3}, {4, 5}] M = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(M, [0, 1, 2]) assert_edges_equal(M.edges(), [(0, 1), (1, 2)]) for n in M: assert M.nodes[n]["nedges"] == 1 assert M.nodes[n]["nnodes"] == 2 assert M.nodes[n]["density"] == 0.5
def test_directed_path(self): G = nx.DiGraph() G.add_path(range(6)) partition = [{0, 1}, {2, 3}, {4, 5}] M = nx.quotient_graph(G, partition, relabel=True) assert_equal(sorted(M), [0, 1, 2]) assert_equal(sorted(M.edges()), [(0, 1), (1, 2)]) for n in M: assert_equal(M.node[n]['nedges'], 1) assert_equal(M.node[n]['nnodes'], 2) assert_equal(M.node[n]['density'], 0.5)
def test_directed_multigraph_path(self): G = nx.MultiDiGraph() nx.add_path(G, range(6)) partition = [{0, 1}, {2, 3}, {4, 5}] M = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(M, [0, 1, 2]) assert_edges_equal(M.edges(), [(0, 1), (1, 2)]) for n in M: assert_equal(M.nodes[n]['nedges'], 1) assert_equal(M.nodes[n]['nnodes'], 2) assert_equal(M.nodes[n]['density'], 0.5)
def test_directed_path(self): G = nx.DiGraph() nx.add_path(G, range(6)) partition = [set([0, 1]), set([2, 3]), set([4, 5])] M = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(M, [0, 1, 2]) assert_edges_equal(M.edges(), [(0, 1), (1, 2)]) for n in M: assert_equal(M.nodes[n]['nedges'], 1) assert_equal(M.nodes[n]['nnodes'], 2) assert_equal(M.nodes[n]['density'], 0.5)
def plot_additional(self, home_nodes, levels=0): """Add nodes to existing plot. Prompt to include link to existing if possible. home_nodes are the nodes to add to the graph""" new_nodes = self._neighbors(home_nodes, levels=levels) new_nodes = home_nodes.union(new_nodes) displayed_data_nodes = set( [v['dataG_id'] for k, v in self.dispG.nodes.items()]) # It is possible the new nodes create a connection with the existing # nodes; in such a case, we don't need to try to find the shortest # path between the two blocks current_num_islands = nx.number_connected_components(self.dispG) new_num_islands = nx.number_connected_components( self.dataG.subgraph(displayed_data_nodes.union(new_nodes))) if new_num_islands > current_num_islands: # Find shortest path between two blocks graph and, if it exists, # ask the user if they'd like to include those nodes in the # display as well. # First, create a block model of our data graph where what is # current displayed is a block, the new nodes are a a block all_nodes = set(self.dataG.nodes()) singleton_nodes = all_nodes - displayed_data_nodes - new_nodes singleton_nodes = map(lambda x: [x], singleton_nodes) partitions = [displayed_data_nodes, new_nodes] + \ list(singleton_nodes) #B = nx.blockmodel(self.dataG, partitions, multigraph=True) B = nx.quotient_graph(self.dataG, partitions, relabel=True) # Find shortest path between existing display (node 0) and # new display island (node 1) try: path = nx.shortest_path(B, 0, 1) except nx.NetworkXNoPath: pass else: ans = tkm.askyesno( "Plot path?", "A path exists between the " "currently graph and the nodes you've asked to be added " "to the display. Would you like to plot that path?") if ans: # Yes to prompt # Add the nodes from the source graph which are part of # the path to the new_nodes set # Don't include end points because they are the two islands for u in path[1:-1]: Gu = B.nodes[u]['graph'].nodes() assert len(Gu) == 1 Gu = list(Gu)[0] new_nodes.add(Gu) # Plot the new nodes self._plot_additional(new_nodes)
def hiclus_blockmodel(G): """Draw a blockmodel diagram of a clustering""" # Extract largest connected component into graph H H = next(nx.connected_component_subgraphs(G)) # Extract largest connected component into graph H H = nx.connected_component_subgraphs(G)#[0] # Create parititions with hierarchical clustering cluster = create_hc(H) # cluster = create_hc(G) # Build blockmodel graph BM = nx.quotient_graph(H, cluster, create_using=nx.MultiGraph(), relabel = True) lg.GeneralGraph(GM,'HC_cluster_BM')
def labeled_blockmodel(g, partition): """ Perform blockmodel transformation on graph *g* and partition represented by dictionary *partition*. Values of *partition* are used to partition the graph. Keys of *partition* are used to label the nodes of the new graph. """ new_g = nx.quotient_graph(g, list(partition.values()), relabel=True) labels = dict(enumerate(partition.keys())) new_g = nx.relabel_nodes(new_g, labels) return new_g
def labeled_blockmodel(g,partition): """ Perform blockmodel transformation on graph *g* and partition represented by dictionary *partition*. Values of *partition* are used to partition the graph. Keys of *partition* are used to label the nodes of the new graph. """ new_g = nx.quotient_graph(g,partition.values(),relabel=True) labels = dict(enumerate(partition.keys())) new_g = nx.relabel_nodes(new_g,labels) return new_g
def test_barbell_plus(self): G = nx.barbell_graph(3, 0) # Add an extra edge joining the bells. G.add_edge(0, 5) partition = [{0, 1, 2}, {3, 4, 5}] M = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(M, [0, 1]) assert_edges_equal(M.edges(), [(0, 1)]) assert M[0][1]["weight"] == 2 for n in M: assert M.nodes[n]["nedges"] == 3 assert M.nodes[n]["nnodes"] == 3 assert M.nodes[n]["density"] == 1
def test_quotient_graph_edge_relation(): """Tests for specifying an alternate edge relation for the quotient graph. """ G = nx.path_graph(5) identity = lambda u, v: u == v peek = lambda x: next(iter(x)) same_parity = lambda b, c: peek(b) % 2 == peek(c) % 2 actual = nx.quotient_graph(G, identity, same_parity) expected = nx.Graph() expected.add_edges_from([(0, 2), (0, 4), (2, 4)]) expected.add_edge(1, 3) assert_true(nx.is_isomorphic(actual, expected))
def test_barbell_plus(self): G = nx.barbell_graph(3, 0) # Add an extra edge joining the bells. G.add_edge(0, 5) partition = [{0, 1, 2}, {3, 4, 5}] M = nx.quotient_graph(G, partition, relabel=True) assert_equal(sorted(M), [0, 1]) assert_equal(sorted(M.edges()), [(0, 1)]) assert_equal(M[0][1]['weight'], 2) for n in M: assert_equal(M.node[n]['nedges'], 3) assert_equal(M.node[n]['nnodes'], 3) assert_equal(M.node[n]['density'], 1)
def test_weighted_path(self): G = nx.path_graph(6) for i in range(5): G[i][i + 1]["weight"] = i + 1 partition = [{0, 1}, {2, 3}, {4, 5}] M = nx.quotient_graph(G, partition, relabel=True) assert_nodes_equal(M, [0, 1, 2]) assert_edges_equal(M.edges(), [(0, 1), (1, 2)]) assert M[0][1]["weight"] == 2 assert M[1][2]["weight"] == 4 for n in M: assert M.nodes[n]["nedges"] == 1 assert M.nodes[n]["nnodes"] == 2 assert M.nodes[n]["density"] == 1
def test_weighted_path(self): G = nx.path_graph(6) for i in range(5): G[i][i + 1]['weight'] = i + 1 partition = [{0, 1}, {2, 3}, {4, 5}] M = nx.quotient_graph(G, partition, relabel=True) assert_equal(sorted(M), [0, 1, 2]) assert_equal(sorted(M.edges()), [(0, 1), (1, 2)]) assert_equal(M[0][1]['weight'], 2) assert_equal(M[1][2]['weight'], 4) for n in M: assert_equal(M.node[n]['nedges'], 1) assert_equal(M.node[n]['nnodes'], 2) assert_equal(M.node[n]['density'], 1)
def test_quotient_graph_edge_relation(self): """Tests for specifying an alternate edge relation for the quotient graph. """ G = nx.path_graph(5) identity = lambda u, v: u == v same_parity = lambda b, c: (arbitrary_element(b) % 2 == arbitrary_element(c) % 2) actual = nx.quotient_graph(G, identity, same_parity) expected = nx.Graph() expected.add_edges_from([(0, 2), (0, 4), (2, 4)]) expected.add_edge(1, 3) assert_true(nx.is_isomorphic(actual, expected))
def test_quotient_graph_complete_bipartite(self): """Tests that the quotient graph of the complete bipartite graph under the "same neighbors" node relation is `K_2`. """ G = nx.complete_bipartite_graph(2, 3) # Two nodes are equivalent if they are not adjacent but have the same # neighbor set. same_neighbors = lambda u, v: (u not in G[v] and v not in G[u] and G[u] == G[v]) expected = nx.complete_graph(2) actual = nx.quotient_graph(G, same_neighbors) # It won't take too long to run a graph isomorphism algorithm on such # small graphs. assert_true(nx.is_isomorphic(expected, actual))
def test_condensation_as_quotient(self): """This tests that the condensation of a graph can be viewed as the quotient graph under the "in the same connected component" equivalence relation. """ # This example graph comes from the file `test_strongly_connected.py`. G = nx.DiGraph() G.add_edges_from([(1, 2), (2, 3), (2, 11), (2, 12), (3, 4), (4, 3), (4, 5), (5, 6), (6, 5), (6, 7), (7, 8), (7, 9), (7, 10), (8, 9), (9, 7), (10, 6), (11, 2), (11, 4), (11, 6), (12, 6), (12, 11)]) scc = list(nx.strongly_connected_components(G)) C = nx.condensation(G, scc) component_of = C.graph['mapping'] # Two nodes are equivalent if they are in the same connected component. same_component = lambda u, v: component_of[u] == component_of[v] Q = nx.quotient_graph(G, same_component) assert_true(nx.is_isomorphic(C, Q))
for n, p in zip(list(range(len(G))), membership): partition[p].append(n) return list(partition.values()) if __name__ == '__main__': G = nx.read_edgelist("hartford_drug.edgelist") # Extract largest connected component into graph H H = next(nx.connected_component_subgraphs(G)) # Makes life easier to have consecutively labeled integer nodes H = nx.convert_node_labels_to_integers(H) # Create parititions with hierarchical clustering partitions = create_hc(H) # Build blockmodel graph BM = nx.quotient_graph(H, partitions, relabel=True) # Draw original graph pos = nx.spring_layout(H, iterations=100) plt.subplot(211) nx.draw(H, pos, with_labels=False, node_size=10) # Draw block model with weighted edges and nodes sized by number of internal nodes node_size = [BM.nodes[x]['nnodes'] * 10 for x in BM.nodes()] edge_width = [(2 * d['weight']) for (u, v, d) in BM.edges(data=True)] # Set positions to mean of positions of internal nodes from original graph posBM = {} for n in BM: xy = numpy.array([pos[u] for u in BM.nodes[n]['graph']]) posBM[n] = xy.mean(axis=0) plt.subplot(212)
def test_overlapping_blocks(self): G = nx.path_graph(6) partition = [{0, 1, 2}, {2, 3}, {4, 5}] nx.quotient_graph(G, partition)