@@ -1427,18 +1427,23 @@ def __init__(self, boundaries, ncolors, clip=False, extend='neither'):
14271427 they are below ``boundaries[0]`` or mapped to *ncolors* if they are
14281428 above ``boundaries[-1]``. These are then converted to valid indices
14291429 by `Colormap.__call__`.
1430- extend : str, optional
1431- 'neither', 'both', 'min', or 'max': reserve the first (last) colors
1432- of the colormap for data values below (above) the first (last)
1433- boundary value.
1430+ extend : {'neither', 'both', 'min', 'max'}, optional
1431+ Extend the number of bins to include one or both of the
1432+ regions beyond the boundaries. For example, if ``extend``
1433+ is 'min', then the color to which the region between the first
1434+ pair of boundaries is mapped will be distinct from the first
1435+ color in the colormap, and by default a
1436+ `~matplotlib.colorbar.Colorbar` will be drawn with
1437+ the triangle extension on the left side.
14341438
14351439 Notes
14361440 -----
14371441 *boundaries* defines the edges of bins, and data falling within a bin
14381442 is mapped to the color with the same index.
14391443
1440- If the number of bins doesn't equal *ncolors*, the color is chosen
1441- by linear interpolation of the bin number onto color numbers.
1444+ If the number of bins, including any extensions, doesn't equal
1445+ *ncolors*, the color is chosen by linear interpolation of the
1446+ bin number onto color numbers.
14421447 """
14431448 if clip and extend != 'neither' :
14441449 raise ValueError ("'clip=True' is not compatible with 'extend'" )
@@ -1448,25 +1453,15 @@ def __init__(self, boundaries, ncolors, clip=False, extend='neither'):
14481453 self .boundaries = np .asarray (boundaries )
14491454 self .N = len (self .boundaries )
14501455 self .Ncmap = ncolors
1451-
1452- # Extension. We use the same trick as colorbar.py and add a fake
1453- # boundary were needed.
1454- _b = list (boundaries )
1455- if extend == 'both' :
1456- _b = [_b [0 ] - 1 ] + _b + [_b [- 1 ] + 1 ]
1457- elif extend == 'min' :
1458- _b = [_b [0 ] - 1 ] + _b
1459- elif extend == 'max' :
1460- _b = _b + [_b [- 1 ] + 1 ]
14611456 self .extend = extend
14621457
1463- # needed for the interpolation but should not be seen from outside
1464- self ._b = np . array ( _b )
1465- self . _N = len ( self . _b )
1466- if self ._N - 1 == self . Ncmap :
1467- self ._interp = False
1468- else :
1469- self ._interp = True
1458+ self . _N = self . N - 1 # number of colors needed
1459+ self ._offset = 0
1460+ if extend in ( 'min' , 'both' ):
1461+ self ._N += 1
1462+ self ._offset = 1
1463+ if extend in ( 'max' , 'both' ) :
1464+ self ._N += 1
14701465
14711466 def __call__ (self , value , clip = None ):
14721467 if clip is None :
@@ -1480,11 +1475,9 @@ def __call__(self, value, clip=None):
14801475 max_col = self .Ncmap - 1
14811476 else :
14821477 max_col = self .Ncmap
1483- iret = np .zeros (xx .shape , dtype = np .int16 )
1484- for i , b in enumerate (self ._b ):
1485- iret [xx >= b ] = i
1486- if self ._interp :
1487- scalefac = float (self .Ncmap - 1 ) / (self ._N - 2 )
1478+ iret = np .digitize (xx , self .boundaries ) - 1 + self ._offset
1479+ if self .Ncmap > self ._N :
1480+ scalefac = (self .Ncmap - 1 ) / (self ._N - 1 )
14881481 iret = (iret * scalefac ).astype (np .int16 )
14891482 iret [xx < self .vmin ] = - 1
14901483 iret [xx >= self .vmax ] = max_col
0 commit comments