Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 313a998

Browse filesBrowse files
committed
Only use offset if it saves >=2 sig. digits.
Tests cases courtesy of @WeatherGod. Slightly improved numerical accuracy.
1 parent c73a275 commit 313a998
Copy full SHA for 313a998

File tree

2 files changed

+56
-57
lines changed
Filter options

2 files changed

+56
-57
lines changed

‎lib/matplotlib/tests/test_ticker.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_ticker.py
+37-42Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -164,48 +164,43 @@ def test_ScalarFormatter_offset_value():
164164
fig, ax = plt.subplots()
165165
formatter = ax.get_xaxis().get_major_formatter()
166166

167-
def update_ticks(ax):
168-
return next(ax.get_xaxis().iter_ticks())
169-
170-
ax.set_xlim(123, 189)
171-
update_ticks(ax)
172-
assert_equal(formatter.offset, 0)
173-
174-
ax.set_xlim(-189, -123)
175-
update_ticks(ax)
176-
assert_equal(formatter.offset, 0)
177-
178-
ax.set_xlim(12341, 12349)
179-
update_ticks(ax)
180-
assert_equal(formatter.offset, 12340)
181-
182-
ax.set_xlim(-12349, -12341)
183-
update_ticks(ax)
184-
assert_equal(formatter.offset, -12340)
185-
186-
ax.set_xlim(99999.5, 100010.5)
187-
update_ticks(ax)
188-
assert_equal(formatter.offset, 100000)
189-
190-
ax.set_xlim(-100010.5, -99999.5)
191-
update_ticks(ax)
192-
assert_equal(formatter.offset, -100000)
193-
194-
ax.set_xlim(99990.5, 100000.5)
195-
update_ticks(ax)
196-
assert_equal(formatter.offset, 100000)
197-
198-
ax.set_xlim(-100000.5, -99990.5)
199-
update_ticks(ax)
200-
assert_equal(formatter.offset, -100000)
201-
202-
ax.set_xlim(1233999, 1234001)
203-
update_ticks(ax)
204-
assert_equal(formatter.offset, 1234000)
205-
206-
ax.set_xlim(-1234001, -1233999)
207-
update_ticks(ax)
208-
assert_equal(formatter.offset, -1234000)
167+
def check_offset_for(left, right, offset):
168+
ax.set_xlim(left, right)
169+
# Update ticks.
170+
next(ax.get_xaxis().iter_ticks())
171+
assert_equal(formatter.offset, offset)
172+
173+
test_data = [(123, 189, 0),
174+
(-189, -123, 0),
175+
(12341, 12349, 12340),
176+
(-12349, -12341, -12340),
177+
(99999.5, 100010.5, 100000),
178+
(-100010.5, -99999.5, -100000),
179+
(99990.5, 100000.5, 100000),
180+
(-100000.5, -99990.5, -100000),
181+
(1233999, 1234001, 1234000),
182+
(-1234001, -1233999, -1234000),
183+
# Test cases courtesy of @WeatherGod
184+
(.4538, .4578, .45),
185+
(3789.12, 3783.1, 3780),
186+
(45124.3, 45831.75, 45000),
187+
(0.000721, 0.0007243, 0.00072),
188+
(12592.82, 12591.43, 12590),
189+
(9., 12., 0),
190+
(900., 1200., 0),
191+
(1900., 1200., 0),
192+
(0.99, 1.01, 1),
193+
(9.99, 10.01, 10),
194+
(99.99, 100.01, 100),
195+
(5.99, 6.01, 6),
196+
(15.99, 16.01, 16),
197+
(-0.452, 0.492, 0),
198+
(-0.492, 0.492, 0),
199+
(12331.4, 12350.5, 12300),
200+
(-12335.3, 12335.3, 0)]
201+
202+
for left, right, offset in test_data:
203+
yield check_offset_for, left, right, offset
209204

210205

211206
def _logfe_helper(formatter, base, locs, i, expected_result):

‎lib/matplotlib/ticker.py

Copy file name to clipboardExpand all lines: lib/matplotlib/ticker.py
+19-15Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -564,34 +564,38 @@ def _compute_offset(self):
564564
lmin, lmax = locs.min(), locs.max()
565565
# min, max comparing absolute values (we want division to round towards
566566
# zero so we work on absolute values).
567-
abs_min, abs_max = sorted(map(abs, [lmin, lmax]))
568-
# Only use offset if there are at least two ticks, every tick has the
569-
# same sign, and if the span is small compared to the absolute values.
570-
if (lmin == lmax or lmin <= 0 <= lmax or
571-
(abs_max - abs_min) / abs_max >= 1e-2):
567+
abs_min, abs_max = sorted([abs(float(lmin)), abs(float(lmax))])
568+
# Only use offset if there are at least two ticks and every tick has
569+
# the same sign.
570+
if lmin == lmax or lmin <= 0 <= lmax:
572571
self.offset = 0
573572
return
574573
sign = math.copysign(1, lmin)
575574
# What is the smallest power of ten such that abs_min and abs_max are
576575
# equal up to that precision?
577-
oom = 10 ** int(math.log10(abs_max) + 1)
576+
# Note: Internally using oom instead of 10 ** oom avoids some numerical
577+
# accuracy issues.
578+
oom = math.ceil(math.log10(abs_max))
578579
while True:
579-
if abs_min // oom != abs_max // oom:
580-
oom *= 10
580+
if abs_min // 10 ** oom != abs_max // 10 ** oom:
581+
oom += 1
581582
break
582-
oom /= 10
583-
if (abs_max - abs_min) / oom <= 1e-2:
583+
oom -= 1
584+
if (abs_max - abs_min) / 10 ** oom <= 1e-2:
584585
# Handle the case of straddling a multiple of a large power of ten
585586
# (relative to the span).
586587
# What is the smallest power of ten such that abs_min and abs_max
587588
# at most 1 apart?
588-
oom = 10 ** int(math.log10(abs_max) + 1)
589+
oom = math.ceil(math.log10(abs_max))
589590
while True:
590-
if abs_max // oom - abs_min // oom > 1:
591-
oom *= 10
591+
if abs_max // 10 ** oom - abs_min // 10 ** oom > 1:
592+
oom += 1
592593
break
593-
oom /= 10
594-
self.offset = sign * (abs_max // oom) * oom
594+
oom -= 1
595+
# Only use offset if it saves at least two significant digits.
596+
self.offset = (sign * (abs_max // 10 ** oom) * 10 ** oom
597+
if abs_max // 10 ** oom >= 10
598+
else 0)
595599

596600
def _set_orderOfMagnitude(self, range):
597601
# if scientific notation is to be used, find the appropriate exponent

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.