Matplotlib 通过GridSpec自定义图形布局

前言

 这篇文章主要学习如何根据GridSpec和一些其他的函数实现自定义图形布局

使用GridSpec和其他函数自定义图形布局

  以下函数或方法实现创建axes上的网格的组合

  或许是创建figures和axes最主要的方式,与 matplotlib.pyplot.subplot() 类似,
但是同时创建并放置图形上的所有轴。更多详情请看matplotlib.figure.Figure.subplots.

  指定将放置子图的网格的几何形状。

  需要设置网格的行数和列数。以及子图的布局参数可以调整

  在给定的GridSpec上指定子图的位置

  一个类似于subplot() 的辅助函数,但是使用基于0的索引并让subplot占用多个单元格。本文章没有介绍该函数。


导入

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec



快速入门指南

使用subplots()非常简单。它返回一个Figure实例和一个Axes对象数组 。

fig1,f1_axes = plt.subplots(ncols=2,nrows=2,constrained_layout=True)

对于像上面这样的简单用例,gridspec可能过于冗长。

你必须分别创建图形和GridSpec 实例,然后将gridspec实例的元素传递给 add_subplot() 函数来创建axes对象。

gridspec元素的访问方式通常与numpy数组相同。

fig2 = plt.figure(constrained_layout=True)
spec2 = gridspec.GridSpec(ncols=2,nrows=2,figure=fig2)
f2_ax1 = fig2.add_subplot(spec2[0,0])
f2_ax2 = fig2.add_subplot(spec2[0,1])
f2_ax3 = fig2.add_subplot(spec2[1,0])
f2_ax4 = fig2.add_subplot(spec2[1,1])

可以看出和subplots()方式结果相同

gridspec的强大之处在于能够创建跨越行和列的子图。注意,NumPy slice Syntax 用于选择每个子图将占据的gridspec部分。

请注意,我们还使用了便捷方法Figure.add_gridspec 代替gridspec.GridSpec,有可能为用户节省了导入时间,并使名称空间更整洁。

fig3 = plt.figure(constrained_layout=True)
gs = fig3.add_gridspec(3,3)

#关于切片可参考另一篇文章Numpy学习中的切片学习
f3_ax1 = fig3.add_subplot(gs[0,:])
f3_ax1.set_title('gs[0,:]')
f3_ax1 = fig3.add_subplot(gs[1,:-1])
f3_ax1.set_title('gs[1,:-1]')
f3_ax1 = fig3.add_subplot(gs[1:,-1])
f3_ax1.set_title('gs[1:,-1]')
f3_ax1 = fig3.add_subplot(gs[-1,0])
f3_ax1.set_title('gs[-1,0]')
f3_ax1 = fig3.add_subplot(gs[-1,-2])
f3_ax1.set_title('gs[-1,-2]')

接下来展示的方法与上面的方法类似,

初始化统一的网格规范,然后使用numpy索引和切片为给定的子图分配多个“单元格”。

fig4 = plt.figure(constrained_layout=True)
spec4 = fig4.add_gridspec(ncols=2,nrows=2)
anno_opts = dict(xy=(0.5,0.5),xycoords='axes fraction',va='center',ha='center')

f4_ax1 = fig4.add_subplot(spec4[0,0])
f4_ax1.annotate('GridSpec[0,0]',**anno_opts)
fig4.add_subplot(spec4[0, 1]).annotate('GridSpec[0, 1:]', **anno_opts)
fig4.add_subplot(spec4[1, 0]).annotate('GridSpec[1:, 0]', **anno_opts)
fig4.add_subplot(spec4[1, 1]).annotate('GridSpec[1:, 1:]', **anno_opts)

  另一个方式是使用width_ratios和height_ratios参数。这些关键字参数是数字列表。

  请注意,绝对值是没有意义的,只有它们的相对比率重要。这意味着width_ratio =[2, 4, 8]与width_ratio =[1, 2, 4]在同样宽的数字内相等。

fig5 = plt.figure(constrained_layout=True)
widths = [2,3,1.5]
heights = [1,3,2]
spec5 = fig5.add_gridspec(ncols=3,nrows=3,width_ratios=widths,height_ratios=heights)

for row in range(3):
    for col in range(3):
        ax = fig5.add_subplot(spec5[row,col])
        label = 'Width: {}\nHeight: {}'.format(widths[col],heights[row])
        ax.annotate(label,(0.1,0.5),xycoords='axes fraction',va='center')

 学习使用width_ratio和height_ratio特别有用,因为函数subplots()在gridspec_kw参数中接受它们。

 为此,GridSpec 接受的任何参数都可以通过gridspec_kw参数传递给subplots()

 此示例在不直接使用gridspec实例的情况下重新创建前面的图。

gs_kw = dict(width_ratios=widths,height_ratios=heights)
fig6,f6_axes = plt.subplots(ncols=3,nrows=3,constrained_layout=True,gridspec_kw=gs_kw)

for r,row in enumerate(f6_axes):
    for c,ax in enumerate(row):
        label = 'Width:{}\nHeight:{}'.format(widths[c],heights[r])
        ax.annotate(label,(0.1,0.5),xycoords='axes fraction',va='center')

subplots和get_gridspec方法可以组合使用,因为有时使用subplots创建大多数子图,然后删除其中一些并组合它们更方便。

在这里,我们将最后一列中底部的两个轴组合起来创建一个布局。

fig7,f7_axs = plt.subplots(ncols=3,nrows=3)
gs = f7_axs[1,2].get_gridspec()

#删除[1,-1],[2,-1]的axes
for ax in f7_axs[1:,-1]:
    ax.remove()
axbig = fig7.add_subplot(gs[1:,-1])    
axbig.annotate('Big Axes \nGridSpec[1:, -1]', (0.1, 0.5),
               xycoords='axes fraction', va='center')

#调整子图之间及其周围的填充。
fig7.tight_layout()



精细调整Gridspec布局

当显示地使用GridSpec时,可以通过改变gridspec的参数来调整子图的布局

请注意,此选项与constrained_layout或者 Figure.tight_layout 都不兼容,两者都通过调整子图大小以填充figure。

参数请看:matplotlib.gridspec.GridSpec

fig8 = plt.figure(constrained_layout=False)
gs1 = fig8.add_gridspec(nrows=3,ncols=3,left=0.05,right=0.48,wspace=0.05)
f8_ax1 = fig8.add_subplot(gs1[:-1,:])
f8_ax2 = fig8.add_subplot(gs1[-1,:-1])
f8_ax3 = fig8.add_subplot(gs1[-1,-1])



GridSpec之SubplotSpec

你可以通过SubplotSpec 创建GridSpec,在这种情况下,它的布局参数被设置为给定SubplotSpec的位置。

fig10 = plt.figure(constrained_layout=False)
gs0 = fig10.add_gridspec(1,2)

gs00 = gs0[0].subgridspec(2,3)
gs01 = gs0[1].subgridspec(3,2)

for i in range(2):
    for j in range(3):
        fig10.add_subplot(gs00[i,j])
        fig10.add_subplot(gs01[j,i])



如果你发现文章中出现的错误或者有任何疑问欢迎在下方评论区留言


点个赞和关注支持一下啦.

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值