Ahmad Esmaeili
Ahmad Esmaeili

Reputation: 105

Smooth animation of a network using networkx and matplotlib

I am trying to animate the layout changes of a networks graph. My test code is as follows:

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import networkx as nx
import random
import numpy as np

fig = plt.figure()

node_number = 0
G =nx.Graph()
G.add_node(node_number, Position=np.asarray([random.randrange(0,100), random.randrange(0,100)]))

while True:
    if node_number < 50:
        node_number += 1
        G.add_node(node_number, Position=np.asarray([random.randrange(0,100), random.randrange(0,100)]))
        ns=list(G.nodes())
        ns.remove(node_number)
        G.add_edge(node_number, random.choice(ns))
    else:
        break

source_pos = list(nx.get_node_attributes(G, 'Position').values())
target_pos = list(nx.circular_layout(G).values())
def anim(t):
    global source_pos
    global target_pos
    interpolation = np.asarray(source_pos)*(1-t) + np.asarray(target_pos)*t
    plt.clf()
    plt.cla()
    nx.draw(G, pos=interpolation)
    ax= plt.gca()
    ax.collections[0].set_edgecolor("#000000")

ani = animation.FuncAnimation(fig, anim, repeat=False, frames=300, interval=20)
plt.show()

The code generates a weird transition no matter how I adjust the intervals or frames of the animation. I am attaching the output for the above code. Could anyone please help me with the mistake I am making?

enter image description here

Upvotes: 2

Views: 795

Answers (1)

david
david

Reputation: 1501

When you pass t at the anim function, you pass a frame number so that you have to divide it by frames count in this line:

interpolation = np.asarray(source_pos)*(1-t/299) + np.asarray(target_pos)*t/299

(since frames count is 300: 0 to 299)

Additionaly, you could use while node_number < 50: and remove test part instead of while True

EDIT So I use random.random() to get a random position between -1 and 1. The animation is far better.

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import networkx as nx
import random
import numpy as np

fig = plt.figure()

G =nx.Graph()
node_number = 0
while node_number < 50:
        G.add_node(node_number,
                   Position=np.asarray([random.random() * 2 -1,
                                        random.random() * 2 -1]))
        ns=list(G.nodes())
        G.add_edge(node_number, random.choice(ns))
        node_number += 1


s_pos = nx.get_node_attributes(G, 'Position')
t_pos = nx.circular_layout(G)


def anim(t):
    global s_pos
    global t_pos
    interpolation = {i: s_pos[i]*(1-t/299) + t_pos[i] * t/299  for i in range(50)}
    plt.clf()
    plt.cla()
    nx.draw(G, pos=interpolation)


ani = animation.FuncAnimation(fig, anim, repeat=False, frames=300, interval=20)
plt.show()

Upvotes: 1

Related Questions