Search code examples
pythongraphnetworkxgraphvizdot

Storing networkx graph object with non-unique nodes as graphviz file


I want to store in graphviz file a networkx object that has non-unique nodes. I have created non-unique nodes in networkx using labels. But it's just able to display the nodes with non-unique labels.

G = nx.MultiDiGraph()
G.add_node(0)
G.add_node(1)
G.add_node(2)
labels = {0: 'a', 1: 'b', 2: 'a'}
pos=nx.spring_layout(G)
nx.draw_networkx_nodes(G,pos)
nx.draw_networkx_edges(G,pos)
nx.draw_networkx_labels(MG,pos,labels,font_size=16)

This gives return value of last statement and the output:


return value: {0: Text(-0.6135625730904766, -0.6074010681652476, 'a'),
 1: Text(0.9319946933900001, -0.3925989318347525, 'b'),
 2: Text(-0.31843212029952345, 1.0, 'a')}

networkx output

Is there a way to take this output from draw_networkx_labels and use it to create graphviz file. I need non-unique nodes in graphviz file output. I'm trying to do something like below:

x = nx.draw_networkx_labels(G,pos,labels,font_size=16)
write_dot(x, "dot.gv")
s = Source.from_file('dot.gv')
s.view()

This will throw error as nx.draw_networkx_labels does not return the object it prints above. If I just use G object, it will not use labels 'a' and 'b'. Also, is there a simpler way to create non-unique nodes in networkx?


Solution

  • You are confusing nodes with node labels. It doesn't make sense to add duplicate nodes in a graph. However, you can add non-unique labels to existing nodes of in a Graph.

    Take a look at this code:

    import networkx as nx
    
    G = nx.MultiDiGraph()
    G.add_nodes_from(list(range(5)))
    
    labels = {
        0: 'a',
        1: 'b',
        2: 'a',
        3: 'c',
        4: 'd'}
    
    G.add_edge(0, 1)
    G.add_edge(2, 1)
    G.add_edge(3, 2)
    G.add_edge(3, 4)
    
    # Add the labels as a separate attribute in each node
    nx.set_node_attributes(G, labels, 'label')
    
    pos=nx.spring_layout(G)
    nx.draw_networkx_nodes(G,pos)
    nx.draw_networkx_edges(G,pos)
    nx.draw_networkx_labels(G,pos,labels,font_size=16)
    

    enter image description here

    Now coming to saving the graph in a graphviz file format:

    from networkx.drawing.nx_agraph import write_dot
    from graphviz import Source
    
    write_dot(G, "dot.gv")
    Source.from_file('dot.gv')
    

    enter image description here

    As you can see as per your question, the label names are preserved. You can further read the pygraphviz documentation to further manipulate the graph you have obtained.

    References:

    You can check out this Google Colab notebook for the code shown above.