@@ -1586,7 +1586,8 @@ class MaxNLocator(Locator):
1586
1586
steps = None ,
1587
1587
integer = False ,
1588
1588
symmetric = False ,
1589
- prune = None )
1589
+ prune = None ,
1590
+ min_n_ticks = 2 )
1590
1591
1591
1592
def __init__ (self , * args , ** kwargs ):
1592
1593
"""
@@ -1618,6 +1619,11 @@ def __init__(self, *args, **kwargs):
1618
1619
removed. If prune=='both', the largest and smallest ticks
1619
1620
will be removed. If prune==None, no ticks will be removed.
1620
1621
1622
+ *min_n_ticks*
1623
+ While the estimated number of ticks is less than the minimum,
1624
+ the target value *nbins* is incremented and the ticks are
1625
+ recalculated.
1626
+
1621
1627
"""
1622
1628
if args :
1623
1629
kwargs ['nbins' ] = args [0 ]
@@ -1660,11 +1666,27 @@ def set_params(self, **kwargs):
1660
1666
self ._integer = kwargs ['integer' ]
1661
1667
if self ._integer :
1662
1668
self ._steps = [n for n in self ._steps if _divmod (n , 1 )[1 ] < 0.001 ]
1669
+ if 'min_n_ticks' in kwargs :
1670
+ self ._min_n_ticks = max (1 , kwargs ['min_n_ticks' ])
1663
1671
1664
1672
def _raw_ticks (self , vmin , vmax ):
1665
- nbins = self ._nbins
1666
- if nbins == 'auto' :
1667
- nbins = max (min (self .axis .get_tick_space (), 9 ), 1 )
1673
+ if self ._nbins == 'auto' :
1674
+ nbins = max (min (self .axis .get_tick_space (), 9 ),
1675
+ max (1 , self ._min_n_ticks - 1 ))
1676
+ else :
1677
+ nbins = self ._nbins
1678
+
1679
+ while True :
1680
+ ticks = self ._try_raw_ticks (vmin , vmax , nbins )
1681
+ nticks = ((ticks <= vmax ) & (ticks >= vmin )).sum ()
1682
+ if nticks >= self ._min_n_ticks :
1683
+ break
1684
+ nbins += 1
1685
+
1686
+ self ._nbins_used = nbins # Maybe useful for troubleshooting.
1687
+ return ticks
1688
+
1689
+ def _try_raw_ticks (self , vmin , vmax , nbins ):
1668
1690
scale , offset = scale_range (vmin , vmax , nbins )
1669
1691
if self ._integer :
1670
1692
scale = max (1 , scale )
@@ -1675,9 +1697,8 @@ def _raw_ticks(self, vmin, vmax):
1675
1697
best_vmax = vmax
1676
1698
best_vmin = vmin
1677
1699
1678
- for step in self ._steps :
1679
- if step < scaled_raw_step :
1680
- continue
1700
+ steps = (x for x in self ._steps if x >= scaled_raw_step )
1701
+ for step in steps :
1681
1702
step *= scale
1682
1703
best_vmin = vmin // step * step
1683
1704
best_vmax = best_vmin + step * nbins
@@ -1713,11 +1734,10 @@ def tick_values(self, vmin, vmax):
1713
1734
return self .raise_if_exceeds (locs )
1714
1735
1715
1736
def view_limits (self , dmin , dmax ):
1716
- if rcParams ['axes.autolimit_mode' ] == 'round_numbers' :
1717
- if self ._symmetric :
1718
- maxabs = max (abs (dmin ), abs (dmax ))
1719
- dmin = - maxabs
1720
- dmax = maxabs
1737
+ if self ._symmetric :
1738
+ maxabs = max (abs (dmin ), abs (dmax ))
1739
+ dmin = - maxabs
1740
+ dmax = maxabs
1721
1741
1722
1742
dmin , dmax = mtransforms .nonsingular (
1723
1743
dmin , dmax , expander = 1e-12 , tiny = 1e-13 )
@@ -2163,9 +2183,11 @@ class AutoLocator(MaxNLocator):
2163
2183
def __init__ (self ):
2164
2184
if rcParams ['_internal.classic_mode' ]:
2165
2185
nbins = 9
2186
+ steps = [1 , 2 , 5 , 10 ]
2166
2187
else :
2167
2188
nbins = 'auto'
2168
- MaxNLocator .__init__ (self , nbins = nbins , steps = [1 , 2 , 5 , 10 ])
2189
+ steps = [1 , 2 , 2.5 , 5 , 10 ]
2190
+ MaxNLocator .__init__ (self , nbins = nbins , steps = steps )
2169
2191
2170
2192
2171
2193
class AutoMinorLocator (Locator ):
0 commit comments