diff --git a/lib/matplotlib/tests/test_ticker.py b/lib/matplotlib/tests/test_ticker.py index 32def5d9cbc9..c95526ecf987 100644 --- a/lib/matplotlib/tests/test_ticker.py +++ b/lib/matplotlib/tests/test_ticker.py @@ -38,6 +38,27 @@ def test_integer(self, vmin, vmax, steps, expected): loc = mticker.MaxNLocator(nbins=5, integer=True, steps=steps) assert_almost_equal(loc.tick_values(vmin, vmax), expected) + @pytest.mark.parametrize('kwargs, errortype, match', [ + ({'foo': 0}, TypeError, + re.escape("set_params() got an unexpected keyword argument 'foo'")), + ({'steps': [2, 1]}, ValueError, "steps argument must be an increasing"), + ({'steps': 2}, ValueError, "steps argument must be an increasing"), + ({'steps': [2, 11]}, ValueError, "steps argument must be an increasing"), + ]) + def test_errors(self, kwargs, errortype, match): + with pytest.raises(errortype, match=match): + mticker.MaxNLocator(**kwargs) + + @pytest.mark.parametrize('steps, result', [ + ([1, 2, 10], [1, 2, 10]), + ([2, 10], [1, 2, 10]), + ([1, 2], [1, 2, 10]), + ([2], [1, 2, 10]), + ]) + def test_padding(self, steps, result): + loc = mticker.MaxNLocator(steps=steps) + assert (loc._steps == result).all() + class TestLinearLocator: def test_basic(self): @@ -45,6 +66,10 @@ def test_basic(self): test_value = np.array([-0.8, -0.3, 0.2]) assert_almost_equal(loc.tick_values(-0.8, 0.2), test_value) + def test_zero_numticks(self): + loc = mticker.LinearLocator(numticks=0) + loc.tick_values(-0.8, 0.2) == [] + def test_set_params(self): """ Create linear locator with presets={}, numticks=2 and change it to @@ -55,6 +80,15 @@ def test_set_params(self): assert loc.numticks == 8 assert loc.presets == {(0, 1): []} + def test_presets(self): + loc = mticker.LinearLocator(presets={(1, 2): [1, 1.25, 1.75], + (0, 2): [0.5, 1.5]}) + assert loc.tick_values(1, 2) == [1, 1.25, 1.75] + assert loc.tick_values(2, 1) == [1, 1.25, 1.75] + assert loc.tick_values(0, 2) == [0.5, 1.5] + assert loc.tick_values(0.0, 2.0) == [0.5, 1.5] + assert (loc.tick_values(0, 1) == np.linspace(0, 1, 11)).all() + class TestMultipleLocator: def test_basic(self): @@ -590,6 +624,23 @@ def test_values(self, vmin, vmax, expected): ticks = sym.tick_values(vmin=vmin, vmax=vmax) assert_array_equal(ticks, expected) + def test_subs(self): + sym = mticker.SymmetricalLogLocator(base=10, linthresh=1, subs=[2.0, 4.0]) + sym.create_dummy_axis() + sym.axis.set_view_interval(-10, 10) + assert (sym() == [-20., -40., -2., -4., 0., 2., 4., 20., 40.]).all() + + def test_extending(self): + sym = mticker.SymmetricalLogLocator(base=10, linthresh=1) + sym.create_dummy_axis() + sym.axis.set_view_interval(8, 9) + assert (sym() == [1.0]).all() + sym.axis.set_view_interval(8, 12) + assert (sym() == [1.0, 10.0]).all() + assert sym.view_limits(10, 10) == (1, 100) + assert sym.view_limits(-10, -10) == (-100, -1) + assert sym.view_limits(0, 0) == (-0.001, 0.001) + class TestAsinhLocator: def test_init(self): diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py index b4793929de9b..df848ef04ad8 100644 --- a/lib/matplotlib/ticker.py +++ b/lib/matplotlib/ticker.py @@ -657,12 +657,12 @@ def format_data(self, value): # docstring inherited e = math.floor(math.log10(abs(value))) s = round(value / 10**e, 10) - exponent = self._format_maybe_minus_and_locale("%d", e) significand = self._format_maybe_minus_and_locale( "%d" if s % 1 == 0 else "%1.10g", s) if e == 0: return significand - elif self._useMathText or self._usetex: + exponent = self._format_maybe_minus_and_locale("%d", e) + if self._useMathText or self._usetex: exponent = "10^{%s}" % exponent return (exponent if s == 1 # reformat 1x10^y as 10^y else rf"{significand} \times {exponent}") @@ -675,7 +675,6 @@ def get_offset(self): """ if len(self.locs) == 0: return '' - s = '' if self.orderOfMagnitude or self.offset: offsetStr = '' sciNotStr = '' @@ -694,8 +693,8 @@ def get_offset(self): s = fr'${sciNotStr}\mathdefault{{{offsetStr}}}$' else: s = ''.join((sciNotStr, offsetStr)) - - return self.fix_minus(s) + return self.fix_minus(s) + return '' def set_locs(self, locs): # docstring inherited @@ -1055,9 +1054,6 @@ def _non_decade_format(self, sign_string, base, fx, usetex): def __call__(self, x, pos=None): # docstring inherited - usetex = mpl.rcParams['text.usetex'] - min_exp = mpl.rcParams['axes.formatter.min_exponent'] - if x == 0: # Symlog return r'$\mathdefault{0}$' @@ -1070,23 +1066,25 @@ def __call__(self, x, pos=None): is_x_decade = _is_close_to_int(fx) exponent = round(fx) if is_x_decade else np.floor(fx) coeff = round(b ** (fx - exponent)) - if is_x_decade: - fx = round(fx) if self.labelOnlyBase and not is_x_decade: return '' if self._sublabels is not None and coeff not in self._sublabels: return '' + if is_x_decade: + fx = round(fx) + # use string formatting of the base if it is not an integer if b % 1 == 0.0: base = '%d' % b else: base = '%s' % b - if abs(fx) < min_exp: + if abs(fx) < mpl.rcParams['axes.formatter.min_exponent']: return r'$\mathdefault{%s%g}$' % (sign_string, x) elif not is_x_decade: + usetex = mpl.rcParams['text.usetex'] return self._non_decade_format(sign_string, base, fx, usetex) else: return r'$\mathdefault{%s%s^{%d}}$' % (sign_string, base, fx) @@ -1554,7 +1552,7 @@ def symbol(self): symbol = self._symbol if not symbol: symbol = '' - elif mpl.rcParams['text.usetex'] and not self._is_latex: + elif not self._is_latex and mpl.rcParams['text.usetex']: # Source: http://www.personal.ceu.hu/tex/specchar.htm # Backslash must be first for this to work correctly since # it keeps getting added in @@ -1801,8 +1799,6 @@ def __call__(self): def tick_values(self, vmin, vmax): vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05) - if vmax < vmin: - vmin, vmax = vmax, vmin if (vmin, vmax) in self.presets: return self.presets[(vmin, vmax)] @@ -2356,13 +2352,13 @@ def tick_values(self, vmin, vmax): numdec = math.floor(log_vmax) - math.ceil(log_vmin) if isinstance(self._subs, str): - _first = 2.0 if self._subs == 'auto' else 1.0 if numdec > 10 or b < 3: if self._subs == 'auto': return np.array([]) # no minor or major ticks else: subs = np.array([1.0]) # major ticks else: + _first = 2.0 if self._subs == 'auto' else 1.0 subs = np.arange(_first, b) else: subs = self._subs @@ -2386,23 +2382,14 @@ def tick_values(self, vmin, vmax): decades = np.arange(math.floor(log_vmin) - stride, math.ceil(log_vmax) + 2 * stride, stride) - if hasattr(self, '_transform'): - ticklocs = self._transform.inverted().transform(decades) - if have_subs: - if stride == 1: - ticklocs = np.ravel(np.outer(subs, ticklocs)) - else: - # No ticklocs if we have >1 decade between major ticks. - ticklocs = np.array([]) - else: - if have_subs: - if stride == 1: - ticklocs = np.concatenate( - [subs * decade_start for decade_start in b ** decades]) - else: - ticklocs = np.array([]) + if have_subs: + if stride == 1: + ticklocs = np.concatenate( + [subs * decade_start for decade_start in b ** decades]) else: - ticklocs = b ** decades + ticklocs = np.array([]) + else: + ticklocs = b ** decades _log.debug('ticklocs %r', ticklocs) if (len(subs) > 1 @@ -2422,8 +2409,8 @@ def view_limits(self, vmin, vmax): vmin, vmax = self.nonsingular(vmin, vmax) if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers': - vmin = _decade_less_equal(vmin, self._base) - vmax = _decade_greater_equal(vmax, self._base) + vmin = _decade_less_equal(vmin, b) + vmax = _decade_greater_equal(vmax, b) return vmin, vmax @@ -2503,7 +2490,6 @@ def __call__(self): return self.tick_values(vmin, vmax) def tick_values(self, vmin, vmax): - base = self._base linthresh = self._linthresh if vmax < vmin: @@ -2540,6 +2526,8 @@ def tick_values(self, vmin, vmax): # Check if linear range is present has_b = (has_a and vmax > -linthresh) or (has_c and vmin < linthresh) + base = self._base + def get_log_range(lo, hi): lo = np.floor(np.log(lo) / np.log(base)) hi = np.ceil(np.log(hi) / np.log(base)) @@ -2573,11 +2561,7 @@ def get_log_range(lo, hi): if has_c: decades.extend(base ** (np.arange(c_lo, c_hi, stride))) - # Add the subticks if requested - if self._subs is None: - subs = np.arange(2.0, base) - else: - subs = np.asarray(self._subs) + subs = np.asarray(self._subs) if len(subs) > 1 or subs[0] != 1.0: ticklocs = [] @@ -2604,8 +2588,7 @@ def view_limits(self, vmin, vmax): vmin = _decade_less(vmin, b) vmax = _decade_greater(vmax, b) - result = mtransforms.nonsingular(vmin, vmax) - return result + return mtransforms.nonsingular(vmin, vmax) class AsinhLocator(Locator): @@ -2773,7 +2756,7 @@ def tick_values(self, vmin, vmax): # linscale: ... 1e-3 1e-2 1e-1 1/2 1-1e-1 1-1e-2 1-1e-3 ... # b-scale : ... -3 -2 -1 0 1 2 3 ... def ideal_ticks(x): - return 10 ** x if x < 0 else 1 - (10 ** (-x)) if x > 0 else 1 / 2 + return 10 ** x if x < 0 else 1 - (10 ** (-x)) if x > 0 else 0.5 vmin, vmax = self.nonsingular(vmin, vmax) binf = int( pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy