networkx 是一个非常强大的图论库,它不仅可以用来创建和操作图结构,还内置了多种绘图功能,它的绘图功能主要依赖于 matplotlib 库。

安装必要的库
你需要确保已经安装了 networkx 和 matplotlib,如果还没有安装,可以通过 pip 安装:
pip install networkx matplotlib
基本绘图流程
使用 networkx 画图的基本流程非常简单,通常遵循以下三个步骤:
- 创建图:使用
networkx.Graph()创建一个无向图,或networkx.DiGraph()创建一个有向图。 - 添加节点和边:向图中添加顶点和连接顶点的线。
- 绘制图形:使用
networkx.draw()或其相关函数将图绘制出来。
示例:一个简单的无向图
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_node("D")
# 也可以一次性添加多个节点
G.add_nodes_from(["E", "F", "G"])
# 3. 添加边
# 可以一个一个添加
G.add_edge("A", "B")
G.add_edge("B", "C")
G.add_edge("C", "D")
G.add_edge("D", "A")
G.add_edge("A", "E")
G.add_edge("B", "F")
# 也可以一次性添加多条边
G.add_edges_from([("C", "G"), ("D", "G")])
# 4. 绘制图形
nx.draw(G, with_labels=True)
# 5. 显示图形
plt.show()
运行这段代码,你将得到一个简单的图形,其中节点用字母表示,边用线连接,with_labels=True 使得节点上显示标签。
核心绘图函数详解
networkx 提供了多个 draw 系列的函数,以适应不同的绘图需求。

| 函数 | 描述 |
|---|---|
nx.draw(G, ...) |
最通用的绘图函数,根据图的类型自动选择布局。 |
nx.draw_networkx_nodes(G, pos, ...) |
只绘制节点。pos 是一个字典,定义了节点的位置。 |
nx.draw_networkx_edges(G, pos, ...) |
只绘制边。 |
nx.draw_networkx_labels(G, pos, ...) |
只绘制节点标签。 |
nx.draw_networkx_edge_labels(G, pos, ...) |
只绘制边的标签。 |
nx.draw_circular(G, ...) |
将节点排列在一个圆圈上。 |
nx.draw_random(G, ...) |
随机排列节点。 |
nx.draw_spectral(G, ...) |
基于图的拉普拉斯矩阵的特征向量进行布局。 |
nx.draw_spring(G, ...) |
使用 Fruchterman-Reingold 力导向算法布局,是默认布局,效果通常很好。 |
nx.draw_shell(G, ...) |
将节点排列在同心圆上。 |
重要提示:当你想对图的各个部分(节点、边、标签)进行精细化控制时,最佳实践是分别调用 draw_networkx_nodes, draw_networkx_edges, draw_networkx_labels,这样可以独立设置每个部分的样式(如颜色、大小、透明度等)。
示例:精细化控制绘图
import networkx as nx
import matplotlib.pyplot as plt
# 创建一个有向图
G = nx.DiGraph()
G.add_edges_from([(1, 2), (1, 3), (2, 4), (3, 4), (4, 5), (5, 1)])
# 设置布局(强烈建议先确定布局)
pos = nx.spring_layout(G, seed=42) # seed 参数确保每次运行布局都一样
# 分别绘制各个部分
# 1. 绘制边
nx.draw_networkx_edges(
G, pos,
arrowstyle='->', # 箭头样式
arrowsize=20, # 箭头大小
edge_color='gray' # 边的颜色
)
# 2. 绘制节点
nx.draw_networkx_nodes(
G, pos,
node_size=700, # 节点大小
node_color='skyblue', # 节点颜色
alpha=0.8 # 透明度
)
# 3. 绘制节点标签
nx.draw_networkx_labels(
G, pos,
font_size=12,
font_family='sans-serif'
)
# 4. 绘制边标签 (可选)
edge_labels = nx.get_edge_attributes(G, 'weight') # 假设边有权重
# 如果你的边没有权重属性,可以手动创建一个字典
# edge_labels = {(u, v): f'{u}-{v}' for u, v in G.edges()}
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
并显示"Directed Graph with Custom Styling")
plt.axis('off') # 关闭坐标轴
plt.show()
常用布局算法
布局是图形可视化的关键,它决定了节点在画布上的排列方式。
Spring Layout (力导向布局)
这是最常用的布局,模拟弹簧系统,节点之间互相吸引或排斥,最终达到一个能量较低的稳定状态。
import networkx as nx import matplotlib.pyplot as plt G = nx.karate_club_graph() # networkx 内置的一个经典图 pos = nx.spring_layout(G, k=0.15, iterations=50) # k和iterations可以调整布局松紧度 nx.draw(G, pos, with_labels=True) plt.show()
Circular Layout (环形布局)
将所有节点均匀地放置在一个圆上,适用于节点关系比较均匀或需要展示环形结构的图。

pos = nx.circular_layout(G) nx.draw(G, pos, with_labels=True, node_color='lightgreen') plt.show()
Shell Layout (同心圆布局)
将节点放置在一系列同心圆上,可以指定哪些节点在哪个圆上,非常有用。
# 将节点0-7放在内圈,其余节点放在外圈 shells = [[0, 1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]] pos = nx.shell_layout(G, nlist=shells) nx.draw(G, pos, with_labels=True, node_color='salmon') plt.show()
Spectral Layout (谱布局)
基于图的邻接矩阵或拉普拉斯矩阵的特征向量进行布局,常用于揭示图的社群结构。
pos = nx.spectral_layout(G) nx.draw(G, pos, with_labels=True, node_color='plum') plt.show()
高级技巧与自定义
根据节点属性设置样式
你可以为节点或边存储任意属性,然后根据这些属性来设置颜色、大小等。
import networkx as nx
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
# 创建图并为节点添加 'type' 属性
G = nx.Graph()
G.add_nodes_from([1, 2, 3, 4, 5], type='default')
G.add_nodes_from([6, 7], type='special') # 6和7是特殊节点
G.add_edges_from([(1, 2), (2, 3), (3, 4), (4, 1), (1, 5), (5, 6), (6, 7)])
# 根据属性设置颜色
node_colors = []
for node in G.nodes():
if G.nodes[node]['type'] == 'special':
node_colors.append('red')
else:
node_colors.append('skyblue')
pos = nx.spring_layout(G)
nx.draw(G, pos, with_labels=True, node_color=node_colors, node_size=800)
plt.show()
保存图形
使用 matplotlib.pyplot.savefig() 函数可以将图形保存为图片文件。
# ... 绘图代码 ...
nx.draw(G, pos, with_labels=True, node_color=node_colors, node_size=800)
# 保存为 PNG 图片,dpi 可以控制分辨率
plt.savefig("my_network_graph.png", dpi=300)
# 保存为 PDF 或 SVG 矢量图,适合用于论文或报告
# plt.savefig("my_network_graph.pdf")
# plt.savefig("my_network_graph.svg")
plt.show() # show() 会清空画布,savefig() 要在 show() 之前调用
处理大规模图
对于节点和边非常多的图,直接绘制可能会变得一团糟(称为 "hairball")。
- 使用
nx.spring_layout的k和iterations参数:调整k(节点间最优距离)可以控制图的松散程度。 - 考虑社区发现算法:先使用
networkx.community模块中的算法找出图的社区,然后用不同的颜色标记不同的社区,这样可以更好地展示图的结构。 - 使用
nxviz或pyvis:networkx主要基于matplotlib,适合静态图,对于交互式的大规模图可视化,可以考虑pyvis库,它可以生成一个可缩放、可拖拽的 HTML 页面。
networkx 的绘图功能虽然简单易上手,但要画出美观、信息量大的图,需要多加练习和尝试。
核心要点:
- 安装:
networkx和matplotlib。 - 流程:建图 -> 加节点/边 -> 调用
nx.draw()或其子函数绘图。 - 布局:
pos是关键,spring_layout是首选,circular_layout和shell_layout也有特定用途。 - 自定义:通过
node_color,node_size,edge_color等参数以及分别调用draw_networkx_*函数来精细控制样式。 - 保存:使用
plt.savefig()。
希望这份详细的指南能帮助你开始使用 networkx 进行图可视化!
