Version of imshow which shows the value under the cursor. Modified from poppy: http://www.stsci.edu/~mperrin/software/poppy/_modules/poppy/utils.html
def imshowz(image, ax=None, *args, **kwargs):
""" wrapper for matplotlib imshow that displays the value under the cursor position
Wrapper for pyplot.imshow that sets up a custom mouseover display formatter
so that mouse motions over the image are labeled in the status bar with
pixel numerical value as well as X and Y coords.
Why this behavior isn't the matplotlib default, I have no idea...
"""
if ax is None: ax = plt.gca()
myax = ax.imshow(image, cmap='gray', origin='lower', interpolation='none', *args, **kwargs)
aximage = ax.images[0].properties()['array']
# need to account for half pixel offset of array coordinates for mouseover relative to pixel center,
# so that the whole pixel from e.g. ( 1.5, 1.5) to (2.5, 2.5) is labeled with the coordinates of pixel (2,2)
# We use the extent and implementation to map back from the data coord to pixel coord
# There is probably an easier way to do this...
imext = ax.images[0].get_extent() # returns [-X, X, -Y, Y]
imsize = ax.images[0].get_size() # returns [sY, sX]g
# map data coords back to pixel coords:
#pixx = (x - imext[0])/(imext[1]-imext[0])*imsize[1]
#pixy = (y - imext[2])/(imext[3]-imext[2])*imsize[0]
# and be sure to clip appropriatedly to avoid array bounds errors
report_pixel = lambda x, y : "(%6.3f, %6.3f) %-12.6g" % (x,y, aximage[np.floor( (y - imext[2])/(imext[3]-imext[2])*imsize[0] ).clip(0,imsize[0]-1), np.floor( (x - imext[0])/(imext[1]-imext[0])*imsize[1] ).clip(0,imsize[1]-1)])
#(x,y, aximage[np.floor(y+0.5),np.floor(x+0.5)]) # this works for regular pixels w/out an explicit extent= call
ax.format_coord = report_pixel
return ax