我对用Python制作网络图完全是个新手。我了解到networkx库可以用来在Python语言中绘制网络图。
我有11个节点。Node1,Node2,...,Node11。我想把它们画在四个不同的层次上。Node1在1级。Node2和Node3在2级。Node4到Node7在level3中,Node8到Node11在4级。
我已经在level 1和level 2之间创建了一个非常简单的基本网络图,使用
# Build a dataframe with 4 connections
df = pd.DataFrame({ 'from':['Node1',"Node1"], 'to':["Node2","Node3"]})
# Build your graph
G=nx.from_pandas_edgelist(df, 'from', 'to')
# Plot it
nx.draw(G, arrows = True, with_labels = True)
plt.show()它看起来像这样:

我想在同一方向上绘制Node2和Node3,分别在其上方和下方朝向Node1的右侧。是否也可以在节点中使用矩形而不是圆形,还可以在节点外部显示标签吗?
为了在level 2和level3之间绘制图形,我想问用户在Node2和Node3之间是否有边缘链接,其中Node4、Node5、Node6和Node7各有一个。另外,我想问用户在3级和4级的每个节点之间是否有边链路?
它应该如下所示,level 2和level 3以及level 3和level 4之间的连接应该基于用户输入。获取此网络图的合适方法是什么?有没有其他的库更适合这样做呢?

发布于 2021-10-13 01:07:54
基于堆栈溢出的其他问题:networkx add_node with specific position
您可以使用draw(..., pos=dictionary, ...)在特定位置设置节点。
positions = {
'Node1': (0, 0),
'Node2': (1, 1),
'Node3': (1, -1),
'Node4': (2, 2),
'Node5': (2, 0),
}
draw(..., pos=positions, ...)最小工作代码
import pandas as pd
import networkx as nx
from matplotlib import pyplot as plt
df = pd.DataFrame({
'from': ['Node1', 'Node1', 'Node2', 'Node2'],
'to': ['Node2', 'Node3', 'Node4', 'Node5']
})
G = nx.from_pandas_edgelist(df, 'from', 'to')
positions = {
'Node1': (0, 0),
'Node2': (1, 1),
'Node3': (1, -1),
'Node4': (2, 2),
'Node5': (2, 0),
}
nx.draw(G, pos=positions, arrows=True, with_labels=True)
plt.show()结果:

根据Stackoverflow上的其他答案-你可以像在matplotlib中一样使用node_shape来改变形状。我只找到了正方形- node_shape='s' -使用node_size=1000,我可以更改所有正方形的大小,或者使用列表/元组node_size=(1000, 1000, ...)分别更改每个节点的大小
nx.draw(G, pos=positions, arrows=True, with_labels=True, node_shape='s', node_size=1000)结果:

基于文档,我发现你可以单独绘制nodes,labels,edges,这样你就可以为labes使用不同的位置,并将它们设置在节点之上。
nodes_positions = {
'Node1': (0, 0),
'Node2': (1, 1),
'Node3': (1, -1),
'Node4': (2, 2),
'Node5': (2, 0),
}
labels_positions = {
'Node1': (0, 0.3),
'Node2': (1, 1.3),
'Node3': (1, -0.7),
'Node4': (2, 2.3),
'Node5': (2, 0.3),
}
nx.draw_networkx_nodes(G, pos=nodes_positions, node_shape='s', node_size=1000)
nx.draw_networkx_labels(G, pos=labels_positions)
nx.draw_networkx_edges(G, pos=nodes_positions)结果:

文档:
编辑:
最后一张图片的完整示例代码
import pandas as pd
import networkx as nx
from matplotlib import pyplot as plt
#df = pd.DataFrame({
# 'from': ['Node1', 'Node1', 'Node2', 'Node2'],
# 'to': ['Node2', 'Node3', 'Node4', 'Node5']
#})
df = pd.DataFrame([
# pairs (from, to)
('Node1', 'Node2'),
('Node1', 'Node3'),
('Node2', 'Node4'),
('Node2', 'Node5'),
], columns=['from', 'to'])
G = nx.from_pandas_edgelist(df, 'from', 'to')
nodes_positions = {
'Node1': (0, 0),
'Node2': (1, 1),
'Node3': (1, -1),
'Node4': (2, 2),
'Node5': (2, 0),
}
labels_positions = {
'Node1': (0, 0.3),
'Node2': (1, 1.3),
'Node3': (1, -0.7),
'Node4': (2, 2.3),
'Node5': (2, 0.3),
}
#nx.draw(G, pos=positions, arrows=True, with_labels=True, node_shape='s', node_size=1000)
nx.draw_networkx_nodes(G, pos=nodes_positions, node_shape='s', node_size=1000)
nx.draw_networkx_labels(G, pos=labels_positions)
nx.draw_networkx_edges(G, pos=nodes_positions)
plt.show()发布于 2021-10-13 20:06:04
furas已经回答了我问题的前半部分。对于第二部分,我使用for-loop创建了两个列表,以确定两个特定节点之间是否存在链接,并相应地更新了列表。使用该列表,我创建了一个包含From和To列的数据帧,这两个列反映了从任何父节点到子节点的链接。
a = ["Node1","Node1"]
b = ["Node2","Node3"]
#Ask if you want link between nodes 2 and 3, with each of node 4 to 7
for i in range(2,4):
for j in range(4,8):
edge = input(f"Edge between {i} and {j}?")
if edge == "Yes":
a.append(f"Node{i}")
b.append(f"Node{j}")
#Ask if you want link between nodes 4 and 7, with each of node 5 to 8
for i in range(4,8):
for j in range(8,12):
edge = input(f"Edge between {i} and {j}?")
if edge == "Yes":
a.append(f"Node{i}")
b.append(f"Node{j}")
#Create a dataframe using the lists a and b
df = pd.DataFrame([])
df["From"] = a
df["To"] = b
dfhttps://stackoverflow.com/questions/69547451
复制相似问题