Using NetworkX with matplotlib.ArtistAnimation
What I want to do is create an animation in which the nodes of a graph change color with time. When I search for information on animation in matplotlib, I usually see examples that look something like this:
#!/usr/bin/python
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.animation import ArtistAnimation
fig = plt.figure(figsize=(8,8))
images = []
for i in range(10):
data = np.random.random(100).reshape(10,10)
imgplot = plt.imshow(data)
images.append([imgplot])
anim = ArtistAnimation(fig, images, interval=50, blit=True)
anim.save('this-one-works.mp4')
plt.show()
So I thought I could just do something like this:
#!/usr/bin/python
import numpy as np
import networkx as nx
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.animation import ArtistAnimation
G = nx.Graph()
G.add_edges_from([(0,1),(1,2),(2,0)])
fig = plt.figure(figsize=(8,8))
pos=nx.graphviz_layout(G)
images = []
for i in range(10):
nc = np.random.random(3)
imgplot = nx.draw(G,pos,with_labels=False,node_color=nc) # this doesn't work
images.append([imgplot])
anim = ArtistAnimation(fig, images, interval=50, blit=True)
anim.save('not-this-one.mp4')
plt.show()
What I'm stuck on is how, after drawing the graph using nx.draw(), I can get an object of the appropriate type to put in the array being passed to ArtistAnimation. In the first example, plt.imshow() returns an object of type matplot.image.AxesImage, but nx.draw() doesn't actually return anything. Is there a way that I can get my hands on a suitable image object?
Completely different approaches are welcome, of course (it seems like there's always many different ways to do the same thing in matplotlib), as long as I can save my animation as an mp4 when I'm done.
Thanks!
--craig
import numpy as np
import networkx as nx
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
G = nx.Graph()
G.add_edges_from([(0,1),(1,2),(2,0)])
fig = plt.figure(figsize=(8,8))
pos=nx.graphviz_layout(G)
nc = np.random.random(3)
nodes = nx.draw_networkx_nodes(G,pos,node_color=nc)
edges = nx.draw_networkx_edges(G,pos)
def update(n):
nc = np.random.random(3)
nodes.set_array(nc)
return nodes,
anim = FuncAnimation(fig, update, interval=50, blit=True)
nx.draw
does not return anything, hence why your method didn't work. The easiest way to do this is to draw the nodes
and edges
using nx.draw_networkx_nodes
and nx.draw_networkx_edges
which return PatchCollection
and LineCollection
objects. You can then update the color of the nodes using set_array
.
Using the same general frame work you can also move the nodes around (via set_offsets
for the PatchCollection
and set_verts
or set_segments
for LineCollection
)
best animation tutorial I have seen: http://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/