文章目录

  • 专栏导读
  • 一、热力图介绍
    • 1. 介绍
    • 2. 参数说明
  • 二、绘制热力图
    • 1. 普通热力图
    • 2. 添加坐标轴和标题
    • 3. 添加热力标尺
    • 4. 添加色块数值
    • 5. 修改热力图颜色
    • 6. 突出特殊数据
  • 三、应用场景
    • 1. 适用场景
    • 2. 不适用场景

专栏导读

本文已收录于《100天精通Python从入门到就业》:本专栏专门针对零基础和需要进阶提升的同学所准备的一套完整教学,从0到100的不断进阶深入,后续还有实战项目,轻松应对面试,专栏订阅地址:https://blog.csdn.net/yuan2019035055/category_11466020.html

  • 优点订阅限时9.9付费专栏进入千人全栈VIP答疑群,作者优先解答机会(代码指导、远程服务),群里大佬众多可以抱团取暖(大厂内推机会)
  • 专栏福利简历指导、招聘内推、每周送实体书、80G全栈学习视频、300本IT电子书:Python、Java、前端、大数据、数据库、算法、爬虫、数据分析、机器学习、面试题库等等

一、热力图介绍

1. 介绍

  • 热力图(Heat Map)是一种基于色彩对数据集进行可视化的方法,可表现出数据空间内各点之间的相关性,从而揭示影响结果的因素的变化趋势。例如,较大的值由较深的颜色表示,较小的值由较浅的颜色表示;较大的值由偏暖的颜色表示,较小的值由较冷的颜色表示,等等。
  • 从数据结构来划分,热力图一般分为两种。第一,表格型热力图,也称色块图。它需要 2 个分类字段和 1 个数值字段,分类字段确定 x、y 轴,将图表划分为规整的矩形块。数值字段决定了矩形块的颜色。第二,非表格型热力图,或曰平滑的热力图,它需要 3 个数值字段,可绘制在平行坐标系中(2个数值字段分别确定x、y轴,1个数值字段确定着色)。

特点:热力图的最大特点就是能够穿透和揭示大量数据之间的空间关系,将复杂的结果可视化。它以色调的方式展示变量之间的关系,不同的色调对应着不同的值范围,渐变的颜色向着更多的变量、密集的空间和复杂的表现形式揭示变量之间的关系。

应用场景

  • 热力图适合用于查看总体的情况、发现异常值、显示多个变量之间的差异,以及检测它们之间是否存在任何相关性。
  • 热力图在各行业有着广泛的应用,尤其是在市场营销、数据分析及空间数据处理领域,比如用热力图可以分析航班的晚间到达率,可以分析疾病的集中地区,可以整理出某个行业的流行程度等。

2. 参数说明

Matplotlib绘制热力图的函数是imshow():

imshow( X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=None, vmin=None, vmax=None, origin=None, extent=None, *, interpolation_stage=None, filternorm=True, filterrad=4.0, resample=None, url=None, data=None, **kwargs )

主要参数说明如下:

  1. X和Y:表示矩阵的行和列,X对应列,Y对应行。

  2. C:表示矩阵中每个元素的值,即热力图的颜色值。

  3. cmap:表示热力图的颜色映射,可以使用Matplotlib中的任意颜色映射。

  4. norm:表示归一化的方式,可以使用Matplotlib中的任意归一化方式。

  5. aspect:表示图像的长宽比。

  6. interpolation:表示插值方式,可以使用Matplotlib中的任意插值方式。

  7. alpha:表示透明度。

  8. vmin和vmax:表示颜色映射的范围。

  9. origin:表示图像的原点位置,可以是“upper”或“lower”。

  10. extent:表示图像的范围,以左下角和右上角坐标表示。

  11. filternorm和filterrad:表示滤波器的大小。

  12. resample:表示是否对图像进行重采样。

  13. ax:表示要绘制热力图的坐标轴对象。

  14. **kwargs:表示其他Matplotlib绘图函数的参数,如linewidths、edgecolors等。

二、绘制热力图

1. 普通热力图

下面我们就通过例子来讲述热力图的绘制,示例代码如下:

import matplotlib.pyplot as pltimport numpy as np# 生成学生成绩矩阵grades = np.array([[80, 90, 70, 60, 85, 92], [85, 88, 91, 69, 78, 90], [75, 92, 80, 78, 86, 88], [60, 70, 88, 82, 75, 90], [91, 80, 75, 70, 89, 88], [95, 85, 78, 80, 92, 90]])# 绘制热力图fig, ax = plt.subplots()im = ax.imshow(grades)# 显示图像plt.show()

上面代码将一个二维数组传入到 imshow 方法中便可以绘制一个热力图,每个色块的颜色代表数据的大小,运行结果:

2. 添加坐标轴和标题

上面只是绘制了色块,并没有指明 x 轴 和 y 轴代表的含义,下面我们加上 x 轴和 y 轴的标签,并加上标题。示例代码如下:

import matplotlib.pyplot as pltimport numpy as np# 生成学生成绩矩阵subjects = ['Chinese', 'Math', 'English', 'Physics', 'Chemistry', 'Biology']grades = np.array([[80, 90, 70, 60, 85, 92], [85, 88, 91, 69, 78, 90], [75, 92, 80, 78, 86, 88], [60, 70, 88, 82, 75, 90], [91, 80, 75, 70, 89, 88], [95, 85, 78, 80, 92, 90]])# 绘制热力图fig, ax = plt.subplots()im = ax.imshow(grades)# 添加坐标轴标签ax.set_xticks(np.arange(len(subjects)))ax.set_yticks(np.arange(len(grades)))ax.set_xticklabels(subjects)ax.set_yticklabels(['Student {}'.format(i+1) for i in range(len(grades))])ax.set_xlabel('Subject')ax.set_ylabel('Student')# 添加图像标题ax.set_title("Grades Heatmap")# 显示图像plt.show()

上面代码中,x 轴代表学生的姓名,y 轴代表学科的名称,二维数组中的数据代表某个学生的某学科的成绩,运行结果:

3. 添加热力标尺

上图中,我们加上了 x 轴和 y 轴代表的含义以及整个图的标题,但是现在我们还不知道不同色块所对应的数值的大小,下面我们就来加上。示例代码如下:

import matplotlib.pyplot as pltimport numpy as np# 生成学生成绩矩阵subjects = ['Chinese', 'Math', 'English', 'Physics', 'Chemistry', 'Biology']grades = np.array([[80, 90, 70, 60, 85, 92], [85, 88, 91, 69, 78, 90], [75, 92, 80, 78, 86, 88], [60, 70, 88, 82, 75, 90], [91, 80, 75, 70, 89, 88], [95, 85, 78, 80, 92, 90]])# 绘制热力图fig, ax = plt.subplots()im = ax.imshow(grades)# 添加坐标轴标签ax.set_xticks(np.arange(len(subjects)))ax.set_yticks(np.arange(len(grades)))ax.set_xticklabels(subjects)ax.set_yticklabels(['Student {}'.format(i+1) for i in range(len(grades))])ax.set_xlabel('Subject')ax.set_ylabel('Student')# 添加图像标题ax.set_title("Grades Heatmap")# 添加颜色条cbar = ax.figure.colorbar(im, ax=ax)# 显示图像plt.show()

上面的代码中,我们通过调用 colorbar 函数来加上数值和颜色的对应规则。代码执行后得到的图形如下图所示:

4. 添加色块数值

上图我们便加上了颜色和数值的对应规则。接下来我们再为每个色块加上所代表的数值。例如:

import matplotlib.pyplot as pltimport numpy as np# 生成学生成绩矩阵subjects = ['Chinese', 'Math', 'English', 'Physics', 'Chemistry', 'Biology']grades = np.array([[80, 90, 70, 60, 85, 92], [85, 88, 91, 69, 78, 90], [75, 92, 80, 78, 86, 88], [60, 70, 88, 82, 75, 90], [91, 80, 75, 70, 89, 88], [95, 85, 78, 80, 92, 90]])# 绘制热力图fig, ax = plt.subplots()im = ax.imshow(grades)# 添加坐标轴标签ax.set_xticks(np.arange(len(subjects)))ax.set_yticks(np.arange(len(grades)))ax.set_xticklabels(subjects)ax.set_yticklabels(['Student {}'.format(i+1) for i in range(len(grades))])ax.set_xlabel('Subject')ax.set_ylabel('Student')# 添加图像标题ax.set_title("Grades Heatmap")# 添加颜色条cbar = ax.figure.colorbar(im, ax=ax)# 在每个格子中添加文字标注for i in range(len(grades)):for j in range(len(subjects)):text = ax.text(j, i, grades[i, j], ha="center", va="center", color="black")# 显示图像plt.show()

上面的代码中,我们通过一个循环来为每个色块加上对应的数值。代码执行后得到的图形如下图所示:

5. 修改热力图颜色

改变热力图的颜色,只需要更改参数中的cmap即可,使用cmap可以改变图的颜色,cmap可以选择:

Accent, Accent_r, Blues, Blues_r, BrBG, BrBG_r, BuGn, BuGn_r, BuPu, BuPu_r, CMRmap, CMRmap_r, Dark2, Dark2_r, GnBu, GnBu_r, Greens, Greens_r, Greys, Greys_r, OrRd, OrRd_r, Oranges, Oranges_r, PRGn, PRGn_r, Paired, Paired_r, Pastel1, Pastel1_r, Pastel2, Pastel2_r, PiYG, PiYG_r, PuBu, PuBuGn, PuBuGn_r, PuBu_r, PuOr, PuOr_r, PuRd, PuRd_r, Purples, Purples_r, RdBu, RdBu_r, RdGy, RdGy_r, RdPu, RdPu_r, RdYlBu, RdYlBu_r, RdYlGn, RdYlGn_r, Reds, Reds_r, Set1, Set1_r, Set2, Set2_r, Set3, Set3_r, Spectral, Spectral_r, Wistia, Wistia_r, YlGn, YlGnBu, YlGnBu_r, YlGn_r, YlOrBr, YlOrBr_r, YlOrRd, YlOrRd_r, afmhot, afmhot_r, autumn, autumn_r, binary, binary_r, bone, bone_r, brg, brg_r, bwr, bwr_r, cividis, cividis_r, cool, cool_r, coolwarm, coolwarm_r, copper, copper_r, cubehelix, cubehelix_r, flag, flag_r, gist_earth, gist_earth_r, gist_gray, gist_gray_r, gist_heat, gist_heat_r, gist_ncar, gist_ncar_r, gist_rainbow, gist_rainbow_r, gist_stern, gist_stern_r, gist_yarg, gist_yarg_r, gnuplot, gnuplot2, gnuplot2_r, gnuplot_r, gray, gray_r, hot, hot_r, hsv, hsv_r, icefire, icefire_r, inferno, inferno_r, jet, jet_r, magma, magma_r, mako, mako_r, nipy_spectral, nipy_spectral_r, ocean, ocean_r, pink, pink_r, plasma, plasma_r, prism, prism_r, rainbow, rainbow_r, rocket, rocket_r, seismic, seismic_r, spring, spring_r, summer, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, terrain, terrain_r, twilight, twilight_r, twilight_shifted, twilight_shifted_r, viridis, viridis_r, vlag, vlag_r, winter, winter_r

案例代码:

import matplotlib.pyplot as pltimport numpy as np# 生成学生成绩矩阵subjects = ['Chinese', 'Math', 'English', 'Physics', 'Chemistry', 'Biology']grades = np.array([[80, 90, 70, 60, 85, 92], [85, 88, 91, 69, 78, 90], [75, 92, 80, 78, 86, 88], [60, 70, 88, 82, 75, 90], [91, 80, 75, 70, 89, 88], [95, 85, 78, 80, 92, 90]])# 绘制热力图fig, ax = plt.subplots()im = ax.imshow(grades, cmap='YlOrRd')# 添加坐标轴标签ax.set_xticks(np.arange(len(subjects)))ax.set_yticks(np.arange(len(grades)))ax.set_xticklabels(subjects)ax.set_yticklabels(['Student {}'.format(i+1) for i in range(len(grades))])ax.set_xlabel('Subject')ax.set_ylabel('Student')# 添加图像标题ax.set_title("Grades Heatmap")# 添加颜色条cbar = ax.figure.colorbar(im, ax=ax)# 在每个格子中添加文字标注for i in range(len(grades)):for j in range(len(subjects)):text = ax.text(j, i, grades[i, j], ha="center", va="center", color="black")# 显示图像plt.show()

运行结果:

6. 突出特殊数据

下面代码中我们将圈出最高分和最低分,代码如下:

import matplotlib.pyplot as pltimport numpy as np# 生成学生成绩矩阵subjects = ['Chinese', 'Math', 'English', 'Physics', 'Chemistry', 'Biology']grades = np.array([[80, 90, 70, 60, 85, 92], [85, 88, 91, 69, 78, 90], [75, 92, 80, 78, 86, 88], [60, 70, 88, 82, 75, 90], [91, 80, 75, 70, 89, 88], [95, 85, 78, 80, 92, 90]])# 绘制热力图fig, ax = plt.subplots()im = ax.imshow(grades)# 添加坐标轴标签ax.set_xticks(np.arange(len(subjects)))ax.set_yticks(np.arange(len(grades)))ax.set_xticklabels(subjects)ax.set_yticklabels(['Student {}'.format(i+1) for i in range(len(grades))])ax.set_xlabel('Subject')ax.set_ylabel('Student')# 添加图像标题ax.set_title("Grades Heatmap")# 添加颜色条cbar = ax.figure.colorbar(im, ax=ax)# 在每个格子中添加文字标注for i in range(len(grades)):for j in range(len(subjects)):text = ax.text(j, i, grades[i, j], ha="center", va="center", color="black")# 找到最高分和最低分max_grade = np.max(grades)min_grade = np.min(grades)# 找到最高分和最低分对应的学科和学生max_grade_index = np.argwhere(grades == max_grade)min_grade_index = np.argwhere(grades == min_grade)# 在热力图上用红色和蓝色圆圈标出最高分和最低分for index in max_grade_index:ax.scatter(index[1], index[0], marker='o', s=200, c='r', edgecolors='k', linewidths=1)for index in min_grade_index:ax.scatter(index[1], index[0], marker='o', s=200, c='b', edgecolors='k', linewidths=1)# 在圆圈旁边添加文字标注for index in max_grade_index:ax.text(index[1]+0.3, index[0]+0.3, max_grade, color='r', fontsize=12)for index in min_grade_index:ax.text(index[1]+0.3, index[0]+0.3, min_grade, color='b', fontsize=12)# 显示图像plt.show()

最高分用红色圈出,最低分用蓝色圈出,运行结果:

三、应用场景

1. 适用场景

热力图的优势在于“空间利用率高”,可以容纳较为庞大的数据。热力图不仅有助于发现数据间的关系、找出极值,也常用于刻画数据的整体样貌,方便在数据集之间进行比较(例如将每个运动员的历年成绩都浓缩成一张热力图,再进行比较)。如果将某行或某列设置为时间变量,热力图也可用于展示数据随时间的变化。例如,用热力图来反映一个城市一年中的温度变化,气候的冷暖走向,一目了然。

2. 不适用场景

尽管热力图能够容纳较多的数据,但反过来说,人们很难将其中的色块转换为精确的数字。因此,当需要清楚知道数值的时候,可能需要额外的标注。