Matplotlib剑客行——布局指南与多图实现(更新)

布局指南

简单示例

在 Matplotlib 中,轴(包括子图)的位置在标准化图形坐标,你的轴标签或标题(有时甚至是刻度标签)超出图形区域,因此需要剪辑。
在这里插入图片描述
为了防止这种情况,需要调整轴的位置。

  • 通过调整子图参数 Figure.subplots_adjust.来手动完成 但是,用 constrained_layout=True关键字参数将自动地进行调整。
  • 这个 Figure.tight_layout是自动填充的
    • tight_layout()还将调整子图间距以最小化重叠
    • tight_layout()可以采用关键字参数 pad , w_pad 和 h_pad ,控制周围的额外填充图形边界和子图之间
fig, ax = plt.subplots(constrained_layout=True)
example_plot(ax, fontsize=24)

当你有多个子图时,你通常会看到不同的标签轴相互重叠

fig, axs = plt.subplots(2, 2, constrained_layout=False)
for ax in axs.flat:
    example_plot(ax)
  • 输出图像:

在这里插入图片描述

  • 在调用 plt.subplots 指定 constrained_layout=True,使布局得到适当的约束
  • tight_layout 函数可以调整子图的相对大小使字符不会重叠
fig, axs = plt.subplots(2, 2, constrained_layout=True)
for ax in axs.flat:
    example_plot(ax)
  • 输出图像:

在这里插入图片描述

字幕——标题
  • constrained_layout也可以腾出空间来设置标题 suptitle.
fig, axs = plt.subplots(2, 2, figsize=(4, 4), constrained_layout=True)
fig.suptitle('Big Suptitle')
plt.show()
  • 输出图像:

在这里插入图片描述

传说——图例

图例可以放置在其父轴之外。 约束布局旨在处理此问题 Axes.legend(). 但是,受约束的布局不处理通过创建的图例 Figure.legend().

fig, ax = plt.subplots(constrained_layout=True)
ax.plot(np.arange(10), label='This is a plot')
ax.legend(loc='center left', bbox_to_anchor=(0.8, 0.5))
  • 输出图像:

在这里插入图片描述
但是,有多个子图时这将会压缩子图布局的空间
在这里插入图片描述
解决这种尴尬的更好方法是简单地使用提供的图例方法 Figure.legend:
在这里插入图片描述

填充与间距
  • 轴之间的填充,水平由 w_pad 和 wspace 和垂直由 h_pad 和 hspace
    • 这些可以通过 set_constrained_layout_pads( w/h_pad, w/hspace) 编辑
    • 子图之间的间距由 wspace 和 hspace 设置
  • 也可以通过 plt.subplots_adjust(wspace=0,hspace=0)设定
    • wspace,hspace:用于控制宽度和高度的百分比,比如subplot之间的间距

多图实现

多图——plt.subplots
subplots参数
  • plt.subplots(nrows, ncols, index, sharex, sharey)

    • nrows子图的行数
    • ncols子图的列数
    • index 取子图的索引
    • sharex 所有子图使用相同的x轴刻度
    • sharey 所有子图使用相同的y轴刻度
      • sharex,sharey:是否共享x,y刻度
    • figsize 参数可以指定整个画布的大小
  • 当我们调用plot时,如果设置plt.figure(),则会自动调用figure()生成一个figure, 严格的讲,是生成subplots(111)

  • 先创建图表figure,然后生成子图,(2,2,1)代表创建2*2的矩阵表格,然后选择第一个,顺序是从左到右从上到下

在调用subplot时一般需要传入三位数字,分别代表总行数,总列数,当前子图的index
2*2 四个子图 index:1 选择了其中第一个子图
ax1 = plt.subplot(221)
ax2 = plt.subplot(222)
ax3 = plt.subplot(223)
ax4 = plt.subplot(224) 当三位数都小于10时,可以省略中间的逗号,这行命令等价于plt.subplot(2,2,4)

超出,则会报错
plt.subplot(225)

两种实现方式
OO风格
import matplotlib.pyplot as plt

x = ["深圳", "广州", "北京", "上海"]
y = [1, 3, 2, 5]
fig, axs = plt.subplots(2, 2)

# 下标[nrows][ncols]
# 第一张子图
axs[0][0].bar(x, y)
# 第二张子图
axs[0][1].pie(y, labels=x)
# 第三张子图
axs[1][0].plot(x, y)
# 第四张子图
axs[1][1].barh(x, y)
plt.show()
  • 输出图像:
    在这里插入图片描述
plplot风格
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
x = ["深圳", "广州", "北京", "上海"]
y = [1, 3, 2, 5]

# 第一张子图
plt.subplot(2, 2, 1)
plt.bar(x, y)
# 第二张子图
plt.subplot(2, 2, 2)
plt.pie(y, labels=x)
# 第三张子图
plt.subplot(2, 2, 3)
plt.plot(x, y)
# 第四张子图
plt.subplot(2, 2, 4)
plt.barh(x, y)
plt.show()
  • 输出图像:
    在这里插入图片描述
多合一显示——plt.subplot
均匀图中图
  • 使用plt.figure创建一个图像窗口.使用plt.subplot来创建小图
  • plt.subplot(2,2,1)表示将整个图像窗口分为2行2列, 当前位置为1. 使用plt.plot([0,1],[0,1])在第1个位置创建一个小图。
  • plt.subplot(2,2,2)表示将整个图像窗口分为2行2列, 当前位置为2。使用plt.plot([0,1],[0,2])在第2个位置创建一个小图。
  • plt.subplot(2,2,3)表示将整个图像窗口分为2行2列,当前位置为3。 plt.subplot(2,2,3)可以简写成plt.subplot(223)。使用plt.plot([0,1],[0,3])在第3个位置创建一个小图。
  • plt.subplot(224)表示将整个图像窗口分为2行2列, 当前位置为4。使用plt.plot([0,1],[0,4])在第4个位置创建一个小图。
plt.figure()

plt.subplot(2,2,1)
plt.plot([0,1],[0,1])

plt.subplot(2,2,2)
plt.plot([0,1],[0,2])

plt.subplot(223)
plt.plot([0,1],[0,3])

plt.subplot(224)
plt.plot([0,1],[0,4])
不均匀图中图
  • 使用plt.subplot(2,1,1)将整个图像窗口分为2行1列, 当前位置为1。使用plt.plot([0,1],[0,1])在第1个位置创建一个小图。
  • 使用plt.subplot(2,3,4)将整个图像窗口分为2行3列, 当前位置为4。使用plt.plot([0,1],[0,2])在第4个位置创建一个小图。
    • 上一步中使用plt.subplot(2,1,1)将整个图像窗口分为2行1列, 第1个小图占用了第1个位置, 也就是整个第1行。
    • 这一步中使用plt.subplot(2,3,4)将整个图像窗口分为2行3列, 于是整个图像窗口的第1行就变成了3列, 也就是成了3个位置, 于是第2行的第1个位置是整个图像窗口的第4个位置。
plt.subplot(2,1,1)
plt.plot([0,1],[0,1])

plt.subplot(2,3,4)
plt.plot([0,1],[0,2])
  • 以此类推,依次创建第5、6位置上的子图
plt.subplot(235)
plt.plot([0,1],[0,3])

plt.subplot(236)
plt.plot([0,1],[0,4])
不均匀子图——add_gridspec
区域切割
  • 使用 GridSpec 绘制非均匀子图
  • 利用 add_gridspec 可以指定相对宽度比例 width_ratios 和相对高度比例参数 height_ratios

spec = fig.add_gridspec(nrows=2, ncols=2, width_ratios=[1,3],height_ratios=[1,2])
表示将整个画布裁剪为2 行2列的区域,width_ratios=[1, 3]表示横向将两列的宽度按照1:3进行裁剪,同理height_ratios=[1,2]表示纵向按照1:2进行裁剪

x = ["深圳", "广州", "北京", "上海"]
y = [1, 3, 2, 5]
fig = plt.figure(figsize=(10, 8))

spec = fig.add_gridspec(nrows=2, ncols=2, width_ratios=[1, 3], height_ratios=[1, 2])
ax = fig.add_subplot(spec[0, 0])
ax.bar(x, y)

ax = fig.add_subplot(spec[0, 1])
ax.plot(x, y)

ax = fig.add_subplot(spec[1, 0])
ax.pie(y, labels=x)

ax = fig.add_subplot(spec[1, 1])
ax.barh(x, y)
plt.show()
  • 输出图像:
    在这里插入图片描述
  • spec还支持切片的方式,譬如我们将第二行展示为整个条形图
x = ["深圳", "广州", "北京", "上海"]
y = [1, 3, 2, 5]
fig = plt.figure(figsize=(10, 8))

spec = fig.add_gridspec(nrows=2, ncols=2, width_ratios=[1, 3], height_ratios=[1, 2])
ax = fig.add_subplot(spec[0, 0])
ax.bar(x, y)

ax = fig.add_subplot(spec[0, 1])
ax.plot(x, y)

# 第二行整块区域显示条形图
ax = fig.add_subplot(spec[1, :])
ax.barh(x, y)

# 调整各区域之间的距离
plt.subplots_adjust(hspace=0.3, wspace=0.2)
plt.show()
  • 输出图像:
    在这里插入图片描述
添加元素
  • ax子图同样可以通过set_title、set_xlable等方法添加子图标题,坐标轴标题等
  • 如果需要添加大标题可以通过fig.suptitle()来完成。
评论 45
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王者与CV

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值