杰瑞科技汇

NetworkX如何绘制Python网络图?

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

NetworkX如何绘制Python网络图?-图1
(图片来源网络,侵删)

安装必要的库

你需要确保已经安装了 networkxmatplotlib,如果还没有安装,可以通过 pip 安装:

pip install networkx matplotlib

基本绘图流程

使用 networkx 画图的基本流程非常简单,通常遵循以下三个步骤:

  1. 创建图:使用 networkx.Graph() 创建一个无向图,或 networkx.DiGraph() 创建一个有向图。
  2. 添加节点和边:向图中添加顶点和连接顶点的线。
  3. 绘制图形:使用 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 系列的函数,以适应不同的绘图需求。

NetworkX如何绘制Python网络图?-图2
(图片来源网络,侵删)
函数 描述
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 (环形布局)

将所有节点均匀地放置在一个圆上,适用于节点关系比较均匀或需要展示环形结构的图。

NetworkX如何绘制Python网络图?-图3
(图片来源网络,侵删)
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_layoutkiterations 参数:调整 k(节点间最优距离)可以控制图的松散程度。
  • 考虑社区发现算法:先使用 networkx.community 模块中的算法找出图的社区,然后用不同的颜色标记不同的社区,这样可以更好地展示图的结构。
  • 使用 nxvizpyvisnetworkx 主要基于 matplotlib,适合静态图,对于交互式的大规模图可视化,可以考虑 pyvis 库,它可以生成一个可缩放、可拖拽的 HTML 页面。

networkx 的绘图功能虽然简单易上手,但要画出美观、信息量大的图,需要多加练习和尝试。

核心要点

  1. 安装networkxmatplotlib
  2. 流程:建图 -> 加节点/边 -> 调用 nx.draw() 或其子函数绘图。
  3. 布局pos 是关键,spring_layout 是首选,circular_layoutshell_layout 也有特定用途。
  4. 自定义:通过 node_color, node_size, edge_color 等参数以及分别调用 draw_networkx_* 函数来精细控制样式。
  5. 保存:使用 plt.savefig()

希望这份详细的指南能帮助你开始使用 networkx 进行图可视化!

分享:
扫描分享到社交APP
上一篇
下一篇