如何使用 Python 创建和可视化具有平行边和不同权重的有向加权图?

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

我正在开发一个项目,需要在 Python 中创建一个有向加权图,该图允许节点之间具有不同权重的平行边。我正在使用 networkx 库和

Matplotlib
进行可视化。

我的目标是:

  • 创建具有平行边(同一节点之间有多个边)的有向图。
  • 为这些边分配随机权重。
  • 可视化带有显示权重的边缘标签的图表。
import random
import networkx as nx
import matplotlib.pyplot as plt

def create_graph(n_nodes, alpha = 0.5):
    G = nx.MultiDiGraph()
    G.add_nodes_from(range(n_nodes))
    for i in range(n_nodes):
        for j in range(i+1,n_nodes):
            if random.random() < alpha:
                weight=random.randint(1,10)
                G.add_edge(i, j, weight=weight)

            if random.random() < alpha:
                weight=random.randint(1,10)
                G.add_edge(j, i, weight=weight)
    return G
  

def display_graph(G):
    pos = nx.spring_layout(G)  
    weight_labels = nx.get_edge_attributes(G, 'weight')  
    nx.draw(G, pos, with_labels=True, node_color='skyblue', edge_color='gray', node_size=700)
    nx.draw_networkx_edge_labels(G, pos, edge_labels=weight_labels)  
    plt.show()


n_nodes = 5
G = create_graph(n_nodes, alpha = 0.5)
display_graph(G)

但是,当我尝试使用边缘标签可视化图形时,我收到此错误消息:

networkx.exception.NetworkXError: draw_networkx_edge_labels does not support multiedges.

当我尝试显示 MultiDiGraph 的边缘标签时,会发生此错误,并且

draw_networkx_edge_labels
函数似乎不支持平行边缘。

  1. 如何解决此错误并正确可视化具有平行边的有向加权图?
  2. 是否有更好的方法在
    networkx
    中创建和可视化具有平行边的有向图?

如果有任何指导或示例可以帮助我实现这一目标,我将不胜感激。预先感谢您!

python networkx directed-graph graph-visualization weighted-graph
1个回答
0
投票

Networkx 绘图实用程序的一个核心问题是它们被分成不同的功能。对于标记多图边缘,确定边缘标签(

draw_networkx_edge_labels
)位置的函数需要了解边缘路径;然而,边缘路径是在
draw_networkx_edges
中计算的,并且两者之间没有串扰。

为了解决 Networkx 绘图实用程序的这个问题和其他设计问题,我编写了一个名为

Netgraph
的直接替代品。然而,多图支持是相当新的,因此您必须从 dev 分支安装(稳定版本通过 pip 和 conda-forge 分发):

pip install https://github.com/paulbrodersen/netgraph/archive/dev.zip

enter image description here

import random
import networkx as nx
import matplotlib.pyplot as plt

from netgraph import MultiGraph

def create_graph(n_nodes, alpha = 0.5):
    G = nx.MultiDiGraph()
    G.add_nodes_from(range(n_nodes))
    for i in range(n_nodes):
        for j in range(i+1,n_nodes):
            if random.random() < alpha:
                weight=random.randint(1,10)
                G.add_edge(i, j, weight=weight)

            if random.random() < alpha:
                weight=random.randint(1,10)
                G.add_edge(j, i, weight=weight)
    return G

G = create_graph(5)
MultiGraph(
    G,
    node_labels=True,
    node_color="skyblue",
    edge_color="gray",
    edge_labels=nx.get_edge_attributes(G, 'weight'),
    edge_label_fontdict=dict(fontsize=8),
    arrows=True,
)
plt.show()

© www.soinside.com 2019 - 2024. All rights reserved.