3
import matplotlib.pyplot as plt
import numpy as np

n = 16

im = np.eye(n)

fig = plt.figure()
ax = fig.add_subplot(121)
ax.imshow(im)
ax = fig.add_subplot(122)
ax.imshow(im, extent=(0, n, 0, n))

plt.show()

results in the following figure enter image description here

I would have expected that with this extent, both figures are (almost) identical, but they are not: note how the y-axis is flipped. What's more annoying is that the figure on the right is wrong: the value at the origin is show as 0 whereas it is one.

If I flip the y argument in the extent, extent=(0, n, n, 0), I get the expected behavior.

As I understand it, the description of the extent argument of imshow,

extent : scalars (left, right, bottom, top), optional, default: None

The location, in data-coordinates, of the lower-left and upper-right corners. If None, the image is positioned such that the pixel centers fall on zero-based (row, column) indices.

is not really explicit about that behavior.

My question is, why does this flip happen, why do we have to invert top/bottom in the extent to get the expected behavior?

EDIT

I have read this question, the OP does not mention a flipping issue and the answer does not bring the issue either.

Setting origin='lower' element does bring the first image pixel at (0,0) but the image is then displayed upside down.

I am sure there is a simple explanation to explain these behaviors consistently but quite can't pin it yet.

Community
  • 1
  • 1
P-Gn
  • 23,115
  • 9
  • 87
  • 104
  • It's probably because the image is drawn left-to-right and top-to-bottom. So `top=n` and `bottom=0` is "bottom-up". – a_guest Jul 21 '17 at 13:34

1 Answers1

6

The imshow has an argument origin. The default is origin="upper". This conflicts with the setting of the extent, which, according to the documentation, should set the "location, in data-coordinates, of the lower-left and upper-right corners." This, however is only true if origin = "lower" is set.

I have already proposed to extend the documentation with a sentence like

"If you set origin to "upper" any y coordinates you may specify using extent and/or ylim need to be reversed."

This is exactly what you already found out yourself. So options are:

  • If you want the image to origin in the upper left corner:

    origin="upper", extent=(0, n, n, 0)
    
  • If you want the image to origin in the lower left corner:

    origin="lower", extent=(0, n, 0, n)
    
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712