|
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