如上图所示,当带有标题的多个子图并排显示时,多个子图会因区域过于紧凑而出现标题和坐标轴之间相互重叠的问题,而且子图元素的摆放过于紧凑,也影响用户的正常查看。matplotlib中提供了一些调整子图布局的方法,包括约束布局、紧密布局和自定义布局,通过这些方法可以合理布局多个子图。下面将对子图的布局方法进行详细介绍。
一、约束布局
约束布局是指通过一系列限制来确定画布中元素的位置的方式,它预先会确定一个元素的绝对定位,之后以该元素的位置为基点对其他元素进行绝对定位,从而灵活地调整元素的位置。 示例代码如下:
plt.subplots(constrained_layout=True)
效果如下:
%matplotlib auto
import numpy as np
import matplotlib.pyplot as plt
x1 = np.linspace(0, 2 * np.pi, 400)
y1 = np.cos(x1 ** 2)
x2 = np.linspace(0.01, 10, 100)
y2 = np.sin(x2)
fig, ax_arr = plt.subplots(2,2, constrained_layout=True) #启用自动约束布局
#绘制图表
ax1 = ax_arr[0,0]
ax1.set_title('title1')
ax2 = ax_arr[0,1]
ax2.set_title('title2')
ax3 = ax_arr[1,0]
ax3.set_title('title3')
ax4 = ax_arr[1,1]
ax4.set_title('title4')
#展示图表
plt.show()
二、紧密布局
matplotlib中紧密布局和约束布局相似,它采用紧凑的形式将子图排列到画布中,仅适用于刻度标签、坐标轴标签和标签位置的调整。示例代码如下:
tight_layout(pad=1.08, h_pad=None, w_pad=None, rect=None)
效果如下:
%matplotlib auto
import numpy as np
import matplotlib.pyplot as plt
x1 = np.linspace(0, 2 * np.pi, 400)
y1 = np.cos(x1 ** 2)
x2 = np.linspace(0.01, 10, 100)
y2 = np.sin(x2)
fig, ax_arr = plt.subplots(2,2)
#调整子图之间的距离
#plt.tight_layout(pad=1.08, h_pad=8, w_pad=8) #设置坐标系示例之间纵向和横向间距
plt.tight_layout(pad=1.08, rect=(0.25, 0.25, 0.75, 0.75)) #把所有坐标系示例“打包”在一起,整体挪动
#绘制图表
ax1 = ax_arr[0,0]
ax1.set_title('title1')
ax2 = ax_arr[0,1]
ax2.set_title('title2')
ax3 = ax_arr[1,0]
ax3.set_title('title3')
ax4 = ax_arr[1,1]
ax4.set_title('title4')
#展示图表
plt.show()
参数注释:
·pad:表示画布边缘与子图边缘之间的空白区域的大小,默认为1.08。
·h_pad,w_pad:表示相邻子图之间的空白区域的大小。
·rect:表示调整所有子图位置的矩形区域的四元组(left,bottom,right,top),默认为(0,0,1,1)。
三、自定义布局
matplotlib的gridspec模块是专门指定画布中子图位置的模块,该模块中包含一个GridSpec类,通过显式地创建GridSpec类对象来自定义画布中子图的布局结构,使得子图能够更好地适应画布。GridSpec类的构造方法的语法格式如下:
GridSpec(nrows, ncols, figure=None, left=None, bottom=None, right=None, top=None, wspace=None, hspace=None, width_ratios=None, height_ratios=None)
该方法常用参数的含义如下:
·nrows:表示行数。
·ncols:表示列数。
·figure:表示布局的画布。
·left, bottom, right, top:表示子图的范围。
·wspace:表示子图之间预留的宽度量。
·hspace:表示子图之间预留的高度量。
效果如下:
%matplotlib auto
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
#创建画布实例
fig = plt.figure()
#创建“区域规划图”实例(GridSpec实例)
spec = gridspec.GridSpec(nrows=2, ncols=2, figure=fig,
#hspace=2, wspace=2, #设置坐标系示例之间纵向和横向间距
#left=0.25, right=0.9, top=0.9, bottom=0.25 #把所有坐标系示例“打包”在一起,整体伸缩或平移
width_ratios = [1,1], #设置坐标系的相对宽度,每个坐标系的宽度 = 设定值/sum(设定值)
height_ratios = [1,2] #设置坐标系的相对高度,每个坐标系的高度 = 设定值/sum(设定值)
)
#根据给定的“区域规划图”,创建对应的坐标系实例
ax1 = fig.add_subplot(spec[0,0]) #二维数组的切片操作
ax2 = fig.add_subplot(spec[0,1])
ax3 = fig.add_subplot(spec[1,0])
ax4 = fig.add_subplot(spec[1,1])
plt.show()
# width_ratios和height_ratios都是直接把坐标系分成指定的比例