This question already has an answer here:
-
Interactive pixel information of an image in Python?
4 answers
I am using ipython with matplotlib, and I show images in this way:
(started up with: ipython --pylab)
figure()
im = zeros([256,256]) #just a stand-in for my real images
imshow(im)
Now, as I move the cursor over the image, I see the location of the mouse displayed in the lower left corner of the figure window. The numbers displayed are x = column number, y = row number. This is very plot-oriented rather than image-oriented. Can I modify the numbers displayed?
- My first choice would be to display x = row number*scalar, y = column number*scalar
- My second choice would be to display x = row number, y = column number
- My third choice is to not display the numbers for the mouse location at all
Can I do any of these things? I'm not even sure what to call that little mouse-over test display widget. Thanks!
You can do this quite simply on a per axis basis by simply re-assigning format_coord
of the Axes
object, as shown in the examples.
format_coord
is any function which takes 2 arguments (x,y) and returns a string (which is then displayed on the figure.
If you want to have no display simply do:
ax.format_coord = lambda x, y: ''
If you want just the row and column (with out checking)
scale_val = 1
ax.format_coord = lambda x, y: 'r=%d,c=%d' % (scale_val * int(x + .5),
scale_val * int(y + .5))
If you want to do this on every iimage you make, simply define the wrapper function
def imshow(img, scale_val=1, ax=None, *args, **kwargs):
if ax is None:
ax = plt.gca()
im = ax.imshow(img, *args, **kwargs)
ax.format_coord = lambda x, y: 'r=%d,c=%d' % (scale_val * int(x + .5),
scale_val * int(y + .5))
ax.figure.canvas.draw()
return im
which with out much testing I think should more-or-less be drop-in replacement for plt.imshow
Yes, you can. But it's harder than you'd think.
The mouse-tracking label you see is generated by calls to matplotlib.axes.Axes.format_coord in response to mouse tracking. You have to create your own Axes class (overriding format_coord to do what you want it to do), then instruct matplotlib to use it in place of the default one.
Specifically:
Make your own Axes subclass
from matplotlib.axes import Axes
class MyRectilinearAxes(Axes):
name = 'MyRectilinearAxes'
def format_coord(self, x, y):
# Massage your data here -- good place for scalar multiplication
if x is None:
xs = '???'
else:
xs = self.format_xdata(x * .5)
if y is None:
ys = '???'
else:
ys = self.format_ydata(y * .5)
# Format your label here -- I transposed x and y labels
return 'x=%s y=%s' % (ys, xs)
Register your Axes subclass
from matplotlib.projections import projection_registry
projection_registry.register(MyRectilinearAxes)
Create a figure and with your custom axes
figure()
subplot(111, projection="MyRectilinearAxes")
Draw your data as before
im = zeros([256,256]) #just a stand-in for my real images
imshow(im)