8000 Merge pull request #29054 from anntzer/lmt · matplotlib/matplotlib@9db1b97 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9db1b97

Browse files
authored
Merge pull request #29054 from anntzer/lmt
Label log minor ticks if only one log major tick is drawn.
2 parents 203de93 + 915bfad commit 9db1b97

File tree

3 files changed

+54
-28
lines changed

3 files changed

+54
-28
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Minor log tick labels are set depending on number of major log ticks, not on number of decades spanned
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
Previously, by default, on a log-scaled axis, the minor ticks would be
4+
unlabeled if the axis limits spanned more than one decade. The meaning of the
5+
``minor_thresholds`` parameter to `.LogFormatter` has been altered so that the
6+
decision of whether to label the minor ticks is now based on the number of
7+
major ticks drawn within the axis limits.
8+
9+
For example, for an axis spanning from 4 to 60 (with thus a single major log
10+
tick, at 10), minor ticks are now labeled, even though the axis spans more than
11+
one decade.

lib/matplotlib/tests/test_ticker.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,11 +1235,16 @@ def test_sublabel(self):
12351235
ax.set_xlim(1, 80)
12361236
self._sub_labels(ax.xaxis, subs=[])
12371237

1238-
# axis range at 0.4 to 1 decades, label subs 2, 3, 4, 6
1238+
# axis range slightly more than 1 decade, but spanning a single major
1239+
# tick, label subs 2, 3, 4, 6
1240+
ax.set_xlim(.8, 9)
1241+
self._sub_labels(ax.xaxis, subs=[2, 3, 4, 6])
1242+
1243+
# axis range at 0.4 to 1 decade, label subs 2, 3, 4, 6
12391244
ax.set_xlim(1, 8)
12401245
self._sub_labels(ax.xaxis, subs=[2, 3, 4, 6])
12411246

1242-
# axis range at 0 to 0.4 decades, label all
1247+
# axis range at 0 to 0.4 decade, label all
12431248
ax.set_xlim(0.5, 0.9)
12441249
self._sub_labels(ax.xaxis, subs=np.arange(2, 10, dtype=int))
12451250

lib/matplotlib/ticker.py

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -861,20 +861,23 @@ class LogFormatter(Formatter):
861861
862862
labelOnlyBase : bool, default: False
863863
If True, label ticks only at integer powers of base.
864-
This is normally True for major ticks and False for
865-
minor ticks.
864+
This is normally True for major ticks and False for minor ticks.
866865
867866
minor_thresholds : (subset, all), default: (1, 0.4)
868867
If labelOnlyBase is False, these two numbers control
869868
the labeling of ticks that are not at integer powers of
870-
base; normally these are the minor ticks. The controlling
871-
parameter is the log of the axis data range. In the typical
872-
case where base is 10 it is the number of decades spanned
873-
by the axis, so we can call it 'numdec'. If ``numdec <= all``,
874-
all minor ticks will be labeled. If ``all < numdec <= subset``,
875-
then only a subset of minor ticks will be labeled, so as to
876-
avoid crowding. If ``numdec > subset`` then no minor ticks will
877-
be labeled.
869+
base; normally these are the minor ticks.
870+
871+
The first number (*subset*) is the largest number of major ticks for
872+
which minor ticks are labeled; e.g., the default, 1, means that minor
873+
ticks are labeled as long as there is no more than 1 major tick. (It
874+
is assumed that major ticks are at integer powers of *base*.)
875+
876+
The second number (*all*) is a threshold, in log-units of the axis
877+
limit range, over which only a subset of the minor ticks are labeled,
878+
so as to avoid crowding; e.g., with the default value (0.4) and the
879+
usual ``base=10``, all minor ticks are shown only if the axis limit
880+
range spans less than 0.4 decades.
878881
879882
linthresh : None or float, default: None
880883
If a symmetric log scale is in use, its ``linthresh``
@@ -898,12 +901,9 @@ class LogFormatter(Formatter):
898901
899902
Examples
900903
--------
901-
To label a subset of minor ticks when the view limits span up
902-
to 2 decades, and all of the ticks when zoomed in to 0.5 decades
903-
or less, use ``minor_thresholds=(2, 0.5)``.
904-
905-
To label all minor ticks when the view limits span up to 1.5
906-
decades, use ``minor_thresholds=(1.5, 1.5)``.
904+
To label a subset of minor ticks when there are up to 2 major ticks,
905+
and all of the ticks when zoomed in to 0.5 decades or less, use
906+
``minor_thresholds=(2, 0.5)``.
907907
"""
908908

909909
def __init__(self, base=10.0, labelOnlyBase=False,
@@ -971,22 +971,32 @@ def set_locs(self, locs=None):
971971
return
972972

973973
b = self._base
974+
974975
if linthresh is not None: # symlog
975-
# Only compute the number of decades in the logarithmic part of the
976-
# axis
977-
numdec = 0
976+
# Only count ticks and decades in the logarithmic part of the axis.
977+
numdec = numticks = 0
978978
if vmin < -linthresh:
979979
rhs = min(vmax, -linthresh)
980-
numdec += math.log(vmin / rhs) / math.log(b)
980+
numticks += (
981+
math.floor(math.log(abs(rhs), b))
982+
- math.floor(math.nextafter(math.log(abs(vmin), b), -math.inf)))
983+
numdec += math.log(vmin / rhs, b)
981984
if vmax > linthresh:
982985
lhs = max(vmin, linthresh)
983-
numdec += math.log(vmax / lhs) / math.log(b)
986+
numticks += (
987+
math.floor(math.log(vmax, b))
988+
- math.floor(math.nextafter(math.log(lhs, b), -math.inf)))
989+
numdec += math.log(vmax / lhs, b)
984990
else:
985-
vmin = math.log(vmin) / math.log(b)
986-
vmax = math.log(vmax) / math.log(b)
987-
numdec = abs(vmax - vmin)
988-
989-
if numdec > self.minor_thresholds[0]:
991+
lmin = math.log(vmin, b)
992+
lmax = math.log(vmax, b)
993+
# The nextafter call handles the case where vmin is exactly at a
994+
# decade (e.g. there's one major tick between 1 and 5).
995+
numticks = (math.floor(lmax)
996+
- math.floor(math.nextafter(lmin, -math.inf)))
997+
numdec = abs(lmax - lmin)
998+
999+
if numticks > self.minor_thresholds[0]:
9901000
# Label only bases
9911001
self._sublabels = {1}
9921002
elif numdec > self.minor_thresholds[1]:

0 commit comments

Comments
 (0)
0