networkx 是一个强大的图论库,而 matplotlib 是 Python 最常用的绘图库。networkx 主要负责创建和操作图结构(节点和边),而 matplotlib 则负责将这些结构可视化。

安装必要的库
确保你已经安装了 networkx 和 matplotlib,如果还没有安装,可以通过 pip 进行安装:
pip install networkx matplotlib
基本绘图流程
使用 networkx 画图的基本流程非常简单,通常分为三步:
- 创建图: 创建一个
Graph对象(无向图)或DiGraph对象(有向图)。 - 添加节点和边: 向图中添加代表实体的节点和代表实体间关系的边。
- 绘制图形: 使用
networkx的draw()函数,结合matplotlib将图画出来。
示例:从简单到复杂
示例 1:最简单的无向图
这是一个最基础的例子,展示如何创建一个包含 3 个节点和 2 条边的图。
import networkx as nx
import matplotlib.pyplot as plt
# 1. 创建一个空的无向图
G = nx.Graph()
# 2. 添加节点和边
# 可以一个一个添加
G.add_node("A")
G.add_node("B")
G.add_node("C")
G.add_edge("A", "B")
G.add_edge("B", "C")
# 也可以一次性添加
# G.add_nodes_from(["A", "B", "C"])
# G.add_edges_from([("A", "B"), ("B", "C")])
# 3. 绘制图形
nx.draw(G, with_labels=True)
# 显示图形
plt.show()
代码解释:

nx.Graph(): 创建一个无向图。G.add_node(): 添加一个节点。G.add_edge(): 添加一条边,如果节点不存在,会自动创建。nx.draw(): 核心绘图函数,with_labels=True表示在节点上显示标签。plt.show(): 显示matplotlib生成的图像窗口。
运行这段代码,你会得到一个非常简单的图形:
示例 2:有向图和带权重的图
我们画一个有向图,并且边带有权重(距离或成本)。
import networkx as nx
import matplotlib.pyplot as plt
# 1. 创建一个有向图
G = nx.DiGraph()
# 2. 添加带权重的边
# 在添加边时,可以通过第三个参数传入权重
G.add_edge("X", "Y", weight=8)
G.add_edge("Y", "Z", weight=3)
G.add_edge("X", "Z", weight=2)
# 3. 绘制图形
# 使用不同的布局算法
pos = nx.spring_layout(G, seed=42) # spring_layout 是一种常用的布局,seed保证每次运行结果一致
# 绘制节点
nx.draw_networkx_nodes(G, pos, node_size=700)
# 绘制边
nx.draw_networkx_edges(G, pos, edgelist=G.edges(), arrowstyle='->', arrowsize=20)
# 绘制节点标签
nx.draw_networkx_labels(G, pos)
# 绘制边的权重标签
edge_labels = nx.get_edge_attributes(G, 'weight')
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
# 设置图形标题和显示"带权重的有向图")
plt.axis('off') # 关闭坐标轴
plt.show()
代码解释:
nx.DiGraph(): 创建一个有向图。G.add_edge("X", "Y", weight=8): 添加一条从 X 到 Y 的有向边,并设置其权重为 8。nx.spring_layout(G, seed=42): 为图节点计算一个布局位置。spring_layout是一种基于物理模拟的布局,看起来比较自然。seed参数确保每次运行代码时,节点的位置是固定的,便于对比。nx.draw_networkx_nodes(): 只绘制节点。nx.draw_networkx_edges(): 只绘制边,arrowstyle='->'让箭头显示出来。nx.draw_networkx_labels(): 只绘制节点标签。nx.get_edge_attributes(G, 'weight'): 获取所有边的权重属性。nx.draw_networkx_edge_labels(): 绘制边的权重标签。plt.axis('off'): 隐藏不必要的坐标轴。
运行结果:
nx.draw() 的常用参数
nx.draw() 函数本身非常强大,它内部集成了多种绘图元素,直接使用它可以快速出图,但为了美观和清晰,通常会拆分成多个函数调用,下面是 nx.draw() 的一些常用参数:
| 参数 | 说明 |
|---|---|
G |
要绘制的图对象。 |
pos |
节点位置的字典,格式为 {node: (x, y)},如果不提供,networkx 会自动选择一种布局。 |
with_labels |
是否在节点上显示标签。 |
node_size |
节点的大小,可以是一个数值或一个列表(为每个节点指定不同大小)。 |
node_color |
节点的颜色,可以是一个颜色名称、颜色代码或列表。 |
font_size |
节点标签的字体大小。 |
font_color |
节点标签的字体颜色。 |
width |
边的宽度。 |
edge_color |
边的颜色。 |
style |
边的样式,如 'solid', 'dashed', 'dotted'。 |
alpha |
透明度,0.0(完全透明)到 1.0(完全不透明)。 |
示例:使用 nx.draw() 参数
import networkx as nx
import matplotlib.pyplot as plt
G = nx.karate_club_graph() # networkx 内置的一个经典社交网络图
# 使用 nx.draw 的多种参数进行自定义绘制
nx.draw(
G,
with_labels=True,
node_size=800, # 节点更大
node_color="skyblue", # 节点颜色
font_size=10, # 字体大小
font_weight="bold", # 字体加粗
width=1.5, # 边更宽
edge_color="gray" # 边的颜色
)
"Zachary's Karate Club Graph")
plt.show()
常用布局算法
节点的排列方式(布局)对图形的可读性至关重要。networkx 提供了多种布局算法:
nx.circular_layout(G): 节点在一个圆环上排列。nx.random_layout(G): 节点随机排列。nx.shell_layout(G): 节点在同心圆上排列。nx.spring_layout(G): 基于力导向算法,模拟弹簧,是默认且最常用的布局。nx.spectral_layout(G): 基于图的拉普拉斯特征向量。
示例:对比不同布局
import networkx as nx
import matplotlib.pyplot as plt
G = nx.karate_club_graph()
# 定义不同的布局
layouts = {
"Circular Layout": nx.circular_layout(G),
"Random Layout": nx.random_layout(G),
"Spring Layout": nx.spring_layout(G),
"Shell Layout": nx.shell_layout(G)
}
# 绘制四种布局的图
plt.figure(figsize=(16, 12))
for i, (name, pos) in enumerate(layouts.items()):
plt.subplot(2, 2, i + 1)
nx.draw(G, pos, with_labels=True, node_size=500, node_color="lightgreen")
plt.title(name)
plt.axis('off')
plt.tight_layout()
plt.show()
运行结果会展示四种不同的排列方式,直观地看出 spring_layout 在这个案例下效果较好。
保存图形
使用 matplotlib 的 savefig() 函数可以轻松将图形保存为文件。
import networkx as nx
import matplotlib.pyplot as plt
G = nx.Graph()
G.add_edges_from([(1, 2), (1, 3), (2, 4), (3, 4), (4, 5)])
# 绘制图形
nx.draw(G, with_labels=True, node_color="orange", node_size=800)
# 保存为 PNG 文件
plt.savefig("my_network.png", dpi=300, bbox_inches='tight')
# 保存为 PDF 文件 (矢量图,无损放大)
plt.savefig("my_network.pdf", bbox_inches='tight')
print("图形已保存!")
plt.show() # 注意:savefig 应该在 show() 之前调用,否则可能保存空白图
使用 networkx 画图的核心是 “先建图,再绘图”。
- 建图: 使用
nx.Graph(),nx.DiGraph()等创建图对象,用add_node(s)和add_edge(s)添加元素。 - 布局: 使用
nx.spring_layout(),nx.circular_layout()等为节点计算位置。 - 绘图: 可以使用
nx.draw()快速绘制,或者使用nx.draw_networkx_nodes(),nx.draw_networkx_edges(),nx.draw_networkx_labels()等函数精细控制每个元素。 - 美化: 通过调整
node_size,node_color,width,font_size等参数来美化图形。 - 保存: 使用
plt.savefig()将图形保存到本地。
掌握了这些基本操作,你就可以开始用 Python 可视化各种复杂的关系网络了。
