def colorize(agg, color_key, how='eq_hist', min_alpha=20):
    """Color a CategoricalAggregate by field.

    Parameters
    ----------
    agg : DataArray
    color_key : dict or iterable
        A mapping of fields to colors. Can be either a ``dict`` mapping from
        field name to colors, or an iterable of colors in the same order as the
        record fields.
    how : str or callable, optional
        The interpolation method to use. Valid strings are 'cbrt' [default],
        'log', and 'linear'. Callables take 2 arguments - a 2-dimensional
        array of magnitudes at each pixel, and a boolean mask array indicating
        missingness. They should return a numeric array of the same shape, with
        `NaN`s where the mask was True.
    min_alpha : float, optional
        The minimum alpha value to use for non-empty pixels, in [0, 255].
    """
    if not isinstance(agg, xr.DataArray):
        raise TypeError("agg must be an instance of DataArray")
    if not agg.ndim == 3:
        raise ValueError("agg must be 3D")
    cats = agg.indexes[agg.dims[-1]]
    if not isinstance(color_key, dict):
        color_key = dict(zip(cats, color_key))
    if len(color_key) != len(cats):
        raise ValueError("Number of colors doesn't match number of fields")
    if not (0 <= min_alpha <= 255):
        raise ValueError("min_alpha must be between 0 and 255")
    colors = [rgb(color_key[c]) for c in cats]
    rs, gs, bs = map(np.array, zip(*colors))
    data = agg.data
    total = data.sum(axis=2)
    r = (data.dot(rs)/total).astype(np.uint8)
    g = (data.dot(gs)/total).astype(np.uint8)
    b = (data.dot(bs)/total).astype(np.uint8)
    offset = total.min()
    mask = np.isnan(total)
    if offset == 0:
        mask = mask | (total <= 0)
        offset = total[total > 0].min()
    a = _normalize_interpolate_how(how)(total - offset, mask)
    a = np.interp(a, [np.nanmin(a), np.nanmax(a)],
                  [min_alpha, 255], left=0, right=255).astype(np.uint8)
    r[mask] = g[mask] = b[mask] = 255
    return Image(np.dstack([r, g, b, a]).view(np.uint32).reshape(a.shape),
                 dims=agg.dims[:-1], coords=list(agg.coords.values())[:-1])
dataset/ETHPy150Open bokeh/datashader/datashader/transfer_functions.py/colorize/original