|
164 | 164 | from matplotlib.externals import six |
165 | 165 |
|
166 | 166 | import decimal |
| 167 | +import itertools |
167 | 168 | import locale |
168 | 169 | import math |
169 | 170 | import numpy as np |
@@ -680,36 +681,29 @@ def _compute_offset(self): |
680 | 681 | self.offset = 0 |
681 | 682 | return |
682 | 683 | lmin, lmax = locs.min(), locs.max() |
683 | | - # min, max comparing absolute values (we want division to round towards |
684 | | - # zero so we work on absolute values). |
685 | | - abs_min, abs_max = sorted([abs(float(lmin)), abs(float(lmax))]) |
686 | 684 | # Only use offset if there are at least two ticks and every tick has |
687 | 685 | # the same sign. |
688 | 686 | if lmin == lmax or lmin <= 0 <= lmax: |
689 | 687 | self.offset = 0 |
690 | 688 | return |
| 689 | + # min, max comparing absolute values (we want division to round towards |
| 690 | + # zero so we work on absolute values). |
| 691 | + abs_min, abs_max = sorted([abs(float(lmin)), abs(float(lmax))]) |
691 | 692 | sign = math.copysign(1, lmin) |
692 | 693 | # What is the smallest power of ten such that abs_min and abs_max are |
693 | 694 | # equal up to that precision? |
694 | 695 | # Note: Internally using oom instead of 10 ** oom avoids some numerical |
695 | 696 | # accuracy issues. |
696 | | - oom = math.ceil(math.log10(abs_max)) |
697 | | - while True: |
698 | | - if abs_min // 10 ** oom != abs_max // 10 ** oom: |
699 | | - oom += 1 |
700 | | - break |
701 | | - oom -= 1 |
| 697 | + oom_max = math.ceil(math.log10(abs_max)) |
| 698 | + oom = 1 + next(oom for oom in itertools.count(oom_max, -1) |
| 699 | + if abs_min // 10 ** oom != abs_max // 10 ** oom) |
702 | 700 | if (abs_max - abs_min) / 10 ** oom <= 1e-2: |
703 | 701 | # Handle the case of straddling a multiple of a large power of ten |
704 | 702 | # (relative to the span). |
705 | 703 | # What is the smallest power of ten such that abs_min and abs_max |
706 | | - # at most 1 apart? |
707 | | - oom = math.ceil(math.log10(abs_max)) |
708 | | - while True: |
709 | | - if abs_max // 10 ** oom - abs_min // 10 ** oom > 1: |
710 | | - oom += 1 |
711 | | - break |
712 | | - oom -= 1 |
| 704 | + # are no more than 1 apart at that precision? |
| 705 | + oom = 1 + next(oom for oom in itertools.count(oom_max, -1) |
| 706 | + if abs_max // 10 ** oom - abs_min // 10 ** oom > 1) |
713 | 707 | # Only use offset if it saves at least two significant digits. |
714 | 708 | self.offset = (sign * (abs_max // 10 ** oom) * 10 ** oom |
715 | 709 | if abs_max // 10 ** oom >= 10 |
|
0 commit comments