@@ -866,7 +866,12 @@ class LogFormatter(Formatter):
866866 major and minor ticks; the tick locations might be set manually,
867867 or by a locator that puts ticks at integer powers of base and
868868 at intermediate locations. For this situation, disable the
869- minor_thresholds logic by using ``minor_thresholds=(np.inf, np.inf)``.
869+ minor_thresholds logic by using ``minor_thresholds=(np.inf, np.inf)``,
870+ so that all ticks will be labeled.
871+
872+ To disable labeling of minor ticks when 'labelOnlyBase' is False,
873+ use ``minor_thresholds=(0, 0)``. This is the default for the
874+ "classic" style.
870875
871876 Examples
872877 --------
@@ -877,14 +882,18 @@ class LogFormatter(Formatter):
877882 To label all minor ticks when the view limits span up to 1.5
878883 decades, use ``minor_thresholds=(1.5, 1.5)``.
879884
880-
881885 """
882886 def __init__ (self , base = 10.0 , labelOnlyBase = False ,
883- minor_thresholds = ( 1 , 0.4 ) ,
887+ minor_thresholds = None ,
884888 linthresh = None ):
885889
886890 self ._base = float (base )
887891 self .labelOnlyBase = labelOnlyBase
892+ if minor_thresholds is None :
893+ if rcParams ['_internal.classic_mode' ]:
894+ minor_thresholds = (0 , 0 )
895+ else :
896+ minor_thresholds = (1 , 0.4 )
888897 self .minor_thresholds = minor_thresholds
889898 self ._sublabels = None
890899 self ._linthresh = linthresh
@@ -925,7 +934,6 @@ def set_locs(self, locs=None):
925934 b = self ._base
926935
927936 vmin , vmax = self .axis .get_view_interval ()
928- self .d = abs (vmax - vmin )
929937
930938 # Handle symlog case:
931939 linthresh = self ._linthresh
@@ -957,15 +965,20 @@ def set_locs(self, locs=None):
957965 # Add labels between bases at log-spaced coefficients;
958966 # include base powers in case the locations include
959967 # "major" and "minor" points, as in colorbar.
960- c = np .logspace (0 , 1 , b // 2 + 1 , base = b )
968+ c = np .logspace (0 , 1 , int ( b ) // 2 + 1 , base = b )
961969 self ._sublabels = set (np .round (c ))
970+ # For base 10, this yields (1, 2, 3, 4, 6, 10).
962971 else :
963- self ._sublabels = set (np .linspace (1 , b , b ))
972+ # Label all integer multiples of base**n.
973+ self ._sublabels = set (np .arange (1 , b + 1 ))
964974
965975 def __call__ (self , x , pos = None ):
966976 """
967977 Return the format for tick val `x`.
968978 """
979+ vmin , vmax = self .axis .get_view_interval ()
980+ vmin , vmax = mtransforms .nonsingular (vmin , vmax , expander = 0.05 )
981+ d = abs (vmax - vmin )
969982 b = self ._base
970983 if x == 0.0 :
971984 return '0'
@@ -986,7 +999,7 @@ def __call__(self, x, pos=None):
986999 elif x < 1 :
9871000 s = '%1.0e' % x
9881001 else :
989- s = self .pprint_val (x , self . d )
1002+ s = self .pprint_val (x , d )
9901003 if sign == - 1 :
9911004 s = '-%s' % s
9921005
@@ -1795,6 +1808,33 @@ def __init__(self, *args, **kwargs):
17951808 self .set_params (** self .default_params )
17961809 self .set_params (** kwargs )
17971810
1811+ @staticmethod
1812+ def _validate_steps (steps ):
1813+ if not np .iterable (steps ):
1814+ raise ValueError ('steps argument must be a sequence of numbers '
1815+ 'from 1 to 10' )
1816+ steps = np .asarray (steps )
1817+ if np .any (np .diff (steps ) <= 0 ):
1818+ raise ValueError ('steps argument must be uniformly increasing' )
1819+ if steps [- 1 ] > 10 or steps [0 ] < 1 :
1820+ warnings .warn ('Steps argument should be a sequence of numbers\n '
1821+ 'increasing from 1 to 10, inclusive. Behavior with\n '
1822+ 'values outside this range is undefined, and will\n '
1823+ 'raise a ValueError in future versions of mpl.' )
1824+ if steps [0 ] != 1 :
1825+ steps = np .hstack ((1 , steps ))
1826+ if steps [- 1 ] != 10 :
1827+ steps = np .hstack ((steps , 10 ))
1828+ return steps
1829+
1830+ @staticmethod
1831+ def _staircase (steps ):
1832+ # Make an extended staircase within which the needed
1833+ # step will be found. This is probably much larger
1834+ # than necessary.
1835+ flights = (0.1 * steps [:- 1 ], steps , 10 * steps [1 ])
1836+ return np .hstack (flights )
1837+
17981838 def set_params (self , ** kwargs ):
17991839 """Set parameters within this locator."""
18001840 if 'nbins' in kwargs :
@@ -1816,23 +1856,16 @@ def set_params(self, **kwargs):
18161856 if 'steps' in kwargs :
18171857 steps = kwargs ['steps' ]
18181858 if steps is None :
1819- self ._steps = [1 , 1.5 , 2 , 2.5 , 3 , 4 , 5 , 6 , 8 , 10 ]
1859+ self ._steps = np . array ( [1 , 1.5 , 2 , 2.5 , 3 , 4 , 5 , 6 , 8 , 10 ])
18201860 else :
1821- if int (steps [- 1 ]) != 10 :
1822- steps = list (steps )
1823- steps .append (10 )
1824- self ._steps = steps
1825- # Make an extended staircase within which the needed
1826- # step will be found. This is probably much larger
1827- # than necessary.
1828- flights = (0.1 * np .array (self ._steps [:- 1 ]),
1829- self ._steps ,
1830- [10 * self ._steps [1 ]])
1831- self ._extended_steps = np .hstack (flights )
1861+ self ._steps = self ._validate_steps (steps )
1862+ self ._extended_steps = self ._staircase (self ._steps )
18321863 if 'integer' in kwargs :
18331864 self ._integer = kwargs ['integer' ]
18341865 if self ._integer :
1835- self ._steps = [n for n in self ._steps if _divmod (n , 1 )[1 ] < 0.001 ]
1866+ self ._steps = np .array ([n for n in self ._steps
1867+ if _divmod (n , 1 )[1 ] < 0.001 ])
1868+ self ._extended_steps = self ._staircase (self ._steps )
18361869 if 'min_n_ticks' in kwargs :
18371870 self ._min_n_ticks = max (1 , kwargs ['min_n_ticks' ])
18381871
@@ -1870,8 +1903,8 @@ def _raw_ticks(self, vmin, vmax):
18701903 step = max (1 , step )
18711904 best_vmin = (_vmin // step ) * step
18721905
1873- low = round (Base (step ).le (_vmin - best_vmin ) / step )
1874- high = round (Base (step ).ge (_vmax - best_vmin ) / step )
1906+ low = np . round (Base (step ).le (_vmin - best_vmin ) / step )
1907+ high = np . round (Base (step ).ge (_vmax - best_vmin ) / step )
18751908 ticks = np .arange (low , high + 1 ) * step + best_vmin + offset
18761909 nticks = ((ticks <= vmax ) & (ticks >= vmin )).sum ()
18771910 if nticks >= self ._min_n_ticks :
0 commit comments