如何向子图添加固定宽度的边框

时间:2017-08-01 15:28:41

标签: python matplotlib

我想为某些子图添加彩色边框,并以像素为单位指定固定宽度。我通过向轴后面的图形添加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)

这似乎是一个很好的起点,但是当调整图形大小时,边框的相对厚度也会发生变化。如何指定要缩放的变换并将贴片转换为固定宽度边框,而不管窗口缩放?或者,有没有更好的方法来解决这个问题?

原始图

Original figure

缩放图 - 边框不均匀

Scaled figure

1 个答案:

答案 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()

这是原始数字:

subplots with rectangle-underlay

这是缩放的数字(线条看起来更薄,因为我增加数字大小):

scaled version of same figure