首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用networkx绘制网络图,并询问Python中的父节点和子节点之间是否应该有连接?

如何使用networkx绘制网络图,并询问Python中的父节点和子节点之间是否应该有连接?
EN

Stack Overflow用户
提问于 2021-10-12 21:54:28
回答 2查看 117关注 0票数 0

我对用Python制作网络图完全是个新手。我了解到networkx库可以用来在Python语言中绘制网络图。

我有11个节点。Node1,Node2,...,Node11。我想把它们画在四个不同的层次上。Node1在1级。Node2和Node3在2级。Node4到Node7在level3中,Node8到Node11在4级。

我已经在level 1和level 2之间创建了一个非常简单的基本网络图,使用

代码语言:javascript
复制
# 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之间的连接应该基于用户输入。获取此网络图的合适方法是什么?有没有其他的库更适合这样做呢?

EN

回答 2

Stack Overflow用户

发布于 2021-10-13 01:07:54

基于堆栈溢出的其他问题:networkx add_node with specific position

您可以使用draw(..., pos=dictionary, ...)在特定位置设置节点。

代码语言:javascript
复制
positions = {
    'Node1': (0, 0),
    'Node2': (1, 1),
    'Node3': (1, -1),
    'Node4': (2, 2),
    'Node5': (2, 0),
}  

draw(..., pos=positions, ...)

最小工作代码

代码语言:javascript
复制
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, ...)分别更改每个节点的大小

代码语言:javascript
复制
nx.draw(G, pos=positions, arrows=True, with_labels=True, node_shape='s', node_size=1000)

结果:

基于文档,我发现你可以单独绘制nodeslabelsedges,这样你就可以为labes使用不同的位置,并将它们设置在节点之上。

代码语言:javascript
复制
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)

结果:

文档:

编辑:

最后一张图片的完整示例代码

代码语言:javascript
复制
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()
票数 3
EN

Stack Overflow用户

发布于 2021-10-13 20:06:04

furas已经回答了我问题的前半部分。对于第二部分,我使用for-loop创建了两个列表,以确定两个特定节点之间是否存在链接,并相应地更新了列表。使用该列表,我创建了一个包含FromTo列的数据帧,这两个列反映了从任何父节点到子节点的链接。

代码语言:javascript
复制
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
df
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69547451

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档