杰瑞科技汇

Networkx绘图怎么自定义节点样式?

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

Networkx绘图怎么自定义节点样式?-图1
(图片来源网络,侵删)

安装必要的库

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

pip install networkx matplotlib

基本绘图流程

使用 networkx 画图的基本流程非常简单,通常分为三步:

  1. 创建图: 创建一个 Graph 对象(无向图)或 DiGraph 对象(有向图)。
  2. 添加节点和边: 向图中添加代表实体的节点和代表实体间关系的边。
  3. 绘制图形: 使用 networkxdraw() 函数,结合 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()

代码解释:

Networkx绘图怎么自定义节点样式?-图2
(图片来源网络,侵删)
  • 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 在这个案例下效果较好。


保存图形

使用 matplotlibsavefig() 函数可以轻松将图形保存为文件。

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 画图的核心是 “先建图,再绘图”

  1. 建图: 使用 nx.Graph(), nx.DiGraph() 等创建图对象,用 add_node(s)add_edge(s) 添加元素。
  2. 布局: 使用 nx.spring_layout(), nx.circular_layout() 等为节点计算位置。
  3. 绘图: 可以使用 nx.draw() 快速绘制,或者使用 nx.draw_networkx_nodes(), nx.draw_networkx_edges(), nx.draw_networkx_labels() 等函数精细控制每个元素。
  4. 美化: 通过调整 node_size, node_color, width, font_size 等参数来美化图形。
  5. 保存: 使用 plt.savefig() 将图形保存到本地。

掌握了这些基本操作,你就可以开始用 Python 可视化各种复杂的关系网络了。

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