多子图自由~
多子图是文献、日常数据展示常用方法,本文细讲子图(Axes)。
节选自👉Python matplotlib教程(优惠中)
Python Matplotlib中创建Axes时,是基于matplotlib.figure.Figure或者matplotlib.pyplot上的方法。以下详细介绍不同的添加Axes方式,
6.2.1 add_axes逐个添加Axes
add_axes可以手动在一个Figure上创建自定义位置的Axes,通过left、bottom、width和height四个参数指定Axes的精确位置和大小,这四个参数都是Figure的width和height的百分比,
##6.1.4_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.2.1 add_axes逐个添加Axes
'''import matplotlib.pyplot as plt
# 创建一个matplotlib.figure.Figure
fig = plt.figure(dpi=150, edgecolor='grey')
fig.patch.set_linewidth(1)
# 在matplotlib.figure.Figure上添加四个Axes,并自定义它们的位置
ax1 = fig.add_axes([
0.1, # 左边距:Axes左边与Figure左边的距离,占Figure宽度的10%(0到1之间的比例)
0.6, # 底边距:Axes底边与Figure底边的距离,占Figure高度的60%(0到1之间的比例)
0.35, # 宽度:Axes的宽度,占Figure总宽度的35%(0到1之间的比例)
0.3
]) # 高度:Axes的高度,占Figure总高度的30%(0到1之间的比例)
ax2 = fig.add_axes([0.6, 0.6, 0.35, 0.3])
ax3 = fig.add_axes([0.1, 0.1, 0.35, 0.3])
ax4 = fig.add_axes([0.6, 0.1, 0.35, 0.3])
# 给每个Axes添加标题
ax1.set_title("Axes 1")
ax2.set_title("Axes 2")
ax3.set_title("Axes 3")
ax4.set_title("Axes 4")
plt.show()
6.2.2 Figure.add_subplot逐个添加Axes
在Figure上逐个添加Axes,使用从1开始的索引(类似Matlab)。可以通过指定网格单元的范围来跨越多列或多行。
##6.2.2_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.2.2 Figure.add_subplot逐个添加Axes
'''import matplotlib.pyplot as plt
# 创建一个matplotlib.figure.Figure
fig = plt.figure(dpi=150, edgecolor='grey')
fig.patch.set_linewidth(1)
# 使用add_subplot创建3个Axes
# 2行2列的网格
ax1 = fig.add_subplot(2, 2, 1) # 第一个子图,占据第一行第一列
ax1.set_title("Axes 1")
ax2 = fig.add_subplot(2, 2, 2) # 第二个子图,占据第一行第二列
ax2.set_title("Axes 2")
# 第三个子图,跨越多列(跨越第二行的两列)
ax3 = fig.add_subplot(2, 2, (3, 4)) # 使用(3, 4)来表示跨越第三、第四个网格单元
ax3.set_title("Axes 3 (spanning columns)")
# 调整子图间距
plt.tight_layout()
# 显示图形
plt.show()
6.2.3 pyplot.subplot逐个添加Axes
功能同章节“6.2.2 Figure.add_subplot逐个添加Axes”,只是本节使用了pyplot中的subplot方法,
##6.2.3_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.2.3 pyplot.subplot逐个添加Axes
'''import matplotlib.pyplot as plt
# 创建一个matplotlib.figure.Figure
fig = plt.figure(dpi=150, edgecolor='grey')
fig.patch.set_linewidth(1)
# 使用pyplot.subplot创建3个Axes
# 2行2列的网格
ax1 = plt.subplot(2, 2, 1) # 第一个子图,占据第一行第一列
ax1.set_title("Axes 1")
ax2 = plt.subplot(2, 2, 2) # 第二个子图,占据第一行第二列
ax2.set_title("Axes 2")
# 第三个子图,跨越多列(跨越第二行的两列)
ax3 = plt.subplot(2, 2, (3, 4)) # 使用(3, 4)来表示跨越第三、第四个网格单元
ax3.set_title("Axes 3 (spanning columns)")
plt.tight_layout() # 调整子图间距
plt.show()
6.2.4 Figure.subplot_mosaic更灵活添加Axes
又一种创建图形和网格布局的简单方法,并且具有额外的灵活性,Axes(坐标轴)也可以跨越行或列。Axes 会以带标签的字典形式返回,而不是数组。
##6.2.4_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.2.4 Figure.subplot_mosaic更灵活添加Axes
'''import matplotlib.pyplot as plt
# 创建一个matplotlib.figure.Figure
fig = plt.figure(dpi=150, edgecolor='grey')
fig.patch.set_linewidth(1)
# 使用subplot_mosaic创建带有标签的布局
# 'A'、'B' 等为标签,可以通过字典访问
layout = """
AAB
CDD
EEE
"""
# 创建子图布局,使用字符串表示法定义各个子图的位置
ax_dict = fig.subplot_mosaic(layout)
# 给每个子图添加标题
ax_dict['A'].set_title('Axes A (spanning 2 columns)')
ax_dict['B'].set_title('Axes B')
ax_dict['C'].set_title('Axes C')
ax_dict['D'].set_title('Axes D')
ax_dict['E'].set_title('Axes E (spanning 2 columns)')
# 调整子图间距
plt.tight_layout()
# 显示图形
plt.show()
6.2.5 pyplot.subplot_mosaic更灵活添加Axes
同“ 6.2.4 Figure.subplot_mosaic更灵活添加Axes”,
##6.2.5_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.2.5 pyplot.subplot_mosaic更灵活添加Axes
'''import matplotlib.pyplot as plt
## 使用pyplot.subplot_mosaic创建带有标签的布局
# 'A'、'B' 等为标签,可以通过字典访问
layout = """
AAB
CDD
EEE
"""
# 使用pyplot接口创建带有标签的子图布局
fig, ax_dict = plt.subplot_mosaic(layout, dpi=150)
# 给每个子图添加标题
ax_dict['A'].set_title('Axes A (spanning 2 columns)')
ax_dict['B'].set_title('Axes B')
ax_dict['C'].set_title('Axes C')
ax_dict['D'].set_title('Axes D')
ax_dict['E'].set_title('Axes E (spanning 2 columns)')
plt.tight_layout()
# 显示图形
plt.show()
6.2.6 GridSpec添加Axes
GridSpec提供了更精细的Axes控制,可以轻松实现跨行跨列,通过指定网格的行和列,用户可以将Axes放在任意网格单元内,并可以灵活地调整各个单元的大小。
#6.2.6_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.2.6 GridSpec添加Axes
'''import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
# 创建一个matplotlib.figure.Figure
fig = plt.figure(dpi=150)
# 创建GridSpec布局
gs = gridspec.GridSpec(
3,
3, #3行3列的网格
figure=fig)
# 创建第一个子图,跨越第一行的两列
ax1 = fig.add_subplot(gs[0, 0:2]) # 占据第一行的前两列
ax1.set_title("Axes 1 (spanning 2 columns)")
# 创建第二个子图,位于第一行第三列
ax2 = fig.add_subplot(gs[0, 2]) # 占据第一行的第三列
ax2.set_title("Axes 2")
# 创建第三个子图,跨越第二行和第三行的第一列
ax3 = fig.add_subplot(gs[1:, 0]) # 占据第二、第三行的第一列
ax3.set_title("Axes 3 (spanning 2 rows)")
# 创建第四个子图,位于第二行第二列
ax4 = fig.add_subplot(gs[1, 1]) # 占据第二行的第二列
ax4.set_title("Axes 4")
# 创建第五个子图,位于第二行第三列
ax5 = fig.add_subplot(gs[1, 2]) # 占据第二行的第三列
ax5.set_title("Axes 5")
# 创建第六个子图,跨越第三行的第二、第三列
ax6 = fig.add_subplot(gs[2, 1:3]) # 占据第三行的第二、第三列
ax6.set_title("Axes 6 (spanning 2 columns)")
# 调整子图间距
plt.tight_layout()
plt.show()
6.2.7 Figure.subfigures添加嵌套Axes
有时候,需要在同一个Figure中放置两个或更多子图组,但子图组的功能和布局上是独立的,而且每个子图组中可以嵌套Axes。
#6.2.7_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.2.7 Figure.subfigures添加嵌套Axes
'''import matplotlib.pyplot as plt
fig = plt.figure(figsize=(15, 8), dpi=150)
# 创建外层子图组(3列)
subfigs = fig.subfigures(1, 3, wspace=0.05, hspace=0.05)
# 左侧子图组(6个子图,2行3列)
left_subfig = subfigs[0].subplots(2, 3) # 2行3列
for i, ax in enumerate(left_subfig.flatten(), start=1):
ax.set_xticks([])
ax.set_yticks([])
ax.set_facecolor('lightgray')
ax.set_title(f"Left Subplot {i}")
subfigs[0].set_facecolor('lightcoral')
subfigs[0].text(0.5, 0.95, "Left Subfigures", fontsize=16, ha='center')
# 中间子图组(4个子图,2行2列)
middle_subfig = subfigs[1].subplots(2, 2) # 2行2列
for i, ax in enumerate(middle_subfig.flatten(), start=1):
ax.set_xticks([])
ax.set_yticks([])
ax.set_facecolor('lightgray')
ax.set_title(f"Middle Subplot {i}")
subfigs[1].set_facecolor('lightgreen')
subfigs[1].text(0.5, 0.95, "Middle Subfigures", fontsize=16, ha='center')
# 右侧子图组(3个子图,3行1列)
right_subfig = subfigs[2].subplots(3, 1) # 3行1列
for i, ax in enumerate(right_subfig.flatten(), start=1):
ax.set_xticks([])
ax.set_yticks([])
ax.set_facecolor('lightgray')
ax.set_title(f"Right Subplot {i}")
subfigs[2].set_facecolor('lightblue')
subfigs[2].text(0.5, 0.95, "Right Subfigures", fontsize=16, ha='center')
plt.show()
在同一个Figure中放置3个子图组,每个子图组中嵌套多个Axes。
6.2.8 多子图方法比较
add_axes、add_subplot、subplot_mosaic、GridSpec、subfigures在Matplotlib中添加子图时的优缺点、适用场景比较:
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
add_axes | 精确控制子图位置和大小,适合复杂布局 | 使用不直观,布局调整繁琐 | 需要自定义子图布局时 |
add_subplot | 简单直观,适合网格布局 | 不够灵活,子图间可能有不规则空隙 | 规则网格布局,快速生成子图 |
subplot_mosaic | 直观命名子图,适合复杂布局 | 功能较新,灵活性不如 add_axes 或 GridSpec | 自定义网格子图布局,命名子图 |
GridSpec | 高度灵活,子图可以跨行列,适合不规则网格布局 | 语法稍复杂,代码较多 | 子图尺寸不均,布局复杂 |
subfigures | 支持独立子图组,每组有独立布局和样式 | 设置复杂,需要较多代码 | 创建多个不同类别的子图组,嵌套图表 |
-END-
节选自:👉保姆级matplotlib教程—详细目录
交流学习(备注399)