在使用matplotlib的FuncAnimation
,其文档及其示例进行了2天的努力后,我仍然对如何解决以下内容毫无头绪:
我想要为动画做的是绘制一个图形,其中节点相对于嵌套列表子集的某些条目的总和着色。然后进一步移动子集的范围(不包括第一个列表,在末尾添加另一个列表)并使用根据新子集着色的节点重绘图形。
这是一个最小的运行示例:
# graph
import networkx as nx
G=nx.Graph()
G.add_node(0)
G.add_node(1)
# list
from random import randint
l=[]
[l.append([randint(0,9),randint(0,9)]) for i in range(10)]
#functions for animation
def single_frame(dummy,interval,G,max_inv,ax):
"""plots a frame of the investment in given interval,
as interval a sniplet of self.l is expected"""
import networkx as nx
inv_into_node=[]
for i in range(len(interval[0])): inv_into_node.append([])
for i in interval:
[inv_into_node[k].append(x) for k,x in enumerate(i)]
sum_inv=[sum(x) for x in inv_into_node]
col_list=[]
for i in sum_inv:
col_list.append([1-i/float(max_inv),1-i/float(max_inv),1])
nx.draw_networkx(G,single_frame.pos,ax=ax,node_color=col_list,with_labels=True)
ax.axis('off')
return ax.get_children()
#this one produces the input list for the upper
def int_update():
interval=int_update.i
if int_update.counter:
interval=interval[1:]
interval.append(int_update.data[int_update.counter-1])
int_update.i=interval
int_update.counter+=1
return interval
#animation
import matplotlib.animation as ani
import matplotlib.pyplot as plt
int_update.counter=0
int_update.i=[[9,9],[9,9]]
int_update.data=l
single_frame.pos=nx.graphviz_layout(G)
fig,ax=plt.subplots()
#import pdb;pdb.set_trace()
movie = ani.FuncAnimation(fig, single_frame,frames=9,fargs=(int_update(),G,20,ax))
movie.save('whatever.mp4')
现在有几个问题:
保存的电影显示节点,但它们具有初始步骤的颜色且不会更改
我在return语句中添加的内容并不重要:ax
,ax.get_children()
或者根本没有任何内容。我还试图在single_frame
函数内生成轴对象,然后将其作为输出返回,这导致返回一个空白电影。
所以我的第一个问题是为什么它不起作用,我怎样才能让它起作用?第二个是FuncAnimation
期望作为函数输出的东西?我认为它应该采取函数返回的任何内容并将其放入fig
,这将提供给FuncAnimation
调用。但事实显然并非如此......
感谢帮助!
编辑:感谢评论,我解决了问题,只是为了完整性,低于上层代码的运行版本# graph
import networkx as nx
G=nx.Graph()
G.add_node(0)
G.add_node(1)
# list
from random import randint
l=[]
[l.append([randint(0,9),randint(0,9)]) for i in range(10)]
#functions for animation
def color_list(interval):
"""updating func"""
# def rgb_to_hex(rgb):
# return '#%02x%02x%02x' % rgb
#calculate color
inv_into_node=[]
for i in range(len(interval[0])): inv_into_node.append([])
for i in interval:
[inv_into_node[k].append(x) for k,x in enumerate(i)]
sum_inv=[sum(x) for x in inv_into_node]
col_list=[]
for i in sum_inv:
col_list.append((1-i/float(20),1-i/float(20),1))
return col_list
def int_update():
interval=int_update.i
if int_update.counter:
interval=interval[1:]
interval.append(int_update.data[int_update.counter])
int_update.i=interval
int_update.counter+=1
return interval
def update(n):
col_list=color_list(int_update())
nodes.set_facecolor(col_list)
return nodes,
int_update.counter=0
int_update.i=[[0,0],[0,0]]
int_update.data=l
#animation
import matplotlib.animation as ani
import matplotlib.pyplot as plt
fig=plt.figure()
pos=nx.graphviz_layout(G)
nodes = nx.draw_networkx_nodes(G,pos,node_color=color_list([[0,0],[0,0]]))
edges = nx.draw_networkx_edges(G,pos)
labs=nx.draw_networkx_labels(G,pos)
#import pdb;pdb.set_trace()
movie = ani.FuncAnimation(fig, update,frames=len(l)-1)
movie.save('kex.mp4')