添加具有约束布局的外部边距?

Noa*_*oah 6 python matplotlib

生成图形以保存到 pdf 文件时,我想调整图形相对于页面边缘的位置,例如沿所有边添加英寸边距。据我所知,这样做的解决方案(例如,在这个问题中)要么:

  1. 不使用constrained_layout模式 -plt.subplots_adjust()在创建图形之后但在fig.savefig()弄乱受约束的布局之前应用
  2. 实际上不要定量地调整图形的位置——添加bbox_inches="tight"pad=-1似乎没有做任何有意义的事情

有没有一种直接的方法来调整受限布局图形的外部边距?

例如:

fig = plt.figure(constrained_layout=True, figsize=(11, 8.5))

page_grid = gridspec.GridSpec(nrows=2, ncols=1, figure=fig)

# this doesn't appear to do anything with constrained_layout=True
page_grid.update(left=0.2, right=0.8, bottom=0.2, top=0.8)

top_row_grid = gridspec.GridSpecFromSubplotSpec(1, 3, subplot_spec=page_grid[0])
for i in range(3):
    ax = fig.add_subplot(top_row_grid[:, i], aspect="equal")

n_bottom_row_plots = 10
qc_grid = gridspec.GridSpecFromSubplotSpec(1, n_bottom_row_plots, subplot_spec=page_grid[1])
for i, metric in enumerate(range(n_bottom_row_plots)):
    ax = fig.add_subplot(qc_grid[:, i])
    plt.plot(np.arange(5), np.arange(5))

fig.suptitle("my big label", fontweight="bold", fontsize="x-large", y=0.9)

# this ruins the constrained layout
# plt.subplots_adjust(left=0.2,right=0.8, bottom=0.2, top=0.8)

fig.savefig("temp.png", facecolor="coral")
Run Code Online (Sandbox Code Playgroud)

产生以下结果(我想在边缘看到更多的珊瑚!):

在此处输入图片说明

Saa*_*ter 5

您是否尝试过使用约束布局填充选项?

fig.set_constrained_layout_pads(w_pad=4./72., h_pad=4./72.,
            hspace=0./72., wspace=0./72.)
Run Code Online (Sandbox Code Playgroud)

虽然这可能有助于间距,但受限布局将限制您可以添加到定义空间的对象数量。

''' Here is the modified code '''

import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import matplotlib.gridspec as gridspec
import numpy as np


fig = plt.figure(constrained_layout=True, figsize=(11, 8.5))
fig.set_constrained_layout_pads(w_pad=2./12., h_pad=4./12.,
            hspace=0., wspace=0.)
page_grid = gridspec.GridSpec(nrows=2, ncols=1, figure=fig)

fig.suptitle("My BIG Label", fontweight="bold", fontsize="x-large", y=0.98)


# this doesn't appear to do anything with constrained_layout=True
page_grid.update(left=0.2, right=0.8, bottom=0.2, top=0.8)

top_row_grid = gridspec.GridSpecFromSubplotSpec(1, 3, subplot_spec=page_grid[0])
for i in range(3):
    ax = fig.add_subplot(top_row_grid[:, i], aspect="equal")

n_bottom_row_plots = 10
qc_grid = gridspec.GridSpecFromSubplotSpec(1, n_bottom_row_plots, subplot_spec=page_grid[1])
for i, metric in enumerate(range(n_bottom_row_plots)):
    ax = fig.add_subplot(qc_grid[:, i])
    plt.plot(np.arange(5), np.arange(5))


# this ruins the constrained layout
# plt.subplots_adjust(left=0.2,right=0.8, bottom=0.2, top=0.8)

fig.savefig("temp.png", facecolor="coral")
Run Code Online (Sandbox Code Playgroud)


Sam*_*ell 1

您可以设置布局引擎在其中运行的矩形。请参阅https://matplotlib.org/stable/api/layout_engine_api.htmlrect中每个引擎的参数。

不幸的是,它不是 API 的一个非常友好的部分,特别是因为TightLayoutEngineConstrainedLayoutEngine具有不同的语义rectTightLayoutEngine使用rect = (left, bottom, right, top)ConstrainedLayoutEngine使用rect = (left, bottom, width, height)

def set_margins(fig, margins):
    """Set figure margins as [left, right, top, bottom] in inches
    from the edges of the figure."""
    left,right,top,bottom = margins
    width, height = fig.get_size_inches()
    #convert to figure coordinates:
    left, right = left/width, 1-right/width
    bottom, top = bottom/height, 1-top/height
    #get the layout engine and convert to its desired format
    engine = fig.get_layout_engine()
    if isinstance(engine, matplotlib.layout_engine.TightLayoutEngine):
        rect = (left, bottom, right, top)
    elif isinstance(engine, matplotlib.layout_engine.ConstrainedLayoutEngine):
        rect = (left, bottom, right-left, top-bottom)
    else:
        raise RuntimeError('Cannot adjust margins of unsupported layout engine')
    #set and recompute the layout
    engine.set(rect=rect)
    engine.execute(fig)
Run Code Online (Sandbox Code Playgroud)

以你的例子:

fig = plt.figure(constrained_layout=True, figsize=(11, 8.5))

page_grid = gridspec.GridSpec(nrows=2, ncols=1, figure=fig)

#your margins were [0.2, 0.8, 0.2, 0.8] in figure coordinates
#which are 0.2*11 and 0.2*8.5 in inches from the edge
set_margins(fig,[0.2*11, 0.2*11, 0.2*8.5, 0.2*8.5])

top_row_grid = gridspec.GridSpecFromSubplotSpec(1, 3, subplot_spec=page_grid[0])
for i in range(3):
    ax = fig.add_subplot(top_row_grid[:, i], aspect="equal")

n_bottom_row_plots = 10
qc_grid = gridspec.GridSpecFromSubplotSpec(1, n_bottom_row_plots, subplot_spec=page_grid[1])
for i, metric in enumerate(range(n_bottom_row_plots)):
    ax = fig.add_subplot(qc_grid[:, i])
    plt.plot(np.arange(5), np.arange(5))

fig.suptitle("my big label", fontweight="bold", fontsize="x-large", y=0.9)

fig.savefig("temp.png", facecolor="coral")
Run Code Online (Sandbox Code Playgroud)

注意:fig.suptitle文本显然不是由布局引擎处理的,因此它不会移动。

示例图像