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 4e83e9a

Browse filesBrowse files
committed
move labeling logic into LogFormatter
1 parent d1a5aff commit 4e83e9a
Copy full SHA for 4e83e9a

File tree

Expand file treeCollapse file tree

3 files changed

+96
-106
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+96
-106
lines changed

‎lib/matplotlib/axis.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axis.py
+2-10Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -889,23 +889,15 @@ def iter_ticks(self):
889889
Iterate through all of the major and minor ticks.
890890
"""
891891
majorLocs = self.major.locator()
892-
try:
893-
hasLabel = self.major.locator.show_tick_label(majorLocs)
894-
except AttributeError:
895-
hasLabel = np.ones(np.asarray(majorLocs).size, dtype=np.bool)
896892
majorTicks = self.get_major_ticks(len(majorLocs))
897893
self.major.formatter.set_locs(majorLocs)
898-
majorLabels = [self.major.formatter(val, i) if hasLabel[i] else ''
894+
majorLabels = [self.major.formatter(val, i)
899895
for i, val in enumerate(majorLocs)]
900896

901897
minorLocs = self.minor.locator()
902-
try:
903-
hasLabel = self.major.locator.show_tick_label(minorLocs)
904-
except AttributeError:
905-
hasLabel = np.ones(np.asarray(minorLocs).size, dtype=np.bool)
906898
minorTicks = self.get_minor_ticks(len(minorLocs))
907899
self.minor.formatter.set_locs(minorLocs)
908-
minorLabels = [self.minor.formatter(val, i) if hasLabel[i] else ''
900+
minorLabels = [self.minor.formatter(val, i)
909901
for i, val in enumerate(minorLocs)]
910902

911903
major_minor = [

‎lib/matplotlib/tests/test_ticker.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_ticker.py
+44-43Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,6 @@ def test_AutoMinorLocator():
5050
assert_almost_equal(ax.xaxis.get_ticklocs(minor=True), test_value)
5151

5252

53-
def _sub_labels(axis, subs=()):
54-
"Test whether locator marks subs to be labeled"
55-
loc = axis.get_minor_locator()
56-
minor_tlocs = axis.get_minorticklocs()
57-
coefs = minor_tlocs / 10**(np.floor(np.log10(minor_tlocs)))
58-
label = [np.round(c) in subs for c in coefs]
59-
assert_equal(loc.show_tick_label(minor_tlocs), label)
60-
61-
@cleanup
6253
def test_LogLocator():
6354
loc = mticker.LogLocator(numticks=5)
6455
assert_raises(ValueError, loc.tick_values, 0, 1000)
@@ -72,31 +63,6 @@ def test_LogLocator():
7263
test_value = np.array([0.5, 1., 2., 4., 8., 16., 32., 64., 128., 256.])
7364
assert_almost_equal(loc.tick_values(1, 100), test_value)
7465

75-
# test label locator
76-
fig, ax = plt.subplots()
77-
ax.set_xscale('log')
78-
ax.xaxis.set_major_locator(mticker.LogLocator(base=10, subs=[]))
79-
ax.xaxis.set_minor_locator(mticker.LogLocator(base=10,
80-
subs=np.arange(2, 10)))
81-
# axis range above 3 decades, only bases are labeled
82-
ax.set_xlim(1, 1e4)
83-
loc = ax.xaxis.get_major_locator()
84-
show_major_labels = loc.show_tick_label(ax.xaxis.get_majorticklocs())
85-
assert np.all(show_major_labels)
86-
_sub_labels(ax.xaxis, subs=[])
87-
88-
# axis range at 2 to 3 decades, label sub 3
89-
ax.set_xlim(1, 800)
90-
_sub_labels(ax.xaxis, subs=[3])
91-
92-
# axis range at 1 to 2 decades, label subs 2 and 5
93-
ax.set_xlim(1, 80)
94-
_sub_labels(ax.xaxis, subs=[2, 5])
95-
96-
# axis range at 0 to 1 decades, label subs 2, 3, 6
97-
ax.set_xlim(1, 8)
98-
_sub_labels(ax.xaxis, subs=[2, 3, 6])
99-
10066

10167
def test_LinearLocator_set_params():
10268
"""
@@ -241,6 +207,48 @@ def check_offset_for(left, right, offset):
241207
yield check_offset_for, right, left, offset
242208

243209

210+
def _sub_labels(axis, subs=()):
211+
"Test whether locator marks subs to be labeled"
212+
fmt = axis.get_minor_formatter()
213+
minor_tlocs = axis.get_minorticklocs()
214+
fmt.set_locs(minor_tlocs)
215+
coefs = minor_tlocs / 10**(np.floor(np.log10(minor_tlocs)))
216+
label_expected = [np.round(c) in subs for c in coefs]
217+
label_test = [fmt(x) != '' for x in minor_tlocs]
218+
assert_equal(label_test, label_expected)
219+
220+
221+
@cleanup
222+
def test_LogFormatter_sublabel():
223+
# test label locator
224+
fig, ax = plt.subplots()
225+
ax.set_xscale('log')
226+
ax.xaxis.set_major_locator(mticker.LogLocator(base=10, subs=[]))
227+
ax.xaxis.set_minor_locator(mticker.LogLocator(base=10,
228+
subs=np.arange(2, 10)))
229+
ax.xaxis.set_major_formatter(mticker.LogFormatter())
230+
ax.xaxis.set_minor_formatter(mticker.LogFormatter(labelOnlyBase=False))
231+
# axis range above 3 decades, only bases are labeled
232+
ax.set_xlim(1, 1e4)
233+
fmt = ax.xaxis.get_major_formatter()
234+
fmt.set_locs(ax.xaxis.get_majorticklocs())
235+
show_major_labels = [fmt(x) != '' for x in ax.xaxis.get_majorticklocs()]
236+
assert np.all(show_major_labels)
237+
_sub_labels(ax.xaxis, subs=[])
238+
239+
# axis range at 2 to 3 decades, label sub 3
240+
ax.set_xlim(1, 800)
241+
_sub_labels(ax.xaxis, subs=[3])
242+
243+
# axis range at 1 to 2 decades, label subs 2 and 5
244+
ax.set_xlim(1, 80)
245+
_sub_labels(ax.xaxis, subs=[2, 5])
246+
247+
# axis range at 0 to 1 decades, label subs 2, 3, 6
248+
ax.set_xlim(1, 8)
249+
_sub_labels(ax.xaxis, subs=[2, 3, 6])
250+
251+
244252
def _logfe_helper(formatter, base, locs, i, expected_result):
245253
vals = base**locs
246254
labels = [formatter(x, pos) for (x, pos) in zip(vals, i)]
@@ -295,15 +303,9 @@ def test_LogFormatterSciNotation():
295303
(2e-05, '${2\\times10^{-5}}$'),
296304
(2, '${2\\times10^{0}}$'),
297305
(200000, '${2\\times10^{5}}$'),
298-
(3.1415926535897935e-05, '${3.14159\\times10^{-5}}$'),
299-
(3.141592653589793, '${3.14159\\times10^{0}}$'),
300-
(314159.2653589793, '${3.14159\\times10^{5}}$'),
301306
(5e-05, '${5\\times10^{-5}}$'),
302307
(5, '${5\\times10^{0}}$'),
303308
(500000, '${5\\times10^{5}}$'),
304-
(8.5e-05, '${8.5\\times10^{-5}}$'),
305-
(8.5, '${8.5\\times10^{0}}$'),
306-
(850000.0, '${8.5\\times10^{5}}$'),
307309
),
308310
2: (
309311
(0.03125, '${2^{-5}}$'),
@@ -312,13 +314,12 @@ def test_LogFormatterSciNotation():
312314
(0.0375, '${1.2\\times2^{-5}}$'),
313315
(1.2, '${1.2\\times2^{0}}$'),
314316
(38.4, '${1.2\\times2^{5}}$'),
315-
(0.044194173824159223, '${1.41421\\times2^{-5}}$'),
316-
(1.4142135623730951, '${1.41421\\times2^{0}}$'),
317-
(45.254833995939045, '${1.41421\\times2^{5}}$')),
317+
)
318318
}
319319

320320
for base in test_cases.keys():
321321
formatter = mticker.LogFormatterSciNotation(base=base)
322+
formatter.sublabel = set([1, 2, 5, 1.2])
322323
for value, expected in test_cases[base]:
323324
with matplotlib.rc_context({'text.usetex': False}):
324325
nose.tools.assert_equal(formatter(value), expected)

‎lib/matplotlib/ticker.py

Copy file name to clipboardExpand all lines: lib/matplotlib/ticker.py
+50-53Lines changed: 50 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,7 @@ def __init__(self, base=10.0, labelOnlyBase=True):
820820
"""
821821
self._base = base + 0.0
822822
self.labelOnlyBase = labelOnlyBase
823+
self.sublabel = [1, ]
823824

824825
def base(self, base):
825826
"""
@@ -839,29 +840,50 @@ def label_minor(self, labelOnlyBase):
839840
"""
840841
self.labelOnlyBase = labelOnlyBase
841842

843+
def set_locs(self, locs):
844+
b = self._base
845+
846+
vmin, vmax = self.axis.get_view_interval()
847+
self.d = abs(vmax - vmin)
848+
vmin = math.log(vmin) / math.log(b)
849+
vmax = math.log(vmax) / math.log(b)
850+
851+
numdec = abs(vmax - vmin)
852+
853+
if numdec > 3:
854+
# Label only bases
855+
self.sublabel = set((1,))
856+
else:
857+
# Add labels between bases at log-spaced coefficients
858+
c = np.logspace(0, 1, (4 - int(numdec)) + 1, base=b)
859+
self.sublabel = set(np.round(c))
860+
842861
def __call__(self, x, pos=None):
843862
"""
844863
Return the format for tick val `x` at position `pos`.
845864
"""
846-
vmin, vmax = self.axis.get_view_interval()
847-
d = abs(vmax - vmin)
848865
b = self._base
849866
if x == 0.0:
850867
return '0'
851868
sign = np.sign(x)
852869
# only label the decades
853870
fx = math.log(abs(x)) / math.log(b)
854871
isDecade = is_close_to_int(fx)
855-
if not isDecade and self.labelOnlyBase:
856-
s = ''
857-
elif x > 10000:
858-
s = '%1.0e' % x
859-
elif x < 1:
860-
s = '%1.0e' % x
872+
exponent = np.round(fx) if isDecade else np.floor(fx)
873+
coeff = np.round(x / b ** exponent)
874+
if coeff in self.sublabel:
875+
if not isDecade and self.labelOnlyBase:
876+
s = ''
877+
elif x > 10000:
878+
s = '%1.0e' % x
879+
elif x < 1:
880+
s = '%1.0e' % x
881+
else:
882+
s = self.pprint_val(x, self.d)
883+
if sign == -1:
884+
s = '-%s' % s
861885
else:
862-
s = self.pprint_val(x, d)
863-
if sign == -1:
864-
s = '-%s' % s
886+
s = ''
865887

866888
return self.fix_minus(s)
867889

@@ -977,6 +999,8 @@ def __call__(self, x, pos=None):
977999

9781000
fx = math.log(abs(x)) / math.log(b)
9791001
is_decade = is_close_to_int(fx)
1002+
exponent = np.round(fx) if is_decade else np.floor(fx)
1003+
coeff = np.round(x / b ** exponent)
9801004

9811005
sign_string = '-' if x < 0 else ''
9821006

@@ -986,19 +1010,22 @@ def __call__(self, x, pos=None):
9861010
else:
9871011
base = '%s' % b
9881012

989-
if not is_decade and self.labelOnlyBase:
990-
return ''
991-
elif not is_decade:
992-
return self._non_decade_format(sign_string, base, fx, usetex)
993-
else:
994-
if usetex:
995-
return (r'$%s%s^{%d}$') % (sign_string,
996-
base,
997-
nearest_long(fx))
1013+
if coeff in self.sublabel:
1014+
if not is_decade and self.labelOnlyBase:
1015+
return ''
1016+
elif not is_decade:
1017+
return self._non_decade_format(sign_string, base, fx, usetex)
9981018
else:
999-
return ('$%s$' % _mathdefault(
1000-
'%s%s^{%d}' %
1001-
(sign_string, base, nearest_long(fx))))
1019+
if usetex:
1020+
return (r'$%s%s^{%d}$') % (sign_string,
1021+
base,
1022+
nearest_long(fx))
1023+
else:
1024+
return ('$%s$' % _mathdefault(
1025+
'%s%s^{%d}' %
1026+
(sign_string, base, nearest_long(fx))))
1027+
else:
1028+
return ''
10021029

10031030

10041031
class LogFormatterSciNotation(LogFormatterMathtext):
@@ -1276,11 +1303,6 @@ def __call__(self):
12761303
# hence there is no *one* interface to call self.tick_values.
12771304
raise NotImplementedError('Derived must override')
12781305

1279-
def show_tick_label(self, locs):
1280-
"""Return boolean array on whether to show a label for the given
1281-
locations"""
1282-
return np.ones(np.asarray(locs).size, dtype=np.bool)
1283-
12841306
def raise_if_exceeds(self, locs):
12851307
"""raise a RuntimeError if Locator attempts to create more than
12861308
MAXTICKS locs"""
@@ -1925,31 +1947,6 @@ def tick_values(self, vmin, vmax):
19251947

19261948
return self.raise_if_exceeds(np.asarray(ticklocs))
19271949

1928-
def show_tick_label(self, ticklocs):
1929-
b = self._base
1930-
1931-
vmin, vmax = self.axis.get_view_interval()
1932-
vmin = math.log(vmin) / math.log(b)
1933-
vmax = math.log(vmax) / math.log(b)
1934-
1935-
numdec = abs(vmax - vmin)
1936-
1937-
if numdec > 3:
1938-
# Label only bases
1939-
sublabel = set((1,))
1940-
else:
1941-
# Add labels between bases at log-spaced coefficients
1942-
c = np.logspace(0, 1, (4 - int(numdec)) + 1, base=b)
1943-
sublabel = set(np.round(c))
1944-
1945-
fx = np.log(abs(ticklocs)) / np.log(b)
1946-
exponents = np.array([np.round(x) if is_close_to_int(x)
1947-
else np.floor(x)
1948-
for x in fx])
1949-
coeffs = np.round(ticklocs / b ** exponents)
1950-
1951-
return [c in sublabel for c in coeffs]
1952-
19531950
def view_limits(self, vmin, vmax):
19541951
'Try to choose the view limits intelligently'
19551952
b = self._base

0 commit comments

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