singularli
singularli

Reputation: 225

How do I determine the [fig]size of a matplotlib.image.AxesImage in pixel?

This code renders the Lenna image with matplotlib,

import urllib
import matplotlib.pyplot as plt
imgurl = 'https://upload.wikimedia.org/wikipedia/en/thumb/7/7d/Lenna_%28test_image%29.png/330px-Lenna_%28test_image%29.png'
f = urllib.request.urlopen(imgurl)
img = plt.imread(f)
axi = plt.imshow(img)

enter image description here

where axi is an instance of matplotlib.image.AxesImage

How do I determine the [fig]size of the AxesImage in pixel? the expected value might (330, 330)

I tried axi.get_window_extent() and got

Bbox([[112.68, 36.00000000000003], [330.12, 253.44000000000003]])

Where do those values (112.68, 330.12) come from?

Upvotes: 1

Views: 1866

Answers (2)

tdy
tdy

Reputation: 41437

To get the raw image size

Use AxesImage.get_size():

axi.get_size()

# (330, 330)

To convert the axes extent into pixels

Adjust the window extent by Figure.dpi:

axi = plt.imshow(img)
fig = plt.gcf()

bbox = axi.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
width = bbox.width * fig.dpi
height = bbox.height * fig.dpi

# 334.79999999999995 217.43999999999997

The reason this is not 330x330 is because of how plt.imshow() handles the aspect ratio. If you plot with aspect='auto', the underlying axes' shape becomes visible:

axi = plt.imshow(img, aspect='auto')

lenna with auto aspect


To coerce the underlying axes into desired shape

Manually define figsize and rect using the pixel dimensions and desired dpi:

width_px, height_px, _ = img.shape
dpi = 96

figsize = (width_px / dpi, height_px / dpi) # inches
rect = [0, 0, 1, 1] # [left, bottom, width, height] as fraction of figsize

fig = plt.figure(figsize=figsize, dpi=dpi) # in inches
axes = fig.add_axes(rect=rect)
axi = axes.imshow(img, aspect='auto')

lenna with auto aspect but manual axes

Then the extent pixels will be exactly 330x330:

bbox = axi.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
width = bbox.width * fig.dpi
height = bbox.height * fig.dpi

# 330.0 330.0

Upvotes: 3

wingnut
wingnut

Reputation: 111

axi.get_size() gives (330,330) - why not use that?

Upvotes: 1

Related Questions