在networkx中获取带有边标签、颜色和权重的复杂图,并逐步复制它

问题描述 投票:0回答:1

我有一个有序概念类别的数据集,我按照它们出现的顺序将它们绘制成图表,并根据节点之间的连接多次出现的时间来标注概念距离和厚度。

我在 networkx 中有一张由我制作的图表:

  1. 一次添加一条边;然后
  2. 将字典中的所有边缘信息添加到标签中;然后
  3. 将位置放在位置字典中的所有内容上

我花了很多时间才弄清楚如何正确绘制图表,但我现在对此很满意。 我的问题是我想获取一个完整的图 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

animation networkx
1个回答
0
投票

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 = ...
    
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.