[英]How to add border or frame around individual subplots
I want to create an image like this, but I'm unable to put the individual plots inside a frame.我想创建这样的图像,但我无法将各个图放在框架内。
I don't know why you are getting so much flak from the others.我不知道为什么你会从其他人那里得到这么多的抨击。 Your problem is crystal-clear, but the solution is anything but.
您的问题很清楚,但解决方案却绝非如此。 I couldn't find anything that explains the process for axes on the first two pages of google, and I knew exactly what I was looking for.
我在谷歌的前两页上找不到任何解释轴的过程的东西,我确切地知道我在找什么。
Anyway, figures and axes have a patch attribute, which is the rectangle that makes up the backgound.无论如何,图形和坐标轴都有一个 patch 属性,即构成背景的矩形。 Setting a figure frame is hence pretty straightforward:
因此,设置图形框架非常简单:
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())
Now the axes are a much tougher nut to crack.现在,轴是一个更难破解的螺母。 We could use the same approach as for the figure (which @jody-klymak I think is suggesting), however, the patch only corresponds to the area that is inside the axis limits, ie it does not include the tick labels, axis labels, nor the title.
我们可以使用与图相同的方法(我认为@jody-klymak 建议),但是,补丁只对应于轴范围内的区域,即它不包括刻度标签、轴标签、也不是标题。
However, axes have a get_tightbbox
method, which is what we are after.但是,axes 有一个
get_tightbbox
方法,这就是我们所追求的。 However, using that also has some gotchas, as explained in the code comments.但是,使用它也有一些问题,如代码注释中所述。
# 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()
I found something very similar and somehow configured it out what its doing.
我发现了一些非常相似的东西,并以某种方式对其进行了配置。
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)
The code is a bit complex but once we get to know what part of the bracket inside the Rectangle() is doing what its quite easy to get the code.代码有点复杂,但是一旦我们知道 Rectangle() 中括号的哪一部分在做什么,就很容易得到代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.