|
155 | 155 | from matplotlib.externals import six
|
156 | 156 |
|
157 | 157 | import decimal
|
| 158 | +import itertools |
158 | 159 | import locale
|
159 | 160 | import math
|
160 | 161 | import numpy as np
|
@@ -565,36 +566,29 @@ def _compute_offset(self):
|
565 | 566 | self.offset = 0
|
566 | 567 | return
|
567 | 568 | lmin, lmax = locs.min(), locs.max()
|
568 |
| - # min, max comparing absolute values (we want division to round towards |
569 |
| - # zero so we work on absolute values). |
570 |
| - abs_min, abs_max = sorted([abs(float(lmin)), abs(float(lmax))]) |
571 | 569 | # Only use offset if there are at least two ticks and every tick has
|
572 | 570 | # the same sign.
|
573 | 571 | if lmin == lmax or lmin <= 0 <= lmax:
|
574 | 572 | self.offset = 0
|
575 | 573 | return
|
| 574 | + # min, max comparing absolute values (we want division to round towards |
| 575 | + # zero so we work on absolute values). |
| 576 | + abs_min, abs_max = sorted([abs(float(lmin)), abs(float(lmax))]) |
576 | 577 | sign = math.copysign(1, lmin)
|
577 | 578 | # What is the smallest power of ten such that abs_min and abs_max are
|
578 | 579 | # equal up to that precision?
|
579 | 580 | # Note: Internally using oom instead of 10 ** oom avoids some numerical
|
580 | 581 | # accuracy issues.
|
581 |
| - oom = math.ceil(math.log10(abs_max)) |
582 |
| - while True: |
583 |
| - if abs_min // 10 ** oom != abs_max // 10 ** oom: |
584 |
| - oom += 1 |
585 |
| - break |
586 |
| - oom -= 1 |
| 582 | + oom_max = math.ceil(math.log10(abs_max)) |
| 583 | + oom = 1 + next(oom for oom in itertools.count(oom_max, -1) |
| 584 | + if abs_min // 10 ** oom != abs_max // 10 ** oom) |
587 | 585 | if (abs_max - abs_min) / 10 ** oom <= 1e-2:
|
588 | 586 | # Handle the case of straddling a multiple of a large power of ten
|
589 | 587 | # (relative to the span).
|
590 | 588 | # What is the smallest power of ten such that abs_min and abs_max
|
591 |
| - # at most 1 apart? |
592 |
| - oom = math.ceil(math.log10(abs_max)) |
593 |
| - while True: |
594 |
| - if abs_max // 10 ** oom - abs_min // 10 ** oom > 1: |
595 |
| - oom += 1 |
596 |
| - break |
597 |
| - oom -= 1 |
| 589 | + # are no more than 1 apart at that precision? |
| 590 | + oom = 1 + next(oom for oom in itertools.count(oom_max, -1) |
| 591 | + if abs_max // 10 ** oom - abs_min // 10 ** oom > 1) |
598 | 592 | # Only use offset if it saves at least two significant digits.
|
599 | 593 | self.offset = (sign * (abs_max // 10 ** oom) * 10 ** oom
|
600 | 594 | if abs_max // 10 ** oom >= 10
|
|
0 commit comments