Python 数据可视化 · 教材配套演示

第2章 使用 matplotlib 绘制简单图表

本章使用 matplotlib 库的 pyplot 子模块,学习绘制十类基础统计图表。每个图表均配有"语法说明 + 示例代码 + 实例演练",实例数据与教材完全一致。

◎

学习目标

学完本章,你将掌握以下内容:

1

掌握 绘制折线图,掌握 绘制柱形图或堆积柱形图

2

掌握 绘制条形图或堆积条形图,绘制堆积面积图、直方图

3

掌握 绘制箱形图,绘制雷达图,绘制误差棒图

4

掌握 绘制饼图或圆环图,绘制散点图或气泡图

2.1

绘制折线图

使用 pyplot 的 plot() 函数可以快速地绘制折线图。

语法与参数

plot(x, y, fmt, scalex=True, scaley=True, data=None, label=None, *args, **kwargs)
  • x / y:分别表示 x 轴与 y 轴对应的数据
  • fmt:定义图的基本属性的字符串,形式为 [color][marker][line],即颜色、点型、线型
  • label:图例中的标签
  • plot() 函数会返回一个包含 Line2D 类对象(代表线条)的列表

绘制具有多个线条的折线图(三种方式)

第1种

plt.plot(x1, y1)
plt.plot(x2, y2)

第2种

plt.plot(x1, y1, x2, y2)

第3种

arr = np.array([[1,2,3],
               [4,5,6],
               [7,8,9],
               [10,11,12]])
plt.plot(arr[0], arr[1:])
实例 1

2.1.2 实例1:未来15天最高气温和最低气温

人们每天的生活离不开天气预报,无论是居家还是外出,人们都时刻关注着天气的变化,以便随时备好伞具、增减衣服,或者为后期的出行计划做好准备。本实例根据表2-1的数据,将日期列的数据作为x轴数据,将最高气温和最低气温两列的数据作为y轴数据,使用 plot() 函数绘制折线图。

📈 由图可知,未来15天的最高气温和最低气温都呈现 逐步下降后反弹 的趋势。
表2-1 北京市未来15天的最高气温和最低气温(单位:℃)
2.2

绘制柱形图或堆积柱形图

使用 pyplot 的 bar() 函数可以快速地绘制柱形图或堆积柱形图。

语法与参数

bar(x, height, width=0.8, bottom=None, align='center', tick_label=None, xerr=None, yerr=None, **kwargs)
  • x:柱形的 x 轴坐标值(刻度值);height:柱形的高度
  • width:柱形的宽度;bottom:柱形底部的 y 轴坐标值,默认为 0
  • align:柱形与 x 轴刻度值的对齐方式('center' 居中 / 'edge' 边缘)
  • tick_label:每个柱形的刻度标签
  • xerr / yerr:柱形顶部误差棒的横向/纵向偏差
  • 绘制堆积柱形图:通过给 bottom 参数传值,使后绘制的柱形位于先绘制的柱形上方
  • 返回值:BarContainer 类对象(柱形容器),可访问 patches 或 errorbar 属性获取所有柱形或误差棒

示例代码

# 绘制有一组柱形的柱形图
x = np.arange(5)
y1 = np.array([10, 8, 7, 11, 13])
bar_width = 0.3
plt.bar(x, y1, tick_label=['a','b','c','d','e'],
        width=bar_width)

# 绘制有两组柱形的柱形图
y2 = np.array([9, 6, 5, 10, 12])
plt.bar(x+bar_width, y2, width=bar_width)

# 绘制堆积柱形图(后柱位于先柱上方)
plt.bar(x, y2, bottom=y1, width=bar_width)

# 绘制有误差棒的柱形图
error = [2, 1, 2.5, 2, 1.5]
plt.bar(x, y1, width=bar_width, yerr=error)
实例 2

2.2.2 实例2:2013~2019财年阿里巴巴淘宝和天猫平台的GMV

随着互联网与电子商务的快速发展,人们的消费模式发生了翻天覆地的变化,越来越多的消费者选择网络购物,省时省力。本实例根据表2-2的数据,将财年列的数据作为x轴数据,将GMV列的数据作为y轴数据,使用 bar() 函数绘制柱形图(柱形宽度为0.5)。

📊 由图可知,2019财年的GMV最高,约60000亿元,2013~2019财年GMV逐年稳步增长。
表2-2 2013—2019财年淘宝和天猫平台的GMV(单位:亿元)
2.3

绘制条形图或堆积条形图

使用 pyplot 的 barh() 函数可以快速地绘制条形图或堆积条形图。

语法与参数

barh(y, width, height=0.8, left=None, align='center', *, **kwargs)
  • y:条形的 y 轴坐标值;width:条形的宽度
  • height:条形的高度(粗细),默认 0.8
  • left:条形左侧的 x 轴坐标值,默认为 0
  • 绘制堆积条形图:通过给 left 参数传值,使后绘制的条形位于先绘制的条形右方
  • xerr / yerr:为条形添加误差棒
  • 返回值:BarContainer 类对象

示例代码

# 绘制有一组条形的条形图
y = np.arange(5)
x1 = np.array([10, 8, 7, 11, 13])
bar_height = 0.3
plt.barh(y, x1, tick_label=['a','b','c','d','e'],
         height=bar_height)

# 绘制有两组条形的条形图
x2 = np.array([9, 6, 5, 10, 12])
plt.barh(y+bar_height, x2, height=bar_height)

# 绘制堆积条形图(后条位于先条右方)
plt.barh(y, x2, left=x1, height=bar_height)

# 绘制有误差棒的条形图
error = [2, 1, 2.5, 2, 1.5]
plt.barh(y, x2, left=x1, height=bar_height,
         xerr=error)
实例 3

2.3.2 实例3:各商品种类的网购替代率

网络购物已经成为人们日常生活的一部分,它在创造新的消费方式的同时,也在改变着人们的消费模式和习惯,成为拉动居民消费的重要渠道。本实例根据表2-3的数据,将商品种类列的数据作为y轴的刻度标签,将替代率列的数据作为x轴数据,使用 barh() 函数绘制条形图(条形高度为0.6,x轴刻度值保留1位小数)。

📊 由图可知,工艺品、收藏品 的网购替代率最低,家政、家教、保姆等生活服务 的网购替代率最高。
表2-3 各商品种类的网购替代率(部分)
2.4

绘制堆积面积图

使用 pyplot 的 stackplot() 函数可以快速地绘制堆积面积图。

语法与参数

stackplot(x, y, labels=(), baseline='zero', data=None, *args, **kwargs)
  • x:x 轴数据,可以是一维数组
  • y:y 轴数据,可以是一维或二维数组,也可以是多个一维数组
  • labels:每个填充区域的名称,常与 legend() 配合绘制图例
  • baseline:计算基线的方法,可为 'zero'(零基线)、'sym'(对称基线)、'wiggle' 或 'weighted_wiggle'(流图)

示例代码

# 绘制有三个填充区域堆叠的堆积面积图
x = np.arange(6)
y1 = np.array([1,4,3,5,6,7])
y2 = np.array([1,3,4,2,7,6])
y3 = np.array([3,4,3,6,5,5])
plt.stackplot(x, y1, y2, y3)
实例 4

2.4.2 实例4:物流公司物流费用统计

近些年我国物流行业蓬勃发展,目前已经有近几千家物流公司,其中部分物流公司大打价格战,以更低的价格吸引更多的客户,从而抢占市场份额。本实例根据表2-4的数据,将月份列的数据作为x轴的刻度标签,将A公司、B公司、C公司这三列数据作为y轴的数据,使用 stackplot() 函数绘制堆积面积图。

📈 由图可知,12月份 A、B、C 三个公司物流费用的总和最高,B公司的物流费用呈逐年上升趋势。
表2-4 A、B、C物流公司物流费用统计(单位:万元)
2.5

绘制直方图

使用 pyplot 的 hist() 函数可以快速地绘制直方图。

语法与参数

hist(x, bins=None, range=None, density=None, weights=None, bottom=None, **kwargs)
  • x:输入值,即所有矩形条的值
  • bins:矩形条的个数,即分成多少块(区间)
  • range:矩形条的上下界(范围),超出上下界的将被舍弃
  • density:True → 以频率绘制矩形条(频率=频数/样本总数);False → 以频数绘制(默认)
  • weights:每个样本点对应的权重
  • bottom:每个矩形条底部的 y 轴坐标值(基线)
  • histtype:矩形条的样式,如 'bar'、'stepfilled'(填充的线条)等

示例代码

# 准备50个随机测试数据
scores = np.random.randint(0, 100, 50)

# 绘制填充的线条直方图
plt.hist(scores, bins=8,
         histtype='stepfilled')
实例 5

2.5.2 实例5:人脸识别的灰度直方图

人脸识别技术是一种生物特征识别技术,它通过从装有摄像头的终端设备拍摄的人脸图像中抽取人的个性化特征,以此来识别人的身份。灰度直方图能直观展示图像灰度值的分布情况。本实例使用一组 10000 个随机数作为人脸图像的灰度值,使用 hist() 函数绘制包含 25 个矩形条的灰度直方图(随机种子 19680801)。

📷 由图可知,25个矩形条的灰度值分布大致在 -4 ~ 4 之间,其中 0.5 ~ 0 附近的灰度值出现频率最高,频率呈中间高、两侧低的正态分布形态。
random_state = np.random.RandomState(19680801)
radom_x = random_state.randn(10000)
# 绘制包含25个矩形条的直方图
plt.hist(radom_x, bins=25)
2.6

绘制饼图或圆环图

使用 pyplot 的 pie() 函数可以快速地绘制饼图或圆环图。

语法与参数

pie(x, explode=None, labels=None, autopct=None, pctdistance=0.6, startangle=None, *, data=None)
  • x:扇形的数据(各扇形面积比例)
  • explode:各扇形离开圆心的距离
  • labels:各扇形的标签
  • autopct:以百分比形式显示扇形上的数值(如 '%3.1f%%' 表示数值保留1位小数)
  • pctdistance:百分比数值距离圆心的半径比例
  • startangle:起始角度(第一个扇形逆时针旋转的角度),默认从 x 轴正方向开始
  • shadow:是否显示阴影
  • 绘制圆环图:设置 wedgeprops={'width': 0.7}(扇形宽度)与 pctdistance=0.75

示例代码

data = np.array([20, 50, 10, 15, 30, 55])
pie_labels = np.array(['A','B','C','D','E','F'])

# 绘制饼图:半径为1.5,数值保留1位小数
plt.pie(data, radius=1.5, labels=pie_labels,
        autopct='%3.1f%%')

# 绘制圆环图
plt.pie(data, radius=1.5,
        wedgeprops={'width': 0.7},
        labels=pie_labels, autopct='%3.1f%%',
        pctdistance=0.75)
实例 6

2.6.2 实例6:支付宝月账单报告

近年来随着支付App的出现,人们的生活发生了翻天覆地的变化,无论是到超市选购商品,还是跟朋友聚餐,或是来一场说走就走的旅行,都可以使用移动支付App轻松完成支付,非常便捷。本实例根据表2-5的数据,将分类列的数据作为饼图的标签,将各分类对应的金额与总支出金额的比例作为饼图的数据,使用 pie() 函数绘制饼图(起始角度为90,人情往来离开圆心距离为0.1,显示阴影)。

🥧 由图可知,绿色扇形(餐饮美食)的面积最大,说明餐饮美食方面的支出在当月总支出中占比最大;橙色扇形(人情往来)的面积最小,说明人情往来的支出在当月总支出中占比最小。
表2-5 用户A某月使用支付宝的消费明细(单位:元)
2.7

绘制散点图或气泡图

使用 pyplot 的 scatter() 函数可以快速地绘制散点图或气泡图。

语法与参数

scatter(x, y, s=None, c=None, marker=None, cmap=None, linewidths=None, edgecolors=None, *, **kwargs)
  • x / y:数据点的横、纵坐标值
  • s:数据点的大小(面积),传值后即为气泡图
  • c:数据点的颜色
  • marker:数据点的点型
  • cmap:将数值映射为颜色的色彩映射表
  • linewidths / edgecolors:数据点(气泡)边缘的线条宽度与颜色

示例代码

# 绘制散点图
num = 50
x = np.random.rand(num)
y = np.random.rand(num)
plt.scatter(x, y)

# 绘制气泡图
area = (30 * np.random.rand(num))**2
plt.scatter(x, y, s=area)
实例 7

2.7.2 实例7:汽车速度与制动距离的关系

汽车的制动距离主要取决于汽车的车速。若车速增加1倍,则汽车的制动距离将增大至近4倍。本实例根据表2-6的数据,将车速(km/h)列的数据作为x轴的数据,将制动距离(m)列的数据作为y轴的数据,使用 scatter() 函数绘制散点图。

🚗 由图可知,制动距离随着车速的增加呈现 曲线(加速)式上升 的趋势——车速越高,制动距离增大得越快。
表2-6 车速与制动距离的关系
2.8

绘制箱形图

使用 pyplot 的 boxplot() 函数可以快速地绘制箱形图。

语法与参数

boxplot(x, notch=None, sym=None, vert=None, whis=None, positions=None, widths=None, *, data=None)
  • x:要绘制箱形图的数据
  • notch:箱体是否有凹口(True → 凹口显示中位数附近置信区间)
  • sym:异常点对应的符号(默认 'b+' 蓝色加号)
  • vert:箱体是横向还是纵向(False → 横向摆放)
  • whis:箱体上下须与四分位数的距离,默认 1.5 倍四分位差
  • positions:箱体的位置;widths:箱体的宽度
  • meanline:是否用线标示均值;patch_artist:是否给箱体填充颜色
  • showfliers:是否显示异常值;labels:箱体的标签

示例代码

# 绘制不显示异常值的箱形图
data = np.random.randn(100)
plt.boxplot(data, meanline=True,
            widths=0.3, patch_artist=True,
            showfliers=False)
实例 8

2.8.2 实例8:2017年和2018年全国发电量统计

本实例根据表2-7的数据,将发电量(亿千瓦时)列的数据作为x轴的数据,将2017年和2018年作为y轴的刻度标签,使用 boxplot() 函数绘制箱形图(显示中位数、显示异常值,箱体宽度0.5、填充颜色、横向摆放)。

📦 由图可知,2017年每月的发电量大多分布于 4800~5300亿千瓦时 范围内,2018年每月的发电量大多分布于 5250~5700亿千瓦时 范围内。
表2-7 2017年和2018年全国发电量统计(单位:亿千瓦·时)
2.9

绘制雷达图

使用 pyplot 的 polar() 函数可以快速地绘制雷达图。

语法与参数

polar(theta, r, **kwargs)
  • theta:极坐标系中每个数据点的角度数据(弧度制)
  • r:极坐标系中每个数据点的半径数据
  • 绘制雷达图时需要闭合曲线:角度首尾相接、数据首尾复制一份

实例说明

霍兰德职业兴趣测试是由美国职业指导专家霍兰德根据他本人大量的职业咨询经验及其职业类型理论编制的测评工具。它将职业类型划分为:研究型(I)、艺术型(A)、社会型(S)、企业型(E)、传统型(C)、现实型(R)。本实例根据表2-8的数据,将标题一行的数据作为雷达图的标签,将其余行的数据作为雷达图的数据,使用 polar() 函数绘制雷达图。

实例 9

2.9.2 实例9:霍兰德职业兴趣测试

🕸 由图可知:用户1 偏向于现实型人格;用户2 偏向于研究型人格;用户3 偏向于艺术型人格;用户4 偏向于企业型人格;用户5 偏向于社会型人格;用户6 偏向于传统型人格。
表2-8 6名用户霍兰德职业兴趣测试的结果
2.10

绘制误差棒图

使用 pyplot 的 errorbar() 函数可以快速地绘制误差棒图。

语法与参数

errorbar(x, y, yerr=None, xerr=None, fmt='', ecolor=None, *, data=None, **kwargs)
  • x / y:数据点的位置
  • yerr / xerr:数据点的纵向/横向误差范围
  • fmt:数据点的标记样式与线条样式(如 'o')
  • ecolor:误差棒的颜色;capsize:误差棒端帽的大小;capthick:端帽粗细

示例代码

# 绘制误差棒图
x = np.arange(5)
y = (25, 32, 34, 20, 25)
y_offset = (3, 5, 2, 3, 3)
plt.errorbar(x, y, yerr=y_offset,
             capsize=3, capthick=2)
实例 10

2.10.2 实例10:4个树种不同季节的细根生物量

细根生物量的多少反映了根系从土壤中吸收水分和养分的能力,是植物地下部分集汇能力的重要体现。不同树种细根生物量存在差异性,各树种细根生物量在不同季节间差异较为明显。本实例根据表2-9的数据,将季节列的数据作为x轴的刻度标签,将其他列的数据作为y轴的数据,使用 errorbar() 函数绘制误差棒图。

🌿 由图可知,杉木 的细根生物量最多,说明杉木吸收水分和养分的能力最强;马尾松 的细根生物量最少,说明马尾松吸收水分和养分的能力最弱。
表2-9 4个树种不同季节的细根生物量(单位:g)
2.11

本章小结

本章主要介绍了如何使用 matplotlib 库的绘图函数绘制简单的图表,包括折线图、柱形图或堆积柱形图、条形图或堆积条形图、堆积面积图、直方图、饼图或圆环图、散点图或气泡图、箱形图、雷达图、误差棒图。通过学习本章的内容,希望大家能够掌握绘图函数的用法,可以使用这些函数绘制简单的图表,为后续的学习打好扎实的基础。

plot()bar()barh()stackplot() hist()pie()scatter()boxplot() polar()errorbar()