从零开始学Python可视化(三): 堆积图

堆积图常用于综合展示不同分类的指标趋势以及它们的总和的趋势。比如说,我们想看一下过去二十年来中国人口总量的变化趋势,同时,我们又想看一下男、女性人口各自的变化趋势,甚至我们还想看一下它们各自占比的变化趋势,这时,我们就可以用堆积图来更高效、更简洁地展示出来。


欢迎大家关注我的个人博客【数洞】 【备用站】

我们举这样一个例子,有一个班里有20名学生,它们的编号分别是0-19,y1、y2、y3分别代表本次月考他们的语文、数学和英语的成绩,我们想观察这些学生的总成绩以及各科成绩的情况。

1. 堆积柱状图

首先,我们使用堆积柱状图来达到我们的目的:

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(0, 20, 20)
y1 = np.random.randint(50, 100, 20)
y2 = np.random.randint(50, 100, 20)
y3 = np.random.randint(50, 100, 20)

# 堆积柱状图
plt.bar(x, y1, color='r', label='语文')
plt.bar(x, y2, bottom=y1, color='g', label='数学')
plt.bar(x, y3, bottom=y1+y2, color='c', label='英语')

# 显示范围
plt.xlim(-2, 22)
plt.ylim(0, 280)

# 添加图例
plt.legend(loc='upper right')
plt.grid(axis='y', color='gray', linestyle=':', linewidth=2)

plt.show()

可以看到,有四位同学的总成绩高于250分,还有些同学严重偏科,另外有一个同学平均下来在及格线下方……大家不同太为他担心,因为这些都是随机生成的数据。

从零开始学Python可视化(三): 堆积图_第1张图片
image

我们还可以将柱子横过来:

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(0, 20, 20)
y1 = np.random.randint(50, 100, 20)
y2 = np.random.randint(50, 100, 20)
y3 = np.random.randint(50, 100, 20)

# 堆积柱状图
plt.barh(x, y1, color='r', label='语文')
plt.barh(x, y2, left=y1, color='g', label='数学')
plt.barh(x, y3, left=y1+y2, color='c', label='英语')

# 显示范围
plt.ylim(-2, 22)
plt.xlim(0, 300)

# 添加图例
plt.legend(loc='lower right')

plt.show()
从零开始学Python可视化(三): 堆积图_第2张图片
image

我们需要将bottom参数的名字改成left,这样更符合我们的视觉认知,其他参数上没有什么分别。

2. 堆积折线图

这次,我们假设小明参加了20次月考,我们想看下他的总成绩以及语数外三科成绩的变化趋势。

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
# 假设一个班里有20名学生,x代表他们的编号,y1/y2/y3分别是他们本次月考的成绩。
x = np.linspace(0, 20, 20)
y1 = np.random.randint(50, 100, 20)
y2 = np.random.randint(50, 100, 20)
y3 = np.random.randint(50, 100, 20)

# 堆积柱状图
plt.stackplot(x, y1, y2, y3, baseline='zero', labels=['语文', '数学', '英语'], colors=['r', 'g', 'c'])

# 显示范围
plt.xlim(-2, 22)
plt.ylim(0, 300)

# 添加图例和网格线
plt.legend(loc='upper right')
plt.grid(axis='y', color='gray', linestyle=':', linewidth=2)

plt.show()

嗯……小明的成绩太不稳定了,不过还好,平均成绩还没到过及格线以下。从这张图里边,我们看不到明显的上升或者下降的趋势。

从零开始学Python可视化(三): 堆积图_第3张图片
image

这样我们看到了成绩的变化趋势,但是我们不能清楚地分辨小明哪科成绩更好,哪科成绩是短板,因此我们需要看一下小明的总成绩中各科成绩占比的变化趋势。

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
# 假设一个班里有20名学生,x代表他们的编号,y1/y2/y3分别是他们本次月考的成绩。
x = np.linspace(0, 20, 20)
y1 = np.random.randint(50, 100, 20)
y2 = np.random.randint(50, 100, 20)
y3 = np.random.randint(50, 100, 20)

# 计算百分比
y1p = y1 / (y1 + y2 + y3)
y2p = y2 / (y1 + y2 + y3)
y3p = y3 / (y1 + y2 + y3)

# 比例堆积柱状图
plt.stackplot(x, y1p, y2p, y3p, baseline='zero', labels=['语文', '数学', '英语'], colors=['r', 'g', 'c'])

# 显示范围
plt.xlim(0, 20)
plt.ylim(0, 1)

# 添加图例
plt.legend(loc='upper right')
plt.grid(axis='y', color='gray', linestyle=':', linewidth=2)

plt.show()
从零开始学Python可视化(三): 堆积图_第4张图片
image

由于这里各科的成绩都是我们随机生成的,所以我们从图中并不能看出来小明的强弱势科目,但这种表现方式非常实用。比如我们要分析用户结构的变化趋势、分析内容类型分布的趋势等。这种图形相当于在饼图的基础上增加了时间序列的维度,将多个饼图拉伸开来,连接到一起。

今天我们展示了如何绘制堆积柱状图和堆积折线图(面积图),之后这一系列文章每一期会专门针对一个点来进行分享,确保每次大家能用十来分钟就学会一项新的实用技能,这样才不负咱们“功利主义”的“美名”。

你可能感兴趣的:(从零开始学Python可视化(三): 堆积图)