matplotlib subplot与subplots多图参数详解
一、多图绘制入口:subplot 与 subplotsMatplotlib 的 pyplot 提供 subplot() 和 subplots() 两种多子图绘制方式。前者在绘图时需要指定子图位置,每调用一次通常只处理一个子图;后者可以一次生成多个子图,调用时直接使用返回对象中的 ax 即可。
二、subplot:按行列位置逐个添加子图
subplot 常见调用形式包括:
subplot(nrows, ncols, index, **kwargs)
subplot(pos, **kwargs)
subplot(**kwargs)
subplot(ax)
它会把整个绘图区域分成 nrows 行、ncols 列,然后按从左到右、从上到下的顺序给每个子区域编号为 1...N。左上角子区域编号为 1,右下角编号为 N,具体使用哪个子区域由 index 决定。
当 nrows=1、ncols=2 时,图表被划分为 1x2 区域,对应坐标是 (1,1)、(1,2)。index=1 表示第一行第一列,index=2 表示第一行第二列。示例代码:
import matplotlib.pyplot as plt
import numpy as np
#plot 1:
xpoints = np.array()
ypoints = np.array()
plt.subplot(1, 2, 1)
plt.plot(xpoints,ypoints)
plt.title("plot 1")
#plot 2:
x = np.array()
y = np.array()
plt.subplot(1, 2, 2)
plt.plot(x,y)
plt.title("plot 2")
plt.suptitle("W3Cschool subplot Test")
plt.show()
当 nrows=2、ncols=2 时,区域被划分为 2x2,对应坐标是 (1,1)、(1,2)、(2,1)、(2,2)。index 依次为:1 对应 (1,1),2 对应 (1,2),3 对应 (2,1),4 对应 (2,2)。代码示例:
import matplotlib.pyplot as plt
import numpy as np
#plot 1:
x = np.array()
y = np.array()
plt.subplot(2, 2, 1)
plt.plot(x,y)
plt.title("plot 1")
#plot 2:
x = np.array()
y = np.array()
plt.subplot(2, 2, 2)
plt.plot(x,y)
plt.title("plot 2")
#plot 3:
x = np.array()
y = np.array()
plt.subplot(2, 2, 3)
plt.plot(x,y)
plt.title("plot 3")
#plot 4:
x = np.array()
y = np.array()
plt.subplot(2, 2, 4)
plt.plot(x,y)
plt.title("plot 4")
plt.suptitle("W3Cschool subplot Test")
plt.show()
三、subplots:一次创建画布和多个 Axes
subplots() 的语法格式为:
matplotlib.pyplot.subplots(nrows=1, ncols=1, *, sharex=False, sharey=False, squeeze=True, subplot_kw=None, gridspec_kw=None, **fig_kw)
关键参数含义如下:
- nrows:默认 1,设置图表行数。
- ncols:默认 1,设置图表列数。
- sharex、sharey:设置 x、y 轴是否共享属性,默认 false,可设为 'none'、'all'、'row' 或 'col'。False 或 none 表示每个子图的 x 轴或 y 轴独立;True 或 'all' 表示所有子图共享 x 轴或 y 轴;'row' 表示每个子图行共享一个 x 轴或 y 轴;'col' 表示每个子图列共享一个 x 轴或 y 轴。
- squeeze:布尔值,默认 True,表示额外维度从返回的 Axes 对象中挤出。对于 N*1 或 1*N 个子图,返回一维数组;对于 N*M,且 N>1、M>1,返回二维数组。如果设为 False,则不进行挤压操作,返回元素为 Axes 实例的二维数组,即使最终是 1x1。
- subplot_kw:可选字典,把关键字传递给 add_subplot() 来创建每个子图。
- gridspec_kw:可选字典,把关键字传递给 GridSpec 构造函数,用于创建放在网格里的子图。
- **fig_kw:把详细关键字参数传给 figure() 函数。
实践中,subplots 返回的 fig 代表画布,ax 或 axs 代表一个或多个 Axes。示例代码:
import matplotlib.pyplot as plt
import numpy as np
# 创建一些测试数据 -- 图1
x = np.linspace(0, 2*np.pi, 400)
y = np.sin(x**2)
# 创建一个画像和子图 -- 图2
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_title('Simple plot')
# 创建两个子图 -- 图3
f, (ax1, ax2) = plt.subplots(1, 2, sharey=True)
ax1.plot(x, y)
ax1.set_title('Sharing Y axis')
ax2.scatter(x, y)
# 创建四个子图 -- 图4
fig, axs = plt.subplots(2, 2, subplot_kw=dict(projection="polar"))
axs.plot(x, y)
axs.scatter(x, y)
# 共享 x 轴
plt.subplots(2, 2, sharex='col')
# 共享 y 轴
plt.subplots(2, 2, sharey='row')
# 共享 x 轴和 y 轴
plt.subplots(2, 2, sharex='all', sharey='all')
# 这个也是共享 x 轴和 y 轴
plt.subplots(2, 2, sharex=True, sharey=True)
# 创建标识为 10 的图,已经存在的则删除
fig, ax = plt.subplots(num=10, clear=True)
plt.show()
四、参数选择与适用场景
从调用方式看,subplot 更适合按位置逐个添加子图:每次调用传入行数、列数和 index,随后用 plt.plot、plt.title 等当前轴方法绘图。subplots 更适合一次性搭好画布和子图数组,再通过 ax 对象分别绘图,尤其在需要共享轴、统一设置 subplot_kw 或 gridspec_kw 时更直接。
需要特别注意 squeeze 对返回结构的影响:1x2 这类布局在默认 squeeze=True 时可直接解包成两个 Axes;2x2 这类行列都大于 1 的布局返回二维数组,需要用 axs、axs 等方式访问。若希望无论行列数如何都得到二维数组,可把 squeeze=False。共享轴方面,sharex/sharey 的 False、none、True、all、row、col 分别对应独立、全部共享、按行共享和按列共享,实际选择应结合坐标刻度可读性与子图布局决定。
总结来说,subplot 与 subplots 都是 Matplotlib 绘制多图的常用入口,核心差异在于定位方式、返回对象和参数传递方式。逐个定位子图时用 subplot,批量创建并统一管理 Axes 时用 subplots,理解了行列编号、index、sharex/sharey、squeeze 等参数后,多子图代码会更容易维护。
Re: matplotlib subplot与subplots多图参数详解
楼主整理得很清楚,subplot 和 subplots 这两个入口的区别一下就明白了。subplot 更像是按位置逐个占坑,index 从左到右、从上到下编号,左上角是 1,右下角是 N;subplots 则是一次把画布和多个 Axes 都建好,后面直接用返回的 fig、ax 或 axs 来画。 我对 sharex、sharey 和 squeeze 这两个点印象比较深。共享轴用 False/none、True/all、row、col 来控制,做对比图时很方便;squeeze 默认 True 时,1xN 或 Nx1 会返回一维数组,N 和 M 都大于 1 才返回二维数组,如果要统一按二维下标访问,设成 False 会省心很多。subplot_kw 和 gridspec_kw 这种传参方式也很实用,比如投影方式或网格布局参数。 示例代码覆盖了 1x2、2x2 和 subplots 常见用法,很适合拿来对着跑一遍。感谢分享,收藏了。Re: matplotlib subplot与subplots多图参数详解
楼主这篇整理得挺清楚,subplot 和 subplots 的定位区分得很明白。subplot 按 nrows、ncols、index 从左到右、从上到下编号,左上为 1、右下为 N,这个规则配合 1x2 和 2x2 的示例很好理解;subplots 一次拿到 fig 和 ax/axs,后面直接操作 ax,比反复调用 plt.subplot 清爽不少。参数部分里 sharex、sharey 的 all、row、col 取值,以及 squeeze 默认 True 时 N*1 或 1*N 返回一维数组、N*M 返回二维数组,这两个细节平时很容易忽略,写出来很有帮助。subplot_kw 传 projection 做极坐标子图、gridspec_kw 和 fig_kw 的分工也交代得比较清楚。示例从简单到多图逐步展开,适合边看边练。帖子末尾好像停在 plt.subp,期待后续把共享轴那部分补全。Re: matplotlib subplot与subplots多图参数详解
楼主这篇整理得挺清楚,subplot 和 subplots 的区别讲得很直观,尤其是 subplot 的 index 编号顺序、subplots 里 sharex/sharey 的几种取值,还有 squeeze 对返回 Axes 形状的影响,这些平时确实容易混。示例从 1x2 到 2x2,再到 polar 子图,一步步看下来比较好懂。日常画多个子图时,subplots 一次拿到 fig 和 axs 确实会省事很多,subplot 更适合按位置逐个添加。最后一段代码好像停在 plt.subp 那里了,是不是编辑时被截断了?有空可以补上共享坐标轴的完整示例,应该会更有帮助。感谢分享。
页:
[1]