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

Skip to content

Commit 4b542fc

Browse files
committed
add LogFormatterSciNotation
move print logic from fromatter to locator move label logic to independent function remove redundancy LogFormatterSciNotation is now a subclass of LogFormatterMathtext, and the differences (how labels are formatted for non-decade ticks) have been factored out in a `_non_decade_format` function. fix default showLabel bool
1 parent 2a7f606 commit 4b542fc

File tree

3 files changed

+72
-15
lines changed

3 files changed

+72
-15
lines changed

lib/matplotlib/axis.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -883,15 +883,17 @@ def iter_ticks(self):
883883
Iterate through all of the major and minor ticks.
884884
"""
885885
majorLocs = self.major.locator()
886+
hasLabel = self.major.locator.show_tick_label(majorLocs)
886887
majorTicks = self.get_major_ticks(len(majorLocs))
887888
self.major.formatter.set_locs(majorLocs)
888-
majorLabels = [self.major.formatter(val, i)
889+
majorLabels = [self.major.formatter(val, i) if hasLabel[i] else ''
889890
for i, val in enumerate(majorLocs)]
890891

891892
minorLocs = self.minor.locator()
893+
hasLabel = self.major.locator.show_tick_label(minorLocs)
892894
minorTicks = self.get_minor_ticks(len(minorLocs))
893895
self.minor.formatter.set_locs(minorLocs)
894-
minorLabels = [self.minor.formatter(val, i)
896+
minorLabels = [self.minor.formatter(val, i) if hasLabel[i] else ''
895897
for i, val in enumerate(minorLocs)]
896898

897899
major_minor = [

lib/matplotlib/scale.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from matplotlib.cbook import dedent
1010
from matplotlib.ticker import (NullFormatter, ScalarFormatter,
11-
LogFormatterMathtext, LogitFormatter)
11+
LogFormatterSciNotation, LogitFormatter)
1212
from matplotlib.ticker import (NullLocator, LogLocator, AutoLocator,
1313
SymmetricalLogLocator, LogitLocator)
1414
from matplotlib.transforms import Transform, IdentityTransform
@@ -304,9 +304,9 @@ def set_default_locators_and_formatters(self, axis):
304304
log scaling.
305305
"""
306306
axis.set_major_locator(LogLocator(self.base))
307-
axis.set_major_formatter(LogFormatterMathtext(self.base))
307+
axis.set_major_formatter(LogFormatterSciNotation(self.base))
308308
axis.set_minor_locator(LogLocator(self.base, self.subs))
309-
axis.set_minor_formatter(NullFormatter())
309+
axis.set_minor_formatter(LogFormatterSciNotation(self.base))
310310

311311
def get_transform(self):
312312
"""
@@ -462,10 +462,10 @@ def set_default_locators_and_formatters(self, axis):
462462
symmetrical log scaling.
463463
"""
464464
axis.set_major_locator(SymmetricalLogLocator(self.get_transform()))
465-
axis.set_major_formatter(LogFormatterMathtext(self.base))
465+
axis.set_major_formatter(LogFormatterSciNotation(self.base))
466466
axis.set_minor_locator(SymmetricalLogLocator(self.get_transform(),
467467
self.subs))
468-
axis.set_minor_formatter(NullFormatter())
468+
axis.set_minor_formatter(LogFormatterSciNotation(self.base))
469469

470470
def get_transform(self):
471471
"""

lib/matplotlib/ticker.py

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,6 @@ def pprint_val(self, x, d):
910910
s = s.rstrip('0').rstrip('.')
911911
return s
912912

913-
914913
class LogFormatterExponent(LogFormatter):
915914
"""
916915
Format values for log axis using ``exponent = log_base(value)``.
@@ -951,6 +950,14 @@ class LogFormatterMathtext(LogFormatter):
951950
Format values for log axis using ``exponent = log_base(value)``.
952951
"""
953952

953+
def _non_decade_format(self, sign_string, base, fx, usetex):
954+
'Return string for non-decade locations'
955+
if usetex:
956+
return (r'$%s%s^{%.2f}$') % (sign_string, base, fx)
957+
else:
958+
return ('$%s$' % _mathdefault('%s%s^{%.2f}' %
959+
(sign_string, base, fx)))
960+
954961
def __call__(self, x, pos=None):
955962
"""
956963
Return the format for tick value `x`.
@@ -981,13 +988,7 @@ def __call__(self, x, pos=None):
981988
if not is_decade and self.labelOnlyBase:
982989
return ''
983990
elif not is_decade:
984-
if usetex:
985-
return (r'$%s%s^{%.2f}$') % \
986-
(sign_string, base, fx)
987-
else:
988-
return ('$%s$' % _mathdefault(
989-
'%s%s^{%.2f}' %
990-
(sign_string, base, fx)))
991+
return self._non_decade_format(sign_string, base, fx, usetex)
991992
else:
992993
if usetex:
993994
return (r'$%s%s^{%d}$') % (sign_string,
@@ -998,6 +999,28 @@ def __call__(self, x, pos=None):
998999
'%s%s^{%d}' %
9991000
(sign_string, base, nearest_long(fx))))
10001001

1002+
class LogFormatterSciNotation(LogFormatterMathtext):
1003+
"""
1004+
Format values following scientific notation in a logarithmic axis
1005+
"""
1006+
1007+
def __init__(self, base=10.0, labelOnlyBase=False):
1008+
super(LogFormatterSciNotation, self).__init__(base=base,
1009+
labelOnlyBase=labelOnlyBase)
1010+
1011+
def _non_decade_format(self, sign_string, base, fx, usetex):
1012+
'Return string for non-decade locations'
1013+
b = float(base)
1014+
exponent = math.floor(fx)
1015+
coeff = b ** fx / b ** exponent
1016+
if is_close_to_int(coeff):
1017+
coeff = nearest_long(coeff)
1018+
if usetex:
1019+
return (r'$%g\times%s^{%d}$') % \
1020+
(coeff, base, exponent)
1021+
else:
1022+
return (r'$\mathdefault{%g\times%s^{%d}}$') % \
1023+
(coeff, base, exponent)
10011024

10021025
class LogitFormatter(Formatter):
10031026
"""
@@ -1250,6 +1273,11 @@ def __call__(self):
12501273
# hence there is no *one* interface to call self.tick_values.
12511274
raise NotImplementedError('Derived must override')
12521275

1276+
def show_tick_label(self, locs):
1277+
"""Return boolean array on whether to show a label for the given
1278+
locations"""
1279+
return np.ones(np.asarray(locs).size, dtype=np.bool)
1280+
12531281
def raise_if_exceeds(self, locs):
12541282
"""raise a RuntimeError if Locator attempts to create more than
12551283
MAXTICKS locs"""
@@ -1894,6 +1922,33 @@ def tick_values(self, vmin, vmax):
18941922

18951923
return self.raise_if_exceeds(np.asarray(ticklocs))
18961924

1925+
def show_tick_label(self, ticklocs):
1926+
b = self._base
1927+
1928+
vmin, vmax = self.axis.get_view_interval()
1929+
vmin = math.log(vmin) / math.log(b)
1930+
vmax = math.log(vmax) / math.log(b)
1931+
1932+
numdec = abs(vmax - vmin)
1933+
1934+
if numdec > 3:
1935+
sublabel = set((1))
1936+
elif numdec > 2:
1937+
sublabel = set((1, 3))
1938+
elif numdec > 1:
1939+
sublabel = set((1, 2, 5))
1940+
else:
1941+
sublabel = set((1, 2, 4, 7))
1942+
1943+
label = np.ones(ticklocs.size, dtype=np.bool)
1944+
for i, loc in enumerate(ticklocs):
1945+
exponent = math.floor(math.log(abs(loc)) / math.log(b))
1946+
coeff = loc / b ** nearest_long(exponent)
1947+
if nearest_long(coeff) not in sublabel:
1948+
label[i] = False
1949+
1950+
return label
1951+
18971952
def view_limits(self, vmin, vmax):
18981953
'Try to choose the view limits intelligently'
18991954
b = self._base

0 commit comments

Comments
 (0)