如何为图形和子图添加边框或框架

4

我想创建一个像这样的图像,但是我无法将单独的绘图放入框架中。

enter image description here

3个回答

11

图形和轴有一个补丁属性,它是组成背景的矩形。因此,设置图形框架非常简单:

import matplotlib.pyplot as plt

fig, axes = plt.subplots(2, 1)

# add a bit more breathing room around the axes for the frames
fig.subplots_adjust(top=0.85, bottom=0.15, left=0.2, hspace=0.8)

fig.patch.set_linewidth(10)
fig.patch.set_edgecolor('cornflowerblue')

# When saving the figure, the figure patch parameters are overwritten (WTF?).
# Hence we need to specify them again in the save command.
fig.savefig('test.png', edgecolor=fig.get_edgecolor())

这里输入图片描述

现在轴是一个更难解决的问题。我们可以采用与图形相同的方法(@jody-klymak我想是建议),但是该补丁仅对应于位于轴限制范围内的区域,即它不包括刻度标签、轴标签和标题。

然而,轴有一个get_tightbbox 方法,这就是我们需要的。但是,使用它也有一些小问题,如代码注释所述。

# We want to use axis.get_tightbbox to determine the axis dimensions including all
# decorators, i.e. tick labels, axis labels, etc.
# However, get_tightbox requires the figure renderer, which is not initialized
# until the figure is drawn.
plt.ion()
fig.canvas.draw()

for ii, ax in enumerate(axes):
    ax.set_title(f'Title {ii+1}')
    ax.set_ylabel(f'Y-Label {ii+1}')
    ax.set_xlabel(f'X-Label {ii+1}')
    bbox = ax.get_tightbbox(fig.canvas.get_renderer())
    x0, y0, width, height = bbox.transformed(fig.transFigure.inverted()).bounds
    # slightly increase the very tight bounds:
    xpad = 0.05 * width
    ypad = 0.05 * height
    fig.add_artist(plt.Rectangle((x0-xpad, y0-ypad), width+2*xpad, height+2*ypad, edgecolor='red', linewidth=3, fill=False))

fig.savefig('test2.png', edgecolor=fig.get_edgecolor())
plt.show()

enter image description here


非常感谢您的帮助和关注。我发现您的代码非常有用且易于理解。同时,我还找到了与您的代码非常相似的代码,并成功地进行了配置。 - rohan singh
在将fig.canvas.renderer更改为fig.canvas.get_renderer()后,这个程序可以完美运行。 - Thomas Kühn

1

这里输入图片描述我发现了一些非常相似的东西,然后想办法配置出它在做什么。

autoAxis1 = ax8i[1].axis() #ax8i[1] is the axis where we want the border 

import matplotlib.patches as ptch

rec = ptch.Rectangle((autoAxis1[0]-12,autoAxis1[2]-30),(autoAxis1[1]- 
autoAxis1[0])+18,(autoAxis1[3]- 
autoAxis1[2])+35,fill=False,lw=2,edgecolor='cyan')

rec = ax8i[1].add_patch(rec)

rec.set_clip_on(False)

代码有点复杂,但一旦了解 Rectangle() 内的括号部分各自表示什么,就很容易理解代码。

0
  • seabornmatplotlib的高级API。对于那些希望在seaborn轴级函数周围放置边框的人,流程与其他相同。但是,图级函数需要额外的步骤。
  • 这个答案展示了使用哪些matplotlib方法,但必须从catplot FacetGrid中提取figureaxes对象,如下所示。
  • 'pink'用于使边框在使用黑色StackOverflow背景的人中显示出来。
  • 要重新启用FacetGrid的顶部和左侧脊柱,请参见此答案

图形边框

import seaborn as sns

# load sample dataframe and convert it to a long form
df = sns.load_dataset('geyser')
df = df.melt(id_vars='kind', var_name='cat', value_name='time')

# plot the catplot
g = sns.catplot(data=df, x='kind', y='time', col='cat')

# extract the figure object
fig = g.figure

# use standard matplotlib figure methods
fig.patch.set_linewidth(10)
fig.patch.set_edgecolor('pink')  # substitute 'k' for black

enter image description here

坐标轴边框

g = sns.catplot(data=df, x='kind', y='time', col='cat')

# extract and flatten the numpy array of axes
axes = g.axes.flat

# iterate through each axes and increase the linewidth and add a color
for ax in axes:
    ax.patch.set_linewidth(10)
    ax.patch.set_edgecolor('pink')

enter image description here

图形和坐标轴边框的组合

g = sns.catplot(data=df, x='kind', y='time', col='cat')

axes = g.axes.flat
for ax in axes:
    ax.patch.set_linewidth(5)
    ax.patch.set_edgecolor('k')

fig = g.figure
fig.patch.set_linewidth(10)
fig.patch.set_edgecolor('purple')

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接