def interpolate(agg, low=None, high=None, cmap=None, how='eq_hist'):
    """Convert a 2D DataArray to an image.

    Data is converted to an image either by interpolating between a `low` and
    `high` color [default], or by a specified colormap.

    Parameters
    ----------
    agg : DataArray
    low, high : color name or tuple, optional
        Deprecated. The color for the low and high ends of the scale. Can be
        specified either by name, hexcode, or as a tuple of ``(red, green,
        blue)`` values.
    cmap : list of colors or matplotlib.colors.Colormap, optional
        The colormap to use. Can be either a list of colors (in any of the
        formats described above), or a matplotlib colormap object.
        Default is `["lightblue", "darkblue"]`
    how : str or callable, optional
        The interpolation method to use. Valid strings are 'cbrt' [default],
        'log', 'linear', and 'eq_hist'. 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.
    """
    if not isinstance(agg, xr.DataArray):
        raise TypeError("agg must be instance of DataArray")
    if agg.ndim != 2:
        raise ValueError("agg must be 2D")
    if cmap is not None:
        if low or high:
            raise ValueError("Can't provide both `cmap` and `low` or `high`")
    else:
        # Defaults
        cmap = ['lightblue', 'darkblue']
        if low or high:
            with warnings.catch_warnings():
                warnings.simplefilter('always', DeprecationWarning)
                w = DeprecationWarning("Using `low` and `high` is deprecated. "
                                       "Instead use `cmap=[low, high]`")
                warnings.warn(w)
            cmap = [low or cmap[0], high or cmap[1]]
    how = _normalize_interpolate_how(how)
    data = agg.data
    if np.issubdtype(data.dtype, np.bool_):
        mask = ~data
        interp = data
    else:
        if np.issubdtype(data.dtype, np.integer):
            mask = data == 0
        else:
            mask = np.isnan(data)
        offset = data[~mask].min()
        interp = data - offset
    data = how(interp, mask)
    span = [np.nanmin(data), np.nanmax(data)]
    if isinstance(cmap, Iterator):
        cmap = list(cmap)
    if isinstance(cmap, list):
        rspan, gspan, bspan = np.array(list(zip(*map(rgb, cmap))))
        span = np.linspace(span[0], span[1], len(cmap))
        r = np.interp(data, span, rspan, left=255).astype(np.uint8)
        g = np.interp(data, span, gspan, left=255).astype(np.uint8)
        b = np.interp(data, span, bspan, left=255).astype(np.uint8)
        a = np.where(np.isnan(data), 0, 255).astype(np.uint8)
        img = np.dstack([r, g, b, a]).view(np.uint32).reshape(a.shape)
    elif callable(cmap):
        # Assume callable is matplotlib colormap
        img = cmap((data - span[0])/(span[1] - span[0]), bytes=True)
        img[:, :, 3] = np.where(np.isnan(data), 0, 255).astype(np.uint8)
        img = img.view(np.uint32).reshape(data.shape)
    else:
        raise TypeError("Expected `cmap` of `matplotlib.colors.Colormap` or "
                        "`list`, got: '{0}'".format(type(cmap)))
    return Image(img, coords=agg.coords, dims=agg.dims)
dataset/ETHPy150Open bokeh/datashader/datashader/transfer_functions.py/interpolate/original