使用以下代码从数据框中绘制图形:
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,使输出类似于下图?
答案 0 :(得分:2)
Networkx无法正确绘制平行边。如果要绘制它们,则需要使用带有write_dot函数的Graphviz(Agraph)创建DOT文件,并稍后将其转换为图像:
nx.nx_agraph.write_dot(G, path_to_store_dot_file)
答案 1 :(得分:1)
您还可以使用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
显示:
答案 2 :(得分:1)
我发现@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()
答案 3 :(得分:0)
我也找到了解决此问题的更快方法。这会将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()
在这里,您可以看到一张图片: