热图
热图是直方图的二维版本,可以替代散点图。和散点图一样,要绘制的两个数字变量的值位于坐标轴上。和直方图类似,图形区域被划分为网格,并将每个网格的点数加起来。因为没有空间表示长条高度,因此用网格颜色表示计数。你可以通过 Matplotlib 的 hist2d
函数实现热图。
plt.figure(figsize = [12, 5])
# left plot: scatterplot of discrete data with jitter and transparency
plt.subplot(1, 2, 1)
sb.regplot(data = df, x = 'disc_var1', y = 'disc_var2', fit_reg = False,
x_jitter = 0.2, y_jitter = 0.2, scatter_kws = {'alpha' : 1/3})
# right plot: heat map with bin edges between values
plt.subplot(1, 2, 2)
bins_x = np.arange(0.5, 10.5+1, 1)
bins_y = np.arange(-0.5, 10.5+1, 1)
plt.hist2d(data = df, x = 'disc_var1', y = 'disc_var2',
bins = [bins_x, bins_y])
plt.colorbar();
注意,因为有两个变量,因此 "bins" 参数接受了包含两个分箱边缘规格的列表,每个维度一个规格。和单变量直方图一样,选择合适的分箱尺寸很重要。我们添加了 colorbar
函数调用,以向图形的一侧添加色条,显示从计数到颜色的映射。
随着热图中的颜色越来越亮,从蓝色变成黄色,相应单元格中的点计数越来越高。
热图还可以用作条形图的二维版本,按照两个分类变量(而不是数字变量)的计数绘制图形。seaborn 中的函数 heatmap
专门用于绘制分类热图。稍后我们将在这节课的“聚类条形图”部分详细讲解这方面的知识。
其他版本
要选择其他调色板,可以在 hist2d
中设置 "cmap" 参数。设置调色板的最简单方式是使用字符串引用内置 Matplotlib 调色板。你可以在 Pyplot API 文档的此部分找到有效字符串列表。下节课将详细讨论图形中的颜色。暂时我将通过一个示例介绍如何通过设置 cmap = 'viridis_r'
更改默认的 "viridis" 调色板。
此外,我想区分计数为零的单元格和计数非零的单元格。"cmin" 参数指定了单元格要达到什么样的最低值才能绘制出来。在 hist2d
调用中添加 cmin = 0.5
参数后,只有至少包含一个数据点的单元格才会有颜色。
bins_x = np.arange(0.5, 10.5+1, 1)
bins_y = np.arange(-0.5, 10.5+1, 1)
plt.hist2d(data = df, x = 'disc_var1', y = 'disc_var2',
bins = [bins_x, bins_y], cmap = 'viridis_r', cmin = 0.5)
plt.colorbar()
如果你有大量数据,可能需要向图形中的单元格添加注释,表示每个单元格的点数。在 hist2d
调用中,我们必须挨个地添加文本元素,就像在上节课挨个地向条形图中添加文本元素一样。我们可以直接通过 hist2d
返回的结果得出要注释的计数,该函数返回的结果不仅包括图形对象,还包括计数数组和两个分箱边缘向量。
# hist2d returns a number of different variables, including an array of counts
bins_x = np.arange(0.5, 10.5+1, 1)
bins_y = np.arange(-0.5, 10.5+1, 1)
h2d = plt.hist2d(data = df, x = 'disc_var1', y = 'disc_var2',
bins = [bins_x, bins_y], cmap = 'viridis_r', cmin = 0.5)
counts = h2d[0]
# loop through the cell counts and add text annotations for each
for i in range(counts.shape[0]):
for j in range(counts.shape[1]):
c = counts[i,j]
if c >= 7: # increase visibility on darkest cells
plt.text(bins_x[i]+0.5, bins_y[j]+0.5, int(c),
ha = 'center', va = 'center', color = 'white')
elif c > 0:
plt.text(bins_x[i]+0.5, bins_y[j]+0.5, int(c),
ha = 'center', va = 'center', color = 'black')
如果热图中有太多的单元格,注释将太多,无法看清。在这种情形下,建议不要添加注释,直接通过数据和色条传达信息。通常你会在单元格很少的分类热图中看到注释。实际上,seaborn 的 heatmap
函数中内置了一个添加注释的参数,稍后我们将讲解。