@@ -1476,7 +1476,8 @@ class MaxNLocator(Locator):
1476
1476
steps = None ,
1477
1477
integer = False ,
1478
1478
symmetric = False ,
1479
- prune = None )
1479
+ prune = None ,
1480
+ min_n_ticks = 2 )
1480
1481
1481
1482
def __init__ (self , * args , ** kwargs ):
1482
1483
"""
@@ -1508,6 +1509,11 @@ def __init__(self, *args, **kwargs):
1508
1509
removed. If prune=='both', the largest and smallest ticks
1509
1510
will be removed. If prune==None, no ticks will be removed.
1510
1511
1512
+ *min_n_ticks*
1513
+ While the estimated number of ticks is less than the minimum,
1514
+ the target value *nbins* is incremented and the ticks are
1515
+ recalculated.
1516
+
1511
1517
"""
1512
1518
if args :
1513
1519
kwargs ['nbins' ] = args [0 ]
@@ -1550,11 +1556,27 @@ def set_params(self, **kwargs):
1550
1556
self ._integer = kwargs ['integer' ]
1551
1557
if self ._integer :
1552
1558
self ._steps = [n for n in self ._steps if _divmod (n , 1 )[1 ] < 0.001 ]
1559
+ if 'min_n_ticks' in kwargs :
1560
+ self ._min_n_ticks = max (1 , kwargs ['min_n_ticks' ])
1553
1561
1554
1562
def _raw_ticks (self , vmin , vmax ):
1555
- nbins = self ._nbins
1556
- if nbins == 'auto' :
1557
- nbins = max (min (self .axis .get_tick_space (), 9 ), 1 )
1563
+ if self ._nbins == 'auto' :
1564
+ nbins = max (min (self .axis .get_tick_space (), 9 ),
1565
+ self ._min_n_ticks )
1566
+ else :
1567
+ nbins = self ._nbins
1568
+
1569
+ while True :
1570
+ ticks = self ._try_raw_ticks (vmin , vmax , nbins )
1571
+ nticks = ((ticks <= vmax ) & (ticks >= vmin )).sum ()
1572
+ if nticks >= self ._min_n_ticks :
1573
+ break
1574
+ nbins += 1
1575
+
1576
+ self ._nbins_used = nbins # Maybe useful for troubleshooting.
1577
+ return ticks
1578
+
1579
+ def _try_raw_ticks (self , vmin , vmax , nbins ):
1558
1580
scale , offset = scale_range (vmin , vmax , nbins )
1559
1581
if self ._integer :
1560
1582
scale = max (1 , scale )
@@ -1565,9 +1587,8 @@ def _raw_ticks(self, vmin, vmax):
1565
1587
best_vmax = vmax
1566
1588
best_vmin = vmin
1567
1589
1568
- for step in self ._steps :
1569
- if step < scaled_raw_step :
1570
- continue
1590
+ steps = (x for x in self ._steps if x >= scaled_raw_step )
1591
+ for step in steps :
1571
1592
step *= scale
1572
1593
best_vmin = vmin // step * step
1573
1594
best_vmax = best_vmin + step * nbins
@@ -1603,11 +1624,10 @@ def tick_values(self, vmin, vmax):
1603
1624
return self .raise_if_exceeds (locs )
1604
1625
1605
1626
def view_limits (self , dmin , dmax ):
1606
- if rcParams ['axes.autolimit_mode' ] == 'round_numbers' :
1607
- if self ._symmetric :
1608
- maxabs = max (abs (dmin ), abs (dmax ))
1609
- dmin = - maxabs
1610
- dmax = maxabs
1627
+ if self ._symmetric :
1628
+ maxabs = max (abs (dmin ), abs (dmax ))
1629
+ dmin = - maxabs
1630
+ dmax = maxabs
1611
1631
1612
1632
dmin , dmax = mtransforms .nonsingular (
1613
1633
dmin , dmax , expander = 1e-12 , tiny = 1e-13 )
@@ -2053,9 +2073,11 @@ class AutoLocator(MaxNLocator):
2053
2073
def __init__ (self ):
2054
2074
if rcParams ['_internal.classic_mode' ]:
2055
2075
nbins = 9
2076
+ steps = [1 , 2 , 5 , 10 ]
2056
2077
else :
2057
2078
nbins = 'auto'
2058
- MaxNLocator .__init__ (self , nbins = nbins , steps = [1 , 2 , 5 , 10 ])
2079
+ steps = [1 , 2 , 2.5 , 5 , 10 ]
2080
+ MaxNLocator .__init__ (self , nbins = nbins , steps = steps )
2059
2081
2060
2082
2061
2083
class AutoMinorLocator (Locator ):
0 commit comments