如何在 Networkx 和 matplotlib 中标记多图的边缘?
How to label edges of a Multigraph in Networkx and matplotlib?
我有一个无向多重图,我想用标签绘制边缘,有什么建议吗?我遵循建议,但仍然没有边缘标签。
Drawing multiple edges between two nodes with networkx by atomh33ls
G=nx.MultiGraph ()
G.add_edge(1,2,weight=7)
G.add_edge(1,2,weight=2)
G.add_edge(1,2,weight=3)
G.add_edge(3,1,weight=2)
G.add_edge(3,2,weight=3)
node_label = nx.get_node_attributes(G,'id')
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, label=node_label)
nx.draw_networkx_labels(G, pos, label=node_label)
edge_labels=nx.get_edge_attributes(G,'weight')
ax = plt.gca()
for e in G.edges:
ax.annotate("",
xy=pos[e[0]], xycoords='data',
xytext=pos[e[1]], textcoords='data',
arrowprops=dict(arrowstyle="-", color="0.5",
shrinkA=5, shrinkB=5,
patchA=None, patchB=None,
connectionstyle="arc3,rad=rrr".replace('rrr',str(0.3*e[2])
),
),
)
#nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
plt.axis('off')
plt.show()
nx.get_edge_attributes
返回的字典具有结构(source, dest, enum):attr
,其中第三个字段仅枚举每条边的出现。第三个字段是必需的,因为键在字典中必须是唯一的。然而,这意味着它不能在 nx.draw_networkx_edge_labels
中使用,因为它需要一个 (source, dest):attr
结构化字典。
nx.get_edge_attributes(G,'weight')
# {(1, 2, 0): 7, (1, 2, 1): 2, (1, 2, 2): 3, (1, 3, 0): 2, (2, 3, 0): 3}
所以这在 MultiGraphs 上确实行不通。您 可以 做的事情,遵循与 , is to label
the edges with the weight values, and export the graph to dot
with nx.write_dot
相同的想法,这将在可视化中使用那些 labels
。
感谢@yatu。这是迄今为止标记的无向多图的优雅解决方案。
请给我更多改进风格的提示!
import networkx as nx
import matplotlib.pyplot as plt
from IPython.display import Image
G=nx.MultiGraph ()
G.add_edge(1,2,weight=1)
G.add_edge(1,2,weight=2)
G.add_edge(1,2,weight=3)
G.add_edge(3,1,weight=4)
G.add_edge(3,2,weight=5)
for edge in G.edges(data=True): edge[2]['label'] = edge[2]['weight']
node_label = nx.get_node_attributes(G,'id')
pos = nx.spring_layout(G)
node_label = nx.get_node_attributes(G,'id')
pos = nx.spring_layout(G)
p=nx.drawing.nx_pydot.to_pydot(G)
p.write_png('multi.png')
Image(filename='multi.png')
我有一个无向多重图,我想用标签绘制边缘,有什么建议吗?我遵循建议,但仍然没有边缘标签。 Drawing multiple edges between two nodes with networkx by atomh33ls
G=nx.MultiGraph ()
G.add_edge(1,2,weight=7)
G.add_edge(1,2,weight=2)
G.add_edge(1,2,weight=3)
G.add_edge(3,1,weight=2)
G.add_edge(3,2,weight=3)
node_label = nx.get_node_attributes(G,'id')
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, label=node_label)
nx.draw_networkx_labels(G, pos, label=node_label)
edge_labels=nx.get_edge_attributes(G,'weight')
ax = plt.gca()
for e in G.edges:
ax.annotate("",
xy=pos[e[0]], xycoords='data',
xytext=pos[e[1]], textcoords='data',
arrowprops=dict(arrowstyle="-", color="0.5",
shrinkA=5, shrinkB=5,
patchA=None, patchB=None,
connectionstyle="arc3,rad=rrr".replace('rrr',str(0.3*e[2])
),
),
)
#nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
plt.axis('off')
plt.show()
nx.get_edge_attributes
返回的字典具有结构(source, dest, enum):attr
,其中第三个字段仅枚举每条边的出现。第三个字段是必需的,因为键在字典中必须是唯一的。然而,这意味着它不能在 nx.draw_networkx_edge_labels
中使用,因为它需要一个 (source, dest):attr
结构化字典。
nx.get_edge_attributes(G,'weight')
# {(1, 2, 0): 7, (1, 2, 1): 2, (1, 2, 2): 3, (1, 3, 0): 2, (2, 3, 0): 3}
所以这在 MultiGraphs 上确实行不通。您 可以 做的事情,遵循与 label
the edges with the weight values, and export the graph to dot
with nx.write_dot
相同的想法,这将在可视化中使用那些 labels
。
感谢@yatu。这是迄今为止标记的无向多图的优雅解决方案。 请给我更多改进风格的提示!
import networkx as nx
import matplotlib.pyplot as plt
from IPython.display import Image
G=nx.MultiGraph ()
G.add_edge(1,2,weight=1)
G.add_edge(1,2,weight=2)
G.add_edge(1,2,weight=3)
G.add_edge(3,1,weight=4)
G.add_edge(3,2,weight=5)
for edge in G.edges(data=True): edge[2]['label'] = edge[2]['weight']
node_label = nx.get_node_attributes(G,'id')
pos = nx.spring_layout(G)
node_label = nx.get_node_attributes(G,'id')
pos = nx.spring_layout(G)
p=nx.drawing.nx_pydot.to_pydot(G)
p.write_png('multi.png')
Image(filename='multi.png')