diff --git a/doc/users/next_whats_new/2018-10-10-AL.rst b/doc/users/next_whats_new/2018-10-10-AL.rst new file mode 100644 index 000000000000..ec12e55e88ca --- /dev/null +++ b/doc/users/next_whats_new/2018-10-10-AL.rst @@ -0,0 +1,9 @@ +Improved formatting of image values under cursor when a colorbar is present +``````````````````````````````````````````````````````````````````````````` + +When a colorbar is present, its formatter is now used to format the image +values under the mouse cursor in the status bar. For example, for an image +displaying the values 10,000 and 10,001, the statusbar will now (using default +settings) display the values as ``0.0+1e4`` and ``1.0+1e4`` (or ``10000.0`` +and ``10001.0`` if the offset-text is disabled on the colorbar), whereas both +values were previously displayed as ``1e+04``. diff --git a/lib/matplotlib/artist.py b/lib/matplotlib/artist.py index d2629951734e..3cd33728310f 100644 --- a/lib/matplotlib/artist.py +++ b/lib/matplotlib/artist.py @@ -2,6 +2,7 @@ from functools import wraps import inspect import logging +from numbers import Number import re import warnings @@ -1167,8 +1168,8 @@ def format_cursor_data(self, data): data[0] except (TypeError, IndexError): data = [data] - data_str = ', '.join('{:0.3g}'.format(item) for item in data if - isinstance(item, (np.floating, np.integer, int, float))) + data_str = ', '.join('{:0.3g}'.format(item) for item in data + if isinstance(item, Number)) return "[" + data_str + "]" @property diff --git a/lib/matplotlib/cbook/__init__.py b/lib/matplotlib/cbook/__init__.py index 22c804b88da5..4758c802a7ef 100644 --- a/lib/matplotlib/cbook/__init__.py +++ b/lib/matplotlib/cbook/__init__.py @@ -302,11 +302,25 @@ def local_over_kwdict(local_var, kwargs, *keys): def strip_math(s): - """remove latex formatting from mathtext""" - remove = (r'\mathdefault', r'\rm', r'\cal', r'\tt', r'\it', '\\', '{', '}') - s = s[1:-1] - for r in remove: - s = s.replace(r, '') + """ + Remove latex formatting from mathtext. + + Only handles fully math and fully non-math strings. + """ + if len(s) >= 2 and s[0] == s[-1] == "$": + s = s[1:-1] + for tex, plain in [ + (r"\times", "x"), # Specifically for Formatter support. + (r"\mathdefault", ""), + (r"\rm", ""), + (r"\cal", ""), + (r"\tt", ""), + (r"\it", ""), + ("\\", ""), + ("{", ""), + ("}", ""), + ]: + s = s.replace(tex, plain) return s diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index d3ce8f4bd15e..c8126ba58c95 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -906,6 +906,15 @@ def get_cursor_data(self, event): else: return arr[i, j] + def format_cursor_data(self, data): + if self.colorbar: + return ("[" + + cbook.strip_math(self.colorbar.formatter(data)) + + cbook.strip_math(self.colorbar.formatter.get_offset()) + + "]") + else: + return super().format_cursor_data(data) + class NonUniformImage(AxesImage): def __init__(self, ax, *, interpolation='nearest', **kwargs): diff --git a/lib/matplotlib/tests/test_image.py b/lib/matplotlib/tests/test_image.py index 800895067db5..4281cdfcdde3 100644 --- a/lib/matplotlib/tests/test_image.py +++ b/lib/matplotlib/tests/test_image.py @@ -262,6 +262,24 @@ def test_cursor_data(): assert im.get_cursor_data(event) is None +def test_format_cursor_data(): + from matplotlib.backend_bases import MouseEvent + + fig, ax = plt.subplots() + im = ax.imshow([[10000, 10001]]) + + xdisp, ydisp = ax.transData.transform_point([0, 0]) + event = MouseEvent('motion_notify_event', fig.canvas, xdisp, ydisp) + assert im.get_cursor_data(event) == 10000 + assert im.format_cursor_data(im.get_cursor_data(event)) == "[1e+04]" + + fig.colorbar(im) + fig.canvas.draw() # This is necessary to set up the colorbar formatter. + + assert im.get_cursor_data(event) == 10000 + assert im.format_cursor_data(im.get_cursor_data(event)) == "[0.0+1e4]" + + @image_comparison(baseline_images=['image_clip'], style='mpl20') def test_image_clip(): d = [[1, 2], [3, 4]]