我有一个有序概念类别的数据集,我按照它们出现的顺序将它们绘制成图表,并根据节点之间的连接多次出现的时间来标注概念距离和厚度。
我在 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 调整轴数据限制的大小以适应每次绘制时的绘图元素。当您扩展图表时,数据限制正在发生变化,给人的印象是图表元素在“跳跃”。
最简单的解决方法是在每次更新结束时强制执行恒定的数据限制:
...
xy = np.array(positions.values())
xmin, ymin = np.min(xy, axis=0)
xmax, ymax = np.max(xy, axis=0)
pad_by = 0.05 # may need adjusting
pad_x, pad_y = pad_by * np.ptp(xy, axis=0)
def update_graph(num):
...
ax.set_xlim(xmin - pad_x, xmax + pad_x)
ax.set_ylim(ymin - pad_y, ymax + pad_y)
ax.set_aspect("equal")
ani = ...