I would like to animate a graph that grows over time.
This is what I have so far:
fig = plt.figure()
ims = []
graph = nx.Graph()
for i in range(50):
// Code to modify Graph
nx.draw(graph, pos=nx.get_node_attributes(graph,'Position'))
im = plt.draw()
self.ims.append([im])
ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True,repeat_delay=1000)
ani.save('dynamic_images.mp4')
plt.show()
However, I get the following error message:
File "main.py", line 204, in <module>
repeat_delay=1000)
File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 356, in __init__
TimedAnimation.__init__(self, fig, *args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 304, in __init__
Animation.__init__(self, fig, event_source=event_source, *args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 53, in __init__
self._init_draw()
File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 363, in _init_draw
artist.set_visible(False)
AttributeError: 'NoneType' object has no attribute 'set_visible'
nicomoto@nicomoto-VirtualBox:~/Desktop/CS8903-SpecialProblem/Code/
What I want is an animation, where you can see the graph growing. I can save the graph at each stage, and might be able to create an animation outside matplotlib, but is there any way of getting it work like this?
Upon review, that code wasn't nearly as relevant to this problem as I'd thought. However, I was able to use this SO answer and this SO answer to cobble together an answer for you. Here's code that will create a graph, add 50 random nodes and 50 random edges to it, and display an image of the graph after every node and edge is added. A few of the key changes from your code:
- This code is based on using
pylab.ion()
(see here for more info).
- Your code tries to use one figure and change the image within it. This code creates a new figure for each frame.
- This code doesn't write out to .mp4. If you really need to do that, I would suggest writing the figures out to .png file while rendering them, and converting to mp4 after the fact.
- Note that this code uses
matplotlib.pyplot.pause()
instead of time.sleep()
. The figures won't render if you use time.sleep()
.
Good luck!
import random
import pylab
from matplotlib.pyplot import pause
import networkx as nx
pylab.ion()
graph = nx.Graph()
node_number = 0
graph.add_node(node_number, Position=(random.randrange(0, 100), random.randrange(0, 100)))
def get_fig():
global node_number
node_number += 1
graph.add_node(node_number, Position=(random.randrange(0, 100), random.randrange(0, 100)))
graph.add_edge(node_number, random.choice(graph.nodes()))
fig = pylab.figure()
nx.draw(graph, pos=nx.get_node_attributes(graph,'Position'))
return fig
num_plots = 50;
pylab.show()
for i in range(num_plots):
fig = get_fig()
fig.canvas.draw()
pylab.draw()
pause(2)
pylab.close(fig)
An improved version of bretlance's. Hope it will be helpful. It will show animations but not picture after picture.
Still don't know how the owner of the question
Animate drawing networkx edges
made use of matplotlib's animation
#!/usr/bin/env python
import random
import pylab
from matplotlib.pyplot import pause
import networkx as nx
pylab.ion()
graph = nx.Graph()
node_number = 0
graph.add_node(node_number, Position=(random.randrange(0, 100), random.randrange(0, 100)))
def get_fig():
global node_number
node_number += 1
graph.add_node(node_number, Position=(random.randrange(0, 100), random.randrange(0, 100)))
graph.add_edge(node_number, random.choice(graph.nodes()))
nx.draw(graph, pos=nx.get_node_attributes(graph,'Position'))
num_plots = 50;
pylab.show()
for i in range(num_plots):
get_fig()
pylab.draw()
pause(2)