Coverage for /usr/lib/python3/dist-packages/matplotlib/cm.py: 31%

217 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2025-06-14 15:25 +0200

1""" 

2Builtin colormaps, colormap handling utilities, and the `ScalarMappable` mixin. 

3 

4.. seealso:: 

5 

6 :doc:`/gallery/color/colormap_reference` for a list of builtin colormaps. 

7 

8 :doc:`/tutorials/colors/colormap-manipulation` for examples of how to 

9 make colormaps. 

10 

11 :doc:`/tutorials/colors/colormaps` an in-depth discussion of 

12 choosing colormaps. 

13 

14 :doc:`/tutorials/colors/colormapnorms` for more details about data 

15 normalization. 

16""" 

17 

18from collections.abc import Mapping 

19import functools 

20 

21import numpy as np 

22from numpy import ma 

23 

24import matplotlib as mpl 

25from matplotlib import _api, colors, cbook, scale 

26from matplotlib._cm import datad 

27from matplotlib._cm_listed import cmaps as cmaps_listed 

28 

29 

30@_api.caching_module_getattr # module-level deprecations 

31class __getattr__: 

32 LUTSIZE = _api.deprecated( 

33 "3.5", obj_type="", alternative="rcParams['image.lut']")( 

34 property(lambda self: _LUTSIZE)) 

35 

36 

37_LUTSIZE = mpl.rcParams['image.lut'] 

38 

39 

40def _gen_cmap_registry(): 

41 """ 

42 Generate a dict mapping standard colormap names to standard colormaps, as 

43 well as the reversed colormaps. 

44 """ 

45 cmap_d = {**cmaps_listed} 

46 for name, spec in datad.items(): 

47 cmap_d[name] = ( # Precache the cmaps at a fixed lutsize.. 

48 colors.LinearSegmentedColormap(name, spec, _LUTSIZE) 

49 if 'red' in spec else 

50 colors.ListedColormap(spec['listed'], name) 

51 if 'listed' in spec else 

52 colors.LinearSegmentedColormap.from_list(name, spec, _LUTSIZE)) 

53 # Generate reversed cmaps. 

54 for cmap in list(cmap_d.values()): 

55 rmap = cmap.reversed() 

56 cmap_d[rmap.name] = rmap 

57 return cmap_d 

58 

59 

60class ColormapRegistry(Mapping): 

61 r""" 

62 Container for colormaps that are known to Matplotlib by name. 

63 

64 The universal registry instance is `matplotlib.colormaps`. There should be 

65 no need for users to instantiate `.ColormapRegistry` themselves. 

66 

67 Read access uses a dict-like interface mapping names to `.Colormap`\s:: 

68 

69 import matplotlib as mpl 

70 cmap = mpl.colormaps['viridis'] 

71 

72 Returned `.Colormap`\s are copies, so that their modification does not 

73 change the global definition of the colormap. 

74 

75 Additional colormaps can be added via `.ColormapRegistry.register`:: 

76 

77 mpl.colormaps.register(my_colormap) 

78 """ 

79 def __init__(self, cmaps): 

80 self._cmaps = cmaps 

81 self._builtin_cmaps = tuple(cmaps) 

82 # A shim to allow register_cmap() to force an override 

83 self._allow_override_builtin = False 

84 

85 def __getitem__(self, item): 

86 try: 

87 return self._cmaps[item].copy() 

88 except KeyError: 

89 raise KeyError(f"{item!r} is not a known colormap name") from None 

90 

91 def __iter__(self): 

92 return iter(self._cmaps) 

93 

94 def __len__(self): 

95 return len(self._cmaps) 

96 

97 def __str__(self): 

98 return ('ColormapRegistry; available colormaps:\n' + 

99 ', '.join(f"'{name}'" for name in self)) 

100 

101 def __call__(self): 

102 """ 

103 Return a list of the registered colormap names. 

104 

105 This exists only for backward-compatibility in `.pyplot` which had a 

106 ``plt.colormaps()`` method. The recommended way to get this list is 

107 now ``list(colormaps)``. 

108 """ 

109 return list(self) 

110 

111 def register(self, cmap, *, name=None, force=False): 

112 """ 

113 Register a new colormap. 

114 

115 The colormap name can then be used as a string argument to any ``cmap`` 

116 parameter in Matplotlib. It is also available in ``pyplot.get_cmap``. 

117 

118 The colormap registry stores a copy of the given colormap, so that 

119 future changes to the original colormap instance do not affect the 

120 registered colormap. Think of this as the registry taking a snapshot 

121 of the colormap at registration. 

122 

123 Parameters 

124 ---------- 

125 cmap : matplotlib.colors.Colormap 

126 The colormap to register. 

127 

128 name : str, optional 

129 The name for the colormap. If not given, ``cmap.name`` is used. 

130 

131 force : bool, default: False 

132 If False, a ValueError is raised if trying to overwrite an already 

133 registered name. True supports overwriting registered colormaps 

134 other than the builtin colormaps. 

135 """ 

136 _api.check_isinstance(colors.Colormap, cmap=cmap) 

137 

138 name = name or cmap.name 

139 if name in self: 

140 if not force: 

141 # don't allow registering an already existing cmap 

142 # unless explicitly asked to 

143 raise ValueError( 

144 f'A colormap named "{name}" is already registered.') 

145 elif (name in self._builtin_cmaps 

146 and not self._allow_override_builtin): 

147 # We don't allow overriding a builtin unless privately 

148 # coming from register_cmap() 

149 raise ValueError("Re-registering the builtin cmap " 

150 f"{name!r} is not allowed.") 

151 

152 # Warn that we are updating an already existing colormap 

153 _api.warn_external(f"Overwriting the cmap {name!r} " 

154 "that was already in the registry.") 

155 

156 self._cmaps[name] = cmap.copy() 

157 

158 def unregister(self, name): 

159 """ 

160 Remove a colormap from the registry. 

161 

162 You cannot remove built-in colormaps. 

163 

164 If the named colormap is not registered, returns with no error, raises 

165 if you try to de-register a default colormap. 

166 

167 .. warning:: 

168 

169 Colormap names are currently a shared namespace that may be used 

170 by multiple packages. Use `unregister` only if you know you 

171 have registered that name before. In particular, do not 

172 unregister just in case to clean the name before registering a 

173 new colormap. 

174 

175 Parameters 

176 ---------- 

177 name : str 

178 The name of the colormap to be removed. 

179 

180 Raises 

181 ------ 

182 ValueError 

183 If you try to remove a default built-in colormap. 

184 """ 

185 if name in self._builtin_cmaps: 

186 raise ValueError(f"cannot unregister {name!r} which is a builtin " 

187 "colormap.") 

188 self._cmaps.pop(name, None) 

189 

190 def get_cmap(self, cmap): 

191 """ 

192 Return a color map specified through *cmap*. 

193 

194 Parameters 

195 ---------- 

196 cmap : str or `~matplotlib.colors.Colormap` or None 

197 

198 - if a `.Colormap`, return it 

199 - if a string, look it up in ``mpl.colormaps`` 

200 - if None, return the Colormap defined in :rc:`image.cmap` 

201 

202 Returns 

203 ------- 

204 Colormap 

205 """ 

206 # get the default color map 

207 if cmap is None: 

208 return self[mpl.rcParams["image.cmap"]] 

209 

210 # if the user passed in a Colormap, simply return it 

211 if isinstance(cmap, colors.Colormap): 

212 return cmap 

213 if isinstance(cmap, str): 

214 _api.check_in_list(sorted(_colormaps), cmap=cmap) 

215 # otherwise, it must be a string so look it up 

216 return self[cmap] 

217 raise TypeError( 

218 'get_cmap expects None or an instance of a str or Colormap . ' + 

219 f'you passed {cmap!r} of type {type(cmap)}' 

220 ) 

221 

222 

223# public access to the colormaps should be via `matplotlib.colormaps`. For now, 

224# we still create the registry here, but that should stay an implementation 

225# detail. 

226_colormaps = ColormapRegistry(_gen_cmap_registry()) 

227globals().update(_colormaps) 

228 

229 

230@_api.deprecated( 

231 '3.6', 

232 pending=True, 

233 alternative="``matplotlib.colormaps.register(name)``" 

234) 

235def register_cmap(name=None, cmap=None, *, override_builtin=False): 

236 """ 

237 Add a colormap to the set recognized by :func:`get_cmap`. 

238 

239 Register a new colormap to be accessed by name :: 

240 

241 LinearSegmentedColormap('swirly', data, lut) 

242 register_cmap(cmap=swirly_cmap) 

243 

244 Parameters 

245 ---------- 

246 name : str, optional 

247 The name that can be used in :func:`get_cmap` or :rc:`image.cmap` 

248 

249 If absent, the name will be the :attr:`~matplotlib.colors.Colormap.name` 

250 attribute of the *cmap*. 

251 

252 cmap : matplotlib.colors.Colormap 

253 Despite being the second argument and having a default value, this 

254 is a required argument. 

255 

256 override_builtin : bool 

257 

258 Allow built-in colormaps to be overridden by a user-supplied 

259 colormap. 

260 

261 Please do not use this unless you are sure you need it. 

262 """ 

263 _api.check_isinstance((str, None), name=name) 

264 if name is None: 

265 try: 

266 name = cmap.name 

267 except AttributeError as err: 

268 raise ValueError("Arguments must include a name or a " 

269 "Colormap") from err 

270 # override_builtin is allowed here for backward compatibility 

271 # this is just a shim to enable that to work privately in 

272 # the global ColormapRegistry 

273 _colormaps._allow_override_builtin = override_builtin 

274 _colormaps.register(cmap, name=name, force=override_builtin) 

275 _colormaps._allow_override_builtin = False 

276 

277 

278def _get_cmap(name=None, lut=None): 

279 """ 

280 Get a colormap instance, defaulting to rc values if *name* is None. 

281 

282 Parameters 

283 ---------- 

284 name : `matplotlib.colors.Colormap` or str or None, default: None 

285 If a `.Colormap` instance, it will be returned. Otherwise, the name of 

286 a colormap known to Matplotlib, which will be resampled by *lut*. The 

287 default, None, means :rc:`image.cmap`. 

288 lut : int or None, default: None 

289 If *name* is not already a Colormap instance and *lut* is not None, the 

290 colormap will be resampled to have *lut* entries in the lookup table. 

291 

292 Returns 

293 ------- 

294 Colormap 

295 """ 

296 if name is None: 

297 name = mpl.rcParams['image.cmap'] 

298 if isinstance(name, colors.Colormap): 

299 return name 

300 _api.check_in_list(sorted(_colormaps), name=name) 

301 if lut is None: 

302 return _colormaps[name] 

303 else: 

304 return _colormaps[name].resampled(lut) 

305 

306# do it in two steps like this so we can have an un-deprecated version in 

307# pyplot. 

308get_cmap = _api.deprecated( 

309 '3.6', 

310 name='get_cmap', 

311 pending=True, 

312 alternative=( 

313 "``matplotlib.colormaps[name]`` " + 

314 "or ``matplotlib.colormaps.get_cmap(obj)``" 

315 ) 

316)(_get_cmap) 

317 

318 

319@_api.deprecated( 

320 '3.6', 

321 pending=True, 

322 alternative="``matplotlib.colormaps.unregister(name)``" 

323) 

324def unregister_cmap(name): 

325 """ 

326 Remove a colormap recognized by :func:`get_cmap`. 

327 

328 You may not remove built-in colormaps. 

329 

330 If the named colormap is not registered, returns with no error, raises 

331 if you try to de-register a default colormap. 

332 

333 .. warning:: 

334 

335 Colormap names are currently a shared namespace that may be used 

336 by multiple packages. Use `unregister_cmap` only if you know you 

337 have registered that name before. In particular, do not 

338 unregister just in case to clean the name before registering a 

339 new colormap. 

340 

341 Parameters 

342 ---------- 

343 name : str 

344 The name of the colormap to be un-registered 

345 

346 Returns 

347 ------- 

348 ColorMap or None 

349 If the colormap was registered, return it if not return `None` 

350 

351 Raises 

352 ------ 

353 ValueError 

354 If you try to de-register a default built-in colormap. 

355 """ 

356 cmap = _colormaps.get(name, None) 

357 _colormaps.unregister(name) 

358 return cmap 

359 

360 

361def _auto_norm_from_scale(scale_cls): 

362 """ 

363 Automatically generate a norm class from *scale_cls*. 

364 

365 This differs from `.colors.make_norm_from_scale` in the following points: 

366 

367 - This function is not a class decorator, but directly returns a norm class 

368 (as if decorating `.Normalize`). 

369 - The scale is automatically constructed with ``nonpositive="mask"``, if it 

370 supports such a parameter, to work around the difference in defaults 

371 between standard scales (which use "clip") and norms (which use "mask"). 

372 

373 Note that ``make_norm_from_scale`` caches the generated norm classes 

374 (not the instances) and reuses them for later calls. For example, 

375 ``type(_auto_norm_from_scale("log")) == LogNorm``. 

376 """ 

377 # Actually try to construct an instance, to verify whether 

378 # ``nonpositive="mask"`` is supported. 

379 try: 

380 norm = colors.make_norm_from_scale( 

381 functools.partial(scale_cls, nonpositive="mask"))( 

382 colors.Normalize)() 

383 except TypeError: 

384 norm = colors.make_norm_from_scale(scale_cls)( 

385 colors.Normalize)() 

386 return type(norm) 

387 

388 

389class ScalarMappable: 

390 """ 

391 A mixin class to map scalar data to RGBA. 

392 

393 The ScalarMappable applies data normalization before returning RGBA colors 

394 from the given colormap. 

395 """ 

396 

397 def __init__(self, norm=None, cmap=None): 

398 """ 

399 Parameters 

400 ---------- 

401 norm : `.Normalize` (or subclass thereof) or str or None 

402 The normalizing object which scales data, typically into the 

403 interval ``[0, 1]``. 

404 If a `str`, a `.Normalize` subclass is dynamically generated based 

405 on the scale with the corresponding name. 

406 If *None*, *norm* defaults to a *colors.Normalize* object which 

407 initializes its scaling based on the first data processed. 

408 cmap : str or `~matplotlib.colors.Colormap` 

409 The colormap used to map normalized data values to RGBA colors. 

410 """ 

411 self._A = None 

412 self._norm = None # So that the setter knows we're initializing. 

413 self.set_norm(norm) # The Normalize instance of this ScalarMappable. 

414 self.cmap = None # So that the setter knows we're initializing. 

415 self.set_cmap(cmap) # The Colormap instance of this ScalarMappable. 

416 #: The last colorbar associated with this ScalarMappable. May be None. 

417 self.colorbar = None 

418 self.callbacks = cbook.CallbackRegistry(signals=["changed"]) 

419 

420 callbacksSM = _api.deprecated("3.5", alternative="callbacks")( 

421 property(lambda self: self.callbacks)) 

422 

423 def _scale_norm(self, norm, vmin, vmax): 

424 """ 

425 Helper for initial scaling. 

426 

427 Used by public functions that create a ScalarMappable and support 

428 parameters *vmin*, *vmax* and *norm*. This makes sure that a *norm* 

429 will take precedence over *vmin*, *vmax*. 

430 

431 Note that this method does not set the norm. 

432 """ 

433 if vmin is not None or vmax is not None: 

434 self.set_clim(vmin, vmax) 

435 if isinstance(norm, colors.Normalize): 

436 raise ValueError( 

437 "Passing a Normalize instance simultaneously with " 

438 "vmin/vmax is not supported. Please pass vmin/vmax " 

439 "directly to the norm when creating it.") 

440 

441 # always resolve the autoscaling so we have concrete limits 

442 # rather than deferring to draw time. 

443 self.autoscale_None() 

444 

445 def to_rgba(self, x, alpha=None, bytes=False, norm=True): 

446 """ 

447 Return a normalized rgba array corresponding to *x*. 

448 

449 In the normal case, *x* is a 1D or 2D sequence of scalars, and 

450 the corresponding ndarray of rgba values will be returned, 

451 based on the norm and colormap set for this ScalarMappable. 

452 

453 There is one special case, for handling images that are already 

454 rgb or rgba, such as might have been read from an image file. 

455 If *x* is an ndarray with 3 dimensions, 

456 and the last dimension is either 3 or 4, then it will be 

457 treated as an rgb or rgba array, and no mapping will be done. 

458 The array can be uint8, or it can be floating point with 

459 values in the 0-1 range; otherwise a ValueError will be raised. 

460 If it is a masked array, the mask will be ignored. 

461 If the last dimension is 3, the *alpha* kwarg (defaulting to 1) 

462 will be used to fill in the transparency. If the last dimension 

463 is 4, the *alpha* kwarg is ignored; it does not 

464 replace the preexisting alpha. A ValueError will be raised 

465 if the third dimension is other than 3 or 4. 

466 

467 In either case, if *bytes* is *False* (default), the rgba 

468 array will be floats in the 0-1 range; if it is *True*, 

469 the returned rgba array will be uint8 in the 0 to 255 range. 

470 

471 If norm is False, no normalization of the input data is 

472 performed, and it is assumed to be in the range (0-1). 

473 

474 """ 

475 # First check for special case, image input: 

476 try: 

477 if x.ndim == 3: 

478 if x.shape[2] == 3: 

479 if alpha is None: 

480 alpha = 1 

481 if x.dtype == np.uint8: 

482 alpha = np.uint8(alpha * 255) 

483 m, n = x.shape[:2] 

484 xx = np.empty(shape=(m, n, 4), dtype=x.dtype) 

485 xx[:, :, :3] = x 

486 xx[:, :, 3] = alpha 

487 elif x.shape[2] == 4: 

488 xx = x 

489 else: 

490 raise ValueError("Third dimension must be 3 or 4") 

491 if xx.dtype.kind == 'f': 

492 if norm and (xx.max() > 1 or xx.min() < 0): 

493 raise ValueError("Floating point image RGB values " 

494 "must be in the 0..1 range.") 

495 if bytes: 

496 xx = (xx * 255).astype(np.uint8) 

497 elif xx.dtype == np.uint8: 

498 if not bytes: 

499 xx = xx.astype(np.float32) / 255 

500 else: 

501 raise ValueError("Image RGB array must be uint8 or " 

502 "floating point; found %s" % xx.dtype) 

503 return xx 

504 except AttributeError: 

505 # e.g., x is not an ndarray; so try mapping it 

506 pass 

507 

508 # This is the normal case, mapping a scalar array: 

509 x = ma.asarray(x) 

510 if norm: 

511 x = self.norm(x) 

512 rgba = self.cmap(x, alpha=alpha, bytes=bytes) 

513 return rgba 

514 

515 def set_array(self, A): 

516 """ 

517 Set the value array from array-like *A*. 

518 

519 Parameters 

520 ---------- 

521 A : array-like or None 

522 The values that are mapped to colors. 

523 

524 The base class `.ScalarMappable` does not make any assumptions on 

525 the dimensionality and shape of the value array *A*. 

526 """ 

527 if A is None: 

528 self._A = None 

529 return 

530 

531 A = cbook.safe_masked_invalid(A, copy=True) 

532 if not np.can_cast(A.dtype, float, "same_kind"): 

533 raise TypeError(f"Image data of dtype {A.dtype} cannot be " 

534 "converted to float") 

535 

536 self._A = A 

537 

538 def get_array(self): 

539 """ 

540 Return the array of values, that are mapped to colors. 

541 

542 The base class `.ScalarMappable` does not make any assumptions on 

543 the dimensionality and shape of the array. 

544 """ 

545 return self._A 

546 

547 def get_cmap(self): 

548 """Return the `.Colormap` instance.""" 

549 return self.cmap 

550 

551 def get_clim(self): 

552 """ 

553 Return the values (min, max) that are mapped to the colormap limits. 

554 """ 

555 return self.norm.vmin, self.norm.vmax 

556 

557 def set_clim(self, vmin=None, vmax=None): 

558 """ 

559 Set the norm limits for image scaling. 

560 

561 Parameters 

562 ---------- 

563 vmin, vmax : float 

564 The limits. 

565 

566 The limits may also be passed as a tuple (*vmin*, *vmax*) as a 

567 single positional argument. 

568 

569 .. ACCEPTS: (vmin: float, vmax: float) 

570 """ 

571 # If the norm's limits are updated self.changed() will be called 

572 # through the callbacks attached to the norm 

573 if vmax is None: 

574 try: 

575 vmin, vmax = vmin 

576 except (TypeError, ValueError): 

577 pass 

578 if vmin is not None: 

579 self.norm.vmin = colors._sanitize_extrema(vmin) 

580 if vmax is not None: 

581 self.norm.vmax = colors._sanitize_extrema(vmax) 

582 

583 def get_alpha(self): 

584 """ 

585 Returns 

586 ------- 

587 float 

588 Always returns 1. 

589 """ 

590 # This method is intended to be overridden by Artist sub-classes 

591 return 1. 

592 

593 def set_cmap(self, cmap): 

594 """ 

595 Set the colormap for luminance data. 

596 

597 Parameters 

598 ---------- 

599 cmap : `.Colormap` or str or None 

600 """ 

601 in_init = self.cmap is None 

602 

603 self.cmap = _ensure_cmap(cmap) 

604 if not in_init: 

605 self.changed() # Things are not set up properly yet. 

606 

607 @property 

608 def norm(self): 

609 return self._norm 

610 

611 @norm.setter 

612 def norm(self, norm): 

613 _api.check_isinstance((colors.Normalize, str, None), norm=norm) 

614 if norm is None: 

615 norm = colors.Normalize() 

616 elif isinstance(norm, str): 

617 try: 

618 scale_cls = scale._scale_mapping[norm] 

619 except KeyError: 

620 raise ValueError( 

621 "Invalid norm str name; the following values are " 

622 "supported: {}".format(", ".join(scale._scale_mapping)) 

623 ) from None 

624 norm = _auto_norm_from_scale(scale_cls)() 

625 

626 if norm is self.norm: 

627 # We aren't updating anything 

628 return 

629 

630 in_init = self.norm is None 

631 # Remove the current callback and connect to the new one 

632 if not in_init: 

633 self.norm.callbacks.disconnect(self._id_norm) 

634 self._norm = norm 

635 self._id_norm = self.norm.callbacks.connect('changed', 

636 self.changed) 

637 if not in_init: 

638 self.changed() 

639 

640 def set_norm(self, norm): 

641 """ 

642 Set the normalization instance. 

643 

644 Parameters 

645 ---------- 

646 norm : `.Normalize` or str or None 

647 

648 Notes 

649 ----- 

650 If there are any colorbars using the mappable for this norm, setting 

651 the norm of the mappable will reset the norm, locator, and formatters 

652 on the colorbar to default. 

653 """ 

654 self.norm = norm 

655 

656 def autoscale(self): 

657 """ 

658 Autoscale the scalar limits on the norm instance using the 

659 current array 

660 """ 

661 if self._A is None: 

662 raise TypeError('You must first set_array for mappable') 

663 # If the norm's limits are updated self.changed() will be called 

664 # through the callbacks attached to the norm 

665 self.norm.autoscale(self._A) 

666 

667 def autoscale_None(self): 

668 """ 

669 Autoscale the scalar limits on the norm instance using the 

670 current array, changing only limits that are None 

671 """ 

672 if self._A is None: 

673 raise TypeError('You must first set_array for mappable') 

674 # If the norm's limits are updated self.changed() will be called 

675 # through the callbacks attached to the norm 

676 self.norm.autoscale_None(self._A) 

677 

678 def changed(self): 

679 """ 

680 Call this whenever the mappable is changed to notify all the 

681 callbackSM listeners to the 'changed' signal. 

682 """ 

683 self.callbacks.process('changed', self) 

684 self.stale = True 

685 

686 

687# The docstrings here must be generic enough to apply to all relevant methods. 

688mpl._docstring.interpd.update( 

689 cmap_doc="""\ 

690cmap : str or `~matplotlib.colors.Colormap`, default: :rc:`image.cmap` 

691 The Colormap instance or registered colormap name used to map scalar data 

692 to colors.""", 

693 norm_doc="""\ 

694norm : str or `~matplotlib.colors.Normalize`, optional 

695 The normalization method used to scale scalar data to the [0, 1] range 

696 before mapping to colors using *cmap*. By default, a linear scaling is 

697 used, mapping the lowest value to 0 and the highest to 1. 

698 

699 If given, this can be one of the following: 

700 

701 - An instance of `.Normalize` or one of its subclasses 

702 (see :doc:`/tutorials/colors/colormapnorms`). 

703 - A scale name, i.e. one of "linear", "log", "symlog", "logit", etc. For a 

704 list of available scales, call `matplotlib.scale.get_scale_names()`. 

705 In that case, a suitable `.Normalize` subclass is dynamically generated 

706 and instantiated.""", 

707 vmin_vmax_doc="""\ 

708vmin, vmax : float, optional 

709 When using scalar data and no explicit *norm*, *vmin* and *vmax* define 

710 the data range that the colormap covers. By default, the colormap covers 

711 the complete value range of the supplied data. It is an error to use 

712 *vmin*/*vmax* when a *norm* instance is given (but using a `str` *norm* 

713 name together with *vmin*/*vmax* is acceptable).""", 

714) 

715 

716 

717def _ensure_cmap(cmap): 

718 """ 

719 Ensure that we have a `.Colormap` object. 

720 

721 For internal use to preserve type stability of errors. 

722 

723 Parameters 

724 ---------- 

725 cmap : None, str, Colormap 

726 

727 - if a `Colormap`, return it 

728 - if a string, look it up in mpl.colormaps 

729 - if None, look up the default color map in mpl.colormaps 

730 

731 Returns 

732 ------- 

733 Colormap 

734 

735 """ 

736 if isinstance(cmap, colors.Colormap): 

737 return cmap 

738 cmap_name = cmap if cmap is not None else mpl.rcParams["image.cmap"] 

739 # use check_in_list to ensure type stability of the exception raised by 

740 # the internal usage of this (ValueError vs KeyError) 

741 _api.check_in_list(sorted(_colormaps), cmap=cmap_name) 

742 return mpl.colormaps[cmap_name]