Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aligning a text box edge with an image corner

I'm looking for a way of exactly aligning (overlaying) the corner edge of my image with corner and edge of a text box edge (bbox or other)

The code in question is:

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

As you can see, the edges of the text box is outside the image. For the life of me, I cannot find a consistent way of aligning the corner of the text box with the corner of the image. Ideally, I'd like the alignment to be independent of font size and image pixel size, but that might be asking a bit too much.

Finally, I'd like to achieve this with a grid of images, like the second example, below.

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

like image 743
TomNorway Avatar asked Jul 20 '16 12:07

TomNorway


People also ask

How do I align text and an image on the same line in Word?

Hold down Shift and use the mouse or touchpad to select the objects that you want to align. Select Shape Format or Picture Format. Select Align. If you don't see Align on the Shape Format tab, select Arrange, and then choose Align.

How do you align text boxes in Powerpoint?

Right-click the text box for which you want to set vertical alignment. On the shortcut menu, click Format Text Box. In the Format Text Box dialog box, click the Text Box tab. In the Vertical alignment box, select Top, Middle, or Bottom.

How do I align text with an image in HTML?

An <img> element is an inline element (display value of inline-block ). It can be easily centered by adding the text-align: center; CSS property to the parent element that contains it. To center an image using text-align: center; you must place the <img> inside of a block-level element such as a div .


2 Answers

Thanks to P-robot for the solution. The key part of the solution is that the annotation text edge is offset x and y by one pixel from the xy coordinate. Any extra padding used increases the necessary amount to compensate for this offset. The second grouping of arguments given to ax.annotate, below, are the relevant ones.

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

Oddly, for the grid of four images, the offset in the x-direction did not require the subtraction of one pixel, which changes xytext to xytext=(padding, -(padding-1)).

Aligned grid of four images

like image 146
TomNorway Avatar answered Sep 26 '22 03:09

TomNorway


The issue is caused from the padding of the bounding box. You can change the padding by passing the pad argument to the bounding box dictionary (for instance pad = 0 will keep the box inside the axes). I'm assuming you want some padding so it's probably best to set a padding argument and remove this from the position of the annotation (in units of pixels).

like image 45
p-robot Avatar answered Sep 26 '22 03:09

p-robot