将文本框边缘与图像角对齐

时间:2016-07-20 12:00:43

标签: python matplotlib

我正在寻找一种精确对齐(覆盖)图像角落边缘与文本框边缘(bbox或其他)边角的方法

有问题的代码是:

import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1)
ax.imshow(np.random.random((256,256)), cmap=plt.get_cmap("viridis"))
ax.axis("off")

ax.annotate(
    s = 'image title', 
    xy=(0, 0), 
    xytext=(0, 0), 
    va='top',
    ha='left',
    fontsize = 15,
    bbox=dict(facecolor='white', alpha=1),
    )
plt.show()

Single image

如您所见,文本框的边缘位于图像之外。对于我的生活,我找不到一种一致的方法来将文本框的角与图像的角对齐。理想情况下,我希望对齐与字体大小和图像像素大小无关,但这可能有点过分。

最后,我想用一个图像网格实现这一点,如下面的第二个例子。

import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8, 8))
images = 4*[np.random.random((256,256))]

gs = gridspec.GridSpec(
    nrows=2, 
    ncols=2,
    top=1., 
    bottom=0., 
    right=1., 
    left=0., 
    hspace=0.,
    wspace=0.,
)
for g, i in zip(gs, range(len(images))):
    ax = plt.subplot(g)
    im = ax.imshow(
        images[i],
        cmap=plt.get_cmap("viridis")
    )
    ax.set_xticks([])
    ax.set_yticks([])
    ax.annotate(
        s = 'image title', 
        xy=(0, 0), 
        xytext=(0, 0), 
        va='top',
        ha='left',
        fontsize = 15,
        bbox=dict(facecolor='white', alpha=1),
    )

enter image description here

2 个答案:

答案 0 :(得分:2)

问题是由边界框的填充引起的。您可以通过将pad参数传递给边界框字典来更改填充(例如pad = 0将使框保持在轴内)。我假设你想要一些填充,所以最好设置一个填充参数并从注释的位置(以像素为单位)中删除它。

答案 1 :(得分:2)

感谢P-robot的解决方案。解决方案的关键部分是注释文本边将x和y从xy坐标偏移一个像素。使用的任何额外填充增加了补偿此偏移所需的量。下面给出ax.annotate的第二组论据是相关的。

fig, ax = plt.subplots(1)
ax.imshow(np.random.random((256,256)), cmap=plt.get_cmap("viridis"))
ax.axis("off")

padding = 5
ax.annotate(
    s = 'image title', 
    fontsize = 12,

    xy=(0, 0), 
    xytext=(padding-1, -(padding-1)), 
    textcoords = 'offset pixels',
    bbox=dict(facecolor='white', alpha=1, pad=padding),
    va='top',
    ha='left',
    )
plt.show()

Aligned image

奇怪的是,对于四幅图像的网格,x方向的偏移不需要减去一个像素,这会将xytext更改为xytext=(padding, -(padding-1))

Aligned grid of four images