How do I change the scale of imshow in matplotlib without stretching the image?


I wanted to plot using imshow in a manner similar to the second example here but to redefine the scale for the axis. I'd also like the image to stay still while I do this!

The code from the example:

from scipy import *
from pylab import *

# Creating the grid of coordinates x,y 
x,y = ogrid[-1.:1.:.01, -1.:1.:.01]

z = 3*y*(3*x**2-y**2)/4 + .5*cos(6*pi * sqrt(x**2 +y**2) + arctan2(x,y))

# Creating image
imshow(z, origin='lower', extent=[-1,1,-1,1])

title('A spiral !')

# Adding a line plot slicing the z matrix just for fun. 
plot(x[:], z[50, :])


If I modify the extent to be wider, eg:

imshow(z, origin='lower', extent=[-4,4,-1,1])

Then the resulting image is stretched. But all I wanted to do was change the ticks to coincide with my data. I know I can use pcolor to conserve the X and Y data, though that has other ramifications to it.

I found this answer which allows me to manually redo all the ticks:

How do I convert (or scale) axis values and redefine the tick frequency in matplotlib?

But that seems a bit overkill.

Is there a way to only change the extent shown by the labels?

5/23/2017 12:16:51 PM

Accepted Answer

A help(imshow) will find the aspect argument, which after a bit of experimentation seems to give what you want (a square image of the spiral but with x scale from -4 to 4 and y from -1 to 1) when used like this:

imshow(z, origin='lower', extent=[-4,4,-1,1], aspect=4)

But now your plot is still from -1 to 1, so you'd have to modify that as well...

plot(x[:]*4, z[50, :])

I think when you have several elements that would have to be modified, just using a one-line tick relabeling instead isn't overkill:

xticks(xticks()[0], [str(t*4) for t in xticks()[0]])
6/10/2012 3:56:09 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow