Matplotlib imshow: Data rotated?

Question:

I was trying to plot some data with scatter. My code is

import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
from scipy.interpolate import griddata
data = np.loadtxt('file1.txt')
x = data[:,0]
y = data[:,1]
z = data[:,2]
plt.scatter(x, y, c=z, s=100, cmap=mpl.cm.spectral)
cbar=plt.colorbar()
s=18
plt.ylabel(r"$a_v$", size=s)
plt.xlabel(r"$a_{rm min}$", size=s)
plt.xlim([x.min(),x.max()])
plt.ylim([y.min(),y.max()])
plt.show()

The result is
enter image description here

Now I came on the idea to try imshow with the some data, soince I didn’t like the circles of scatter.
So I tried this

from matplotlib.mlab import griddata
import matplotlib.pyplot as plt
data = np.loadtxt('file1.txt')
x = data[:,0]
y = data[:,1]
z = data[:,2]

N = 30j
extent = (min(x), max(x), min(y), max(y))

xs,ys = np.mgrid[extent[0]:extent[1]:N, extent[2]:extent[3]:N]

resampled = griddata(x, y, z, xs, ys)

plt.imshow(resampled.T, extent=extent)
s=18
plt.ylabel(r"$a_v$", size=s)
plt.xlabel(r"$a_{rm min}$", size=s)
plt.xlim([x.min(),x.max()])
plt.ylim([y.min(),y.max()])
cbar=plt.colorbar()
plt.show()

With this result:
enter image description here

My problem is obviosly why imshow() does invert the data? What happens here exactly?

PS: Here are the data, in case someone would like to play with them

Asked By: Tengis

||

Answers:

It’s not inverted, just flipped. The origin for imshow default to the upper left rather than the lower left. imshow has a parameter to specify the origin, it’s named origin. Alternatively you can set the default in your matplotlib.conf.

Answered By: Bernhard

Look at the keyword arguments of imshow. There is origin. The default is “upper”, but you want “lower”.

The default makes sense for plotting images, that usually start at the top-left corner. For most matrix-plotting, you’ll want origin="lower"

Answered By: Thorsten Kranz

BTW, you could use marker=’s’ to draw squares in your scatter plot instead of circles and then just keep your original code.

Answered By: dhpizza

Consider to use pcolormesh or contourf if you want to plot data of the form f(X, Y) = Z. imshow simply plots data Z, scaling and resampling has do be done manually.

Answered By: lumbric

For those who may still have problem with imshow, although the origin keyword helps, be aware of the coordinate axes as well.

Generally, for an array of shape (M, N), the first index runs along the vertical, the second index runs along the horizontal. The pixel centers are at integer positions ranging from 0 to N’ = N – 1 horizontally and from 0 to M’ = M – 1

You can find more details from the matplotlib website.

For example, consider the following code:

M=5; N=10
a=np.zeros((M, N))
for i in range(M):
    for j in range(N):
        a[i,j]=i**2
plt.imshow(a, origin="lower")
print(f'here is a:n{a}n')
print(f'shape of a: {a.shape}')
print(f'a[0,0]: {a[0,0]}')
print(f'a[0,5]: {a[0,5]}')
print(f'a[0,9]: {a[0,9]}')
print(f'a[4,0]: {a[4,0]}')

Here is the output:

enter image description here

Answered By: learner
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.