查看全课大纲(第 71 / 101 节)
  1. 1.数据分析基本概念
  2. 2.学习数据分析的一般路线
  3. 3.数据分析的流程
  4. 4.数据类型
  5. 5.环境部署(1)
  6. 6.环境部署(2)
  7. 7.课程介绍
  8. 8.TXT文件操作
  9. 9.JSON文件操作
  10. 10.CSV文件操作
  11. 11.Excel文件操作
  12. 12.数据库及SQL常用语法
  13. 13.数据库基本操作
  14. 14.数据库多表连接
  15. 15.实战:欧洲职业足球数据库分析
  16. 16.爬虫简介
  17. 17.URL管理模块
  18. 18.网页下载模块
  19. 19.网页解析模块(1)
  20. 20.网页解析模块(2)
  21. 21.Scrapy简介
  22. 22.Scrapy使用步骤(1)
  23. 23.Scrapy使用步骤(2)
  24. 24.Scrapy使用步骤(3)
  25. 25.Scrapy使用步骤(4)
  26. 26.实战:获取国内城市空气质量指数数据
  27. 27.NumPy和SciPy介绍
  28. 28.多维数组
  29. 29.多维数组操作
  30. 30.NumPy的常用方法
  31. 31.向量化介绍
  32. 32.向量化及通用函数
  33. 33.实战:2016美国大选分析
  34. 34.数据结构-Series
  35. 35.数据结构-DataFrame
  36. 36.数据结构-Index
  37. 37.Series的索引操作
  38. 38.DataFrame的索引操作
  39. 39.索引操作总结
  40. 40.运算与对齐
  41. 41.函数应用操作(1) -- map
  42. 42.函数应用操作 (2) -- apply applymap
  43. 43.文件读写操作
  44. 44.排序操作
  45. 45.数据清洗--处理缺失数据
  46. 46.数据清洗--处理重复数据
  47. 47.数据清洗--替换数据
  48. 48.常用统计方法(1) -- describe quantile
  49. 49.常用统计方法(2) -- sum mean median count
  50. 50.常用统计方法(3) -- max min idxmax idxmin
  51. 51.常用统计方法(4) -- mad var std cumsum
  52. 52.实战:全球食品数据分析
  53. 53.层级索引
  54. 54.分组与聚合介绍
  55. 55.分组操作(1) -- GroupBy对象及常用聚合操作
  56. 56.分组操作(2) -- 自定义分组及聚合操作
  57. 57.透视表介绍
  58. 58.透视表操作
  59. 59.数据规整(1) -- 数据合并concat
  60. 60.数据规整(2) -- 数据连接merge
  61. 61.数据重构(3) -- 数据重构stack unstack
  62. 62.实战:互联网电影资料库分析
  63. 63.探索性数据分析EDA介绍
  64. 64.EDA的目的
  65. 65.EDA常用工具
  66. 66.Matplotlib绘图基本介绍
  67. 67.Matplotlib画布
  68. 68.散点图和柱状图的绘制
  69. 69.直方图的绘制
  70. 70.矩阵绘图
  71. 71.子图的使用
  72. 72.Matplotlib颜色、标记、线型
  73. 73.Matplotlib坐标刻度、标签、图例、标题
  74. 74.Seaborn介绍
  75. 75.数据集分布可视化(1) -- 单变量分布、双变量分布
  76. 76.数据集分布可视化(2) -- 变量关系可视化
  77. 77.类别数据可视化 -- 类别散布图、类别内数据分布、类别内统计图
  78. 78.交互式数据可视化工具Bokeh介绍
  79. 79.Bokeh绘制散点图、柱状图、盒子图、弦图
  80. 80.Bokeh绘制常用图形元素
  81. 81.3D绘图 -- mplot3d
  82. 82.3D曲线可视化
  83. 83.3D散点图可视化
  84. 84.3D柱状图可视化
  85. 85.Pandas绘图
  86. 86.实战:Lending Club借贷数据探索性分析及可视化
  87. 87.机器学习介绍及应用场景
  88. 88.机器学习建模介绍 (1) -- 分类
  89. 89.机器学习建模介绍 (2) -- 回归
  90. 90.机器学习建模介绍 (3) -- 聚类
  91. 91.机器学习分类
  92. 92.机器学习工具scikit-learn
  93. 93.使用scikit-learn的流程
  94. 94.数据集准备及划分
  95. 95.模型选择
  96. 96.数据预处理及特征工程
  97. 97.过拟合与欠拟合
  98. 98.模型调参介绍
  99. 99.模型调参方法
  100. 100.模型测试及评价
  101. 101.实战:通过移动设备行为数据预测性别和年龄

子图的使用

约 7 分钟

📺 正在播放小象学院官方高清录播(支持倍速与清晰度调节)

小象实战讲义 · Python数据分析实战

在数据分析的可视化环节,我们常常需要将多个相关的图表并排展示,以便于对比分析或呈现数据的不同侧面。Matplotlib 提供的子图(Subplot)功能,允许我们在一张画布上创建并管理多个独立的绘图区域。本节将学习如何使用 plt.subplots 函数高效地创建和绘制子图,并理解共享坐标轴等高级控制参数。

💡 核心导读

  • 子图概念:理解如何将一张画布(Figure)划分为多个独立的绘图区域(Axes)。
  • plt.subplots 函数:掌握使用 plt.subplots 函数创建画布和子图数组的核心方法。
  • 子图索引与绘制:学会通过二维数组索引访问每个子图,并在其上调用不同的绘图方法。
  • 坐标轴共享:了解 sharex 和 sharey 参数的作用,实现多个子图间坐标轴的联动。

什么是子图?

子图,顾名思义,是指在一张完整的画布(Figure)上,划分出多个独立的、更小的绘图区域(Axes)。每个子图都可以看作一个独立的画布,你可以在上面绘制散点图、柱状图、直方图等任何类型的图表。

这种布局方式非常实用,例如,你可以将同一数据集的不同可视化视图(如分布、趋势、相关性)并排展示,或者将不同数据集的同类图表放在一起进行对比。

使用 plt.subplots 创建子图

Matplotlib 的 pyplot 模块提供了 subplots 函数,它是创建子图布局最便捷的方法。

该函数的核心参数如下:

  • nrows: 子图布局的行数。
  • ncols: 子图布局的列数。
  • sharex: 布尔值,若为 True,则所有子图共享同一个 x 轴(列方向共享)。
  • sharey: 布尔值,若为 True,则所有子图共享同一个 y 轴(行方向共享)。
  • figsize: 元组,指定整个画布的宽度和高度(单位:英寸)。

plt.subplots 函数会返回两个对象:

  1. fig: 创建的整个画布(Figure)对象。
  2. axs: 一个 numpy.ndarray 数组,其形状为 (nrows, ncols),包含了所有子图(Axes)对象。你可以通过二维索引 axs[row, col] 来访问和操作特定的子图。

下面我们通过一个例子来具体演示。

import matplotlib.pyplot as plt
import numpy as np

# 1. 创建画布和子图数组:2行2列,画布大小为8x8英寸
fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(8, 8))

# 2. 在第一个子图(第0行,第0列)上绘制散点图
# 生成模拟数据
x_scatter = np.random.randn(50)
y_scatter = np.random.randn(50) * 2
axs[0, 0].scatter(x_scatter, y_scatter)
axs[0, 0].set_title('散点图 (Scatter Plot)')

# 3. 在第二个子图(第0行,第1列)上绘制柱状图
x_bar = [1, 2, 3, 4, 5]
height_bar = [5, 2, 7, 8, 2]
axs[0, 1].bar(x_bar, height_bar)
axs[0, 1].set_title('柱状图 (Bar Chart)')

# 4. 在第三个子图(第1行,第0列)上绘制直方图
data_hist = np.random.randn(50)
axs[1, 0].hist(data_hist, bins=10, rwidth=0.8)
axs[1, 0].set_title('直方图 (Histogram)')

# 5. 在第四个子图(第1行,第1列)上绘制热力图(使用imshow)
matrix = np.random.rand(5, 5)
im = axs[1, 1].imshow(matrix, cmap='viridis')
axs[1, 1].set_title('热力图 (Heatmap)')
# 为热力图添加颜色条
plt.colorbar(im, ax=axs[1, 1])

# 6. 自动调整子图布局,防止标签重叠,并显示图形
plt.tight_layout()
plt.show()
(显示一个包含2行2列四个子图的窗口,分别绘制了散点图、柱状图、直方图和热力图)

代码解析:

  1. plt.subplots(2, 2, figsize=(8, 8)) 创建了一个 2x2 的子图网格,并将所有子图对象存储在二维数组 axs 中。
  2. 通过 axs[0, 0]、axs[0, 1] 等索引,我们可以像操作单个 Axes 对象一样,在每个子图上调用 .scatter(), .bar(), .hist(), .imshow() 等绘图方法,以及 .set_title() 等方法设置属性。
  3. plt.tight_layout() 是一个很实用的函数,它能自动调整子图参数,使子图标签、标题等不会互相重叠。
  4. 最后调用 plt.show() 显示图形。

共享坐标轴:sharex 与 sharey

观察上面的图形,你会发现四个子图的 x 轴和 y 轴刻度是各自独立的。在某些对比场景下,我们希望子图使用相同的坐标轴刻度,以便进行精确比较。这时就需要用到 sharex 和 sharey 参数。

  • sharex=True: 同一列的子图将共享 x 轴。最下方子图的 x 轴刻度会作为整列的基准。
  • sharey=True: 同一行的子图将共享 y 轴。最左侧子图的 y 轴刻度会作为整行的基准。

注意:共享坐标轴后,Matplotlib 会把所有相关子图的数据范围取并集作为该轴的显示范围。这保证每个子图的数据都不会被裁掉,但代价是:如果某个子图的数据范围远小于其他子图,它会被“压扁”在共享轴的一小段里,细节不容易看清。

import matplotlib.pyplot as plt
import numpy as np

# 创建画布和子图数组,并共享x轴
fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(8, 8), sharex=True)

# 绘制与之前相同的数据
x_scatter = np.random.randn(50)
y_scatter = np.random.randn(50) * 2
axs[0, 0].scatter(x_scatter, y_scatter)
axs[0, 0].set_title('共享X轴 - 散点图')

x_bar = [1, 2, 3, 4, 5]
height_bar = [5, 2, 7, 8, 2]
axs[0, 1].bar(x_bar, height_bar) # 注意:柱状图的x为1-5
axs[0, 1].set_title('共享X轴 - 柱状图')

data_hist = np.random.randn(50)
axs[1, 0].hist(data_hist, bins=10, rwidth=0.8)
axs[1, 0].set_title('共享X轴 - 直方图')

matrix = np.random.rand(5, 5)
im = axs[1, 1].imshow(matrix, cmap='plasma')
axs[1, 1].set_title('共享X轴 - 热力图')
plt.colorbar(im, ax=axs[1, 1])

plt.tight_layout()
plt.show()
(显示图形。观察可发现,同一列子图的x轴刻度范围变得一致——这个范围是各子图数据范围的并集。
 例如散点图和直方图的数据在x轴上大致分布在[-3,3],而柱状图需要显示x=5的位置,
 共享后的x轴范围会被拉宽到能容纳所有子图的数据;柱状图最右侧的柱子(x=5)依然完整显示,
 只是散点图/直方图在宽轴上会显得相对集中于中段。
 热力图的x轴(0-4)同样被对齐到共享的x轴刻度上。)

共享 y 轴 (sharey=True) 的效果类似,会使同一行的子图 y 轴刻度保持一致。你可以尝试将上面代码中的 sharex=True 改为 sharey=True 来观察效果。

📝 动手练一练

  1. 概念辨析:plt.subplots(3, 1) 和 plt.subplots(1, 3) 创建的子图布局有什么不同?返回的 axs 对象的形状分别是什么?
👉 点击查看参考答案
  • plt.subplots(3, 1) 创建的是 3行1列 的纵向布局,即三个子图竖直排列。注意:由于另一维只有 1(squeeze=True 是默认行为),返回的 axs 是一个一维数组,形状为 (3,)——访问子图直接用 axs[0], axs[1], axs[2];此时写 axs[0, 0] 反而会抛 IndexError(一维数组不接受二维索引)。
  • plt.subplots(1, 3) 创建的是 1行3列 的横向布局,即三个子图水平排列。同理,返回的 axs 也是一维数组,形状为 (3,),用 axs[0], axs[1], axs[2] 访问。
  • 只有当行、列都大于 1(如 subplots(2, 2))时,axs 才是真正的二维数组,才需要用 axs[row, col] 访问。
  1. 动手实践:修改第一个示例代码,创建一个 1行2列的子图布局。在左侧子图绘制正弦曲线 y = sin(x),在右侧子图绘制余弦曲线 y = cos(x),其中 x 的范围为 [0, 2π]。为两个子图分别添加标题,并尝试设置 sharey=True,观察图形变化。
👉 点击查看参考答案
import matplotlib.pyplot as plt
import numpy as np

# 创建1行2列的子图,并共享y轴
fig, axs = plt.subplots(1, 2, figsize=(10, 4), sharey=True)

# 生成x数据
x = np.linspace(0, 2*np.pi, 100)

# 在左侧子图绘制正弦曲线
axs[0].plot(x, np.sin(x), color='blue')
axs[0].set_title('正弦函数 y = sin(x)')
axs[0].grid(True)

# 在右侧子图绘制余弦曲线
axs[1].plot(x, np.cos(x), color='red')
axs[1].set_title('余弦函数 y = cos(x)')
axs[1].grid(True)

plt.tight_layout()
plt.show()
(显示一个横向排列的图形,左侧为蓝色正弦波,右侧为红色余弦波。
 由于设置了sharey=True,两个子图的y轴刻度范围保持一致,便于对比两个函数的振幅。)

本章小结

本节我们学习了 Matplotlib 中子图(Subplot)的核心创建方法。通过 plt.subplots 函数,我们可以灵活地定义画布的网格布局,并便捷地获取每个子图对象进行独立绘图。sharex 和 sharey 参数为我们提供了控制子图间坐标轴关系的强大工具,使得多图对比更加规范和清晰。

📋 行动清单

  • 尝试使用 plt.subplots 创建不同行列数(如 2x3, 3x1)的子图布局,感受 axs 数组的索引方式。
  • 在一个 2x2 的子图中,分别用折线图、散点图、箱线图和饼图展示不同的模拟数据。
  • 修改 sharex 和 sharey 参数,观察同一组数据在不同共享设置下可视化效果的差异,思考其适用的分析场景。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 本节课件:子图的使用
    PDF · 204KB
    下载
  • 全套课件打包(第1-5章)
    ZIP · 12.8MB
    下载
  • 全套课件打包(第6-8章)
    ZIP · 15MB
    下载
  • 实战数据集:AppleStore 应用商城分析
    ZIP · 329KB
    下载
  • 实战数据集:女性服装电商分析
    ZIP · 2.8MB
    下载
  • Python 数据分析环境搭建指南
    PDF · 2MB
    下载
  • Scrapy 安装教程
    PDF · 12.7MB
    下载
  • 附加实战项目:AppleStore 应用商城数据分析
    ZIP · 0.3MB · ipynb + CSV 数据
    下载
  • 附加实战项目:银行电话营销数据分析
    ZIP · 0.4MB · ipynb + CSV 数据
    下载
  • 附加实战项目:女性服装电商评论数据分析
    ZIP · 2.7MB · ipynb + CSV 数据
    下载
  • 附加实战项目:美国化学学会杂志数据分析
    ZIP · 34.2MB · ipynb + SQLite 数据库
    下载