user136819
user136819

Reputation: 239

Python Networkx: How to "redraw" graph after every iteration?

I am trying to simulate addition and removal of nodes and edges based on some conditions in Networkx. I am using for loops for this and nx.MultiDiGraph().
A problem arises when I include the nx.draw() and pylab.show() methods in the loops. Although the graph/network is created without any problem in the first iteration, and then edges are added individually in the second, third ... so on iterations, the network does not "redraw" itself to show the removal of nodes and edges after an "Nth". Also, after the second iteration (when the edges are added), duplicate edges are created again between the same nodes and in the output these edges keep "darkening" after every iteration showing a sort of blotch on the edges and nodes in the output, which I do not desire.
How can I "redraw" the graph after every loop iteration? Also, how can I remove the duplicate edges and nodes that are created after these iterations?
Thanks in advance for the help. (Using Ubuntu 14.04 32-bit VM and Python 2.7)

UPDATE:

Here is an example snippet of the code as specified by Reti43 (I want to show the network changing like a "movie" - with reference to my original question. My question can be understood much clearer with this example code) -

import networkx as nx
import pylab
import matplotlib.pyplot as plt

from matplotlib.pyplot import pause
from matplotlib import pyplot
pylab.ion()

import warnings
warnings.filterwarnings("ignore")

g = nx.MultiDiGraph()

def node():

    for epoch in range(1,9):
        print '------ iteration %d ---------' % epoch
        for nod1 in range(1,7):
            g.add_node(nod1)
            #for nod2 in range(1,7):   # this is how I originally create the graph
                #g.add_edge(nod1,nod2) # ''

        if epoch > 1:
            g.add_edge(1,2)
            g.add_edge(2,3)
            g.add_edge(5,4)
            g.add_edge(4,6)
            print(g.nodes())
            print(g.edges())

        if epoch > 5:
            g.remove_node(5)
            g.remove_edge(1,2)
            g.remove_edge(4,6)

        nx.draw(g, pos=nx.circular_layout(g), with_labels=True)
        #pylab.draw()
        pause(1)
        pylab.show()
#        plt.show()

def main():

    print '--------- Simulation ---------'
    node()
    return 0

if __name__ == '__main__':
    main()

Upvotes: 1

Views: 3457

Answers (1)

Reti43
Reti43

Reputation: 9797

Adding the same edge twice in your graph object will insert a duplicate, which means it'll be considered twice for drawing, thereby increasing its thickness. You also have to call plt.clf() to clear the figure between steps, or else you'll get a superposition of everything drawn up to that point.

Regarding what edges to draw, you have two choices depending on how your program is set up.

1. You can add/remove edges only as necessary.

g = nx.MultiDiGraph()
g.add_nodes_from(range(1, 7))
pos = nx.circular_layout(g)

def node():
    for epoch in range(1, 9):
        if epoch == 2:
            g.add_edges_from([(1, 2), (2, 3), (5, 4), (4, 6)])
        if epoch == 6:
            g.remove_node(5)
            g.remove_edges_from([(1, 2), (4, 6)])

        plt.clf()
        plt.title('Iteration {}'.format(epoch))
        nx.draw(g, pos=pos, with_labels=True)
        plt.pause(1)
        plt.show()

You have to be careful here, because when you remove node 5, all edges related to that node are removed. So if you try to do remove.edge(5, 4) at the same time you'll get an error.

2. You can use the edgelist argument.

This states which edges will be drawn, even if they don't exist in your graph. Basically, when you have edgelist=None, the plot draws whatever is in g.edges.

def node():
    for epoch in range(1, 9):
        edges = []      
        if 1 < epoch <= 5:
            edges = [(1, 2), (2, 3), (5, 4), (4, 6)]
        elif epoch > 5:
            if 5 in g.nodes:
                g.remove_node(5)
            edges = [(2, 3)]

        plt.clf()
        plt.title('Iteration {}'.format(epoch))
        nx.draw(g, pos=pos, edgelist=edges, with_labels=True)
        plt.pause(1)
        plt.show()

Upvotes: 1

Related Questions