29

I'm working on some image processing algorithms using python and matplotlib. I'd like to display the original image and the output image in a figure using a subplot (e.g. the original image next to the output image). The output image(s) are of different size than the original image. I'd like to have the subplot display the images in their actual size (or uniformly scaled) so that I can compare "apples to apples". I currently use:

plt.figure()
plt.subplot(2,1,1)
plt.imshow(originalImage)
plt.subplot(2,1,2)
plt.imshow(outputImage)
plt.show()

The result is that I get the subplot, but both images are scaled so that they are the same size (despite the fact that the axes on the output image are different than the axes of the input image). Just to be explicit: if the input image is 512x512 and the output image is 1024x1024 then both images are displayed as though they are the same size.

Is there a way to force matplotlib to either display the images at their respective actual sizes (preferable solution so that matplotlib's dynamic rescaling doesn't effect the displayed image) or to scale the images such that they are displayed with sizes proportional to their actual sizes?

Doov
  • 863
  • 2
  • 12
  • 25
  • 2
    I think `figimage` may be useful to you ... this question possibly a duplicate of [this](http://stackoverflow.com/questions/25960755/how-to-set-imshow-scale) question... – Ajean Mar 02 '15 at 20:10
  • Thank you. I will check it out. Yes looks like a duplicateish post. Guess I didn't see that one when searching. Thanks! – Doov Mar 03 '15 at 18:08
  • use `sharex` and `sharey` to share axes. See my answer below – MrE Jan 24 '19 at 06:54

3 Answers3

22

This is the answer that you are looking for:

def display_image_in_actual_size(im_path):

    dpi = 80
    im_data = plt.imread(im_path)
    height, width, depth = im_data.shape

    # What size does the figure need to be in inches to fit the image?
    figsize = width / float(dpi), height / float(dpi)

    # Create a figure of the right size with one axes that takes up the full figure
    fig = plt.figure(figsize=figsize)
    ax = fig.add_axes([0, 0, 1, 1])

    # Hide spines, ticks, etc.
    ax.axis('off')

    # Display the image.
    ax.imshow(im_data, cmap='gray')

    plt.show()

display_image_in_actual_size("./your_image.jpg")

Adapted from here.

Community
  • 1
  • 1
Joseph
  • 2,327
  • 1
  • 19
  • 21
13

Adapting Joseph's answer here: Apparently the default dpi changed to 100, so to be safe in the future you can directly access the dpi from the rcParams as

import matplotlib as mpl
import matplotlib.pyplot as plt

def display_image_in_actual_size(im_path):

    dpi = mpl.rcParams['figure.dpi']
    im_data = plt.imread(im_path)
    height, width, depth = im_data.shape

    # What size does the figure need to be in inches to fit the image?
    figsize = width / float(dpi), height / float(dpi)

    # Create a figure of the right size with one axes that takes up the full figure
    fig = plt.figure(figsize=figsize)
    ax = fig.add_axes([0, 0, 1, 1])

    # Hide spines, ticks, etc.
    ax.axis('off')

    # Display the image.
    ax.imshow(im_data, cmap='gray')

    plt.show()

display_image_in_actual_size("./your_image.jpg")
Benjamin Maier
  • 522
  • 6
  • 14
12

If you are looking to show images at their actual size, so the actual pixel size is the same for both images in subplots, you probably just want to use the options sharex and sharey in the subplot definition

fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(15, 7), dpi=80, sharex=True, sharey=True)
ax[1].imshow(image1, cmap='gray')
ax[0].imshow(image2, cmap='gray')

results in:

enter image description here

Where the second image is 1/2 size of the first one.

MrE
  • 19,584
  • 12
  • 87
  • 105