diff --git a/lib/matplotlib/tests/test_ticker.py b/lib/matplotlib/tests/test_ticker.py index 342cad03e2f6..438be20aa7ce 100644 --- a/lib/matplotlib/tests/test_ticker.py +++ b/lib/matplotlib/tests/test_ticker.py @@ -159,20 +159,28 @@ def test_SymmetricalLogLocator_set_params(): nose.tools.assert_equal(sym.numticks, 8) +def _logfe_helper(formatter, base, locs, i, expected_result): + vals = base**locs + labels = [formatter(x, pos) for (x, pos) in zip(vals, i)] + nose.tools.assert_equal(labels, expected_result) + + def test_LogFormatterExponent(): class FakeAxis(object): """Allow Formatter to be called without having a "full" plot set up.""" + def __init__(self, vmin=1, vmax=10): + self.vmin = vmin + self.vmax = vmax + def get_view_interval(self): - return 1, 10 + return self.vmin, self.vmax i = np.arange(-3, 4, dtype=float) expected_result = ['-3', '-2', '-1', '0', '1', '2', '3'] - for base in [2, 5, 10, np.pi, np.e]: + for base in [2, 5.0, 10.0, np.pi, np.e]: formatter = mticker.LogFormatterExponent(base=base) - formatter.axis = FakeAxis() - vals = base**i - labels = [formatter(x, pos) for (x, pos) in zip(vals, i)] - nose.tools.assert_equal(labels, expected_result) + formatter.axis = FakeAxis(1, base**4) + yield _logfe_helper, formatter, base, i, i, expected_result # Should be a blank string for non-integer powers if labelOnlyBase=True formatter = mticker.LogFormatterExponent(base=10, labelOnlyBase=True) @@ -185,10 +193,161 @@ def get_view_interval(self): expected_result = ['0.1', '1e-05', '3.14', '0.2', '-0.2', '-1e-05'] for base in [2, 5, 10, np.pi, np.e]: formatter = mticker.LogFormatterExponent(base, labelOnlyBase=False) - formatter.axis = FakeAxis() - vals = base**locs - labels = [formatter(x, pos) for (x, pos) in zip(vals, i)] - nose.tools.assert_equal(labels, expected_result) + formatter.axis = FakeAxis(1, base**10) + yield _logfe_helper, formatter, base, locs, i, expected_result + + expected_result = ['3', '5', '12', '42'] + locs = np.array([3, 5, 12, 42], dtype='float') + for base in [2, 5.0, 10.0, np.pi, np.e]: + formatter = mticker.LogFormatterExponent(base, labelOnlyBase=False) + formatter.axis = FakeAxis(1, base**50) + yield _logfe_helper, formatter, base, locs, i, expected_result + + +def _pprint_helper(value, domain, expected): + fmt = mticker.LogFormatter() + label = fmt.pprint_val(value, domain) + nose.tools.assert_equal(label, expected) + + +def test_logformatter_pprint(): + test_cases = ( + (3.141592654e-05, 0.001, '3.142e-5'), + (0.0003141592654, 0.001, '3.142e-4'), + (0.003141592654, 0.001, '3.142e-3'), + (0.03141592654, 0.001, '3.142e-2'), + (0.3141592654, 0.001, '3.142e-1'), + (3.141592654, 0.001, '3.142'), + (31.41592654, 0.001, '3.142e1'), + (314.1592654, 0.001, '3.142e2'), + (3141.592654, 0.001, '3.142e3'), + (31415.92654, 0.001, '3.142e4'), + (314159.2654, 0.001, '3.142e5'), + (1e-05, 0.001, '1e-5'), + (0.0001, 0.001, '1e-4'), + (0.001, 0.001, '1e-3'), + (0.01, 0.001, '1e-2'), + (0.1, 0.001, '1e-1'), + (1, 0.001, '1'), + (10, 0.001, '10'), + (100, 0.001, '100'), + (1000, 0.001, '1000'), + (10000, 0.001, '1e4'), + (100000, 0.001, '1e5'), + (3.141592654e-05, 0.015, '0'), + (0.0003141592654, 0.015, '0'), + (0.003141592654, 0.015, '0.003'), + (0.03141592654, 0.015, '0.031'), + (0.3141592654, 0.015, '0.314'), + (3.141592654, 0.015, '3.142'), + (31.41592654, 0.015, '31.416'), + (314.1592654, 0.015, '314.159'), + (3141.592654, 0.015, '3141.593'), + (31415.92654, 0.015, '31415.927'), + (314159.2654, 0.015, '314159.265'), + (1e-05, 0.015, '0'), + (0.0001, 0.015, '0'), + (0.001, 0.015, '0.001'), + (0.01, 0.015, '0.01'), + (0.1, 0.015, '0.1'), + (1, 0.015, '1'), + (10, 0.015, '10'), + (100, 0.015, '100'), + (1000, 0.015, '1000'), + (10000, 0.015, '10000'), + (100000, 0.015, '100000'), + (3.141592654e-05, 0.5, '0'), + (0.0003141592654, 0.5, '0'), + (0.003141592654, 0.5, '0.003'), + (0.03141592654, 0.5, '0.031'), + (0.3141592654, 0.5, '0.314'), + (3.141592654, 0.5, '3.142'), + (31.41592654, 0.5, '31.416'), + (314.1592654, 0.5, '314.159'), + (3141.592654, 0.5, '3141.593'), + (31415.92654, 0.5, '31415.927'), + (314159.2654, 0.5, '314159.265'), + (1e-05, 0.5, '0'), + (0.0001, 0.5, '0'), + (0.001, 0.5, '0.001'), + (0.01, 0.5, '0.01'), + (0.1, 0.5, '0.1'), + (1, 0.5, '1'), + (10, 0.5, '10'), + (100, 0.5, '100'), + (1000, 0.5, '1000'), + (10000, 0.5, '10000'), + (100000, 0.5, '100000'), + (3.141592654e-05, 5, '0'), + (0.0003141592654, 5, '0'), + (0.003141592654, 5, '0'), + (0.03141592654, 5, '0.03'), + (0.3141592654, 5, '0.31'), + (3.141592654, 5, '3.14'), + (31.41592654, 5, '31.42'), + (314.1592654, 5, '314.16'), + (3141.592654, 5, '3141.59'), + (31415.92654, 5, '31415.93'), + (314159.2654, 5, '314159.27'), + (1e-05, 5, '0'), + (0.0001, 5, '0'), + (0.001, 5, '0'), + (0.01, 5, '0.01'), + (0.1, 5, '0.1'), + (1, 5, '1'), + (10, 5, '10'), + (100, 5, '100'), + (1000, 5, '1000'), + (10000, 5, '10000'), + (100000, 5, '100000'), + (3.141592654e-05, 100, '0'), + (0.0003141592654, 100, '0'), + (0.003141592654, 100, '0'), + (0.03141592654, 100, '0'), + (0.3141592654, 100, '0.3'), + (3.141592654, 100, '3.1'), + (31.41592654, 100, '31.4'), + (314.1592654, 100, '314.2'), + (3141.592654, 100, '3141.6'), + (31415.92654, 100, '31415.9'), + (314159.2654, 100, '314159.3'), + (1e-05, 100, '0'), + (0.0001, 100, '0'), + (0.001, 100, '0'), + (0.01, 100, '0'), + (0.1, 100, '0.1'), + (1, 100, '1'), + (10, 100, '10'), + (100, 100, '100'), + (1000, 100, '1000'), + (10000, 100, '10000'), + (100000, 100, '100000'), + (3.141592654e-05, 1000000.0, '3.1e-5'), + (0.0003141592654, 1000000.0, '3.1e-4'), + (0.003141592654, 1000000.0, '3.1e-3'), + (0.03141592654, 1000000.0, '3.1e-2'), + (0.3141592654, 1000000.0, '3.1e-1'), + (3.141592654, 1000000.0, '3.1'), + (31.41592654, 1000000.0, '3.1e1'), + (314.1592654, 1000000.0, '3.1e2'), + (3141.592654, 1000000.0, '3.1e3'), + (31415.92654, 1000000.0, '3.1e4'), + (314159.2654, 1000000.0, '3.1e5'), + (1e-05, 1000000.0, '1e-5'), + (0.0001, 1000000.0, '1e-4'), + (0.001, 1000000.0, '1e-3'), + (0.01, 1000000.0, '1e-2'), + (0.1, 1000000.0, '1e-1'), + (1, 1000000.0, '1'), + (10, 1000000.0, '10'), + (100, 1000000.0, '100'), + (1000, 1000000.0, '1000'), + (10000, 1000000.0, '1e4'), + (100000, 1000000.0, '1e5') + ) + + for value, domain, expected in test_cases: + yield _pprint_helper, value, domain, expected def test_use_offset(): diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py index 450869878c14..3ec4ba318361 100644 --- a/lib/matplotlib/ticker.py +++ b/lib/matplotlib/ticker.py @@ -731,13 +731,15 @@ def pprint_val(self, x, d): else: fmt = '%1.3f' s = fmt % x - #print d, x, fmt, s + tup = s.split('e') if len(tup) == 2: mantissa = tup[0].rstrip('0').rstrip('.') - sign = tup[1][0].replace('+', '') - exponent = tup[1][1:].lstrip('0') - s = '%se%s%s' % (mantissa, sign, exponent) + exponent = int(tup[1]) + if exponent: + s = '%se%d' % (mantissa, exponent) + else: + s = mantissa else: s = s.rstrip('0').rstrip('.') return s @@ -768,7 +770,8 @@ def __call__(self, x, pos=None): elif abs(fx) < 1: s = '%1.0g' % fx else: - s = self.pprint_val(fx, d) + fd = math.log(abs(d)) / math.log(b) + s = self.pprint_val(fx, fd) if sign == -1: s = '-%s' % s