Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commitbeb08c8

Browse files
committed
Merge pull request#5785 from anntzer/better-offsettext-choice
Better choice of offset-text.
1 parentf82fc3b commitbeb08c8

File tree

3 files changed

+90
-19
lines changed

3 files changed

+90
-19
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Improved offset text choice
2+
---------------------------
3+
The default offset-text choice was changed to only use significant digits that
4+
are common to all ticks (e.g. 1231..1239 -> 1230, instead of 1231), except when
5+
they straddle a relatively large multiple of a power of ten, in which case that
6+
multiple is chosen (e.g. 1999..2001->2000).

‎lib/matplotlib/tests/test_ticker.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
frommatplotlib.externalsimportsix
55
importnose.tools
6-
fromnose.toolsimportassert_raises
6+
fromnose.toolsimportassert_equal,assert_raises
77
fromnumpy.testingimportassert_almost_equal
88
importnumpyasnp
99
importmatplotlib
@@ -159,6 +159,53 @@ def test_SymmetricalLogLocator_set_params():
159159
nose.tools.assert_equal(sym.numticks,8)
160160

161161

162+
@cleanup
163+
deftest_ScalarFormatter_offset_value():
164+
fig,ax=plt.subplots()
165+
formatter=ax.get_xaxis().get_major_formatter()
166+
167+
defcheck_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+
(1,1,1),
184+
(123,123,120),
185+
# Test cases courtesy of @WeatherGod
186+
(.4538,.4578,.45),
187+
(3789.12,3783.1,3780),
188+
(45124.3,45831.75,45000),
189+
(0.000721,0.0007243,0.00072),
190+
(12592.82,12591.43,12590),
191+
(9.,12.,0),
192+
(900.,1200.,0),
193+
(1900.,1200.,0),
194+
(0.99,1.01,1),
195+
(9.99,10.01,10),
196+
(99.99,100.01,100),
197+
(5.99,6.01,6),
198+
(15.99,16.01,16),
199+
(-0.452,0.492,0),
200+
(-0.492,0.492,0),
201+
(12331.4,12350.5,12300),
202+
(-12335.3,12335.3,0)]
203+
204+
forleft,right,offsetintest_data:
205+
yieldcheck_offset_for,left,right,offset
206+
yieldcheck_offset_for,right,left,offset
207+
208+
162209
def_logfe_helper(formatter,base,locs,i,expected_result):
163210
vals=base**locs
164211
labels= [formatter(x,pos)for (x,pos)inzip(vals,i)]

‎lib/matplotlib/ticker.py

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@
159159
frommatplotlib.externalsimportsix
160160

161161
importdecimal
162+
importitertools
162163
importlocale
163164
importmath
164165
importnumpyasnp
@@ -635,33 +636,50 @@ def set_locs(self, locs):
635636
vmin,vmax=self.axis.get_view_interval()
636637
d=abs(vmax-vmin)
637638
ifself._useOffset:
638-
self._set_offset(d)
639+
self._compute_offset()
639640
self._set_orderOfMagnitude(d)
640641
self._set_format(vmin,vmax)
641642

642-
def_set_offset(self,range):
643-
# offset of 20,001 is 20,000, for example
643+
def_compute_offset(self):
644644
locs=self.locs
645-
646-
iflocsisNoneornotlen(locs)orrange==0:
645+
iflocsisNoneornotlen(locs):
647646
self.offset=0
648647
return
648+
# Restrict to visible ticks.
649649
vmin,vmax=sorted(self.axis.get_view_interval())
650650
locs=np.asarray(locs)
651651
locs=locs[(vmin<=locs)& (locs<=vmax)]
652-
ave_loc=np.mean(locs)
653-
iflen(locs)andave_loc:# dont want to take log10(0)
654-
ave_oom=math.floor(math.log10(np.mean(np.absolute(locs))))
655-
range_oom=math.floor(math.log10(range))
656-
657-
ifnp.absolute(ave_oom-range_oom)>=3:# four sig-figs
658-
p10=10**range_oom
659-
ifave_loc<0:
660-
self.offset= (math.ceil(np.max(locs)/p10)*p10)
661-
else:
662-
self.offset= (math.floor(np.min(locs)/p10)*p10)
663-
else:
664-
self.offset=0
652+
ifnotlen(locs):
653+
self.offset=0
654+
return
655+
lmin,lmax=locs.min(),locs.max()
656+
# Only use offset if there are at least two ticks and every tick has
657+
# the same sign.
658+
iflmin==lmaxorlmin<=0<=lmax:
659+
self.offset=0
660+
return
661+
# min, max comparing absolute values (we want division to round towards
662+
# zero so we work on absolute values).
663+
abs_min,abs_max=sorted([abs(float(lmin)),abs(float(lmax))])
664+
sign=math.copysign(1,lmin)
665+
# What is the smallest power of ten such that abs_min and abs_max are
666+
# equal up to that precision?
667+
# Note: Internally using oom instead of 10 ** oom avoids some numerical
668+
# accuracy issues.
669+
oom_max=math.ceil(math.log10(abs_max))
670+
oom=1+next(oomforoominitertools.count(oom_max,-1)
671+
ifabs_min//10**oom!=abs_max//10**oom)
672+
if (abs_max-abs_min)/10**oom<=1e-2:
673+
# Handle the case of straddling a multiple of a large power of ten
674+
# (relative to the span).
675+
# What is the smallest power of ten such that abs_min and abs_max
676+
# are no more than 1 apart at that precision?
677+
oom=1+next(oomforoominitertools.count(oom_max,-1)
678+
ifabs_max//10**oom-abs_min//10**oom>1)
679+
# Only use offset if it saves at least two significant digits.
680+
self.offset= (sign* (abs_max//10**oom)*10**oom
681+
ifabs_max//10**oom>=10
682+
else0)
665683

666684
def_set_orderOfMagnitude(self,range):
667685
# if scientific notation is to be used, find the appropriate exponent

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp