Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 04e7088

Browse files
committed
Simplify handling of out-of-bound values Colormap.__call__.
Mostly, we don't need to manually handle/clip out of bounds float values if we compute the masks early enough (note that these masks are always computed at some point anyways, so there's no cost of doing that a bit earlier).
1 parent 99d39bd commit 04e7088

File tree

1 file changed

+10
-20
lines changed

1 file changed

+10
-20
lines changed

lib/matplotlib/colors.py

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -706,30 +706,24 @@ def __call__(self, X, alpha=None, bytes=False):
706706
if not self._isinit:
707707
self._init()
708708

709-
# Take the bad mask from a masked array, or in all other cases defer
710-
# np.isnan() to after we have converted to an array.
711-
mask_bad = X.mask if np.ma.is_masked(X) else None
712709
xa = np.array(X, copy=True)
713-
if mask_bad is None:
714-
mask_bad = np.isnan(xa)
715710
if not xa.dtype.isnative:
716711
xa = xa.byteswap().newbyteorder() # Native byteorder is faster.
717712
if xa.dtype.kind == "f":
718713
xa *= self.N
719-
# Negative values are out of range, but astype(int) would
720-
# truncate them towards zero.
721-
xa[xa < 0] = -1
722714
# xa == 1 (== N after multiplication) is not out of range.
723715
xa[xa == self.N] = self.N - 1
724-
# Avoid converting large positive values to negative integers.
725-
np.clip(xa, -1, self.N, out=xa)
716+
# Pre-compute the masks before casting to int (which can truncate
717+
# negative values to zero or wrap large floats to negative ints).
718+
mask_under = xa < 0
719+
mask_over = xa >= self.N
720+
# If input was masked, get the bad mask from it; else mask out nans.
721+
mask_bad = X.mask if np.ma.is_masked(X) else np.isnan(xa)
726722
with np.errstate(invalid="ignore"):
727723
# We need this cast for unsigned ints as well as floats
728724
xa = xa.astype(int)
729-
# Set the over-range indices before the under-range;
730-
# otherwise the under-range values get converted to over-range.
731-
xa[xa > self.N - 1] = self._i_over
732-
xa[xa < 0] = self._i_under
725+
xa[mask_under] = self._i_under
726+
xa[mask_over] = self._i_over
733727
xa[mask_bad] = self._i_bad
734728

735729
lut = self._lut
@@ -747,13 +741,9 @@ def __call__(self, X, alpha=None, bytes=False):
747741
f"alpha is array-like but its shape {alpha.shape} does "
748742
f"not match that of X {xa.shape}")
749743
rgba[..., -1] = alpha
750-
751744
# If the "bad" color is all zeros, then ignore alpha input.
752-
if (lut[-1] == 0).all() and np.any(mask_bad):
753-
if np.iterable(mask_bad) and mask_bad.shape == xa.shape:
754-
rgba[mask_bad] = (0, 0, 0, 0)
755-
else:
756-
rgba[..., :] = (0, 0, 0, 0)
745+
if (lut[-1] == 0).all():
746+
rgba[mask_bad] = (0, 0, 0, 0)
757747

758748
if not np.iterable(X):
759749
rgba = tuple(rgba)

0 commit comments

Comments
 (0)