4

I'm trying to display 2D data with axis labels using both contour and pcolormesh. As has been noted on the matplotlib user list, these functions obey different conventions: pcolormesh expects the x and y values to specify the corners of the individual pixels, while contour expects the centers of the pixels.

What is the best way to make these behave consistently?

One option I've considered is to make a "centers-to-edges" function, assuming evenly spaced data:

def centers_to_edges(arr):
    dx = arr[1]-arr[0]
    newarr = np.linspace(arr.min()-dx/2,arr.max()+dx/2,arr.size+1)
    return newarr

Another option is to use imshow with the extent keyword set.
The first approach doesn't play nicely with 2D axes (e.g., as created by meshgrid or indices) and the second discards the axis numbers entirely

keflavich
  • 18,278
  • 20
  • 86
  • 118
  • Have you considered using `numpy.griddata` to interpolate all your data to corners? (Or centres) – dmcdougall Apr 02 '13 at 01:29
  • Yes, but that adds unnecessary overhead, and I'm dealing with large data in some cases (though I suppose probably not in the cases where I'm concerned about sub-pixel corner accuracy... hrm). Also, I think you mean `scipy.interpolate.griddata`? – keflavich Apr 02 '13 at 05:03
  • I stand corrected, I did indeed mean `scipy.interpolate.griddata`. If you don't want to interpolate the data because it's too big, try passing an array of shifted x- and y-coordinates to `ax.pcolormesh()`. That way you don't need to touch your data at all. – dmcdougall Apr 02 '13 at 16:10
  • Yeah, that's the intent of `centers_to_edges` - I didn't make that clear, though, so I guess this just means we're on the same page. – keflavich Apr 02 '13 at 17:31

1 Answers1

0

Your data is a regular mesh? If it doesn't, you can use griddata() to obtain it. I think that if your data is too big, a sub-sampling or regularization always is possible. If the data is too big, maybe your output image always will be small compared with it and you can exploit this. If you use imshow() with "extent" and "interpolation='nearest'", you will see that the data is cell-centered, and extent provided the lower edges of cells (corners). On the other hand, contour assumes that the data is cell-centered, and X,Y must be the center of cells. So, you need to be care about the input domain for contour. The trivial example is:

x = np.arange(-10,10,1)
X,Y = np.meshgrid(x,x)
P = X**2+Y**2
imshow(P,extent=[-10,10,-10,10],interpolation='nearest',origin='lower')
contour(X+0.5,Y+0.5,P,20,colors='k')

My tests told me that pcolormesh() is a very slow routine, and I always try to avoid it. griddata and imshow() always is a good choose for me.

Pablo
  • 2,443
  • 1
  • 20
  • 32