def __call__(self, value, clip=None): if clip is None: clip = self.clip result, is_scalar = self.process_value(value) result = ma.masked_less_equal(result, 0, copy=False) self.autoscale_None(result) vmin, vmax = self.vmin, self.vmax if vmin > vmax: raise ValueError("minvalue must be less than or equal to maxvalue") elif vmin <= 0: raise ValueError("values must all be positive") elif vmin == vmax: result.fill(0) else: if clip: mask = ma.getmask(result) result = ma.array(np.clip(result.filled(vmax), vmin, vmax), mask=mask) # in-place equivalent of above can be much faster resdat = result.data mask = result.mask if mask is np.ma.nomask: mask = resdat <= 0 else: mask |= resdat <= 0 cbook._putmask(resdat, mask, 1) np.log(resdat, resdat) resdat -= np.log(vmin) resdat /= np.log(vmax) - np.log(vmin) result = np.ma.array(resdat, mask=mask, copy=False) if is_scalar: result = result[0] return result
def _h_arrows(self, length): """ length is in arrow width units """ # It might be possible to streamline the code # and speed it up a bit by using complex (x,y) # instead of separate arrays; but any gain would be slight. minsh = self.minshaft * self.headlength N = len(length) length = length.reshape(N, 1) # This number is chosen based on when pixel values overflow in Agg # causing rendering errors # length = np.minimum(length, 2 ** 16) np.clip(length, 0, 2**16, out=length) # x, y: normal horizontal arrow x = np.array([0, -self.headaxislength, -self.headlength, 0], np.float64) x = x + np.array([0, 1, 1, 1]) * length y = 0.5 * np.array([1, 1, self.headwidth, 0], np.float64) y = np.repeat(y[np.newaxis, :], N, axis=0) # x0, y0: arrow without shaft, for short vectors x0 = np.array( [0, minsh - self.headaxislength, minsh - self.headlength, minsh], np.float64) y0 = 0.5 * np.array([1, 1, self.headwidth, 0], np.float64) ii = [0, 1, 2, 3, 2, 1, 0, 0] X = x.take(ii, 1) Y = y.take(ii, 1) Y[:, 3:-1] *= -1 X0 = x0.take(ii) Y0 = y0.take(ii) Y0[3:-1] *= -1 shrink = length / minsh X0 = shrink * X0[np.newaxis, :] Y0 = shrink * Y0[np.newaxis, :] short = np.repeat(length < minsh, 8, axis=1) # Now select X0, Y0 if short, otherwise X, Y cbook._putmask(X, short, X0) cbook._putmask(Y, short, Y0) if self.pivot == 'middle': X -= 0.5 * X[:, 3, np.newaxis] elif self.pivot == 'tip': X = X - X[:, 3, np.newaxis] # numpy bug? using -= does not # work here unless we multiply # by a float first, as with 'mid'. elif self.pivot != 'tail': raise ValueError(("Quiver.pivot must have value in {{'middle', " "'tip', 'tail'}} not {0}").format(self.pivot)) tooshort = length < self.minlength if tooshort.any(): # Use a heptagonal dot: th = np.arange(0, 8, 1, np.float64) * (np.pi / 3.0) x1 = np.cos(th) * self.minlength * 0.5 y1 = np.sin(th) * self.minlength * 0.5 X1 = np.repeat(x1[np.newaxis, :], N, axis=0) Y1 = np.repeat(y1[np.newaxis, :], N, axis=0) tooshort = np.repeat(tooshort, 8, 1) cbook._putmask(X, tooshort, X1) cbook._putmask(Y, tooshort, Y1) # Mask handling is deferred to the caller, _make_verts. return X, Y
def _h_arrows(self, length): """ length is in arrow width units """ # It might be possible to streamline the code # and speed it up a bit by using complex (x,y) # instead of separate arrays; but any gain would be slight. minsh = self.minshaft * self.headlength N = len(length) length = length.reshape(N, 1) # This number is chosen based on when pixel values overflow in Agg # causing rendering errors # length = np.minimum(length, 2 ** 16) np.clip(length, 0, 2 ** 16, out=length) # x, y: normal horizontal arrow x = np.array([0, -self.headaxislength, -self.headlength, 0], np.float64) x = x + np.array([0, 1, 1, 1]) * length y = 0.5 * np.array([1, 1, self.headwidth, 0], np.float64) y = np.repeat(y[np.newaxis, :], N, axis=0) # x0, y0: arrow without shaft, for short vectors x0 = np.array([0, minsh - self.headaxislength, minsh - self.headlength, minsh], np.float64) y0 = 0.5 * np.array([1, 1, self.headwidth, 0], np.float64) ii = [0, 1, 2, 3, 2, 1, 0, 0] X = x.take(ii, 1) Y = y.take(ii, 1) Y[:, 3:-1] *= -1 X0 = x0.take(ii) Y0 = y0.take(ii) Y0[3:-1] *= -1 shrink = length / minsh if minsh != 0. else 0. X0 = shrink * X0[np.newaxis, :] Y0 = shrink * Y0[np.newaxis, :] short = np.repeat(length < minsh, 8, axis=1) # Now select X0, Y0 if short, otherwise X, Y cbook._putmask(X, short, X0) cbook._putmask(Y, short, Y0) if self.pivot == 'middle': X -= 0.5 * X[:, 3, np.newaxis] elif self.pivot == 'tip': X = X - X[:, 3, np.newaxis] # numpy bug? using -= does not # work here unless we multiply # by a float first, as with 'mid'. elif self.pivot != 'tail': raise ValueError(("Quiver.pivot must have value in {{'middle', " "'tip', 'tail'}} not {0}").format(self.pivot)) tooshort = length < self.minlength if tooshort.any(): # Use a heptagonal dot: th = np.arange(0, 8, 1, np.float64) * (np.pi / 3.0) x1 = np.cos(th) * self.minlength * 0.5 y1 = np.sin(th) * self.minlength * 0.5 X1 = np.repeat(x1[np.newaxis, :], N, axis=0) Y1 = np.repeat(y1[np.newaxis, :], N, axis=0) tooshort = np.repeat(tooshort, 8, 1) cbook._putmask(X, tooshort, X1) cbook._putmask(Y, tooshort, Y1) # Mask handling is deferred to the caller, _make_verts. return X, Y
def __call__(self, value, clip=None): if clip is None: clip = self.clip result, is_scalar = self.process_value(value) result = ma.masked_less_equal(result, 0, copy=False) self.autoscale_None(result) vmin, vmax = self.vmin, self.vmax if vmin > vmax: raise ValueError("minvalue must be less than or equal to maxvalue") elif vmin <= 0: raise ValueError("values must all be positive") elif vmin == vmax: result.fill(0) else: if clip: mask = ma.getmask(result) val = ma.array(np.clip(result.filled(vmax), vmin, vmax), mask=mask) #result = (ma.log(result)-np.log(vmin))/(np.log(vmax)-np.log(vmin)) # in-place equivalent of above can be much faster resdat = result.data mask = result.mask if mask is np.ma.nomask: mask = (resdat <= 0) else: mask |= resdat <= 0 cbook._putmask(resdat, mask, 1) np.log(resdat, resdat) resdat -= np.log(vmin) resdat /= (np.log(vmax) - np.log(vmin)) result = np.ma.array(resdat, mask=mask, copy=False) if is_scalar: result = result[0] return result
def __call__(self, X, alpha=None, bytes=False): """ Parameters ---------- X : scalar, ndarray The data value(s) to convert to RGBA. For floats, X should be in the interval ``[0.0, 1.0]`` to return the RGBA values ``X*100`` percent along the Colormap line. For integers, X should be in the interval ``[0, Colormap.N)`` to return RGBA values *indexed* from the Colormap with index ``X``. alpha : float, None Alpha must be a scalar between 0 and 1, or None. bytes : bool If False (default), the returned RGBA values will be floats in the interval ``[0, 1]`` otherwise they will be uint8s in the interval ``[0, 255]``. Returns ------- Tuple of RGBA values if X is scalar, othewise an array of RGBA values with a shape of ``X.shape + (4, )``. """ # See class docstring for arg/kwarg documentation. if not self._isinit: self._init() mask_bad = None if not cbook.iterable(X): vtype = 'scalar' xa = np.array([X]) else: vtype = 'array' xma = ma.array(X, copy=True) # Copy here to avoid side effects. mask_bad = xma.mask # Mask will be used below. xa = xma.filled() # Fill to avoid infs, etc. del xma # Calculations with native byteorder are faster, and avoid a # bug that otherwise can occur with putmask when the last # argument is a numpy scalar. if not xa.dtype.isnative: xa = xa.byteswap().newbyteorder() if xa.dtype.kind == "f": # Treat 1.0 as slightly less than 1. vals = np.array([1, 0], dtype=xa.dtype) almost_one = np.nextafter(*vals) cbook._putmask(xa, xa == 1.0, almost_one) # The following clip is fast, and prevents possible # conversion of large positive values to negative integers. xa *= self.N if NP_CLIP_OUT: np.clip(xa, -1, self.N, out=xa) else: xa = np.clip(xa, -1, self.N) # ensure that all 'under' values will still have negative # value after casting to int cbook._putmask(xa, xa < 0.0, -1) xa = xa.astype(int) # Set the over-range indices before the under-range; # otherwise the under-range values get converted to over-range. cbook._putmask(xa, xa > self.N - 1, self._i_over) cbook._putmask(xa, xa < 0, self._i_under) if mask_bad is not None: if mask_bad.shape == xa.shape: cbook._putmask(xa, mask_bad, self._i_bad) elif mask_bad: xa.fill(self._i_bad) if bytes: lut = (self._lut * 255).astype(np.uint8) else: lut = self._lut.copy() # Don't let alpha modify original _lut. if alpha is not None: alpha = min(alpha, 1.0) # alpha must be between 0 and 1 alpha = max(alpha, 0.0) if bytes: alpha = int(alpha * 255) if (lut[-1] == 0).all(): lut[:-1, -1] = alpha # All zeros is taken as a flag for the default bad # color, which is no color--fully transparent. We # don't want to override this. else: lut[:, -1] = alpha # If the bad value is set to have a color, then we # override its alpha just as for any other value. rgba = np.empty(shape=xa.shape + (4,), dtype=lut.dtype) lut.take(xa, axis=0, mode='clip', out=rgba) # twice as fast as lut[xa]; # using the clip or wrap mode and providing an # output array speeds it up a little more. if vtype == 'scalar': rgba = tuple(rgba[0, :]) return rgba
def __call__(self, X, alpha=None, bytes=False): """ *X* is either a scalar or an array (of any dimension). If scalar, a tuple of rgba values is returned, otherwise an array with the new shape = oldshape+(4,). If the X-values are integers, then they are used as indices into the array. If they are floating point, then they must be in the interval (0.0, 1.0). Alpha must be a scalar between 0 and 1, or None. If bytes is False, the rgba values will be floats on a 0-1 scale; if True, they will be uint8, 0-255. """ if not self._isinit: self._init() mask_bad = None if not cbook.iterable(X): vtype = "scalar" xa = np.array([X]) else: vtype = "array" xma = ma.array(X, copy=False) mask_bad = xma.mask xa = xma.data.copy() # Copy here to avoid side effects. del xma # masked values are substituted below; no need to fill them here if xa.dtype.char in np.typecodes["Float"]: # Treat 1.0 as slightly less than 1. cbook._putmask(xa, xa == 1.0, np.nextafter(xa.dtype.type(1), xa.dtype.type(0))) # The following clip is fast, and prevents possible # conversion of large positive values to negative integers. xa *= self.N if NP_CLIP_OUT: np.clip(xa, -1, self.N, out=xa) else: xa = np.clip(xa, -1, self.N) # ensure that all 'under' values will still have negative # value after casting to int cbook._putmask(xa, xa < 0.0, -1) xa = xa.astype(int) # Set the over-range indices before the under-range; # otherwise the under-range values get converted to over-range. cbook._putmask(xa, xa > self.N - 1, self._i_over) cbook._putmask(xa, xa < 0, self._i_under) if mask_bad is not None: if mask_bad.shape == xa.shape: cbook._putmask(xa, mask_bad, self._i_bad) elif mask_bad: xa.fill(self._i_bad) if bytes: lut = (self._lut * 255).astype(np.uint8) else: lut = self._lut.copy() # Don't let alpha modify original _lut. if alpha is not None: alpha = min(alpha, 1.0) # alpha must be between 0 and 1 alpha = max(alpha, 0.0) if bytes: alpha = int(alpha * 255) if (lut[-1] == 0).all(): lut[:-1, -1] = alpha # All zeros is taken as a flag for the default bad # color, which is no color--fully transparent. We # don't want to override this. else: lut[:, -1] = alpha # If the bad value is set to have a color, then we # override its alpha just as for any other value. rgba = np.empty(shape=xa.shape + (4,), dtype=lut.dtype) lut.take(xa, axis=0, mode="clip", out=rgba) # twice as fast as lut[xa]; # using the clip or wrap mode and providing an # output array speeds it up a little more. if vtype == "scalar": rgba = tuple(rgba[0, :]) return rgba
def __call__(self, X, alpha=None, bytes=False): """ *X* is either a scalar or an array (of any dimension). If scalar, a tuple of rgba values is returned, otherwise an array with the new shape = oldshape+(4,). If the X-values are integers, then they are used as indices into the array. If they are floating point, then they must be in the interval (0.0, 1.0). Alpha must be a scalar between 0 and 1, or None. If bytes is False, the rgba values will be floats on a 0-1 scale; if True, they will be uint8, 0-255. """ if not self._isinit: self._init() mask_bad = None if not cbook.iterable(X): vtype = 'scalar' xa = np.array([X]) else: vtype = 'array' xma = ma.array(X, copy=True) # Copy here to avoid side effects. mask_bad = xma.mask # Mask will be used below. xa = xma.filled() # Fill to avoid infs, etc. del xma # Calculations with native byteorder are faster, and avoid a # bug that otherwise can occur with putmask when the last # argument is a numpy scalar. if not xa.dtype.isnative: xa = xa.byteswap().newbyteorder() if xa.dtype.kind == "f": # Treat 1.0 as slightly less than 1. vals = np.array([1, 0], dtype=xa.dtype) almost_one = np.nextafter(*vals) cbook._putmask(xa, xa == 1.0, almost_one) # The following clip is fast, and prevents possible # conversion of large positive values to negative integers. xa *= self.N if NP_CLIP_OUT: np.clip(xa, -1, self.N, out=xa) else: xa = np.clip(xa, -1, self.N) # ensure that all 'under' values will still have negative # value after casting to int cbook._putmask(xa, xa < 0.0, -1) xa = xa.astype(int) # Set the over-range indices before the under-range; # otherwise the under-range values get converted to over-range. cbook._putmask(xa, xa > self.N - 1, self._i_over) cbook._putmask(xa, xa < 0, self._i_under) if mask_bad is not None: if mask_bad.shape == xa.shape: cbook._putmask(xa, mask_bad, self._i_bad) elif mask_bad: xa.fill(self._i_bad) if bytes: lut = (self._lut * 255).astype(np.uint8) else: lut = self._lut.copy() # Don't let alpha modify original _lut. if alpha is not None: alpha = min(alpha, 1.0) # alpha must be between 0 and 1 alpha = max(alpha, 0.0) if bytes: alpha = int(alpha * 255) if (lut[-1] == 0).all(): lut[:-1, -1] = alpha # All zeros is taken as a flag for the default bad # color, which is no color--fully transparent. We # don't want to override this. else: lut[:, -1] = alpha # If the bad value is set to have a color, then we # override its alpha just as for any other value. rgba = np.empty(shape=xa.shape + (4, ), dtype=lut.dtype) lut.take(xa, axis=0, mode='clip', out=rgba) # twice as fast as lut[xa]; # using the clip or wrap mode and providing an # output array speeds it up a little more. if vtype == 'scalar': rgba = tuple(rgba[0, :]) return rgba
def _newcall_(self, X, alpha=None, bytes=False): if not self._isinit: self._init() mask_bad = None if not cbook.iterable(X): vtype = 'scalar' xa = np.array([X]) else: vtype = 'array' xma = ma.array(X, copy=True) # Copy here to avoid side effects. mask_bad = xma.mask # Mask will be used below. xa = xma.filled() # Fill to avoid infs, etc. del xma self._lut[0] = [0, 0, 0, 1] # Calculations with native byteorder are faster, and avoid a # bug that otherwise can occur with putmask when the last # argument is a numpy scalar. if not xa.dtype.isnative: xa = xa.byteswap().newbyteorder() if xa.dtype.kind == "f": # Treat 1.0 as slightly less than 1. vals = np.array([1, 0], dtype=xa.dtype) almost_one = np.nextafter(*vals) cbook._putmask(xa, xa == 1.0, almost_one) # The following clip is fast, and prevents possible # conversion of large positive values to negative integers. xa *= self.N np.clip(xa, -1, self.N, out=xa) # ensure that all 'under' values will still have negative # value after casting to int cbook._putmask(xa, xa < 0.0, -1) xa = xa.astype(int) # Set the over-range indices before the under-range; # otherwise the under-range values get converted to over-range. cbook._putmask(xa, xa > self.N - 1, self._i_over) cbook._putmask(xa, xa < 0, self._i_under) if mask_bad is not None: if mask_bad.shape == xa.shape: cbook._putmask(xa, mask_bad, self._i_bad) elif mask_bad: xa.fill(self._i_bad) if bytes: lut = (self._lut * 255).astype(np.uint8) else: lut = self._lut.copy() # Don't let alpha modify original _lut. if alpha is not None: alpha = min(alpha, 1.0) # alpha must be between 0 and 1 alpha = max(alpha, 0.0) if bytes: alpha = int(alpha * 255) if (lut[-1] == 0).all(): lut[:-1, -1] = alpha # All zeros is taken as a flag for the default bad # color, which is no color--fully transparent. We # don't want to override this. else: lut[:, -1] = alpha # If the bad value is set to have a color, then we # override its alpha just as for any other value. rgba = np.empty(shape=xa.shape + (4,), dtype=lut.dtype) lut.take(xa, axis=0, mode='clip', out=rgba) if vtype == 'scalar': rgba = tuple(rgba[0, :]) return rgba
def __call__(self, X, alpha=None, bytes=False): """ Parameters ---------- X : scalar, ndarray The data value(s) to convert to RGBA. For floats, X should be in the interval ``[0.0, 1.0]`` to return the RGBA values ``X*100`` percent along the Colormap line. For integers, X should be in the interval ``[0, Colormap.N)`` to return RGBA values *indexed* from the Colormap with index ``X``. alpha : float, None Alpha must be a scalar between 0 and 1, or None. bytes : bool If False (default), the returned RGBA values will be floats in the interval ``[0, 1]`` otherwise they will be uint8s in the interval ``[0, 255]``. Returns ------- Tuple of RGBA values if X is scalar, othewise an array of RGBA values with a shape of ``X.shape + (4, )``. """ # See class docstring for arg/kwarg documentation. if not self._isinit: self._init() mask_bad = None if not cbook.iterable(X): vtype = 'scalar' xa = np.array([X]) else: vtype = 'array' xma = ma.array(X, copy=True) # Copy here to avoid side effects. mask_bad = xma.mask # Mask will be used below. xa = xma.filled() # Fill to avoid infs, etc. del xma # Calculations with native byteorder are faster, and avoid a # bug that otherwise can occur with putmask when the last # argument is a numpy scalar. if not xa.dtype.isnative: xa = xa.byteswap().newbyteorder() if xa.dtype.kind == "f": # Treat 1.0 as slightly less than 1. vals = np.array([1, 0], dtype=xa.dtype) almost_one = np.nextafter(*vals) cbook._putmask(xa, xa == 1.0, almost_one) # The following clip is fast, and prevents possible # conversion of large positive values to negative integers. xa *= self.N if NP_CLIP_OUT: np.clip(xa, -1, self.N, out=xa) else: xa = np.clip(xa, -1, self.N) # ensure that all 'under' values will still have negative # value after casting to int cbook._putmask(xa, xa < 0.0, -1) xa = xa.astype(int) # Set the over-range indices before the under-range; # otherwise the under-range values get converted to over-range. cbook._putmask(xa, xa > self.N - 1, self._i_over) cbook._putmask(xa, xa < 0, self._i_under) if mask_bad is not None: if mask_bad.shape == xa.shape: cbook._putmask(xa, mask_bad, self._i_bad) elif mask_bad: xa.fill(self._i_bad) if bytes: lut = (self._lut * 255).astype(np.uint8) else: lut = self._lut.copy() # Don't let alpha modify original _lut. if alpha is not None: alpha = min(alpha, 1.0) # alpha must be between 0 and 1 alpha = max(alpha, 0.0) if bytes: alpha = int(alpha * 255) if (lut[-1] == 0).all(): lut[:-1, -1] = alpha # All zeros is taken as a flag for the default bad # color, which is no color--fully transparent. We # don't want to override this. else: lut[:, -1] = alpha # If the bad value is set to have a color, then we # override its alpha just as for any other value. rgba = np.empty(shape=xa.shape + (4, ), dtype=lut.dtype) lut.take(xa, axis=0, mode='clip', out=rgba) # twice as fast as lut[xa]; # using the clip or wrap mode and providing an # output array speeds it up a little more. if vtype == 'scalar': rgba = tuple(rgba[0, :]) return rgba