I tried various methods found online but can’t add an image at the correct location in the top left corner of my figure.
Here’s one on my attempts, where I try to set exact the size of the generated figure in pixels, and then add a 48×48 px image in top left corner. Issues:
- The figures are not created with the chosen pixel size
- On the X axis, where the origin is left, I need to offset by 34 pixels to get the image near to left border, which makes no sense to me.
- On the Y axis, the image is also badly placed, mostly because the size is not as expected.
Why is the code below failing?
How can I achieve what I want?
import matplotlib.pylab as plt # Plot
from PIL import Image # Add background image
from matplotlib.offsetbox import AnnotationBbox, OffsetImage # Add background image
def plot_image(w, h):
px = 1/plt.rcParams['figure.dpi']
fig,ax = plt.subplots(figsize=(w*px, h*px))
image_path = '......../The Simpsons 48x48.png'
image_data = Image.open(image_path)
image_box = OffsetImage(image_data, zoom=1)
anno_box = AnnotationBbox(image_box, xy=(34,h-48), xycoords='figure pixels', frameon=False)
ax.add_artist(anno_box)
plt.text(0.5, 0.5, f'Requested: {w}x{h}')
plt.text(0.5, 0.4, 'Obtained: 579x455' if w==640 else
'Obtained: 759x561' if w==800 else
'Obtained: 960x711' )
plt.show()
plot_image( 640, 480)
plot_image( 800, 600)
plot_image(1024, 768)
Results:
Image used:
It’s all about understanding the size of the image. Ensure first that the figure size is set correctly in pixels and then correctly place the image in the top left corner using AnnotationBbox
. Here is how you should do this:
import matplotlib.pyplot as plt
from PIL import Image
from matplotlib.offsetbox import AnnotationBbox, OffsetImage
def plot_image(w, h):
px = 1 / plt.rcParams['figure.dpi']
fig, ax = plt.subplots(figsize=(w * px, h * px))
image_path = r"C:Usersserge.degossondevareDownloadshomer.png"
image_data = Image.open(image_path)
image_box = OffsetImage(image_data, zoom=1)
anno_box = AnnotationBbox(image_box, xy=(0, 1), xycoords='axes fraction',
box_alignment=(0, 1), frameon=False)
ax.add_artist(anno_box)
plt.text(0.5, 0.5, f'Requested: {w}x{h}', ha='center', va='center')
plt.text(0.5, 0.4, f'Obtained: {int(fig.bbox.width)}x{int(fig.bbox.height)}', ha='center', va='center')
ax.set_axis_off()
plt.show()
plot_image(640, 480)
plot_image(800, 600)
plot_image(1024, 768)
which gives you