我想为某些子图添加彩色边框,并以像素为单位指定固定宽度。我通过向轴后面的图形添加Rectangle
补丁来编写以下函数。
def add_subplot_border(ax, width=0, color=None):
fig = ax.get_figure()
# Convert bottom-left and top-right to display coordinates
x0, y0 = ax.transAxes.transform((0, 0))
x1, y1 = ax.transAxes.transform((1, 1))
# Adjust margins
x0 -= width
x1 += width
y0 -= width
y1 += width
# Convert back to Axes coordinates
x0, y0 = ax.transAxes.inverted().transform((x0, y0))
x1, y1 = ax.transAxes.inverted().transform((x1, y1))
rect = plt.Rectangle((x0, y0), x1-x0, y1-y0,
color=color,
transform=ax.transAxes,
zorder=-1)
fig.patches.append(rect)
这似乎是一个很好的起点,但是当调整图形大小时,边框的相对厚度也会发生变化。如何指定要缩放的变换并将贴片转换为固定宽度边框,而不管窗口缩放?或者,有没有更好的方法来解决这个问题?
原始图
缩放图 - 边框不均匀
答案 0 :(得分:1)
不是计算边距并使用额外宽度绘制Rectangle
(而是由Axis
覆盖,而是可以给Rectangle
一个线宽(在重新缩放时保留的点数。请注意,该行总是以Rectangle
的边框为中心,所以如果您想要围绕轴的5点框架,则应该请求线宽10(或可能是11)。
我稍微调整了你的功能,并添加了一个用例示例:
from matplotlib import pyplot as plt
def add_subplot_border(ax, width=1, color=None ):
fig = ax.get_figure()
# Convert bottom-left and top-right to display coordinates
x0, y0 = ax.transAxes.transform((0, 0))
x1, y1 = ax.transAxes.transform((1, 1))
# Convert back to Axes coordinates
x0, y0 = ax.transAxes.inverted().transform((x0, y0))
x1, y1 = ax.transAxes.inverted().transform((x1, y1))
rect = plt.Rectangle(
(x0, y0), x1-x0, y1-y0,
color=color,
transform=ax.transAxes,
zorder=-1,
lw=2*width+1,
fill=None,
)
fig.patches.append(rect)
if __name__ == '__main__':
fig,axes = plt.subplots(ncols=2,nrows=2,figsize=(8,8))
colors = 'brgy'
widths = [1,2,4,8]
for ax,col,w in zip(axes.reshape(-1),colors, widths):
add_subplot_border(ax,w,col)
plt.show()
这是原始数字:
这是缩放的数字(线条看起来更薄,因为我增加数字大小):