Currently networkx (version 2.2) doesn't support nested graphs in a way you can easily export and visualize. Consider using graphviz for handling your nested graph and export it to a dot format.
For working with a networkx version of the graph, you can transform the pygraphviz to a networkx graph and vise versa by keeping a 'graph' property for nodes (which is semantically a subgraph), similarly to the result of quotient_graph.
Here is an example of transforming a small networkx graph to pygraphviz with subgraphs, and exporting it as a dot file:
import networkx as nx
import pygraphviz as pgv
G = nx.erdos_renyi_graph(6, 0.5, directed=False)
node_list = [set([0, 1, 2, 3]), set([4, 5])]
pgv_G = pgv.AGraph(directed=True)
pgv_G.add_edges_from(G.edges())
for i, sub_graph in enumerate(node_list):
pgv_G.add_subgraph(sub_graph, name=str(i))
print(pgv_G)
pgv_G.write("test_pgv.dot")
Note that netwrokx also allows writing and reading 'dot' format (see example), however since there is no built-in support for nested graphs it's not too helpful for this purpose.
The reason you can't write the quotient_graph is twofold:
- In a
quotient_graph each node has a 'graph' property, which is a SubDiGraph (or a SubGraph, if the original graph is undirected). A SubDiGraph is a ReadOnlyGraph which means it is not possible to write it using the standard networkx.readwrite utils.
- Even if we convert the
SubDiGraph to a DiGraph, not every graph file format allows to encode a 'graph' property. For example, graphml format supports primitive properties such as booleans, integers etc. Read more here.
One solution that works is to solve the first issue by overriding the 'graph' property with a DiGraph copy of the original SubDiGraph. The second issue can be simply solved by using another file format (e.g., pickle format can work). Read about all supported formats here.
Following is a working example:
g_block = nx.quotient_graph(G=G, partition=node_list, relabel=True)
def subdigraph_to_digraph(subdigraph):
G = nx.DiGraph()
G.add_nodes_from(subdigraph.nodes())
G.add_edges_from(subdigraph.edges())
return G
for node in g_block:
g_block.nodes[node]['graph'] = subdigraph_to_digraph(g_block.nodes[node]['graph'])
nx.write_gpickle(g_block, "test_block.pickle")
This allows to write and load the nested graph for using with netwrokx, however for the purpose of using the exported file in a visualization tool this is not too helpful.