diff --git a/doc/users/next_whats_new/nonuniformimage_mousover.rst b/doc/users/next_whats_new/nonuniformimage_mousover.rst new file mode 100644 index 000000000000..e5a7ab1bd155 --- /dev/null +++ b/doc/users/next_whats_new/nonuniformimage_mousover.rst @@ -0,0 +1,4 @@ +NonUniformImage now has mouseover support +----------------------------------------- +When mousing over a `~matplotlib.image.NonUniformImage` the data values are now +displayed. diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index 0ab02c403d0d..e3269062699c 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -1038,7 +1038,6 @@ def get_cursor_data(self, event): class NonUniformImage(AxesImage): - mouseover = False # This class still needs its own get_cursor_data impl. def __init__(self, ax, *, interpolation='nearest', **kwargs): """ @@ -1190,6 +1189,16 @@ def set_cmap(self, cmap): raise RuntimeError('Cannot change colors after loading data') super().set_cmap(cmap) + def get_cursor_data(self, event): + # docstring inherited + x, y = event.xdata, event.ydata + if (x < self._Ax[0] or x > self._Ax[-1] or + y < self._Ay[0] or y > self._Ay[-1]): + return None + j = np.searchsorted(self._Ax, x) - 1 + i = np.searchsorted(self._Ay, y) - 1 + return self._A[i, j] + class PcolorImage(AxesImage): """ @@ -1322,10 +1331,7 @@ def get_cursor_data(self, event): return None j = np.searchsorted(self._Ax, x) - 1 i = np.searchsorted(self._Ay, y) - 1 - try: - return self._A[i, j] - except IndexError: - return None + return self._A[i, j] class FigureImage(_ImageBase): diff --git a/lib/matplotlib/tests/test_image.py b/lib/matplotlib/tests/test_image.py index 9a40b9baa313..17d0c011ba63 100644 --- a/lib/matplotlib/tests/test_image.py +++ b/lib/matplotlib/tests/test_image.py @@ -365,6 +365,38 @@ def test_cursor_data(): assert im.get_cursor_data(event) == 44 +@pytest.mark.parametrize("xy, data", [ + # x/y coords chosen to be 0.5 above boundaries so they lie within image pixels + [[0.5, 0.5], 0 + 0], + [[0.5, 1.5], 0 + 1], + [[4.5, 0.5], 16 + 0], + [[8.5, 0.5], 16 + 0], + [[9.5, 2.5], 81 + 4], + [[-1, 0.5], None], + [[0.5, -1], None], + ] +) +def test_cursor_data_nonuniform(xy, data): + from matplotlib.backend_bases import MouseEvent + + # Non-linear set of x-values + x = np.array([0, 1, 4, 9, 16]) + y = np.array([0, 1, 2, 3, 4]) + z = x[np.newaxis, :]**2 + y[:, np.newaxis]**2 + + fig, ax = plt.subplots() + im = NonUniformImage(ax, extent=(x.min(), x.max(), y.min(), y.max())) + im.set_data(x, y, z) + ax.add_image(im) + # Set lower min lim so we can test cursor outside image + ax.set_xlim(x.min() - 2, x.max()) + ax.set_ylim(y.min() - 2, y.max()) + + xdisp, ydisp = ax.transData.transform(xy) + event = MouseEvent('motion_notify_event', fig.canvas, xdisp, ydisp) + assert im.get_cursor_data(event) == data, (im.get_cursor_data(event), data) + + @pytest.mark.parametrize( "data, text", [ ([[10001, 10000]], "[10001.000]"),