我正在开发一个项目,需要在 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
函数似乎不支持平行边缘。
networkx
中创建和可视化具有平行边的有向图?如果有任何指导或示例可以帮助我实现这一目标,我将不胜感激。预先感谢您!
Networkx 绘图实用程序的一个核心问题是它们被分成不同的功能。对于标记多图边缘,确定边缘标签(
draw_networkx_edge_labels
)位置的函数需要了解边缘路径;然而,边缘路径是在 draw_networkx_edges
中计算的,并且两者之间没有串扰。
为了解决 Networkx 绘图实用程序的这个问题和其他设计问题,我编写了一个名为
Netgraph
的直接替代品。然而,多图支持是相当新的,因此您必须从 dev 分支安装(稳定版本通过 pip 和 conda-forge 分发):
pip install https://github.com/paulbrodersen/netgraph/archive/dev.zip
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()