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: Compute a reduction by pixel, mapping data to pixels as one or
  more lines.
  
  For aggregates that take in extra fields, the interpolated bins will
  receive the fields from the previous point. In pseudocode:
  
  >>> for i in range(len(rows) - 1):    # doctest: +SKIP
  ...     row0 = rows[i]
  ...     row1 = rows[i + 1]
  ...     for xi, yi in interpolate(row0.x, row0.y, row1.x, row1.y):
  ...         add_to_aggregate(xi, yi, row0)
  
  Parameters
  ----------
  source : pandas.DataFrame, dask.DataFrame, or xarray.DataArray/Dataset
      The input datasource.
  x, y : str or number or list or tuple or np.ndarray
      Specification of the x and y coordinates of each vertex
      * str or number: Column labels in source
      * list or tuple: List or tuple of column labels in source
      * np.ndarray: When axis=1, a literal array of the
        coordinates to be used for every row
  agg : Reduction, optional
      Reduction to compute. Default is ``any()``.
  axis : 0 or 1, default 0
      Axis in source to draw lines along
      * 0: Draw lines using data from the specified columns across
           all rows in source
      * 1: Draw one line per row in source using data from the
           specified columns
  geometry : str
      Column name of a LinesArray of the coordinates of each line. If provided,
      the x and y arguments may not also be provided.
  line_width : number, optional
      Width of the line to draw, in pixels. If zero, the
      default, lines are drawn using a simple algorithm with a
      blocky single-pixel width based on whether the line passes
      through each pixel or does not. If greater than one, lines
      are drawn with the specified width using a slower and
      more complex antialiasing algorithm with fractional values
      along each edge, so that lines have a more uniform visual
      appearance across all angles. Line widths between 0 and 1
      effectively use a line_width of 1 pixel but with a
      proportionate reduction in the strength of each pixel,
      approximating the visual appearance of a subpixel line
      width.
  antialias : bool, optional
      This option is kept for backward compatibility only.
      ``True`` is equivalent to ``line_width=1`` and
      ``False`` (the default) to ``line_width=0``. Do not specify
      both ``antialias`` and ``line_width`` in the same call as a
      ``ValueError`` will be raised if they disagree.
  
  Examples
  --------
  Define a canvas and a pandas DataFrame with 6 rows
  >>> import pandas as pd  # doctest: +SKIP
  ... import numpy as np
  ... import datashader as ds
  ... from datashader import Canvas
  ... import datashader.transfer_functions as tf
  ... cvs = Canvas()
  ... df = pd.DataFrame({
  ...    'A1': [1, 1.5, 2, 2.5, 3, 4],
  ...    'A2': [1.5, 2, 3, 3.2, 4, 5],
  ...    'B1': [10, 12, 11, 14, 13, 15],
  ...    'B2': [11, 9, 10, 7, 8, 12],
  ... }, dtype='float64')
  
  Aggregate one line across all rows, with coordinates df.A1 by df.B1
  >>> agg = cvs.line(df, x='A1', y='B1', axis=0)  # doctest: +SKIP
  ... tf.spread(tf.shade(agg))
  
  Aggregate two lines across all rows. The first with coordinates
  df.A1 by df.B1 and the second with coordinates df.A2 by df.B2
  >>> agg = cvs.line(df, x=['A1', 'A2'], y=['B1', 'B2'], axis=0)  # doctest: +SKIP
  ... tf.spread(tf.shade(agg))
  
  Aggregate two lines across all rows where the lines share the same
  x coordinates. The first line will have coordinates df.A1 by df.B1
  and the second will have coordinates df.A1 by df.B2
  >>> agg = cvs.line(df, x='A1', y=['B1', 'B2'], axis=0)  # doctest: +SKIP
  ... tf.spread(tf.shade(agg))
  
  Aggregate 6 length-2 lines, one per row, where the ith line has
  coordinates [df.A1[i], df.A2[i]] by [df.B1[i], df.B2[i]]
  >>> agg = cvs.line(df, x=['A1', 'A2'], y=['B1', 'B2'], axis=1)  # doctest: +SKIP
  ... tf.spread(tf.shade(agg))
  
  Aggregate 6 length-4 lines, one per row, where the x coordinates
  of every line are [0, 1, 2, 3] and the y coordinates of the ith line
  are [df.A1[i], df.A2[i], df.B1[i], df.B2[i]].
  >>> agg = cvs.line(df,  # doctest: +SKIP
  ...                x=np.arange(4),
  ...                y=['A1', 'A2', 'B1', 'B2'],
  ...                axis=1)
  ... tf.spread(tf.shade(agg))
  
  Aggregate RaggedArrays of variable length lines, one per row
  (requires pandas >= 0.24.0)
  >>> df_ragged = pd.DataFrame({  # doctest: +SKIP
  ...    'A1': pd.array([
  ...        [1, 1.5], [2, 2.5, 3], [1.5, 2, 3, 4], [3.2, 4, 5]],
  ...        dtype='Ragged[float32]'),
  ...    'B1': pd.array([
  ...        [10, 12], [11, 14, 13], [10, 7, 9, 10], [7, 8, 12]],
  ...        dtype='Ragged[float32]'),
  ...    'group': pd.Categorical([0, 1, 2, 1])
  ... })
  ...
  ... agg = cvs.line(df_ragged, x='A1', y='B1', axis=1)
  ... tf.spread(tf.shade(agg))
  
  Aggregate RaggedArrays of variable length lines by group column,
  one per row (requires pandas >= 0.24.0)
  >>> agg = cvs.line(df_ragged, x='A1', y='B1',  # doctest: +SKIP
  ...                agg=ds.count_cat('group'), axis=1)
  ... tf.spread(tf.shade(agg))
docstr_tok: ["Compute","a","reduction","by","pixel",",","mapping","data","to","pixels","as","one","or","more","lines",".","For","aggregates","that","take","in","extra","fields",",","the","interpolated","bins","will","receive","the","fields","from","the","previous","point",".","In","pseudocode",":",">",">",">","for","i","in","range","(","len","(","rows",")","-","1",")",":","#","doctest",":","+SKIP","...","row0","=","rows","[","i","]","...","row1","=","rows","[","i","+","1","]","...","for","xi",",","yi","in","interpolate","(","row0.x",",","row0.y",",","row1.x",",","row1.y",")",":","...","add_to_aggregate","(","xi",",","yi",",","row0",")","Parameters","--","--","--","--","--","source",":","pandas.DataFrame",",","dask.DataFrame",",","or","xarray.DataArray\/Dataset","The","input","datasource",".","x",",","y",":","str","or","number","or","list","or","tuple","or","np.ndarray","Specification","of","the","x","and","y","coordinates","of","each","vertex","*","str","or","number",":","Column","labels","in","source","*","list","or","tuple",":","List","or","tuple","of","column","labels","in","source","*","np.ndarray",":","When","axis=1",",","a","literal","array","of","the","coordinates","to","be","used","for","every","row","agg",":","Reduction",",","optional","Reduction","to","compute",".","Default","is","``","any","(",")","``",".","axis",":","0","or","1",",","default","0","Axis","in","source","to","draw","lines","along","*","0",":","Draw","lines","using","data","from","the","specified","columns","across","all","rows","in","source","*","1",":","Draw","one","line","per","row","in","source","using","data","from","the","specified","columns","geometry",":","str","Column","name","of","a","LinesArray","of","the","coordinates","of","each","line",".","If","provided",",","the","x","and","y","arguments","may","not","also","be","provided",".","line_width",":","number",",","optional","Width","of","the","line","to","draw",",","in","pixels",".","If","zero",",","the","default",",","lines","are","drawn","using","a","simple","algorithm","with","a","blocky","single-pixel","width","based","on","whether","the","line","passes","through","each","pixel","or","does","not",".","If","greater","than","one",",","lines","are","drawn","with","the","specified","width","using","a","slower","and","more","complex","antialiasing","algorithm","with","fractional","values","along","each","edge",",","so","that","lines","have","a","more","uniform","visual","appearance","across","all","angles",".","Line","widths","between","0","and","1","effectively","use","a","line_width","of","1","pixel","but","with","a","proportionate","reduction","in","the","strength","of","each","pixel",",","approximating","the","visual","appearance","of","a","subpixel","line","width",".","antialias",":","bool",",","optional","This","option","is","kept","for","backward","compatibility","only",".","``","True","``","is","equivalent","to","``","line_width=1","``","and","``","False","``","(","the","default",")","to","``","line_width=0","``",".","Do","not","specify","both","``","antialias","``","and","``","line_width","``","in","the","same","call","as","a","``","ValueError","``","will","be","raised","if","they","disagree",".","Examples","--","--","--","--","Define","a","canvas","and","a","pandas","DataFrame","with","6","rows",">",">",">","import","pandas","as","pd","#","doctest",":","+SKIP","...","import","numpy","as","np","...","import","datashader","as","ds","...","from","datashader","import","Canvas","...","import","datashader.transfer_functions","as","tf","...","cvs","=","Canvas","(",")","...","df","=","pd.DataFrame","(","{","...","'A1","'",":","[","1",",","1.5",",","2",",","2.5",",","3",",","4","]",",","...","'A2","'",":","[","1.5",",","2",",","3",",","3.2",",","4",",","5","]",",","...","'B1","'",":","[","10",",","12",",","11",",","14",",","13",",","15","]",",","...","'B2","'",":","[","11",",","9",",","10",",","7",",","8",",","12","]",",","...","}",",","dtype='float64","'",")","Aggregate","one","line","across","all","rows",",","with","coordinates","df.A1","by","df.B1",">",">",">","agg","=","cvs.line","(","df",",","x='A1","'",",","y='B1","'",",","axis=0",")","#","doctest",":","+SKIP","...","tf.spread","(","tf.shade","(","agg",")",")","Aggregate","two","lines","across","all","rows",".","The","first","with","coordinates","df.A1","by","df.B1","and","the","second","with","coordinates","df.A2","by","df.B2",">",">",">","agg","=","cvs.line","(","df",",","x=","[","'A1","'",",","'A2","'","]",",","y=","[","'B1","'",",","'B2","'","]",",","axis=0",")","#","doctest",":","+SKIP","...","tf.spread","(","tf.shade","(","agg",")",")","Aggregate","two","lines","across","all","rows","where","the","lines","share","the","same","x","coordinates",".","The","first","line","will","have","coordinates","df.A1","by","df.B1","and","the","second","will","have","coordinates","df.A1","by","df.B2",">",">",">","agg","=","cvs.line","(","df",",","x='A1","'",",","y=","[","'B1","'",",","'B2","'","]",",","axis=0",")","#","doctest",":","+SKIP","...","tf.spread","(","tf.shade","(","agg",")",")","Aggregate","6","length-2","lines",",","one","per","row",",","where","the","ith","line","has","coordinates","[","df.A1","[","i","]",",","df.A2","[","i","]","]","by","[","df.B1","[","i","]",",","df.B2","[","i","]","]",">",">",">","agg","=","cvs.line","(","df",",","x=","[","'A1","'",",","'A2","'","]",",","y=","[","'B1","'",",","'B2","'","]",",","axis=1",")","#","doctest",":","+SKIP","...","tf.spread","(","tf.shade","(","agg",")",")","Aggregate","6","length-4","lines",",","one","per","row",",","where","the","x","coordinates","of","every","line","are","[","0",",","1",",","2",",","3","]","and","the","y","coordinates","of","the","ith","line","are","[","df.A1","[","i","]",",","df.A2","[","i","]",",","df.B1","[","i","]",",","df.B2","[","i","]","]",".",">",">",">","agg","=","cvs.line","(","df",",","#","doctest",":","+SKIP","...","x=np.arange","(","4",")",",","...","y=","[","'A1","'",",","'A2","'",",","'B1","'",",","'B2","'","]",",","...","axis=1",")","...","tf.spread","(","tf.shade","(","agg",")",")","Aggregate","RaggedArrays","of","variable","length","lines",",","one","per","row","(","requires","pandas",">","=","0.24.0",")",">",">",">","df_ragged","=","pd.DataFrame","(","{","#","doctest",":","+SKIP","...","'A1","'",":","pd.array","(","[","...","[","1",",","1.5","]",",","[","2",",","2.5",",","3","]",",","[","1.5",",","2",",","3",",","4","]",",","[","3.2",",","4",",","5","]","]",",","...","dtype='Ragged","[","float32","]","'",")",",","...","'B1","'",":","pd.array","(","[","...","[","10",",","12","]",",","[","11",",","14",",","13","]",",","[","10",",","7",",","9",",","10","]",",","[","7",",","8",",","12","]","]",",","...","dtype='Ragged","[","float32","]","'",")",",","...","'group","'",":","pd.Categorical","(","[","0",",","1",",","2",",","1","]",")","...","}",")","...","...","agg","=","cvs.line","(","df_ragged",",","x='A1","'",",","y='B1","'",",","axis=1",")","...","tf.spread","(","tf.shade","(","agg",")",")","Aggregate","RaggedArrays","of","variable","length","lines","by","group","column",",","one","per","row","(","requires","pandas",">","=","0.24.0",")",">",">",">","agg","=","cvs.line","(","df_ragged",",","x='A1","'",",","y='B1","'",",","#","doctest",":","+SKIP","...","agg=ds.count_cat","(","'group","'",")",",","axis=1",")","...","tf.spread","(","tf.shade","(","agg",")",")"]
code: def line(
      self,
      source,
      x=None,
      y=None,
      agg=None,
      axis=0,
      geometry=None,
      line_width=0,
      antialias=False,
  ):
      """Compute a reduction by pixel, mapping data to pixels as one or
      more lines.
  
      For aggregates that take in extra fields, the interpolated bins will
      receive the fields from the previous point. In pseudocode:
  
      >>> for i in range(len(rows) - 1):    # doctest: +SKIP
      ...     row0 = rows[i]
      ...     row1 = rows[i + 1]
      ...     for xi, yi in interpolate(row0.x, row0.y, row1.x, row1.y):
      ...         add_to_aggregate(xi, yi, row0)
  
      Parameters
      ----------
      source : pandas.DataFrame, dask.DataFrame, or xarray.DataArray/Dataset
          The input datasource.
      x, y : str or number or list or tuple or np.ndarray
          Specification of the x and y coordinates of each vertex
          * str or number: Column labels in source
          * list or tuple: List or tuple of column labels in source
          * np.ndarray: When axis=1, a literal array of the
            coordinates to be used for every row
      agg : Reduction, optional
          Reduction to compute. Default is ``any()``.
      axis : 0 or 1, default 0
          Axis in source to draw lines along
          * 0: Draw lines using data from the specified columns across
               all rows in source
          * 1: Draw one line per row in source using data from the
               specified columns
      geometry : str
          Column name of a LinesArray of the coordinates of each line. If provided,
          the x and y arguments may not also be provided.
      line_width : number, optional
          Width of the line to draw, in pixels. If zero, the
          default, lines are drawn using a simple algorithm with a
          blocky single-pixel width based on whether the line passes
          through each pixel or does not. If greater than one, lines
          are drawn with the specified width using a slower and
          more complex antialiasing algorithm with fractional values
          along each edge, so that lines have a more uniform visual
          appearance across all angles. Line widths between 0 and 1
          effectively use a line_width of 1 pixel but with a
          proportionate reduction in the strength of each pixel,
          approximating the visual appearance of a subpixel line
          width.
      antialias : bool, optional
          This option is kept for backward compatibility only.
          ``True`` is equivalent to ``line_width=1`` and
          ``False`` (the default) to ``line_width=0``. Do not specify
          both ``antialias`` and ``line_width`` in the same call as a
          ``ValueError`` will be raised if they disagree.
  
      Examples
      --------
      Define a canvas and a pandas DataFrame with 6 rows
      >>> import pandas as pd  # doctest: +SKIP
      ... import numpy as np
      ... import datashader as ds
      ... from datashader import Canvas
      ... import datashader.transfer_functions as tf
      ... cvs = Canvas()
      ... df = pd.DataFrame({
      ...    'A1': [1, 1.5, 2, 2.5, 3, 4],
      ...    'A2': [1.5, 2, 3, 3.2, 4, 5],
      ...    'B1': [10, 12, 11, 14, 13, 15],
      ...    'B2': [11, 9, 10, 7, 8, 12],
      ... }, dtype='float64')
  
      Aggregate one line across all rows, with coordinates df.A1 by df.B1
      >>> agg = cvs.line(df, x='A1', y='B1', axis=0)  # doctest: +SKIP
      ... tf.spread(tf.shade(agg))
  
      Aggregate two lines across all rows. The first with coordinates
      df.A1 by df.B1 and the second with coordinates df.A2 by df.B2
      >>> agg = cvs.line(df, x=['A1', 'A2'], y=['B1', 'B2'], axis=0)  # doctest: +SKIP
      ... tf.spread(tf.shade(agg))
  
      Aggregate two lines across all rows where the lines share the same
      x coordinates. The first line will have coordinates df.A1 by df.B1
      and the second will have coordinates df.A1 by df.B2
      >>> agg = cvs.line(df, x='A1', y=['B1', 'B2'], axis=0)  # doctest: +SKIP
      ... tf.spread(tf.shade(agg))
  
      Aggregate 6 length-2 lines, one per row, where the ith line has
      coordinates [df.A1[i], df.A2[i]] by [df.B1[i], df.B2[i]]
      >>> agg = cvs.line(df, x=['A1', 'A2'], y=['B1', 'B2'], axis=1)  # doctest: +SKIP
      ... tf.spread(tf.shade(agg))
  
      Aggregate 6 length-4 lines, one per row, where the x coordinates
      of every line are [0, 1, 2, 3] and the y coordinates of the ith line
      are [df.A1[i], df.A2[i], df.B1[i], df.B2[i]].
      >>> agg = cvs.line(df,  # doctest: +SKIP
      ...                x=np.arange(4),
      ...                y=['A1', 'A2', 'B1', 'B2'],
      ...                axis=1)
      ... tf.spread(tf.shade(agg))
  
      Aggregate RaggedArrays of variable length lines, one per row
      (requires pandas >= 0.24.0)
      >>> df_ragged = pd.DataFrame({  # doctest: +SKIP
      ...    'A1': pd.array([
      ...        [1, 1.5], [2, 2.5, 3], [1.5, 2, 3, 4], [3.2, 4, 5]],
      ...        dtype='Ragged[float32]'),
      ...    'B1': pd.array([
      ...        [10, 12], [11, 14, 13], [10, 7, 9, 10], [7, 8, 12]],
      ...        dtype='Ragged[float32]'),
      ...    'group': pd.Categorical([0, 1, 2, 1])
      ... })
      ...
      ... agg = cvs.line(df_ragged, x='A1', y='B1', axis=1)
      ... tf.spread(tf.shade(agg))
  
      Aggregate RaggedArrays of variable length lines by group column,
      one per row (requires pandas >= 0.24.0)
      >>> agg = cvs.line(df_ragged, x='A1', y='B1',  # doctest: +SKIP
      ...                agg=ds.count_cat('group'), axis=1)
      ... tf.spread(tf.shade(agg))
      """
      from .glyphs import (
          LineAxis0,
          LinesAxis1,
          LinesAxis1XConstant,
          LinesAxis1YConstant,
          LineAxis0Multi,
          LinesAxis1Ragged,
          LineAxis1Geometry,
          LinesXarrayCommonX,
      )
  
      validate_xy_or_geometry("Line", x, y, geometry)
  
      if agg is None:
          agg = rd.any()
  
      if line_width is None:
          line_width = 0
  
      # Check and convert antialias kwarg to line_width.
      if antialias and line_width != 0:
          raise ValueError(
              "Do not specify values for both the line_width and \n"
              "antialias keyword arguments; use line_width instead."
          )
      if antialias:
          line_width = 1.0
  
      if geometry is not None:
          if spatialpandas and isinstance(
              source, spatialpandas.dask.DaskGeoDataFrame
          ):
              # Downselect partitions to those that may contain lines in viewport
              x_range = (
                  self.x_range
                  if self.x_range is not None
                  else (None, None)
              )
              y_range = (
                  self.y_range
                  if self.y_range is not None
                  else (None, None)
              )
              source = source.cx_partitions[
                  slice(*x_range), slice(*y_range)
              ]
              glyph = LineAxis1Geometry(geometry)
          elif spatialpandas and isinstance(
              source, spatialpandas.GeoDataFrame
          ):
              glyph = LineAxis1Geometry(geometry)
          elif (
              geopandas_source := self._source_from_geopandas(source)
          ) is not None:
              source = geopandas_source
              from datashader.glyphs.line import LineAxis1GeoPandas
  
              glyph = LineAxis1GeoPandas(geometry)
          else:
              raise ValueError(
                  "source must be an instance of spatialpandas.GeoDataFrame, "
                  "spatialpandas.dask.DaskGeoDataFrame, geopandas.GeoDataFrame, or "
                  "dask_geopandas.GeoDataFrame. Received objects of type {typ}".format(
                      typ=type(source)
                  )
              )
  
      elif (
          isinstance(source, Dataset)
          and isinstance(x, str)
          and isinstance(y, str)
      ):
          x_arr = source[x]
          y_arr = source[y]
          if x_arr.ndim != 1:
              raise ValueError(
                  f"x array must have 1 dimension not {x_arr.ndim}"
              )
  
          if y_arr.ndim != 2:
              raise ValueError(
                  f"y array must have 2 dimensions not {y_arr.ndim}"
              )
          if x not in y_arr.dims:
              raise ValueError(
                  "x must be one of the coordinate dimensions of y"
              )
  
          y_coord_dims = list(y_arr.coords.dims)
          x_dim_index = y_coord_dims.index(x)
          glyph = LinesXarrayCommonX(x, y, x_dim_index)
      else:
          # Broadcast column specifications to handle cases where
          # x is a list and y is a string or vice versa
          orig_x, orig_y = x, y
          x, y = _broadcast_column_specifications(x, y)
  
          if axis == 0:
              if isinstance(x, (Number, str)) and isinstance(
                  y, (Number, str)
              ):
                  glyph = LineAxis0(x, y)
              elif isinstance(x, (list, tuple)) and isinstance(
                  y, (list, tuple)
              ):
                  glyph = LineAxis0Multi(tuple(x), tuple(y))
              else:
                  raise ValueError(
                      """
  Invalid combination of x and y arguments to Canvas.line when axis=0.
      Received:
          x: {x}
          y: {y}
  See docstring for more information on valid usage""".format(
                          x=repr(orig_x), y=repr(orig_y)
                      )
                  )
  
          elif axis == 1:
              if isinstance(x, (list, tuple)) and isinstance(
                  y, (list, tuple)
              ):
                  glyph = LinesAxis1(tuple(x), tuple(y))
              elif isinstance(x, np.ndarray) and isinstance(
                  y, (list, tuple)
              ):
                  glyph = LinesAxis1XConstant(x, tuple(y))
              elif isinstance(x, (list, tuple)) and isinstance(
                  y, np.ndarray
              ):
                  glyph = LinesAxis1YConstant(tuple(x), y)
              elif isinstance(x, (Number, str)) and isinstance(
                  y, (Number, str)
              ):
                  glyph = LinesAxis1Ragged(x, y)
              else:
                  raise ValueError(
                      """
  Invalid combination of x and y arguments to Canvas.line when axis=1.
      Received:
          x: {x}
          y: {y}
  See docstring for more information on valid usage""".format(
                          x=repr(orig_x), y=repr(orig_y)
                      )
                  )
  
          else:
              raise ValueError(
                  """
  The axis argument to Canvas.line must be 0 or 1
      Received: {axis}""".format(
                      axis=axis
                  )
              )
  
      if line_width > 0 and (
          (cudf and isinstance(source, cudf.DataFrame))
          or (dask_cudf and isinstance(source, dask_cudf.DataFrame))
      ):
          warnings.warn(
              "Antialiased lines are not supported for CUDA-backed sources, "
              "so reverting to line_width=0"
          )
          line_width = 0
  
      glyph.set_line_width(line_width)
  
      if glyph.antialiased:
          # This is required to identify and report use of reductions that do
          # not yet support antialiasing.
          non_cat_agg = agg
          if isinstance(non_cat_agg, rd.by):
              non_cat_agg = non_cat_agg.reduction
  
          if not isinstance(
              non_cat_agg,
              (
                  rd.any,
                  rd.count,
                  rd.max,
                  rd.min,
                  rd.sum,
                  rd.summary,
                  rd._sum_zero,
                  rd._first_or_last,
                  rd.mean,
                  rd.max_n,
                  rd.min_n,
                  rd._first_n_or_last_n,
                  rd._max_or_min_row_index,
                  rd._max_n_or_min_n_row_index,
                  rd.where,
              ),
          ):
              raise NotImplementedError(
                  f"{type(non_cat_agg)} reduction not implemented for antialiased lines"
              )
  
      return bypixel(
          source, self, glyph, agg, antialias=glyph.antialiased
      )
  
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 3 for calling the Canvas obj's underlying member method code with example usage: obj.line(source, x, y, agg, axis, geometry, line_width, antialias) and returns: bypixel