class_docstr: Raster is a basic 2D element type for presenting either numpy or
  dask arrays as two dimensional raster images.
  
  Arrays with a shape of (N,M) are valid inputs for Raster whereas
  subclasses of Raster (e.g. RGB) may also accept 3D arrays
  containing channel information.
  
  Raster does not support slicing like the Image or RGB subclasses
  and the extents are in matrix coordinates if not explicitly
  specified.
class_docstr_tok: ["Raster","is","a","basic","2D","element","type","for","presenting","either","numpy","or","dask","arrays","as","two","dimensional","raster","images",".","Arrays","with","a","shape","of","(","N",",","M",")","are","valid","inputs","for","Raster","whereas","subclasses","of","Raster","(","e.g",".","RGB",")","may","also","accept","3D","arrays","containing","channel","information",".","Raster","does","not","support","slicing","like","the","Image","or","RGB","subclasses","and","the","extents","are","in","matrix","coordinates","if","not","explicitly","specified","."]
docstr: Sample the Raster along one or both of its dimensions,
  returning a reduced dimensionality type, which is either
  a ItemTable, Curve or Scatter. If two dimension samples
  and a new_xaxis is provided the sample will be the value
  of the sampled unit indexed by the value in the new_xaxis
  tuple.
docstr_tok: ["Sample","the","Raster","along","one","or","both","of","its","dimensions",",","returning","a","reduced","dimensionality","type",",","which","is","either","a","ItemTable",",","Curve","or","Scatter",".","If","two","dimension","samples","and","a","new_xaxis","is","provided","the","sample","will","be","the","value","of","the","sampled","unit","indexed","by","the","value","in","the","new_xaxis","tuple","."]
code: def sample(self, samples=None, bounds=None, **sample_values):
      """
      Sample the Raster along one or both of its dimensions,
      returning a reduced dimensionality type, which is either
      a ItemTable, Curve or Scatter. If two dimension samples
      and a new_xaxis is provided the sample will be the value
      of the sampled unit indexed by the value in the new_xaxis
      tuple.
      """
      if samples is None:
          samples = []
      if isinstance(samples, tuple):
          X, Y = samples
          samples = zip(X, Y)
  
      params = dict(
          self.param.values(onlychanged=True), vdims=self.vdims
      )
      if len(sample_values) == self.ndims or len(samples):
          if not len(samples):
              samples = zip(
                  *[
                      c if isinstance(c, list) else [c]
                      for _, c in sorted(
                          [
                              (self.get_dimension_index(k), v)
                              for k, v in sample_values.items()
                          ]
                      )
                  ]
              )
          table_data = [
              c + (self._zdata[self._coord2matrix(c)],) for c in samples
          ]
          params["kdims"] = self.kdims
          return Table(table_data, **params)
      else:
          dimension, sample_coord = next(iter(sample_values.items()))
          if isinstance(sample_coord, slice):
              raise ValueError(
                  "Raster sampling requires coordinates not slices,"
                  "use regular slicing syntax."
              )
          # Indices inverted for indexing
          sample_ind = self.get_dimension_index(dimension)
          if sample_ind is None:
              raise Exception(
                  f"Dimension {dimension} not found during sampling"
              )
          other_dimension = [
              d for i, d in enumerate(self.kdims) if i != sample_ind
          ]
  
          # Generate sample slice
          sample = [slice(None) for i in range(self.ndims)]
          coord_fn = (
              (lambda v: (v, 0))
              if not sample_ind
              else (lambda v: (0, v))
          )
          sample[sample_ind] = self._coord2matrix(
              coord_fn(sample_coord)
          )[abs(sample_ind - 1)]
  
          # Sample data
          x_vals = self.dimension_values(other_dimension[0].name, False)
          ydata = self._zdata[tuple(sample[::-1])]
          if hasattr(self, "bounds") and sample_ind == 0:
              ydata = ydata[::-1]
          data = list(zip(x_vals, ydata))
          params["kdims"] = other_dimension
          return Curve(data, **params)
  
imports: import colorsys
  from copy import deepcopy
  from operator import itemgetter
  import numpy
  import param
  from ..core import Dataset, Dimension, Element2D, Overlay, config, util
  from ..core.boundingregion import BoundingBox, BoundingRegion
  from ..core.data import ImageInterface
  from ..core.data.interface import DataError
  from ..core.dimension import dimension_name
  from ..core.sheetcoords import SheetCoordinateSystem, Slice
  from .chart import Curve
  from .geom import Selection2DExpr
  from .graphs import TriMesh
  from .tabular import Table
  from .util import categorical_aggregate2d, compute_slice_bounds
label_desc: Use image node_id 5 for calling the Raster obj's underlying member method code with example usage: obj.sample(samples, bounds) and returns: Table, Curve