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 0a9df25

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

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
@@ -567,34 +567,38 @@ def _compute_offset(self):
567567
lmin, lmax = locs.min(), locs.max()
568568
# min, max comparing absolute values (we want division to round towards
569569
# zero so we work on absolute values).
570-
abs_min, abs_max = sorted(map(abs, [lmin, lmax]))
571-
# Only use offset if there are at least two ticks, every tick has the
572-
# same sign, and if the span is small compared to the absolute values.
573-
if (lmin == lmax or lmin <= 0 <= lmax or
574-
(abs_max - abs_min) / abs_max >= 1e-2):
570+
abs_min, abs_max = sorted([abs(float(lmin)), abs(float(lmax))])
571+
# Only use offset if there are at least two ticks and every tick has
572+
# the same sign.
573+
if lmin == lmax or lmin <= 0 <= lmax:
575574
self.offset = 0
576575
return
577576
sign = math.copysign(1, lmin)
578577
# What is the smallest power of ten such that abs_min and abs_max are
579578
# equal up to that precision?
580-
oom = 10 ** int(math.log10(abs_max) + 1)
579+
# Note: Internally using oom instead of 10 ** oom avoids some numerical
580+
# accuracy issues.
581+
oom = math.ceil(math.log10(abs_max))
581582
while True:
582-
if abs_min // oom != abs_max // oom:
583-
oom *= 10
583+
if abs_min // 10 ** oom != abs_max // 10 ** oom:
584+
oom += 1
584585
break
585-
oom /= 10
586-
if (abs_max - abs_min) / oom <= 1e-2:
586+
oom -= 1
587+
if (abs_max - abs_min) / 10 ** oom <= 1e-2:
587588
# Handle the case of straddling a multiple of a large power of ten
588589
# (relative to the span).
589590
# What is the smallest power of ten such that abs_min and abs_max
590591
# at most 1 apart?
591-
oom = 10 ** int(math.log10(abs_max) + 1)
592+
oom = math.ceil(math.log10(abs_max))
592593
while True:
593-
if abs_max // oom - abs_min // oom > 1:
594-
oom *= 10
594+
if abs_max // 10 ** oom - abs_min // 10 ** oom > 1:
595+
oom += 1
595596
break
596-
oom /= 10
597-
self.offset = sign * (abs_max // oom) * oom
597+
oom -= 1
598+
# Only use offset if it saves at least two significant digits.
599+
self.offset = (sign * (abs_max // 10 ** oom) * 10 ** oom
600+
if abs_max // 10 ** oom >= 10
601+
else 0)
598602

599603
def _set_orderOfMagnitude(self, range):
600604
# 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.