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

Commit4e1792b

Browse files
committed
Merge pull request#5785 from anntzer/better-offsettext-choice
Better choice of offset-text.
2 parentsb16e6f3 +782b8a1 commit4e1792b

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
@@ -164,6 +164,7 @@
164164
frommatplotlib.externalsimportsix
165165

166166
importdecimal
167+
importitertools
167168
importlocale
168169
importmath
169170
importnumpyasnp
@@ -663,33 +664,50 @@ def set_locs(self, locs):
663664
vmin,vmax=self.axis.get_view_interval()
664665
d=abs(vmax-vmin)
665666
ifself._useOffset:
666-
self._set_offset(d)
667+
self._compute_offset()
667668
self._set_orderOfMagnitude(d)
668669
self._set_format(vmin,vmax)
669670

670-
def_set_offset(self,range):
671-
# offset of 20,001 is 20,000, for example
671+
def_compute_offset(self):
672672
locs=self.locs
673-
674-
iflocsisNoneornotlen(locs)orrange==0:
673+
iflocsisNoneornotlen(locs):
675674
self.offset=0
676675
return
676+
# Restrict to visible ticks.
677677
vmin,vmax=sorted(self.axis.get_view_interval())
678678
locs=np.asarray(locs)
679679
locs=locs[(vmin<=locs)& (locs<=vmax)]
680-
ave_loc=np.mean(locs)
681-
iflen(locs)andave_loc:# dont want to take log10(0)
682-
ave_oom=math.floor(math.log10(np.mean(np.absolute(locs))))
683-
range_oom=math.floor(math.log10(range))
684-
685-
ifnp.absolute(ave_oom-range_oom)>=3:# four sig-figs
686-
p10=10**range_oom
687-
ifave_loc<0:
688-
self.offset= (math.ceil(np.max(locs)/p10)*p10)
689-
else:
690-
self.offset= (math.floor(np.min(locs)/p10)*p10)
691-
else:
692-
self.offset=0
680+
ifnotlen(locs):
681+
self.offset=0
682+
return
683+
lmin,lmax=locs.min(),locs.max()
684+
# Only use offset if there are at least two ticks and every tick has
685+
# the same sign.
686+
iflmin==lmaxorlmin<=0<=lmax:
687+
self.offset=0
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))])
692+
sign=math.copysign(1,lmin)
693+
# What is the smallest power of ten such that abs_min and abs_max are
694+
# equal up to that precision?
695+
# Note: Internally using oom instead of 10 ** oom avoids some numerical
696+
# accuracy issues.
697+
oom_max=math.ceil(math.log10(abs_max))
698+
oom=1+next(oomforoominitertools.count(oom_max,-1)
699+
ifabs_min//10**oom!=abs_max//10**oom)
700+
if (abs_max-abs_min)/10**oom<=1e-2:
701+
# Handle the case of straddling a multiple of a large power of ten
702+
# (relative to the span).
703+
# What is the smallest power of ten such that abs_min and abs_max
704+
# are no more than 1 apart at that precision?
705+
oom=1+next(oomforoominitertools.count(oom_max,-1)
706+
ifabs_max//10**oom-abs_min//10**oom>1)
707+
# Only use offset if it saves at least two significant digits.
708+
self.offset= (sign* (abs_max//10**oom)*10**oom
709+
ifabs_max//10**oom>=10
710+
else0)
693711

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp