0

I am tyring to animate a networkx graph growing over time. I have it working with curved edges and all. Quite pleased, BUT as the graph grows it slows down Considerably !? Can anyone explain or alter the code given to run faster. I don't think it's my computer that is the problem. NOTE: EVEN without the fancy curved edges it was very slow. A simple nx.draw would cause the same problem


import time
from matplotlib import pyplot as plt
from matplotlib import animation
import networkx as nx
from matplotlib.patches import FancyArrowPatch, Circle
import numpy as np

mainGraph = nx.DiGraph()
nodeToCoordinate_dict = {}
label_coordinatePositions = {}
edgeLabel_coordinatePositions = {}
edgeLabel_values_dict = {}
fig = plt.figure()


#=============================================================

def draw_network(G,pos,ax,sg=None):
    e = None
    for n in G:
        c=Circle(pos[n],radius=0.02,alpha=0.5)
        ax.add_patch(c)
        G.node[n]['patch']=c
        x,y=pos[n]
    seen={}
    for (u,v,d) in G.edges(data=True):
        n1=G.node[u]['patch']
        n2=G.node[v]['patch']
        rad=0.1
        if (u,v) in seen:
            rad=seen.get((u,v))
            rad=(rad+np.sign(rad)*0.1)*-1
        alpha=0.5
        color='k'

        e = FancyArrowPatch(n1.center,n2.center,patchA=n1,patchB=n2,
                            arrowstyle='-|>',
                            connectionstyle='arc3,rad=%s'%rad,
                            mutation_scale=10.0,
                            lw=2,
                            alpha=alpha,
                            color=color)
        seen[(u,v)]=rad
        ax.add_patch(e)

    return e


#========================================================

def animate(i):
    startTime = time.time()
    """perform animation step"""
    global mainGraph, nodeToCoordinate_dict, label_coordinatePositions            

    mainGraph.add_node(str(i%20)+","+str(i/20), pos = (i%20,i/20))
    if not (i%20 == 0):
        mainGraph.add_edge(str(i%20-1)+","+str(i/20), str(i%20)+","+str(i/20))           
        prevNode_coordinate = nodeToCoordinate_dict[str(i%20-1)+","+str(i/20)]

        mainGraph[str(i%20-1)+","+str(i/20)][str(i%20)+","+str(i/20)]['p'] = 1.0
    #END IF    
    nodeToCoordinate_dict[str(i%20)+","+str(i/20)] = (i%20,i/20)                            
    ax=plt.gca()
    draw_network(mainGraph,nodeToCoordinate_dict,ax)
    ax.autoscale()
    plt.axis('equal')
    plt.axis('off')         
    print("time Elapsed = ", time.time()-startTime)
    return None #mainGraph

#====================================================

ani = animation.FuncAnimation(fig, animate, frames= 60,interval=1000)
plt.show()
Ram
  • 158
  • 1
  • 16
  • sorry - when I copy and paste this, I get a plot showing a single node, and then lots of key errors. – Joel Jul 04 '17 at 22:19
  • @Joel that's strange, I copied the code above into a new, isolated script and it ran as expected. Do you have the imports needed ? Maybe an updated networkx and matplotlib. Also, please paste the most relevant error message and I might be able to figure out what your problem is – Ram Jul 05 '17 at 20:17

1 Answers1

0

I Think I figured it out. The function that uses "matplotlib.patches import FancyArrowPatch, Circle" is slowing it down. This is the "draw_network" function.

I tried replacing the drawing code with the simpler (nx.draw(mainGraph, nodeToCoordinate_dict)) and reduced the time interval to 100 (0.1 seconds). Worked like a charm

Now, I just need to figure a way of speeding up the graph with curved edges.

Ram
  • 158
  • 1
  • 16
  • Can you elaborate on how you fixed this? Even with small graphs fancy arrow patches in nx.draw_networkx_edges is incredibly slow. What is your faster alternative? – Reen Dec 12 '18 at 14:35