From 8c4df386438619b872d954865761b4631032ba05 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Thu, 1 Aug 2019 01:22:44 +0200 Subject: [PATCH] Use fix_minus in format_data_short. See changelog. AFAICS, all GUI toolkits (at least qt5/gtk3/wx/tk) display the unicode minus properly. Moving the implementation of the replacement to the base Formatter class is because it is otherwise confusing as to whether `self.fix_minus` does the replacement or not -- one needs to check whether the current class overrides the do-nothing fix_minus. Instead, one can just have a base-class implementation that performs the replacement, and not call `self.fix_minus` if the replacement is not desired. For example, LogFormatter.fix_minus used to do nothing; there are tests that check that. Just don't call fix_minus instead. --- doc/api/next_api_changes/2019-08-01-AL.rst | 10 ++++ lib/matplotlib/tests/test_ticker.py | 8 +++ lib/matplotlib/ticker.py | 68 ++++++++-------------- 3 files changed, 43 insertions(+), 43 deletions(-) create mode 100644 doc/api/next_api_changes/2019-08-01-AL.rst diff --git a/doc/api/next_api_changes/2019-08-01-AL.rst b/doc/api/next_api_changes/2019-08-01-AL.rst new file mode 100644 index 000000000000..afd6ebe6a664 --- /dev/null +++ b/doc/api/next_api_changes/2019-08-01-AL.rst @@ -0,0 +1,10 @@ +API changes +``````````` + +`.Formatter.fix_minus` now performs hyphen-to-unicode-minus replacement +whenever :rc:`axes.unicode_minus` is True; i.e. its behavior matches the one +of ``.ScalarFormatter.fix_minus`` (`.ScalarFormatter` now just inherits that +implementation). + +This replacement is now used by the ``format_data_short`` method of the various +builtin formatter classes, which affects the cursor value in the GUI toolbars. diff --git a/lib/matplotlib/tests/test_ticker.py b/lib/matplotlib/tests/test_ticker.py index 05c553ae2b07..ef680ec43b9b 100644 --- a/lib/matplotlib/tests/test_ticker.py +++ b/lib/matplotlib/tests/test_ticker.py @@ -455,6 +455,14 @@ class TestScalarFormatter: (True, (6, 6), (-1e5, 1e5), 6, False), ] + @pytest.mark.parametrize('unicode_minus, result', + [(True, "\N{MINUS SIGN}1"), (False, "-1")]) + def test_unicode_minus(self, unicode_minus, result): + matplotlib.rcParams['axes.unicode_minus'] = unicode_minus + assert ( + plt.gca().xaxis.get_major_formatter().format_data_short(-1).strip() + == result) + @pytest.mark.parametrize('left, right, offset', offset_data) def test_offset_value(self, left, right, offset): fig, ax = plt.subplots() diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py index f06a91214d70..155e1f7f8d3b 100644 --- a/lib/matplotlib/ticker.py +++ b/lib/matplotlib/ticker.py @@ -280,21 +280,23 @@ def get_offset(self): def set_locs(self, locs): self.locs = locs - def fix_minus(self, s): - """ - Some classes may want to replace a hyphen for minus with the - proper unicode symbol (U+2212) for typographical correctness. - The default is to not replace it. - - Note, if you use this method, e.g., in :meth:`format_data` or - call, you probably don't want to use it for - :meth:`format_data_short` since the toolbar uses this for - interactive coord reporting and I doubt we can expect GUIs - across platforms will handle the unicode correctly. So for - now the classes that override :meth:`fix_minus` should have an - explicit :meth:`format_data_short` method - """ - return s + @staticmethod + def fix_minus(s): + """ + Some classes may want to replace a hyphen for minus with the proper + unicode symbol (U+2212) for typographical correctness. This is a + helper method to perform such a replacement when it is enabled via + :rc:`axes.unicode_minus`. + """ + # Additionally, we disable the replacement when using usetex without + # unicode support (this is deprecated, i.e., in a future version, + # unicode support will always be enabled). + if (rcParams['axes.unicode_minus'] + and (rcParams['text.latex.unicode'] + or not rcParams['text.usetex'])): + return s.replace('-', '\N{MINUS SIGN}') + else: + return s def _set_locator(self, locator): """Subclasses may want to override this to set a locator.""" @@ -565,15 +567,6 @@ def set_useMathText(self, val): useMathText = property(fget=get_useMathText, fset=set_useMathText) - def fix_minus(self, s): - """ - Replace hyphens with a unicode minus. - """ - if rcParams['text.usetex'] or not rcParams['axes.unicode_minus']: - return s - else: - return s.replace('-', '\N{MINUS SIGN}') - def __call__(self, x, pos=None): """ Return the format for tick value *x* at position *pos*. @@ -624,15 +617,12 @@ def set_powerlimits(self, lims): self._powerlimits = lims def format_data_short(self, value): - """ - Return a short formatted string representation of a number. - """ - if self._useLocale: - return locale.format_string('%-12g', (value,)) - elif isinstance(value, np.ma.MaskedArray) and value.mask: - return '' - else: - return '%-12g' % value + # docstring inherited + return ( + "" if isinstance(value, np.ma.MaskedArray) and value.mask else + self.fix_minus( + locale.format_string("%-12g", (value,)) if self._useLocale else + "%-12g" % value)) def format_data(self, value): """ @@ -1026,7 +1016,7 @@ def __call__(self, x, pos=None): vmin, vmax = self.axis.get_view_interval() vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05) s = self._num_to_string(x, vmin, vmax) - return self.fix_minus(s) + return s def format_data(self, value): b = self.labelOnlyBase @@ -1036,9 +1026,7 @@ def format_data(self, value): return value def format_data_short(self, value): - """ - Return a short formatted string representation of a number. - """ + # docstring inherited return '%-12g' % value @cbook.deprecated("3.1") @@ -1462,12 +1450,6 @@ def set_useMathText(self, val): useMathText = property(fget=get_useMathText, fset=set_useMathText) - def fix_minus(self, s): - """ - Replace hyphens with a unicode minus. - """ - return ScalarFormatter.fix_minus(self, s) - def __call__(self, x, pos=None): s = "%s%s" % (self.format_eng(x), self.unit) # Remove the trailing separator when there is neither prefix nor unit