← 返回Book 2目录
第11章

热图与伪彩色

Heatmap & Pseudocolor · 矩阵数据的颜色编码

从热图到分类可视化,掌握5种颜色编码技法

🔥 章节概览

热图(Heatmap)使用颜色编码展示矩阵数据,是数据分析和机器学习中的重要可视化工具。 本章系统讲解热图绘制、伪彩色网格图、kNN分类可视化、几何变换展示, 以及非矢量图片处理等5种技法。通过颜色映射,将数值信息转化为直观的视觉表达, 广泛应用于相关性分析、模型可视化、图像处理等领域。

🔥
热图
矩阵数据颜色编码
🎨
伪彩色
连续函数可视化
🤖
kNN分类
分类器决策区域
🖼️
图像处理
非矢量图显示
11.1

热图

Seaborn中的热图与聚类

🔥 Seaborn中的热图

  • • 图1:热图可视化差尾花数据(4个特征的矩阵)
  • • 图2:热图可视化差尾花数据(聚类热图clustermap,自动排序行列)
  • • 矩阵运算:用热图可视化矩阵分解(Gram Matrix、Cholesky、EVD、SVD)(图15)

🔥 热图实验室(Heatmap Lab)

通过调整参数,理解热图如何用颜色编码展示矩阵数据

0011223344556677
-0.80Colorbar1.00

🔍 数据洞察

📊 相关性矩阵:对角线为1(完全相关)
🔄 对称矩阵:ρ(i,j) = ρ(j,i)
推荐colormap: coolwarm(发散型)

🧪 探索建议

  • • 切换数据类型,观察不同矩阵特征
  • • 尝试不同colormap,理解适用场景
  • • 调整矩阵大小,观察细节变化
  • • 开启数值显示,对比颜色编码

📊 数据类型

🎨 Colormap

8×8

📈 数值统计

最小值:-0.800
最大值:1.000
范围:1.800

📚 热图理论

颜色编码原理
热图将数值映射到颜色,利用视觉系统的色彩感知能力快速识别数据模式。
• 低值→冷色(蓝、绿)
• 高值→暖色(红、黄)
• 或使用感知均匀的colormap
Colormap类型
Sequential(顺序):单向递增数据
Diverging(发散):有中心值(如0)
Qualitative(分类):离散标签
应用场景
• 相关性矩阵:特征关联分析
• 混淆矩阵:分类性能评估
• 基因表达:生物信息学
• 地理数据:温度、降雨分布
设计建议
✓ 选择合适的colormap类型
✓ 考虑色盲友好性(viridis)
✓ 添加colorbar图例
✓ 矩阵较大时隐藏数值
🎯 学习目标:通过动手调整参数,理解热图如何通过颜色编码传递信息。 观察不同colormap的视觉效果,建立"数值→颜色"的映射直觉。
📚 Python绘图代码(基于Ch11原文)
# ===== 示例1:使用seaborn绘制热图 =====
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris

# 加载鸢尾花数据
iris = load_iris()
X = iris.data
feature_names = ['Sepal length, $X_1$', 'Sepal width, $X_2$',
                 'Petal length, $X_3$', 'Petal width, $X_4$']

# 转换为DataFrame
X_df = pd.DataFrame(X, columns=feature_names)

# 绘制热图
fig, ax = plt.subplots(figsize=(3, 4))
sns.heatmap(X_df,
           cmap='RdYlBu_r',           # 色谱
           xticklabels=list(X_df.columns),
           yticklabels=False,         # 关闭纵轴标签
           cbar_kws={"orientation": "vertical"},
           vmin=0, vmax=8)
plt.title('Iris Dataset')
plt.show()


# ===== 示例2:聚类热图(带树状图) =====
sns.clustermap(X_df,
              cmap='RdYlBu_r',
              xticklabels=list(X_df.columns),
              yticklabels=False,
              figsize=(3, 6),
              vmin=0, vmax=8)
plt.show()


# ===== 示例3:格拉姆矩阵可视化 =====
# 计算格拉姆矩阵 G = X^T @ X
G = X.T @ X

fig, axs = plt.subplots(1, 5, figsize=(8, 3),
                       gridspec_kw={'width_ratios': [3, 0.5, 3, 0.5, 3]})

# G矩阵
plt.sca(axs[0])
sns.heatmap(G, cmap='RdYlBu_r',
           vmax=5000, vmin=0,
           annot=True, fmt=".0f",
           cbar_kws={'orientation': 'horizontal'},
           yticklabels=False,
           square='equal')
plt.title('$G$')

# 等号
plt.sca(axs[1])
plt.title('=')
plt.axis('off')

# X^T
plt.sca(axs[2])
sns.heatmap(X.T, cmap='RdYlBu_r',
           vmax=8, vmin=0,
           cbar_kws={'orientation': 'horizontal'},
           xticklabels=False,
           yticklabels=False)
plt.title('$X^T$')

# @符号
plt.sca(axs[3])
plt.title('@')
plt.axis('off')

# X
plt.sca(axs[4])
sns.heatmap(X, cmap='RdYlBu_r',
           vmax=8, vmin=0,
           cbar_kws={'orientation': 'horizontal'},
           xticklabels=False,
           yticklabels=False)
plt.title('$X$')
plt.show()


# ===== 示例4:Cholesky分解可视化 =====
# G = L @ L^T
L = np.linalg.cholesky(G)

fig, axs = plt.subplots(1, 5, figsize=(8, 3),
                       gridspec_kw={'width_ratios': [3, 0.5, 3, 0.5, 3]})

plt.sca(axs[0])
sns.heatmap(G, cmap='RdYlBu_r',
           vmax=5000, vmin=0,
           annot=True, fmt=".0f",
           square='equal')
plt.title('$G$')

plt.sca(axs[1])
plt.title('=')
plt.axis('off')

plt.sca(axs[2])
sns.heatmap(L, cmap='RdYlBu_r',
           annot=True,
           xticklabels=False,
           yticklabels=False)
plt.title('$L$')

plt.sca(axs[3])
plt.title('@')
plt.axis('off')

plt.sca(axs[4])
sns.heatmap(L.T, cmap='RdYlBu_r',
           annot=True,
           xticklabels=False,
           yticklabels=False)
plt.title('$L^T$')
plt.show()


# 💡 关键学习点:
# 1. seaborn.heatmap():快速绘制热图,自动配色
# 2. clustermap():带层次聚类的热图,自动排序
# 3. annot=True:在单元格中显示数值
# 4. cmap参数:选择色谱(RdYlBu_r红黄蓝翻转)
# 5. vmin/vmax:控制色谱范围,保证对比度
11.2

伪彩色网格图

pcolormesh绘制连续函数与几何变换

🎨 pcolormesh函数

  • • 图3:利用pcolormesh绘制伪彩色图(rasterized参数控制栅格化)
  • • 图4:利用pcolormesh绘制正网格
  • • 图16:用pcolormesh函数绘制分类决策边界
  • • 图17:用pcolormesh函数可视化线性、非线性变换(6个变换示例)

🎯 kNN分类动画器(k-Nearest Neighbors Animator)

观察k近邻算法如何通过邻居投票进行分类

类别 0类别 1
准备
速度1x

👀 观察要点

  • • 黄色线连接测试点和k个最近邻
  • • 最近邻会被高亮显示(金色边框)
  • • 投票决定分类(多数获胜)
  • • 背景热图展示整体决策区域

🔢 k值(邻居数量)

k = 5✓ 奇数(避免平局)
✅ k=5:平衡了局部性和稳定性

📚 kNN算法原理

步骤1:计算测试点到所有训练点的距离
步骤2:选择距离最近的k个邻居
步骤3:邻居投票,多数类别获胜
距离公式:d = √[(x₁-x₂)² + (y₁-y₂)²]

⚖️ k值的影响

  • • k小:决策边界复杂,易过拟合
  • • k大:决策边界平滑,易欠拟合
  • • 选择:交叉验证确定最优k
  • • 建议:通常选奇数避免平局

📖 kNN分类理论

🎯
非参数方法
kNN不学习显式模型,而是记住训练数据,基于距离进行分类
📏
距离度量
常用欧氏距离,也可使用曼哈顿距离、闵可夫斯基距离等
⚡
计算复杂度
训练O(1),预测O(n),可用KD树加速
🎓 优缺点
优点:
• 简单直观,易于理解
• 无需训练过程
• 适合多分类问题
缺点:
• 预测速度慢(需遍历)
• 对维度敏感(维度灾难)
• 需选择合适的k值
📚 Python绘图代码(基于Ch11原文)
# ===== 示例1:伪彩色网格图(pcolormesh) =====
import matplotlib.pyplot as plt
import numpy as np

# 生成网格数据
y, x = np.meshgrid(np.linspace(-3, 3, 16), np.linspace(-3, 3, 16))
z = (1 - x/2. + x**5 + y**3) * np.exp(-x**2 - y**2)
z = z[:-1, :-1]  # 移除最后一个值
z_min, z_max = -np.abs(z).max(), np.abs(z).max()

# 绘制伪彩色网格图
fig, ax = plt.subplots()
c = ax.pcolormesh(x, y, z, cmap='RdBu', vmin=z_min, vmax=z_max)
ax.axis([x.min(), x.max(), y.min(), y.max()])
fig.colorbar(c, ax=ax)
plt.show()


# ===== 示例2:KNN分类决策边界 =====
from sklearn import neighbors, datasets
from matplotlib.colors import ListedColormap

# 创建色谱(3类分类)
cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF'])
cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF'])

# 加载鸢尾花数据
iris = datasets.load_iris()
X = iris.data[:, :2]  # 只取前两个特征
y = iris.target

# 定义网格范围
x_min, x_max = 4, 8
y_min, y_max = 2, 5
xx, yy = np.meshgrid(
    np.linspace(x_min, x_max, 40),
    np.linspace(y_min, y_max, 40)
)

# 训练不同的KNN分类器
num_neighbors = [2, 5]

fig = plt.figure(figsize=(6, 9))

for idx, n_neighbors in enumerate(num_neighbors):
    ax = fig.add_subplot(2, 1, idx + 1)
    
    # 训练KNN
    knn = neighbors.KNeighborsClassifier(n_neighbors=n_neighbors)
    knn.fit(X, y)
    
    # 预测网格点
    Z = knn.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    
    # 绘制决策区域(pcolormesh)
    plt.pcolormesh(xx, yy, Z, cmap=cmap_light, shading='auto')
    
    # 绘制训练样本点
    plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold)
    plt.xlabel('Sepal length (cm)')
    plt.ylabel('Sepal width (cm)')
    plt.title(f'KNN (k={n_neighbors})')
    plt.axis('tight')

plt.show()


# 💡 关键学习点:
# 1. pcolormesh():绘制伪彩色网格图,适合规则网格数据
# 2. KNeighborsClassifier:k近邻分类器
# 3. n_neighbors参数:控制决策边界平滑度
#    - k小:边界复杂,易过拟合
#    - k大:边界平滑,可能欠拟合
# 4. ListedColormap:自定义离散色谱
# 5. shading='auto':避免matplotlib警告
11.3

非矢量图片

imread读取图像与图像处理技术

🖼️ matplotlib.image模块

  • • 图5:鸢尾花照片(imread读取,imshow显示2990×2714×3数组)
  • • 像素:图片的基本单位,有特定坐标和颜色亮度值
  • • 颜色:RGB值(红绿蓝三种颜色强度组合),8位数字表示256种颜色,2^24种颜色
  • • 图9:使用色谱展示红色通道
  • • 灰度:Scikit-image将彩色图片转化为灰度图(图10)
  • • 修改部分像素:左上角500×500白色(图11)
  • • 降低像素:采样降低图像大小为15×14(图12)
  • • 插值:imshow()使用interpolation参数控制插值方法(nearest、bilinear、bicubic等)(图13)
  • • 仿射变换:对图片采取各种伪射变换(图14)

📚 章节总结

热图技法

  • ✓ imshow:显示矩阵为图像
  • ✓ matshow:矩阵可视化
  • ✓ pcolor:伪彩色网格
  • ✓ colorbar:颜色条图例

机器学习应用

  • ✓ kNN分类:决策区域可视化
  • ✓ 混淆矩阵:热图展示
  • ✓ 相关性矩阵:特征关联
  • ✓ 权重可视化:神经网络

图像与变换

  • ✓ 图像读取:imread加载图片
  • ✓ 图像显示:imshow展示
  • ✓ 几何变换:伪彩色可视化
  • ✓ 颜色映射:colormap选择

💡 核心洞察: 热图通过颜色编码将数值矩阵转化为视觉图像,使数据模式一目了然。 在数据分析中,相关性矩阵热图揭示特征间关系;在机器学习中,混淆矩阵热图展示分类性能; 在图像处理中,伪彩色技术增强视觉效果。颜色映射(colormap)的选择至关重要, 不同的colormap适合不同类型的数据(连续、发散、分类)。

🎓核心概念解析

热图(Heatmap)

• 用颜色编码表示矩阵中的数值大小
• 颜色深浅反映数值高低
• 适合展示相关性、混淆矩阵等
• 常用colormap:viridis、hot、coolwarm

伪彩色(Pseudocolor)

• 将连续函数值映射到颜色
• 不同于真彩色(RGB)
• 用于科学可视化、地形图
• pcolormesh 高效绘制大规模网格

kNN分类可视化

• k近邻:根据邻居投票分类
• 决策区域:每个点的预测类别
• 用热图展示分类边界
• k值影响边界平滑度

Colormap选择指南

• Sequential(顺序):viridis、plasma
→ 单向递增数据
• Diverging(发散):coolwarm、RdBu
→ 有中心值的数据(如相关性)
• Qualitative(分类):Set1、tab10
→ 离散分类标签

图像数据结构

• 灰度图:(H, W) 单通道
• RGB图:(H, W, 3) 三通道
• RGBA图:(H, W, 4) 含透明度
• 值范围:0-255(uint8)或0-1(float)

应用场景

• 相关性分析:特征关联热图
• 模型评估:混淆矩阵
• 地理数据:温度、降雨分布
• 生物信息:基因表达热图

💻关键函数速查表

热图绘制

plt.imshow(data, cmap='viridis')
plt.matshow(matrix, cmap='coolwarm')
plt.pcolor(X, Y, Z)
plt.colorbar(label='Value')

伪彩色网格

plt.pcolormesh(X, Y, Z, shading='auto')
plt.contourf(X, Y, Z, levels=20)
plt.get_cmap('viridis')

图像处理

img = plt.imread('file.png')
plt.imshow(img)
plt.axis('off') # 隐藏坐标轴

🎯热图应用场景

📊
相关性分析
用热图展示特征间的Pearson相关系数矩阵, 快速识别高度相关的特征,指导特征工程。
🎯
混淆矩阵
分类模型的性能评估,对角线表示正确分类, 非对角线揭示常见误分类模式。
🧬
基因表达
生物信息学中,热图展示不同样本下基因表达水平, 揭示基因调控模式和样本聚类。
🌡️
地理数据
温度、降雨、污染等空间分布数据, 用伪彩色热图直观展示地理模式。
🧠
神经网络
可视化卷积核权重、激活图(activation map)、 注意力权重(attention)等。
📈
时序数据
日历热图展示每天的活动强度, 如GitHub贡献图、健身打卡记录。

📂Python代码文件

本章内容对应以下Jupyter Notebook代码文件:

BK_2_Ch11_01.ipynb小节 11.1
BK_2_Ch11_02.ipynb小节 11.2
BK_2_Ch11_03.ipynb小节 11.3
BK_2_Ch11_04.ipynb小节 11.4
BK_2_Ch11_05.ipynb小节 11.5
📁 代码位置:books/Book2_Beauty-of-Data-Visualization/Book2_Ch11_Python_Codes/

🎨 Colormap推荐

Sequential(顺序型)

• viridis:默认,色盲友好
• plasma:紫红色系
• inferno:暗红色系
• cividis:蓝黄色系
适用:单向递增数据

Diverging(发散型)

• coolwarm:蓝白红
• RdBu:红蓝对比
• seismic:地震色
• bwr:蓝白红
适用:相关性、偏差数据

Qualitative(分类型)

• tab10:10种离散色
• Set1:9种明亮色
• Paired:成对配色
• Accent:强调色
适用:分类标签
💡 选择建议:科学可视化首选viridis(感知均匀、色盲友好), 相关性矩阵用coolwarm(中心为0),分类用tab10。