繁体   English   中英

Networkx:绘制平行边

[英]Networkx: Drawing parallel edges

使用以下代码从数据框中绘制图形:

import pandas as pd
import networkx as nx

df = pd.DataFrame({'id_emp' : [13524791000109, 12053850000137, 4707821000113, 4707821000114, 1],
           'name_emp': ['Cristiano', 'Gaúcho', 'Fenômeno','Angelin', 'Souza'],
           'name_dep': ['Ronaldo','Ronaldo', 'Ronaldo', 'Ronaldo', 'Bruno'],
           'weight_1': [8,9,10,11,12],
           'weight_2':[5,6,7,8,9] })

 G = nx.MultiDiGraph()

 G.add_nodes_from(df['id_emp'], bipartite = 0)
 emp = [v for v in G.nodes if G.nodes[v]['bipartite'] == 0]

 G.add_nodes_from(df['name_dep'], bipartite = 1)
 dep = [v for v in G.nodes if G.nodes[v]['bipartite'] == 1]

 G.add_weighted_edges_from(df[['name_dep', 'id_emp', 'weight_1']].values)
 G.add_weighted_edges_from(df[['id_emp', 'name_dep', 'weight_2']].values)
 edge_width = [a[2]['weight']//2 for a in G.edges(data=True)]

 plt.figure(figsize=(5,5))

 pos = nx.spring_layout(G, k=0.9)
 nx.draw_networkx_nodes(G, pos, nodelist=dep, node_color='#bfbf7f', node_shape="h", node_size=300, with_labels = True)
 nx.draw_networkx_nodes(G, pos, nodelist=emp, node_color='red', node_size=300, with_labels = True)
 nx.draw_networkx_edges(G, pos, width=edge_width, alpha=0.2)

 plt.axis('off')
 plt.show()

输出:

在此处输入图片说明

在所示的示例中,每个顶点都有一个输入边和一个输出边,这将在两个顶点之间配置平行边。 然而,networkx 绘制的图的边彼此重叠,给人的印象是两个顶点之间只有一条边。 那么,如何配置 networkx 以使输出类似于下图?

在此处输入图片说明

Networkx 无法正确绘制平行边。 如果要绘制它们,则需要使用带有write_dot函数的 Graphviz (Agraph) 创建一个 DOT 文件,然后将其转换为图像:

nx.nx_agraph.write_dot(G, path_to_store_dot_file)

您还可以使用graphviz python 库。

sudo apt-get install graphviz
pip install graphviz

我在 Jupyter 笔记本上尝试过(本机支持)

import pandas as pd
import networkx as nx

df = pd.DataFrame({'id_emp' : [13524791000109, 12053850000137, 4707821000113, 4707821000114, 1],
           'name_emp': ['Cristiano', 'Gaúcho', 'Fenômeno','Angelin', 'Souza'],
           'name_dep': ['Ronaldo','Ronaldo', 'Ronaldo', 'Ronaldo', 'Bruno'],
           'weight_1': [8,9,10,11,12],
           'weight_2':[5,6,7,8,9] })

G = nx.MultiDiGraph()

G.add_nodes_from(df['id_emp'], bipartite = 0)
emp = [v for v in G.nodes if G.nodes[v]['bipartite'] == 0]

G.add_nodes_from(df['name_dep'], bipartite = 1)
dep = [v for v in G.nodes if G.nodes[v]['bipartite'] == 1]

G.add_weighted_edges_from(df[['name_dep', 'id_emp', 'weight_1']].values)
G.add_weighted_edges_from(df[['id_emp', 'name_dep', 'weight_2']].values)
edge_width = [a[2]['weight']//2 for a in G.edges(data=True)]

########################################################################
###########################CODE TO ADD##################################
########################################################################
import graphviz

d = graphviz.Digraph()

for n in dep:
    d.node(str(n), color="#bfbf7f")

for n in emp:
    d.node(str(n), color="red")

for e in G.edges:
    d.edge(str(e[0]), str(e[1]))

d.attr(size='8')

# To display the graph on Jupyter
d

显示:

在此处输入图片说明

我发现@AMangipinto 的答案不起作用(使用 nx 2.2 版):另一种方法是在之后直接使用 matplotlib 绘制边缘:

    import pandas as pd
import networkx as nx

df = pd.DataFrame({'id_emp' : [13524791000109, 12053850000137, 4707821000113, 4707821000114, 1],
           'name_emp': ['Cristiano', 'Gaúcho', 'Fenômeno','Angelin', 'Souza'],
           'name_dep': ['Ronaldo','Ronaldo', 'Ronaldo', 'Ronaldo', 'Bruno'],
           'weight_1': [8,9,10,11,12],
           'weight_2':[5,6,7,8,9] })

G = nx.MultiDiGraph()

G.add_nodes_from(df['id_emp'], bipartite = 0)
emp = [v for v in G.nodes if G.nodes[v]['bipartite'] == 0]
G.add_nodes_from(df['name_dep'], bipartite = 1)
dep = [v for v in G.nodes if G.nodes[v]['bipartite'] == 1]

G.add_weighted_edges_from(df[['name_dep', 'id_emp', 'weight_1']].values)
G.add_weighted_edges_from(df[['id_emp', 'name_dep', 'weight_2']].values)
edge_width = [a[2]['weight']//2 for a in G.edges(data=True)]

plt.figure(figsize=(5,5))

pos = nx.spring_layout(G, k=0.9)


nx.draw_networkx_nodes(G, pos, nodelist=dep, node_color='#bfbf7f', node_shape="h", node_size=300, with_labels = True)
nx.draw_networkx_nodes(G, pos, nodelist=emp, node_color='red', node_size=300, with_labels = True)
ax = plt.gca()
for edge in G.edges:
    ax.annotate("",
                xy=pos[edge[0]], xycoords='data',
                xytext=pos[edge[1]], textcoords='data',
                arrowprops=dict(arrowstyle="->", color="0.5",
                                shrinkA=5, shrinkB=5,
                                patchA=None, patchB=None,
                                connectionstyle="arc3,rad=-0.3",
                                ),
                )

plt.axis('off')
plt.show()

在此处输入图片说明

我还找到了解决此问题的更快方法。 这是将connectionstyle关键字添加到 nx.draw_networkx_nodes。

因此,特别是对于您的情况:

import pandas as pd
import networkx as nx

df = pd.DataFrame({'id_emp' : [13524791000109, 12053850000137, 4707821000113, 4707821000114, 1],
           'name_emp': ['Cristiano', 'Gaúcho', 'Fenômeno','Angelin', 'Souza'],
           'name_dep': ['Ronaldo','Ronaldo', 'Ronaldo', 'Ronaldo', 'Bruno'],
           'weight_1': [8,9,10,11,12],
           'weight_2':[5,6,7,8,9] })

G = nx.MultiDiGraph()

G.add_nodes_from(df['id_emp'], bipartite = 0)
emp = [v for v in G.nodes if G.nodes[v]['bipartite'] == 0]
G.add_nodes_from(df['name_dep'], bipartite = 1)
dep = [v for v in G.nodes if G.nodes[v]['bipartite'] == 1]

G.add_weighted_edges_from(df[['name_dep', 'id_emp', 'weight_1']].values)
G.add_weighted_edges_from(df[['id_emp', 'name_dep', 'weight_2']].values)
edge_width = [a[2]['weight']//2 for a in G.edges(data=True)]

plt.figure(figsize=(5,5))

pos = nx.spring_layout(G, k=0.9)

# Here there is the addition:

nx.draw_networkx_nodes(G, pos, connectionstyle='arc3, rad = 0.3', nodelist=dep, node_color='#bfbf7f', node_shape="h", node_size=300, with_labels = True)
nx.draw_networkx_nodes(G, pos, connectionstyle='arc3, rad = 0.3', nodelist=emp, node_color='red', node_size=300, with_labels = True)
nx.draw_networkx_edges(G, pos, connectionstyle='arc3, rad = 0.3', width=edge_width, alpha=0.2)

plt.axis('off')
plt.show()

在这里你可以看到它的样子:

平行边示例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM