使用 NetworkX 和 Matplotlib 动画网络增长
Posted
技术标签:
【中文标题】使用 NetworkX 和 Matplotlib 动画网络增长【英文标题】:Animating Network Growth with NetworkX and Matplotlib 【发布时间】:2012-11-06 09:35:56 【问题描述】:我想制作一个随时间增长的图表。
这是我目前所拥有的:
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()
但是,我收到以下错误消息:
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/
我想要的是一个动画,你可以在其中看到图形的增长。我可以在每个阶段保存图表,也许可以在 matplotlib 之外创建动画,但是有什么办法让它像这样工作吗?
【问题讨论】:
你的后端是什么?我遇到了一些后端的动画问题。你能运行matplotlib的basic_example.py吗? 是的,这对我来说非常适合。至于后端,我只是在ubuntu,python 2.7,numpy,scipy,networkx和matplotlib上......都是最近几天安装的,所以它们是最新版本......我基本上是个学生,正在尝试一些实验,对这些图表进行动画处理真的很有帮助,所以我可以看到它们是如何成长的! 我对networkx不熟悉。也许问题是ArtistAnimation
需要一个 matplotlib 艺术家而不是一个 nx 对象?
更新了我的答案,希望对你有帮助。
【参考方案1】:
经过审查,该代码与我想象的这个问题的相关性并不高。但是,我可以使用this SO answer 和this SO answer 为您拼凑出答案。下面的代码将创建一个图形,向其中添加 50 个随机节点和 50 个随机边,并在添加每个节点和边后显示图形的图像。代码中的一些关键更改:
-
此代码基于使用
pylab.ion()
(有关详细信息,请参阅 here)。
您的代码尝试使用一个图形并更改其中的图像。此代码为每一帧创建一个新图形。
此代码不会写入 .mp4。如果您确实需要这样做,我建议您在渲染时将这些数字写入 .png 文件,然后再转换为 mp4。
请注意,此代码使用matplotlib.pyplot.pause()
而不是time.sleep()
。如果您使用time.sleep()
,这些数字将不会呈现。
祝你好运!
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)
【讨论】:
很抱歉耽搁了,不管怎样,你的建议让我想到了,这是我首先做的,我绘制了图表并存储了单独的 png,然后在外面将它们拼接在一起......我也用 ion 做了一个实现,唯一的问题是我不能将这些保存为 gif 文件,但它很酷,因为你可以看到运行时的变化 谢谢!我打算尝试使用 matplotlib.animation.FuncAnimation 的替代解决方案(有关更多信息,请参阅matplotlib.org/api/animation_api.html),但我只是没有时间。 @Skyler 这段代码已经很老了,库已经进化了。一个简单的解决方法是使用random.choice(list(graph.nodes()))
而不是random.choice(graph.nodes())
。我刚刚添加了一个新的答案,说明代码现在的样子。【参考方案2】:
brtlance 的改进版本。希望它会有所帮助。它会显示动画,但不会显示一张接一张的照片。
还是不知道题主如何 Animate drawing networkx edges 利用matplotlib的动画
#!/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)
【讨论】:
正是我想要的。一幅画到另一幅画之间的过渡很好。减少暂停可以提供流畅的动画。谢谢。 :)【参考方案3】:由于现有答案已经很老了,这里有一个版本的代码在当前版本的 matplotlib 和 networkx 下的样子。
import random
import networkx as nx
import matplotlib.pyplot as plt
graph = nx.Graph()
num_plots = 50
for node_number in range(num_plots):
graph.add_node(node_number, Position=(random.randrange(0, 100), random.randrange(0, 100)))
graph.add_edge(node_number, random.choice(list(graph.nodes())))
nx.draw(graph, pos=nx.get_node_attributes(graph,'Position'))
plt.pause(0.5)
【讨论】:
以上是关于使用 NetworkX 和 Matplotlib 动画网络增长的主要内容,如果未能解决你的问题,请参考以下文章
Networkx 和 Matplotlib:如何访问节点属性并将它们显示为注释
节点的 Networkx 和 matplotlib 颜色图;不同网络的相同地图