matplotlib之pyplot模块——调整子图布局(subplots_adjust、tight_layout)

在pyplot模块中,与调整子图布局的函数主要为subplots_adjusttight_layout,其中subplots_adjust是修改子图间距的通用函数,tight_layout默认执行一种固定的间距配置,也可以自定义间距配置,底层原理类似于subplots_adjust函数。

subplots_adjust函数概述

subplots_adjust函数的功能为调整子图的布局参数。对于没有设置的参数保持不变,初始值由rcParams["figure.subplot.[name]"]提供。

函数的签名为matplotlib.pyplot.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)

函数的参数如下:

  • left:所有子图整体相对于图像的左外边距,距离单位为图像宽度的比例(小数)。可选参数。浮点数。默认值为0.125
  • right:所有子图整体相对于图像的右外边距,距离单位为图像宽度的比例(小数)。可选参数。浮点数。默认值为0.0
  • bottom:所有子图整体相对于图像的下外边距,距离单位为图像高度的比例(小数)。可选参数。浮点数。默认值为0.11
  • top:所有子图整体相对于图像的上外边距,距离单位为图像高度的比例(小数)。可选参数。浮点数。默认值为0.88
  • wspace:子图间宽度内边距,距离单位为子图平均宽度的比例(小数)。浮点数。默认值为0.2
  • hspace:子图间高度内边距,距离单位为子图平均高度的比例(小数)。可选参数。浮点数。默认值为0.2

rcParams["figure.subplot.[name]"]的值如下:

## The figure subplot parameters.  All dimensions are a fraction of the figure width and height.
#figure.subplot.left:   0.125  # the left side of the subplots of the figure
#figure.subplot.right:  0.9    # the right side of the subplots of the figure
#figure.subplot.bottom: 0.11   # the bottom of the subplots of the figure
#figure.subplot.top:    0.88   # the top of the subplots of the figure
#figure.subplot.wspace: 0.2    # the amount of width reserved for space between subplots,
                               # expressed as a fraction of the average axis width
#figure.subplot.hspace: 0.2    # the amount of height reserved for space between subplots,
                               # expressed as a fraction of the average axis height

subplots_adjust函数原理

根据以下源码可知,子图间距的默认设置即rcParams["figure.subplot.[name]"],使用subplots_adjust函数调整后,间距配置保存在figure.subplotpars

pyplot.subplots_adjust()源码

def subplots_adjust(
        left=None, bottom=None, right=None, top=None, wspace=None,
        hspace=None):
    return gcf().subplots_adjust(
        left=left, bottom=bottom, right=right, top=top, wspace=wspace,
        hspace=hspace)

figure.Figure.subplots_adjust()源码

def subplots_adjust(self, left=None, bottom=None, right=None, top=None,
                    wspace=None, hspace=None):
    if self.get_constrained_layout():
        self.set_constrained_layout(False)
        _api.warn_external(
            "This figure was using constrained_layout, but that is "
            "incompatible with subplots_adjust and/or tight_layout; "
            "disabling constrained_layout.")
    self.subplotpars.update(left, bottom, right, top, wspace, hspace)
    for ax in self.axes:
        if isinstance(ax, SubplotBase):
            ax._set_position(ax.get_subplotspec().get_position(self))
    self.stale = True

figure.Figure.__init__()源码

if subplotpars is None:
    subplotpars = SubplotParams()

self.subplotpars = subplotpars

figure.SubplotParams类源码

class SubplotParams:
    """
    A class to hold the parameters for a subplot.
    """
    def __init__(self, left=None, bottom=None, right=None, top=None,
                 wspace=None, hspace=None):
        self.validate = True
        for key in ["left", "bottom", "right", "top", "wspace", "hspace"]:
            setattr(self, key, mpl.rcParams[f"figure.subplot.{key}"])
        self.update(left, bottom, right, top, wspace, hspace)

    def update(self, left=None, bottom=None, right=None, top=None,
               wspace=None, hspace=None):
        """
        Update the dimensions of the passed parameters. *None* means unchanged.
        """
        if self.validate:
            if ((left if left is not None else self.left)
                    >= (right if right is not None else self.right)):
                raise ValueError('left cannot be >= right')
            if ((bottom if bottom is not None else self.bottom)
                    >= (top if top is not None else self.top)):
                raise ValueError('bottom cannot be >= top')
        if left is not None:
            self.left = left
        if right is not None:
            self.right = right
        if bottom is not None:
            self.bottom = bottom
        if top is not None:
            self.top = top
        if wspace is not None:
            self.wspace = wspace
        if hspace is not None:
            self.hspace = hspace

案例:subplots_adjust()修改间距验证

import matplotlib.pyplot as plt

# 原始间距配置
fig,ax=plt.subplots(3,3)
print(vars(fig.subplotpars))
# 通过subplots_adjust()设置间距配置
plt.subplots_adjust(left=0.1,bottom=0.1,right=0.9,top=0.9,wspace=0.1,hspace=0.1)
print(vars(fig.subplotpars))
plt.show()

输出:

{'validate': True, 'left': 0.125, 'bottom': 0.125, 'right': 0.9, 'top': 0.88, 'wspace': 0.2, 'hspace': 0.2}
{'validate': True, 'left': 0.1, 'bottom': 0.1, 'right': 0.9, 'top': 0.9, 'wspace': 0.1, 'hspace': 0.1}

原始间距设置
在这里插入图片描述

subplots_adjust()修改间距后
在这里插入图片描述

tight_layout函数概述

tight_layout函数的功能为子图的内边距。备注:对axes()函数生成的子图无效。

函数的签名为matplotlib.pyplot.tight_layout(*, pad=1.08, h_pad=None, w_pad=None, rect=None)

函数的参数如下:

  • pad:所有子图整体边缘相对于图像边缘的内边距,距离单位为字体大小的比例(小数,与rcParams["font.size"]相关)。可选参数。浮点数。默认值为1.08
  • h_pad, w_pad:子图之间的内边距,距离单位为字体大小的比例(小数)。可选参数。浮点数。默认值为pad
  • rect:绘制子图的矩形区域的归一化坐标。可选参数。4元组(left, bottom, right, top)。默认值为(0, 0, 1, 1)

tight_layout函数原理

根据以下源码可知pyplot.tight_layout()函数主要通过matplotlib.tight_layout模块相关函数构造子图间距设置,最终通过figure.Figure.subplots_adjust函数更新设置。

pyplot.tight_layout()源码

def tight_layout(pad=1.08, h_pad=None, w_pad=None, rect=None):
    gcf().tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)

figure.Figure.tight_layout()源码

def tight_layout(self, *, pad=1.08, h_pad=None, w_pad=None, rect=None):
    from .tight_layout import (
        get_renderer, get_subplotspec_list, get_tight_layout_figure)
    from contextlib import suppress
    subplotspec_list = get_subplotspec_list(self.axes)
    if None in subplotspec_list:
        _api.warn_external("This figure includes Axes that are not "
                            "compatible with tight_layout, so results "
                            "might be incorrect.")

    renderer = get_renderer(self)
    ctx = (renderer._draw_disabled()
            if hasattr(renderer, '_draw_disabled')
            else suppress())
    with ctx:
        kwargs = get_tight_layout_figure(
            self, self.axes, subplotspec_list, renderer,
            pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
    if kwargs:
        self.subplots_adjust(**kwargs)

案例:应用tight_layout后验证间距配置

import matplotlib.pyplot as plt

# 原始间距配置
fig,ax=plt.subplots(3,3)
print(vars(fig.subplotpars))
# 设置tight_layout之后的默认间距配置
plt.tight_layout()
print(vars(fig.subplotpars))
# 设置tight_layout内边距之后的间距配置
plt.tight_layout(h_pad=2.5,w_pad=2.5)
print(vars(fig.subplotpars))
plt.show()

输出为:

{'validate': True, 'left': 0.125, 'bottom': 0.125, 'right': 0.9, 'top': 0.88, 'wspace': 0.2, 'hspace': 0.2}
{'validate': True, 'left': 0.0779513888888889, 'bottom': 0.09652777777777778, 'right': 0.9566261574074074, 'top': 0.9486111111111112, 'wspace': 0.42123244337593335, 'hspace': 0.5247524752475248}
{'validate': True, 'left': 0.0779513888888889, 'bottom': 0.0965277777777778, 'right': 0.9566261574074075, 'top': 0.9486111111111111, 'wspace': 0.6248542240052247, 'hspace': 0.8996088657105613}

扩展

通过设置rcParams['figure.autolayout']=True可图像自动应用tight_layout

## Figure layout
#figure.autolayout: False  # When True, automatically adjust subplot
                           # parameters to make the plot fit the figure
                           # using `tight_layout`
#figure.constrained_layout.use: False  # When True, automatically make plot
                                       # elements fit on the figure. (Not
                                       # compatible with `autolayout`, above).
#figure.constrained_layout.h_pad:  0.04167  # Padding around axes objects. Float representing
#figure.constrained_layout.w_pad:  0.04167  # inches. Default is 3/72 inches (3 points)
#figure.constrained_layout.hspace: 0.02     # Space between subplot groups. Float representing
#figure.constrained_layout.wspace: 0.02     # a fraction of the subplot widths being separated.
  • 30
    点赞
  • 140
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值