コード例 #1
0
    def test_reduce(self):
        from numpy import add, maximum

        assert add.reduce([1, 2, 3]) == 6
        assert maximum.reduce([1]) == 1
        assert maximum.reduce([1, 2, 3]) == 3
        raises(ValueError, maximum.reduce, [])
コード例 #2
0
ファイル: colorvol.py プロジェクト: Yongcheng123/ChimeraX
def _array_value_range(a):

    if len(a) == 0:
        return (None, None)
    from numpy import minimum, maximum
    r = (minimum.reduce(a), maximum.reduce(a))
    return r
コード例 #3
0
ファイル: __init__.py プロジェクト: Khitem/semanticscience
def array_value_range(a):

    if len(a) == 0:
        return (None, None)
    from numpy import minimum, maximum
    r = (minimum.reduce(a), maximum.reduce(a))
    return r
コード例 #4
0
def maximum_norm(v):

    from numpy import maximum
    d2 = maximum.reduce(v[:, 0] * v[:, 0] + v[:, 1] * v[:, 1] +
                        v[:, 2] * v[:, 2])
    import math
    d = math.sqrt(d2)
    return d
コード例 #5
0
 def _get_cover_types(self, lct):
     """Return a list of landcover types present in the lct grid"""
     x = []
     max_type = int(maximum.reduce(ravel(lct)))
     for itype in range(1, max_type+1):
         if sometrue(ravel(lct) == itype):
             x = x + [itype]
     return array(x)
コード例 #6
0
ファイル: shei.py プロジェクト: urban-ai/VIBe2UrbanSim
 def _get_cover_types(self, lct):
     """Return a list of landcover types present in the lct grid"""
     x = []
     max_type = int(maximum.reduce(ravel(lct)))
     for itype in range(1, max_type + 1):
         if sometrue(ravel(lct) == itype):
             x = x + [itype]
     return array(x)
コード例 #7
0
ファイル: test_ufuncs.py プロジェクト: Qointum/pypy
    def test_reduce_1d(self):
        import numpy as np
        from numpy import array, add, maximum, less, float16, complex64

        assert less.reduce([5, 4, 3, 2, 1])
        assert add.reduce([1, 2, 3]) == 6
        assert maximum.reduce([1]) == 1
        assert maximum.reduce([1, 2, 3]) == 3
        raises(ValueError, maximum.reduce, [])

        assert add.reduce(array([True, False] * 200)) == 200
        assert add.reduce(array([True, False] * 200, dtype="int8")) == 200
        assert add.reduce(array([True, False] * 200), dtype="int8") == -56
        assert type(add.reduce(array([True, False] * 200, dtype="float16"))) is float16
        assert type(add.reduce(array([True, False] * 200, dtype="complex64"))) is complex64

        for dtype in ["bool", "int"]:
            assert np.equal.reduce([1, 2], dtype=dtype) == True
            assert np.equal.reduce([1, 2, 0], dtype=dtype) == False
コード例 #8
0
    def test_reduce_1d(self):
        import numpy as np
        from numpy import array, add, maximum, less, float16, complex64

        assert less.reduce([5, 4, 3, 2, 1])
        assert add.reduce([1, 2, 3]) == 6
        assert maximum.reduce([1]) == 1
        assert maximum.reduce([1, 2, 3]) == 3
        raises(ValueError, maximum.reduce, [])

        assert add.reduce(array([True, False] * 200)) == 200
        assert add.reduce(array([True, False] * 200, dtype='int8')) == 200
        assert add.reduce(array([True, False] * 200), dtype='int8') == -56
        assert type(add.reduce(array([True, False] * 200, dtype='float16'))) is float16
        assert type(add.reduce(array([True, False] * 200, dtype='complex64'))) is complex64

        for dtype in ['bool', 'int']:
            assert np.equal.reduce([1, 2], dtype=dtype) == True
            assert np.equal.reduce([1, 2, 0], dtype=dtype) == False
コード例 #9
0
 def cylinder(p):
     r, z = sqrt(p[:, 0] ** 2 + p[:, 1] ** 2), p[:, 2]
     d1, d2, d3 = r - 1.0, z - 1.0, -z - 1.0
     d4, d5 = sqrt(d1 ** 2 + d2 ** 2), sqrt(d1 ** 2 + d3 ** 2)
     d = maximum.reduce([d1, d2, d3])
     ix = (d1 > 0) * (d2 > 0)
     d[ix] = d4[ix]
     ix = (d1 > 0) * (d3 > 0)
     d[ix] = d5[ix]
     return d
コード例 #10
0
ファイル: genstack.py プロジェクト: bwkeller/PASTA
def headerize(image):
    """
	This method generates the FITS headers for the final median and mean 
	images that are saved.
	@type image:	pyfits image
	@param image:	The FITS image of the stacked results
	@returns:		The pyfits image with the proper header values included
	"""
    # These values are used due to a bug in the astlib scale, so my own scale
    # bzero and bscale values must be internally calculated.
    scalingfactor = 0.000001
    maxintvalue = 4294967294
    # This adds the appropriate fits header values
    image[0].header.update("STACKMIN", Stack.percentile_centralpix(0), "Minimum value of central pixel")
    image[0].header.update("STACKMAX", Stack.percentile_centralpix(100), "Maximum value of central pixel")
    image[0].header.update("STACK50", Stack.percentile_centralpix(50), "Median value of central pixel")
    image[0].header.update("STACK25", Stack.percentile_centralpix(25), "25th Percentile value of central pixel")
    image[0].header.update("STACK75", Stack.percentile_centralpix(75), "75th percentile value of central pixel")
    image[0].header.update("STACKNUM", Stack.data.shape[2], "Number of accepted sources used")
    image[0].header.update("BUNIT", units, "")
    image[0].header.update("CRPIX1", 1, "")
    image[0].header.update("CRPIX2", 1, "")
    image[0].header.update("CTYPE1", "RA-CAR", "")
    image[0].header.update("CTYPE2", "DEC-CAR", "")
    # CDELT SHOULD be read from input fits file
    image[0].header.update("CDELT1", cdelt1, "")
    image[0].header.update("CDELT2", cdelt2, "")
    image[0].header.update("CRVAL1", -((image[0].data.shape[0]) / 2.0) * image[0].header["CDELT1"], "")
    image[0].header.update("CRVAL2", -((image[0].data.shape[1]) / 2.0) * image[0].header["CDELT2"], "")
    # These lines are used to scale the image, as some software can only handle
    # int values for the data array
    min = minimum.reduce(minimum.reduce(image[0].data))
    max = maximum.reduce(maximum.reduce(image[0].data))
    # These lines are needed to prevent the lowest intensity pixels from being
    # blanks
    min = min - (scalingfactor * abs(min))
    max = max + (scalingfactor * abs(max))
    _zero = (max + min) / 2.0
    _scale = (max - min) / (4294967294)
    image[0].scale("int32", "", bzero=_zero, bscale=_scale)
    return image
コード例 #11
0
    def fillFormat(self, data):
        import numpy.core.numeric as _nc

        errstate = _nc.seterr(all='ignore')
        try:
            special = isnan(data) | isinf(data)
            valid = not_equal(data, 0) & ~special
            non_zero = absolute(data.compress(valid))
            if len(non_zero) == 0:
                max_val = 0.
                min_val = 0.
            else:
                max_val = maximum.reduce(non_zero)
                min_val = minimum.reduce(non_zero)
                if max_val >= 1.e8:
                    self.exp_format = True
                if not self.suppress_small and (min_val < 0.0001
                                                or max_val / min_val > 1000.):
                    self.exp_format = True
        finally:
            _nc.seterr(**errstate)

        if self.exp_format:
            self.large_exponent = 0 < min_val < 1e-99 or max_val >= 1e100
            self.max_str_len = 8 + self.precision
            if self.large_exponent:
                self.max_str_len += 1
            if self.sign:
                format = '%+'
            else:
                format = '%'
            format = format + '%d.%de' % (self.max_str_len, self.precision)
        else:
            format = '%%.%df' % (self.precision,)
            if len(non_zero):
                precision = max([_digits(x, self.precision, format)
                                 for x in non_zero])
            else:
                precision = 0
            precision = min(self.precision, precision)
            self.max_str_len = len(str(int(max_val))) + precision + 2
            if _nc.any(special):
                self.max_str_len = max(self.max_str_len,
                                       len(_nan_str),
                                       len(_inf_str) + 1)
            if self.sign:
                format = '%#+'
            else:
                format = '%#'
            format = format + '%d.%df' % (self.max_str_len, precision)

        self.special_fmt = '%%%ds' % (self.max_str_len,)
        self.format = format
コード例 #12
0
 def __init__(self, data):
     try:
         max_str_len = max(len(str(maximum.reduce(data))),
                           len(str(minimum.reduce(data))))
         self.format = '%' + str(max_str_len) + 'd'
     except (TypeError, NotImplementedError):
         # if reduce(data) fails, this instance will not be called, just
         # instantiated in formatdict.
         pass
     except ValueError:
         # this occurs when everything is NA
         pass
コード例 #13
0
ファイル: pes.py プロジェクト: christianurich/VIBe2UrbanSim
 def compute(self, dataset_pool):
     constants = dataset_pool.get_dataset('constants')
     fs = ma.filled(self.get_dataset().get_2d_attribute(self.footprint_size).astype(float32), 0)
     lct = ma.filled(self.get_dataset().get_2d_attribute(self.land_cover_type), 0)
     x = zeros(shape=lct.shape, dtype=float32)
     max_type = int(maximum.reduce(ravel(lct)))
     for itype in range(1, max_type+1):
         temp = equal(lct, itype).astype(int32)
         summed = correlate(ma.filled(temp, 0.0),
                            constants['FOOTPRINT'],
                            mode="reflect")
         x += temp * ma.filled(summed / ma.masked_where(fs==0, fs), 0.0)
     return self.get_dataset().flatten_by_id(arcsin(sqrt(x)))
コード例 #14
0
    def plane(self, matrix):

        from numpy import ravel, minimum, maximum, add, multiply, array, float32
        matrix_1d = matrix.ravel()
        dmin = minimum.reduce(matrix_1d)
        if self.min == None or dmin < self.min:
            self.min = dmin
        dmax = maximum.reduce(matrix_1d)
        if self.max == None or dmax > self.max:
            self.max = dmax
        self.sum += add.reduce(matrix_1d)
        # TODO: Don't copy array to get standard deviation.
        # Avoid overflow when squaring integral types
        m2 = array(matrix_1d, float32)
        multiply(m2, m2, m2)
        self.sum2 += add.reduce(m2)
コード例 #15
0
ファイル: pes.py プロジェクト: urban-ai/VIBe2UrbanSim
 def compute(self, dataset_pool):
     constants = dataset_pool.get_dataset('constants')
     fs = ma.filled(
         self.get_dataset().get_2d_attribute(
             self.footprint_size).astype(float32), 0)
     lct = ma.filled(
         self.get_dataset().get_2d_attribute(self.land_cover_type), 0)
     x = zeros(shape=lct.shape, dtype=float32)
     max_type = int(maximum.reduce(ravel(lct)))
     for itype in range(1, max_type + 1):
         temp = equal(lct, itype).astype(int32)
         summed = correlate(ma.filled(temp, 0.0),
                            constants['FOOTPRINT'],
                            mode="reflect")
         x += temp * ma.filled(summed / ma.masked_where(fs == 0, fs), 0.0)
     return self.get_dataset().flatten_by_id(arcsin(sqrt(x)))
コード例 #16
0
    def plane(self, matrix):

        from numpy import ravel, minimum, maximum, add, multiply, array, float32
        matrix_1d = matrix.ravel()
        dmin = minimum.reduce(matrix_1d)
        if self.min == None or dmin < self.min:
            self.min = dmin
        dmax = maximum.reduce(matrix_1d)
        if self.max == None or dmax > self.max:
            self.max = dmax
        self.sum += add.reduce(matrix_1d)
        # TODO: Don't copy array to get standard deviation.
        # Avoid overflow when squaring integral types
        m2 = array(matrix_1d, float32)
        multiply(m2, m2, m2)
        self.sum2 += add.reduce(m2)
コード例 #17
0
ファイル: test_ufuncs.py プロジェクト: Qointum/pypy
    def test_reduce_errors(self):
        from numpy import sin, add, maximum, zeros

        raises(ValueError, sin.reduce, [1, 2, 3])
        assert add.reduce(1) == 1

        assert list(maximum.reduce(zeros((2, 0)), axis=0)) == []
        exc = raises(ValueError, maximum.reduce, zeros((2, 0)), axis=None)
        assert exc.value[0] == ("zero-size array to reduction operation " "maximum which has no identity")
        exc = raises(ValueError, maximum.reduce, zeros((2, 0)), axis=1)
        assert exc.value[0] == ("zero-size array to reduction operation " "maximum which has no identity")

        a = zeros((2, 2)) + 1
        assert (add.reduce(a, axis=1) == [2, 2]).all()
        assert (add.reduce(a, axis=(1,)) == [2, 2]).all()
        exc = raises(ValueError, add.reduce, a, axis=2)
        assert exc.value[0] == "'axis' entry is out of bounds"
コード例 #18
0
    def test_reduce_errors(self):
        from numpy import sin, add, maximum, zeros

        raises(ValueError, sin.reduce, [1, 2, 3])
        assert add.reduce(1) == 1

        assert list(maximum.reduce(zeros((2, 0)), axis=0)) == []
        exc = raises(ValueError, maximum.reduce, zeros((2, 0)), axis=None)
        assert exc.value[0] == ('zero-size array to reduction operation '
                                'maximum which has no identity')
        exc = raises(ValueError, maximum.reduce, zeros((2, 0)), axis=1)
        assert exc.value[0] == ('zero-size array to reduction operation '
                                'maximum which has no identity')

        a = zeros((2, 2)) + 1
        assert (add.reduce(a, axis=1) == [2, 2]).all()
        assert (add.reduce(a, axis=(1,)) == [2, 2]).all()
        exc = raises(ValueError, add.reduce, a, axis=2)
        assert exc.value[0] == "'axis' entry is out of bounds"
コード例 #19
0
def peaks():
    vector, label = weeklydataset_sg_ndata(
        "/media/4AC0AB31C0AB21E5/Documents and Settings/Claudio/Documenti/Thesis/Workloads/MSClaudio/ews/access_log-20110805.csv",
        [],
    )
    x, target = aggregatebymins_sg_ndata(vector[1])

    data = array(target)
    t = array(x)
    data = data.ravel()
    length = len(data)
    print length
    step = 40
    if length % step == 0:
        data.shape = (length / step, step)
    else:
        data.resize((length / step, step))
    max_data = maximum.reduce(data, 1)
    min_data = minimum.reduce(data, 1)

    pylab.plot(t, array(target), "b", label="signal")
    return concatenate((max_data[:, newaxis], min_data[:, newaxis]), 1)
コード例 #20
0
 def __init__(self, data):
     if data.dtype.kind == 'm':
         v = data.view('i8')
         max_str_len = max(len(str(maximum.reduce(v))),
                           len(str(minimum.reduce(v))))
         self.format = '%' + str(max_str_len) + 'd'
コード例 #21
0
ファイル: graphics.py プロジェクト: davidraythompson/hsifind
def get_image_display_data(source, bands=None, **kwargs):
    '''
    Extract RGB data to be displayed from a SpyImage or NumPy array.

    USAGE: rgb = get_image_display_data(source [, bands] [stretch = 1]
                    [stretch_all = 1] [bounds = (lower, upper)] )

    source is the data source and can be either a SpyFile object or a
    NumPy array.  bands is an optional list which specifies the RGB
    channels to display. If bands is not present and source is a SpyFile
    object, it's metadata dict will be checked if it contains a "default
    bands" item.  Otherwise, the first, middle and last band will be
    displayed. If stretch is defined, the contents of rgb will be scaled
    so that the maximum value in the display data will be 1. If
    stretch_all is defined, each color channel will be scaled separately
    so that its maximum value is 1. If bounds is specified, the data will
    be scaled so that lower and upper correspond to 0 and 1, respectively
    . Any values outside of the range (lower, upper) will be clipped.
    '''

    from numpy import take, zeros, repeat, ravel, minimum, maximum, clip, \
        float, int, newaxis
    from spectral import Image
    from exceptions import TypeError

    if not bands:
        bands = []
    if len(bands) != 0 and len(bands) != 1 and len(bands) != 3:
        raise Exception("Invalid number of bands specified.")
    monochrome = 0

    if isinstance(source, Image):
        # Figure out which bands to display
        if len(bands) == 0:
            # No bands specified. What should we show?
            if 'default bands' in source.metadata:
                try:
                    bands = map(int, source.metadata['default bands'])
                except:
                    pass
            elif source.nbands == 1:
                bands = [0]
        if len(bands) == 0:
            # Pick the first, middle, and last bands
            n = source.nbands
            bands = [0, n / 2, n - 1]
        rgb = source.read_bands(bands).astype(float)
    else:
        # It should be a numpy array
        s = source.shape
        if len(s) == 2:
            rgb = source[:, :, newaxis]
        elif (len(s) == 3 and s[2] == 1):
            rgb = source
        elif len(s) == 3:
            if s[2] == 3:
                if len(bands) == 0:
                    # keep data as is.
                    rgb = source.astype(float)
                elif len(bands) == 3:
                    if bands[0] == 0 and bands[1] == 1 and bands[2] == 2:
                        # Same as first 'if', bands just explicit.
                        rgb = source.astype(float)
                    else:
                        rgb = take(source, bands, 2).astype(float)
            elif s[2] > 3 and (len(bands) == 1 or len(bands) == 3):
                rgb = take(source, bands, 2).astype(float)
            else:
                rgb = take(source, [0, s[2] / 2, s[2] - 1], 2).astype(float)
        else:
            raise Exception('Invalid array shape for image display')

    # If it's either color-indexed or monochrome
    if rgb.shape[2] == 1:
        s = rgb.shape
        if "colors" in kwargs:
            rgb = rgb.astype(int)
            rgb3 = zeros((s[0], s[1], 3), int)
            pal = kwargs["colors"]
            for i in range(s[0]):
                for j in range(s[1]):
                    rgb3[i, j] = pal[rgb[i, j, 0]]
            rgb = rgb3
        elif "colorScale" in kwargs and kwargs["colorScale"]:
            # Colors should be generated from the supplied color scale
            # This section assumes rgb colors in the range 0-255.
            rgb = rgb[:, :, 0]
            scale = kwargs["colorScale"]
            if "autoScale" in kwargs and kwargs["autoScale"]:
                scale.set_range(min(rgb.ravel()), max(rgb.ravel()))
            rgb3 = zeros((s[0], s[1], 3), int)
            for i in range(s[0]):
                for j in range(s[1]):
                    rgb3[i, j] = scale(rgb[i, j])
            rgb = rgb3.astype(float) / 255.
        else:
            monochrome = 1
            rgb = repeat(rgb, 3, 2).astype(float)

    if "colors" not in kwargs:
        # Perform any requested color enhancements.
        if "stretch" in kwargs or "bounds" not in kwargs:
            stretch = 1

        if "bounds" in kwargs:
            # Stretch each color within the value bounds
            (lower, upper) = kwargs["bounds"]
            rgb = (rgb - lower) / (upper - lower)
            rgb = clip(rgb, 0, 1)
        elif "stretch_all" in kwargs:
            # Stretch each color over its full range
            for i in range(rgb.shape[2]):
                mmin = minimum.reduce(ravel(rgb[:, :, i]))
                mmax = maximum.reduce(ravel(rgb[:, :, i]))
                rgb[:, :, i] = (rgb[:, :, i] - mmin) / (mmax - mmin)
        elif stretch or ("stretch_all" in kwargs and monochrome):
            # Stretch so highest color channel value is 1
            mmin = minimum.reduce(ravel(rgb))
            mmax = maximum.reduce(ravel(rgb))
            rgb = (rgb - mmin) / (mmax - mmin)

    return rgb
コード例 #22
0
ファイル: graphics.py プロジェクト: Pdgraham/spectral
def get_rgb(source, bands=None, **kwargs):
    '''Extract RGB data for display from a SpyFile object or numpy array.

    USAGE: rgb = get_rgb(source [, bands] [stretch=True]
                         [stretch_all=False] [bounds = (lower, upper)] )

    Arguments:

        `source` (:class:`spectral.SpyFile` or :class:`numpy.ndarray`):

            Data source from which to extract the RGB data.

        `bands` (list of `int`) (optional):

            Optional triplet of indices which specifies the bands to extract
            for the red, green, and blue components, respectively. If this
            arg is not given, SpyFile object, it's metadata dict will be
            checked to see if it contains a "default bands" item.  If it does
            not, then first, middle and last band will be returned.

    Keyword Arguments:

        `stretch` (bool, default True):

            If the `stretch` keyword is True, the RGB values will be scaled
            so the maximum value in the returned array will be 1.

        `stretch_all` (bool, default False):

            If this keyword is True, each color channel will be scaled
            separately such that its maximum value is 1.

        `bounds` (2-tuple of scalars):

            If `bounds` is specified, the data will be scaled so that `lower`
            and `upper` correspond to 0 and 1, respectively. Any values outside
            of the range (`lower`, `upper`) will be clipped.
    '''

    from numpy import (take, zeros, repeat, ravel, minimum, maximum, clip,
                       float, int, newaxis)
    from spectral.spectral import Image
    from exceptions import TypeError

    if not bands:
        bands = []
    if len(bands) != 0 and len(bands) != 1 and len(bands) != 3:
        raise Exception("Invalid number of bands specified.")
    monochrome = 0

    if isinstance(source, Image) and len(source.shape) == 3:
        # Figure out which bands to display
        if len(bands) == 0:
            # No bands specified. What should we show?
            if hasattr(source, 'metadata') and \
              'default bands' in source.metadata:
                try:
                    bands = [int(b) for b in source.metadata['default bands']]
                except:
                    pass
            elif source.shape[-1] == 1:
                bands = [0]
        if len(bands) == 0:
            # Pick the first, middle, and last bands
            n = source.shape[-1]
            bands = [0, n / 2, n - 1]
        rgb = source.read_bands(bands).astype(float)
    else:
        # It should be a numpy array
        s = source.shape
        if len(s) == 2:
            rgb = source[:, :, newaxis]
        elif (len(s) == 3 and s[2] == 1):
            rgb = source
        elif len(s) == 3:
            if s[2] == 3:
                if len(bands) == 0:
                    # keep data as is.
                    rgb = source.astype(float)
                elif len(bands) == 3:
                    if bands[0] == 0 and bands[1] == 1 and bands[2] == 2:
                        # Same as first 'if', bands just explicit.
                        rgb = source.astype(float)
                    else:
                        rgb = take(source, bands, 2).astype(float)
            elif s[2] > 3 and (len(bands) == 1 or len(bands) == 3):
                rgb = take(source, bands, 2).astype(float)
            else:
                rgb = take(source, [0, s[2] / 2, s[2] - 1], 2).astype(float)
        else:
            raise Exception('Invalid array shape for image display')

    if 'colorScale' in kwargs:
        color_scale = kwargs['colorScale']
        warn('Keyword "colorScale" is deprecated. Use "color_scale"',
             UserWarning)
    else:
        color_scale = kwargs.get('color_scale', None)

    if 'autoScale' in kwargs:
        auto_scale = kwargs['autoScale']
        warn('Keyword "autoScale" is deprecated. Use "auto_scale"',
             UserWarning)
    else:
        auto_scale = kwargs.get('auto_scale', False)

    # If it's either color-indexed or monochrome
    if rgb.shape[2] == 1:
        s = rgb.shape
        if "colors" in kwargs:
            rgb = rgb.astype(int)
            pal = kwargs["colors"]
            rgb = pal[rgb[:,:,0]]
        elif color_scale is not None:
            # Colors should be generated from the supplied color scale
            # This section assumes rgb colors in the range 0-255.
            rgb = rgb[:, :, 0]
            scale = color_scale
            if auto_scale:
                scale.set_range(min(rgb.ravel()), max(rgb.ravel()))
            rgb3 = zeros((s[0], s[1], 3), int)
            for i in range(s[0]):
                for j in range(s[1]):
                    rgb3[i, j] = scale(rgb[i, j])
            rgb = rgb3.astype(float) / 255.
        else:
            monochrome = 1
            rgb = repeat(rgb, 3, 2).astype(float)

    if "colors" not in kwargs:
        # Perform any requested color enhancements.
        if "stretch" in kwargs or "bounds" not in kwargs:
            stretch = 1

        if "bounds" in kwargs:
            # Stretch each color within the value bounds
            (lower, upper) = kwargs["bounds"]
            rgb = (rgb - lower) / (upper - lower)
            rgb = clip(rgb, 0, 1)
        elif kwargs.get("stretch_all", False):
            # Stretch each color over its full range
            for i in range(rgb.shape[2]):
                mmin = minimum.reduce(ravel(rgb[:, :, i]))
                mmax = maximum.reduce(ravel(rgb[:, :, i]))
                rgb[:, :, i] = (rgb[:, :, i] - mmin) / (mmax - mmin)
        elif stretch or (kwargs.get("stretch_all", False) and monochrome):
            # Stretch so highest color channel value is 1
            mmin = minimum.reduce(ravel(rgb))
            mmax = maximum.reduce(ravel(rgb))
            rgb = (rgb - mmin) / (mmax - mmin)

    return rgb