networkx 模块
package
本文字数:1.9k 字 | 阅读时长 ≈ 8 min

networkx 模块

package
本文字数:1.9k 字 | 阅读时长 ≈ 8 min

1. networkx 模块

NetworkX 是一个用 Python 语言开发的图论与复杂网络建模工具,内置了常用的图与网络分析算法,可以方便的进行复杂网络数据分析、仿真建模等工作,networkx 的相关文档可以在这里查阅,大量例子

安装 NetworkX: pip install networkx

2. 创建图

import networkx as nx

G = nx.Graph()  #创建空的无向图
G = nx.DiGraph()  #创建空的有向图

3. 图的节点

  1. 添加节点
  1. 添加节点的同时加入自定义属性
  1. 查看节点的属性
  1. 删除节点

下面对上面的节点操作做了一些例子

>>> import networkx as nx
>>> G = nx.Graph() 
>>> G.add_node(1, name='n1',weight=1)
>>> G.add_nodes_from([2,3,4], weight=1)
>>> G.nodes
NodeView((1, 2, 3, 4))
>>> G.nodes(data=True)
NodeDataView({1: {'name': 'n1', 'weight': 1}, 2: {'weight': 1}, 3: {'weight': 1}, 4: {'weight': 1}})
>>> G._node
{1: {'name': 'n1', 'weight': 1}, 2: {'weight': 1}, 3: {'weight': 1}, 4: {'weight': 1}}
>>> G.remove_node(1)
>>> G._node
{2: {'weight': 1}, 3: {'weight': 1}, 4: {'weight': 1}}

4. 图的边

图的边用于表示两个节点之间的关系,因此,边是由两个节点唯一确定的。在添加边时,如果顶点不存在,那么 networkx 会自动把相应的顶点加入到图中

  1. 添加边
  1. 添加边的同时加入自定义属性
  1. 添加边的权重G.add_weighted_edges_from([(1,3,0.75),(2,4,1.2)])
  2. 查看边的属性
  1. 删除边
>>> G = nx.Graph()
>>> G.add_edge(1, 2, weight=4.7, relationship='good')
>>> G.add_edges_from([(3,4,{'color':'blue'}), (1,4,{'weight':8})])
>>> G.add_weighted_edges_from([(1,3,0.75),(2,4,1.2)])
>>> G.edges()
EdgeView([(1, 2), (1, 4), (1, 3), (2, 4), (3, 4)])
>>> G.edges(data=True)
EdgeDataView([(1, 2, {'weight': 4.7, 'relationship': 'good'}), (1, 4, {'weight': 8}), (1, 3, {'weight': 0.75}), (2, 4, {'weight': 1.2}), (3, 4, {'color': 'blue'})])
>>> G.remove_edge(1,2)
>>> G.edges()
EdgeView([(1, 4), (1, 3), (2, 4), (3, 4)])

5. 绘制图

使用 networkx 模块 draw() 等相关函数构造 graph,使用 matplotlib 把图显示出来,draw 包括后面介绍的 draw_networkx draw_networkx_nodes draw_networkx_edges draw_networkx_labels 等函数,他们的功能存在一定的重合,但为什么还要分的这么清楚呢,因为虽然是重合,但是不同函数分别能够提供更多的绘图选项,例如节点和边的标签,节点的形状、边的宽度和颜色等等

  1. nx.draw 基本绘图函数
  1. nx.draw_networkx 高级绘图函数,提供更多绘图选项
  1. nx.draw_networkx_nodes 绘制网络图的节点
  1. nx.draw_networkx_edges 绘制网络图的边
  1. nx.draw_networkx_labels 绘制网络图的节点标签
  1. nx.draw_networkx_edge_labels 绘制网络图的边标签

下面给一个组合使用的例子,从例子中可以看出核心的绘图是这四个函数 nx.draw_networkx_nodes nx.draw_networkx_edges nx.draw_networkx_labels nx.draw_networkx_edge_labels,分别绘制 graph 的节点,边,节点的 label,边的 label

import networkx as nx
import matplotlib.pyplot as plt

# Create a graph
G = nx.Graph()
G.add_edges_from(
    [
        (0, 1, {"weight": 4}),
        (0, 7, {"weight": 8}),
        (1, 7, {"weight": 11}),
        (1, 2, {"weight": 8}),
        (2, 8, {"weight": 2}),
        (2, 5, {"weight": 4}),
        (2, 3, {"weight": 7}),
        (3, 4, {"weight": 9}),
        (3, 5, {"weight": 14}),
        (4, 5, {"weight": 10}),
        (5, 6, {"weight": 2}),
        (6, 8, {"weight": 6}),
        (7, 8, {"weight": 7}),
    ]
)

# Find the minimum spanning tree
T = nx.minimum_spanning_tree(G)

# Visualize the graph and the minimum spanning tree
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, node_color="lightblue", node_size=500)
nx.draw_networkx_edges(G, pos, edge_color="grey")
nx.draw_networkx_labels(G, pos, font_size=12, font_family="sans-serif")
nx.draw_networkx_edge_labels(
    G, pos, edge_labels={(u, v): d["weight"] for u, v, d in G.edges(data=True)}
)
nx.draw_networkx_edges(T, pos, edge_color="green", width=2)
plt.savefig('mst.png')
plt.show()
plt.close()

6. 其他图像的调整

  1. 边框不可见和充满画布
    设置图片没有边框,并且充满画布,不会显得很紧
ax = plt.gca()  # 获取当前的子图对象
ax.spines['top'].set_visible(False)  # 设置边框不可见
ax.spines['right'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['left'].set_visible(False)
plt.margins(0)  # 设置边距为0

效果如下,可以看到边框没了,并且图稍稍大了一点

  1. 字体不遮挡
    当节点的 label 过长时,就会存在着当现象,使用 adjustText 库将 label 的代码调整为如下就可以避免这种情况
nx.draw_networkx_labels(G, pos, font_size=8)
# 替换为
new_texts = []
for label, p in pos.items():
    new_texts.append(plt.text(p[0], p[1], label, fontsize=8))
adjust_text(new_texts)
  1. 图像更清晰
    直接设置 dpi 即可 plt.savefig("graph.png", dpi=300)
4月 06, 2025
3月 10, 2025
12月 31, 2024