Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f718a3b

Browse files
efiringNelleV
authored andcommitted
Improve the minor tick labeling by LogFormatter.
1 parent 46e237a commit f718a3b

File tree

3 files changed

+34
-24
lines changed

3 files changed

+34
-24
lines changed

lib/matplotlib/scale.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,7 @@ def set_default_locators_and_formatters(self, axis):
251251
axis.set_minor_locator(LogLocator(self.base, self.subs))
252252
axis.set_minor_formatter(
253253
LogFormatterSciNotation(self.base,
254-
labelOnlyBase=self.subs,
255-
label_pruning=True))
254+
labelOnlyBase=self.subs))
256255

257256
def get_transform(self):
258257
"""

lib/matplotlib/tests/test_ticker.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,7 @@ def test_LogFormatter_sublabel():
241241
ax.xaxis.set_minor_locator(mticker.LogLocator(base=10,
242242
subs=np.arange(2, 10)))
243243
ax.xaxis.set_major_formatter(mticker.LogFormatter(labelOnlyBase=True))
244-
ax.xaxis.set_minor_formatter(mticker.LogFormatter(
245-
labelOnlyBase=False,
246-
label_pruning=True))
244+
ax.xaxis.set_minor_formatter(mticker.LogFormatter(labelOnlyBase=False))
247245
# axis range above 3 decades, only bases are labeled
248246
ax.set_xlim(1, 1e4)
249247
fmt = ax.xaxis.get_major_formatter()
@@ -263,9 +261,13 @@ def test_LogFormatter_sublabel():
263261
ax.set_xlim(1, 80)
264262
_sub_labels(ax.xaxis, subs=[])
265263

266-
# axis range at 0 to 1 decades, label subs 2, 3, 6
264+
# axis range at 0.4 to 1 decades, label subs 2, 3, 4, 6
267265
ax.set_xlim(1, 8)
268-
_sub_labels(ax.xaxis, subs=[2, 3, 6])
266+
_sub_labels(ax.xaxis, subs=[2, 3, 4, 6])
267+
268+
# axis range at 0 to 0.4 decades, label all
269+
ax.set_xlim(0.5, 0.9)
270+
_sub_labels(ax.xaxis, subs=np.arange(2, 10, dtype=int))
269271

270272

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

lib/matplotlib/ticker.py

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ class LogFormatter(Formatter):
801801
Format values for log axis.
802802
"""
803803
def __init__(self, base=10.0, labelOnlyBase=False,
804-
label_pruning=False):
804+
minor_thresholds=(1, 0.4)):
805805
"""
806806
`base` is used to locate the decade tick, which will be the only
807807
one to be labeled if `labelOnlyBase` is ``True``.
@@ -812,15 +812,21 @@ def __init__(self, base=10.0, labelOnlyBase=False,
812812
base of the logarithm.
813813
814814
labelOnlyBase : bool, optional, default: False
815-
whether to only label decades ticks.
815+
whether label ticks only at integer multiples of base.
816+
This is normally True for major ticks and False for
817+
minor ticks.
816818
817-
label_pruning : bool, optional, default: False
818-
when set to True, label on a subset of ticks.
819+
minor_thresholds : (subset, all), optional, default: (1, 0.4)
820+
Thresholds applied to the data range measured in powers
821+
of the base (numbers of "decades", or 'numdec'), and
822+
effective only when labelOnlyBase is False. Then a
823+
subset of minor ticks will be labeled if `numdec <= subset`,
824+
and all will be labeled if `numdec <= all`.
819825
"""
820826
self._base = base + 0.0
821827
self.labelOnlyBase = labelOnlyBase
822-
self.label_pruning = label_pruning
823-
self._sublabels = [1, ]
828+
self.minor_thresholds = minor_thresholds
829+
self._sublabels = None
824830

825831
def base(self, base):
826832
"""
@@ -872,13 +878,15 @@ def set_locs(self, locs):
872878
vmax = math.log(vmax) / math.log(b)
873879
numdec = abs(vmax - vmin)
874880

875-
if numdec > 1:
881+
if numdec > self.minor_thresholds[0]:
876882
# Label only bases
877883
self._sublabels = set((1,))
878-
else:
884+
elif numdec > self.minor_thresholds[1]:
879885
# Add labels between bases at log-spaced coefficients
880-
c = np.logspace(0, 1, (4 - int(numdec)) + 1, base=b)
886+
c = np.logspace(0, 1, b//2 + 1, base=b)[1:-1]
881887
self._sublabels = set(np.round(c))
888+
else:
889+
self._sublabels = set(np.linspace(2, b-1, b-2))
882890

883891
def __call__(self, x, pos=None):
884892
"""
@@ -895,9 +903,9 @@ def __call__(self, x, pos=None):
895903
exponent = np.round(fx) if isDecade else np.floor(fx)
896904
coeff = np.round(x / b ** exponent)
897905

898-
if self.label_pruning and coeff not in self._sublabels:
906+
if self.labelOnlyBase and not isDecade:
899907
return ''
900-
if not isDecade and self.labelOnlyBase:
908+
if self._sublabels is not None and coeff not in self._sublabels:
901909
return ''
902910

903911
if x > 10000:
@@ -972,16 +980,17 @@ def __call__(self, x, pos=None):
972980
if x == 0:
973981
return '0'
974982
sign = np.sign(x)
983+
x = abs(x)
975984
# only label the decades
976-
fx = math.log(abs(x)) / math.log(b)
985+
fx = math.log(x) / math.log(b)
977986

978987
isDecade = is_close_to_int(fx)
979988
exponent = np.round(fx) if isDecade else np.floor(fx)
980-
coeff = np.round(abs(x) / b ** exponent)
989+
coeff = np.round(x / b ** exponent)
981990

982-
if self.label_pruning and coeff not in self._sublabels:
991+
if self.labelOnlyBase and not isDecade:
983992
return ''
984-
if not isDecade and self.labelOnlyBase:
993+
if self._sublabels is not None and coeff not in self._sublabels:
985994
return ''
986995

987996
if abs(fx) > 10000:
@@ -1039,9 +1048,9 @@ def __call__(self, x, pos=None):
10391048
else:
10401049
base = '%s' % b
10411050

1042-
if self.label_pruning and coeff not in self._sublabels:
1051+
if self.labelOnlyBase and not isDecade:
10431052
return ''
1044-
if not is_decade and self.labelOnlyBase:
1053+
if self._sublabels is not None and coeff not in self._sublabels:
10451054
return ''
10461055

10471056
if not is_decade:

0 commit comments

Comments
 (0)