class_docstr: An abstract canvas representing the space in which to bin.
  
  Parameters
  ----------
  plot_width, plot_height : int, optional
      Width and height of the output aggregate in pixels.
  x_range, y_range : tuple, optional
      A tuple representing the bounds inclusive space ``[min, max]`` along
      the axis.
  x_axis_type, y_axis_type : str, optional
      The type of the axis. Valid options are ``'linear'`` [default], and
      ``'log'``.
class_docstr_tok: ["An","abstract","canvas","representing","the","space","in","which","to","bin",".","Parameters","--","--","--","--","--","plot_width",",","plot_height",":","int",",","optional","Width","and","height","of","the","output","aggregate","in","pixels",".","x_range",",","y_range",":","tuple",",","optional","A","tuple","representing","the","bounds","inclusive","space","``","[","min",",","max","]","``","along","the","axis",".","x_axis_type",",","y_axis_type",":","str",",","optional","The","type","of","the","axis",".","Valid","options","are","``","'linear","'","``","[","default","]",",","and","``","'log","'","``","."]
docstr: Sample a raster dataset by canvas size and bounds.
  
  Handles 2D or 3D xarray DataArrays, assuming that the last two
  array dimensions are the y- and x-axis that are to be
  resampled. If a 3D array is supplied a layer may be specified
  to resample to select the layer along the first dimension to
  resample.
  
  Missing values (those having the value indicated by the
  "nodata" attribute of the raster) are replaced with `NaN` if
  floats, and 0 if int.
  
  Also supports resampling out-of-core DataArrays backed by dask
  Arrays. By default it will try to maintain the same chunksize
  in the output array but a custom chunksize may be provided.
  If there are memory constraints they may be defined using the
  max_mem parameter, which determines how large the chunks in
  memory may be.
  
  Parameters
  ----------
  source : xarray.DataArray or xr.Dataset
      2D or 3D labelled array (if Dataset, the agg reduction must
      define the data variable).
  layer : float
      For a 3D array, value along the z dimension : optional default=None
  ds_method : str (optional)
      Grid cell aggregation method for a possible downsampling.
  us_method : str (optional)
      Grid cell interpolation method for a possible upsampling.
  nan_value : int or float, optional
      Optional nan_value which will be masked out when applying
      the resampling.
  agg : Reduction, optional default=mean()
      Resampling mode when downsampling raster. The supported
      options include: first, last, mean, mode, var, std, min,
      The agg can be specified as either a string name or as a
      reduction function, but note that the function object will
      be used only to extract the agg type (mean, max, etc.) and
      the optional column name; the hardcoded raster code
      supports only a fixed set of reductions and ignores the
      actual code of the provided agg.
  interpolate : str, optional  default=linear
      Resampling mode when upsampling raster.
      options include: nearest, linear.
  chunksize : tuple(int, int) (optional)
      Size of the output chunks. By default this the chunk size is
      inherited from the *src* array.
  max_mem : int (optional)
      The maximum number of bytes that should be loaded into memory
      during the regridding operation.
  
  Returns
  -------
  data : xarray.Dataset
docstr_tok: ["Sample","a","raster","dataset","by","canvas","size","and","bounds",".","Handles","2D","or","3D","xarray","DataArrays",",","assuming","that","the","last","two","array","dimensions","are","the","y-","and","x-axis","that","are","to","be","resampled",".","If","a","3D","array","is","supplied","a","layer","may","be","specified","to","resample","to","select","the","layer","along","the","first","dimension","to","resample",".","Missing","values","(","those","having","the","value","indicated","by","the","''","nodata","''","attribute","of","the","raster",")","are","replaced","with","`","NaN","`","if","floats",",","and","0","if","int",".","Also","supports","resampling","out-of-core","DataArrays","backed","by","dask","Arrays",".","By","default","it","will","try","to","maintain","the","same","chunksize","in","the","output","array","but","a","custom","chunksize","may","be","provided",".","If","there","are","memory","constraints","they","may","be","defined","using","the","max_mem","parameter",",","which","determines","how","large","the","chunks","in","memory","may","be",".","Parameters","--","--","--","--","--","source",":","xarray.DataArray","or","xr.Dataset","2D","or","3D","labelled","array","(","if","Dataset",",","the","agg","reduction","must","define","the","data","variable",")",".","layer",":","float","For","a","3D","array",",","value","along","the","z","dimension",":","optional","default=None","ds_method",":","str","(","optional",")","Grid","cell","aggregation","method","for","a","possible","downsampling",".","us_method",":","str","(","optional",")","Grid","cell","interpolation","method","for","a","possible","upsampling",".","nan_value",":","int","or","float",",","optional","Optional","nan_value","which","will","be","masked","out","when","applying","the","resampling",".","agg",":","Reduction",",","optional","default=mean","(",")","Resampling","mode","when","downsampling","raster",".","The","supported","options","include",":","first",",","last",",","mean",",","mode",",","var",",","std",",","min",",","The","agg","can","be","specified","as","either","a","string","name","or","as","a","reduction","function",",","but","note","that","the","function","object","will","be","used","only","to","extract","the","agg","type","(","mean",",","max",",","etc",".",")","and","the","optional","column","name",";","the","hardcoded","raster","code","supports","only","a","fixed","set","of","reductions","and","ignores","the","actual","code","of","the","provided","agg",".","interpolate",":","str",",","optional","default=linear","Resampling","mode","when","upsampling","raster",".","options","include",":","nearest",",","linear",".","chunksize",":","tuple","(","int",",","int",")","(","optional",")","Size","of","the","output","chunks",".","By","default","this","the","chunk","size","is","inherited","from","the","*","src","*","array",".","max_mem",":","int","(","optional",")","The","maximum","number","of","bytes","that","should","be","loaded","into","memory","during","the","regridding","operation",".","Returns","--","--","--","-","data",":","xarray.Dataset"]
code: def raster(
      self,
      source,
      layer=None,
      upsample_method="linear",  # Deprecated as of datashader=0.6.4
      downsample_method=rd.mean(),  # Deprecated as of datashader=0.6.4
      nan_value=None,
      agg=None,
      interpolate=None,
      chunksize=None,
      max_mem=None,
  ):
      """Sample a raster dataset by canvas size and bounds.
  
      Handles 2D or 3D xarray DataArrays, assuming that the last two
      array dimensions are the y- and x-axis that are to be
      resampled. If a 3D array is supplied a layer may be specified
      to resample to select the layer along the first dimension to
      resample.
  
      Missing values (those having the value indicated by the
      "nodata" attribute of the raster) are replaced with `NaN` if
      floats, and 0 if int.
  
      Also supports resampling out-of-core DataArrays backed by dask
      Arrays. By default it will try to maintain the same chunksize
      in the output array but a custom chunksize may be provided.
      If there are memory constraints they may be defined using the
      max_mem parameter, which determines how large the chunks in
      memory may be.
  
      Parameters
      ----------
      source : xarray.DataArray or xr.Dataset
          2D or 3D labelled array (if Dataset, the agg reduction must
          define the data variable).
      layer : float
          For a 3D array, value along the z dimension : optional default=None
      ds_method : str (optional)
          Grid cell aggregation method for a possible downsampling.
      us_method : str (optional)
          Grid cell interpolation method for a possible upsampling.
      nan_value : int or float, optional
          Optional nan_value which will be masked out when applying
          the resampling.
      agg : Reduction, optional default=mean()
          Resampling mode when downsampling raster. The supported
          options include: first, last, mean, mode, var, std, min,
          The agg can be specified as either a string name or as a
          reduction function, but note that the function object will
          be used only to extract the agg type (mean, max, etc.) and
          the optional column name; the hardcoded raster code
          supports only a fixed set of reductions and ignores the
          actual code of the provided agg.
      interpolate : str, optional  default=linear
          Resampling mode when upsampling raster.
          options include: nearest, linear.
      chunksize : tuple(int, int) (optional)
          Size of the output chunks. By default this the chunk size is
          inherited from the *src* array.
      max_mem : int (optional)
          The maximum number of bytes that should be loaded into memory
          during the regridding operation.
  
      Returns
      -------
      data : xarray.Dataset
      """
      # For backwards compatibility
      if agg is None:
          agg = downsample_method
      if interpolate is None:
          interpolate = upsample_method
  
      upsample_methods = ["nearest", "linear"]
  
      downsample_methods = {
          "first": "first",
          rd.first: "first",
          "last": "last",
          rd.last: "last",
          "mode": "mode",
          rd.mode: "mode",
          "mean": "mean",
          rd.mean: "mean",
          "var": "var",
          rd.var: "var",
          "std": "std",
          rd.std: "std",
          "min": "min",
          rd.min: "min",
          "max": "max",
          rd.max: "max",
      }
  
      if interpolate not in upsample_methods:
          raise ValueError(
              "Invalid interpolate method: options include {}".format(
                  upsample_methods
              )
          )
  
      if not isinstance(source, (DataArray, Dataset)):
          raise ValueError(
              "Expected xarray DataArray or Dataset as "
              "the data source, found %s." % type(source).__name__
          )
  
      column = None
      if isinstance(agg, rd.Reduction):
          agg, column = type(agg), agg.column
          if (
              isinstance(source, DataArray)
              and column is not None
              and source.name != column
          ):
              agg_repr = "%s(%r)" % (agg.__name__, column)
              raise ValueError(
                  "DataArray name %r does not match "
                  "supplied reduction %s." % (source.name, agg_repr)
              )
  
      if isinstance(source, Dataset):
          data_vars = list(source.data_vars)
          if column is None:
              raise ValueError(
                  "When supplying a Dataset the agg reduction "
                  "must specify the variable to aggregate. "
                  "Available data_vars include: %r." % data_vars
              )
          elif column not in source.data_vars:
              raise KeyError(
                  "Supplied reduction column %r not found "
                  "in Dataset, expected one of the following "
                  "data variables: %r." % (column, data_vars)
              )
          source = source[column]
  
      if agg not in downsample_methods.keys():
          raise ValueError(
              "Invalid aggregation method: options include {}".format(
                  list(downsample_methods.keys())
              )
          )
      ds_method = downsample_methods[agg]
  
      if source.ndim not in [2, 3]:
          raise ValueError(
              "Raster aggregation expects a 2D or 3D "
              "DataArray, found %s dimensions" % source.ndim
          )
  
      res = calc_res(source)
      ydim, xdim = source.dims[-2:]
      xvals, yvals = source[xdim].values, source[ydim].values
      left, bottom, right, top = calc_bbox(xvals, yvals, res)
      if layer is not None:
          source = source.sel(**{source.dims[0]: layer})
      array = orient_array(source, res)
  
      if nan_value is not None:
          mask = array == nan_value
          array = np.ma.masked_array(
              array, mask=mask, fill_value=nan_value
          )
          fill_value = nan_value
      elif np.issubdtype(source.dtype, np.integer):
          fill_value = 0
      else:
          fill_value = np.nan
  
      if self.x_range is None:
          self.x_range = (left, right)
      if self.y_range is None:
          self.y_range = (bottom, top)
  
      # window coordinates
      xmin = max(self.x_range[0], left)
      ymin = max(self.y_range[0], bottom)
      xmax = min(self.x_range[1], right)
      ymax = min(self.y_range[1], top)
  
      width_ratio = min(
          (xmax - xmin) / (self.x_range[1] - self.x_range[0]), 1
      )
      height_ratio = min(
          (ymax - ymin) / (self.y_range[1] - self.y_range[0]), 1
      )
  
      if np.isclose(width_ratio, 0) or np.isclose(height_ratio, 0):
          raise ValueError(
              "Canvas x_range or y_range values do not match closely enough "
              "with the data source to be able to accurately rasterize. "
              "Please provide ranges that are more accurate."
          )
  
      w = max(int(round(self.plot_width * width_ratio)), 1)
      h = max(int(round(self.plot_height * height_ratio)), 1)
      cmin, cmax = get_indices(xmin, xmax, xvals, res[0])
      rmin, rmax = get_indices(ymin, ymax, yvals, res[1])
  
      kwargs = dict(
          w=w,
          h=h,
          ds_method=ds_method,
          us_method=interpolate,
          fill_value=fill_value,
      )
      if array.ndim == 2:
          source_window = array[rmin : rmax + 1, cmin : cmax + 1]
          if ds_method in ["var", "std"]:
              source_window = source_window.astype("f")
          if isinstance(source_window, da.Array):
              data = resample_2d_distributed(
                  source_window,
                  chunksize=chunksize,
                  max_mem=max_mem,
                  **kwargs,
              )
          else:
              data = resample_2d(source_window, **kwargs)
          layers = 1
      else:
          source_window = array[:, rmin : rmax + 1, cmin : cmax + 1]
          if ds_method in ["var", "std"]:
              source_window = source_window.astype("f")
          arrays = []
          for arr in source_window:
              if isinstance(arr, da.Array):
                  arr = resample_2d_distributed(
                      arr,
                      chunksize=chunksize,
                      max_mem=max_mem,
                      **kwargs,
                  )
              else:
                  arr = resample_2d(arr, **kwargs)
              arrays.append(arr)
          data = np.dstack(arrays)
          layers = len(arrays)
  
      if w != self.plot_width or h != self.plot_height:
          num_height = self.plot_height - h
          num_width = self.plot_width - w
  
          lpad = xmin - self.x_range[0]
          rpad = self.x_range[1] - xmax
          lpct = lpad / (lpad + rpad) if lpad + rpad > 0 else 0
          left = max(int(np.ceil(num_width * lpct)), 0)
          right = max(num_width - left, 0)
          lshape, rshape = (self.plot_height, left), (
              self.plot_height,
              right,
          )
          if layers > 1:
              lshape, rshape = lshape + (layers,), rshape + (layers,)
          left_pad = np.full(lshape, fill_value, source_window.dtype)
          right_pad = np.full(rshape, fill_value, source_window.dtype)
  
          tpad = ymin - self.y_range[0]
          bpad = self.y_range[1] - ymax
          tpct = tpad / (tpad + bpad) if tpad + bpad > 0 else 0
          top = max(int(np.ceil(num_height * tpct)), 0)
          bottom = max(num_height - top, 0)
          tshape, bshape = (top, w), (bottom, w)
          if layers > 1:
              tshape, bshape = tshape + (layers,), bshape + (layers,)
          top_pad = np.full(tshape, fill_value, source_window.dtype)
          bottom_pad = np.full(bshape, fill_value, source_window.dtype)
  
          concat = (
              da.concatenate
              if isinstance(data, da.Array)
              else np.concatenate
          )
          arrays = (top_pad, data) if top_pad.shape[0] > 0 else (data,)
          if bottom_pad.shape[0] > 0:
              arrays += (bottom_pad,)
          data = (
              concat(arrays, axis=0) if len(arrays) > 1 else arrays[0]
          )
          arrays = (
              (left_pad, data) if left_pad.shape[1] > 0 else (data,)
          )
          if right_pad.shape[1] > 0:
              arrays += (right_pad,)
          data = (
              concat(arrays, axis=1) if len(arrays) > 1 else arrays[0]
          )
  
      # Reorient array to original orientation
      if res[1] > 0:
          data = data[::-1]
      if res[0] < 0:
          data = data[:, ::-1]
  
      # Compute DataArray metadata
  
      # To avoid floating point representation error,
      # do not recompute x coords if same x_range and same plot_width,
      # do not recompute y coords if same y_range and same plot_height
      close_x = (
          np.allclose([left, right], self.x_range)
          and np.size(xvals) == self.plot_width
      )
      close_y = (
          np.allclose([bottom, top], self.y_range)
          and np.size(yvals) == self.plot_height
      )
  
      if close_x:
          xs = xvals
      else:
          x_st = self.x_axis.compute_scale_and_translate(
              self.x_range, self.plot_width
          )
          xs = self.x_axis.compute_index(x_st, self.plot_width)
          if res[0] < 0:
              xs = xs[::-1]
  
      if close_y:
          ys = yvals
      else:
          y_st = self.y_axis.compute_scale_and_translate(
              self.y_range, self.plot_height
          )
          ys = self.y_axis.compute_index(y_st, self.plot_height)
          if res[1] > 0:
              ys = ys[::-1]
  
      coords = {xdim: xs, ydim: ys}
      dims = [ydim, xdim]
      attrs = dict(
          res=res[0], x_range=self.x_range, y_range=self.y_range
      )
  
      # Find nodata value if available in any of the common conventional locations
      # See https://corteva.github.io/rioxarray/stable/getting_started/nodata_management.html
      # and https://github.com/holoviz/datashader/issues/990
      for a in [
          "_FillValue",
          "missing_value",
          "fill_value",
          "nodata",
          "NODATA",
      ]:
          if a in source.attrs:
              attrs["nodata"] = source.attrs[a]
              break
      if "nodata" not in attrs:
          try:
              attrs["nodata"] = source.attrs["nodatavals"][0]
          except Exception:
              pass
  
      # Handle DataArray with layers
      if data.ndim == 3:
          data = data.transpose([2, 0, 1])
          layer_dim = source.dims[0]
          coords[layer_dim] = source.coords[layer_dim]
          dims = [layer_dim] + dims
      return DataArray(data, coords=coords, dims=dims, attrs=attrs)
  
imports: from __future__ import annotations
  from numbers import Number
  from math import log10
  import warnings
  import numpy
  import pandas
  import dask.dataframe
  import dask.array
  from xarray import DataArray, Dataset
  from .utils import Dispatcher, ngjit, calc_res, calc_bbox, orient_array, dshape_from_xarray_dataset
  from .utils import get_indices, dshape_from_pandas, dshape_from_dask
  from .utils import Expr
  from .resampling import resample_2d, resample_2d_distributed
  from .None import reductions
label_desc: Use image node_id 8 for calling the Canvas obj's underlying member method code with example usage: obj.raster(source, layer, upsample_method, downsample_method, nan_value, agg, interpolate, chunksize, max_mem) and returns: DataArray