我有一个有序概念类别的数据集,并按照它们出现的顺序绘制图形,并根据节点之间连接多次发生的时间来标记概念距离和厚度。
我在 networkx 中有一个由以下方式生成的图表:
- 一次添加一条边;然后
- 将字典中的所有边缘信息添加到标签中;然后
- 根据位置词典将位置应用到所有事物上
我花了很长时间才弄清楚如何制作正确的图表,但现在我对它很满意。我的问题是我想采用完整的图表 G 并一次复制一条边,这样我就可以随时制作动画。
这是我所做的,但它非常容易出错,因为标签出现在边缘之前。有什么想法可以正确做到这一点吗?
###############################################
# Doing the bit where we output the video of the graph being constructed
# Create an empty directed graph for animation
positions = pos_dic
G_animated = nx.DiGraph()
# Initialize figure and axis for animation
fig, ax = plt.subplots(figsize=(20, 12))
plt.title(f'Graph for {key} at {timestamp}',font)
# Step 2: Extract the edges, colors, weights, and labels from the original graph
edges = list(G.edges(data=True))
edge_colors = [attr['color'] for u, v, attr in edges]
edge_weights = [attr['weight'] for u, v, attr in edges]
edge_labels = {(u, v): attr['label'] for u, v, attr in edges}
# Step 3: Function to update the graph step by step
def update_graph(num):
ax.clear() # Clear the plot for the next frame
if num < len(edges):
u, v, attr = edges[num]
# Add the nodes if they don't exist yet in G_animated
if u not in G_animated.nodes:
G_animated.add_node(u)
if v not in G_animated.nodes:
G_animated.add_node(v)
# Now, add the edge with the attributes
G_animated.add_edge(u, v, **attr)
# Draw the updated graph with custom positions
edge_color_list = [edge_colors[i] for i in range(len(G_animated.edges))]
nx.draw(G_animated, pos=positions, ax=ax, with_labels=False, node_color='lightblue',
edge_color=edge_color_list, width=edge_weights[:len(G_animated.edges)],
node_size=500, arrows=True)
nx.draw_networkx_labels(G_animated, pos_dic, font_size=11, font_color='black', font_weight='bold', bbox=dict(facecolor='white', edgecolor='black', boxstyle='round,pad=0.3'))
# Draw edge labels (showing the label attributes)
nx.draw_networkx_edge_labels(G_animated, pos=positions, edge_labels=edge_labels)
# Step 4: Create animation object
ani = FuncAnimation(fig, update_graph, frames=len(edges), repeat=False, interval=3000)
# Step 5: Save the animation as a video (e.g., .mp4)
writer = FFMpegWriter(fps=1, metadata=dict(artist='Nick Kelly'), bitrate=1800)
ani.save(f"graph_animation_{key}.mp4", writer=writer)
# plt.show()
plt.close()
# End video here
##################################################
这会产生非常故障的动画,请参阅此文件作为示例:https ://1drv.ms/v/s!AuaSDysD-RqIhOsFSP6pYZCUmvDYvQ?e=iz2k8L
Networkx 调整轴数据限制的大小以适合每次绘制的绘图元素。当您扩展图形时,数据限制会发生变化,给人一种图形元素“跳跃”的印象。
最简单的解决方法是在每次更新结束时强制执行恒定的数据限制: