class_docstr: UMAP Mixin for automagic UMAPing
class_docstr_tok: ["UMAP","Mixin","for","automagic","UMAPing"]
docstr: UMAP the featurized nodes or edges data, or pass in your own X, y (optional) dataframes of values
  
  Example
  
  >>> import graphistry   
  >>> g = graphistry.nodes(pd.DataFrame({'node': [0,1,2], 'data': [1,2,3], 'meta': ['a', 'b', 'c']}))
  >>> g2 = g.umap(n_components=3, spread=1.0, min_dist=0.1, n_neighbors=12, negative_sample_rate=5, local_connectivity=1, repulsion_strength=1.0, metric='euclidean', suffix='', play=0, encode_position=True, encode_weight=True, dbscan=False, engine='auto', feature_engine='auto', inplace=False, memoize=True, verbose=False)
  >>> g2.plot()
  
  Parameters
  
      :X: either a dataframe ndarray of features, or column names to featurize
      :y: either an dataframe ndarray of targets, or column names to featurize
              targets
      :kind: `nodes` or `edges` or None.
              If None, expects explicit X, y (optional) matrices,
              and will Not associate them to nodes or edges.
              If X, y (optional) is given, with kind = [nodes, edges],
              it will associate new matrices to nodes or edges attributes.
      :scale: multiplicative scale for pruning weighted edge DataFrame
              gotten from UMAP, between [0, ..) with high end meaning keep
              all edges
      :n_neighbors: UMAP number of nearest neighbors to include for
              UMAP connectivity, lower makes more compact layouts. Minimum 2
      :min_dist: UMAP float between 0 and 1, lower makes more compact
              layouts.
      :spread: UMAP spread of values for relaxation
      :local_connectivity: UMAP connectivity parameter
      :repulsion_strength: UMAP repulsion strength
      :negative_sample_rate: UMAP negative sampling rate
      :n_components: number of components in the UMAP projection,
              default 2
      :metric: UMAP metric, default 'euclidean'.
              see (UMAP-LEARN)[https://umap-learn.readthedocs.io/
              en/latest/parameters.html] documentation for more.
      :suffix: optional suffix to add to x, y attributes of umap.
      :play: Graphistry play parameter, default 0, how much to evolve
              the network during clustering. 0 preserves the original UMAP layout.
      :encode_weight: if True, will set new edges_df from
              implicit UMAP, default True.
      :encode_position: whether to set default plotting bindings
              -- positions x,y from umap for .plot(), default True
      :dbscan: whether to run DBSCAN on the UMAP embedding, default False.
      :engine: selects which engine to use to calculate UMAP:
              default "auto" will use cuML if available, otherwise UMAP-LEARN.
      :feature_engine: How to encode data
              ("none", "auto", "pandas", "dirty_cat", "torch")
      :inplace: bool = False, whether to modify the current object, default False.
              when False, returns a new object, useful for chaining in a functional paradigm.
      :memoize: whether to memoize the results of this method,
              default True.
      :verbose: whether to print out extra information, default False.
  
  :return: self, with attributes set with new data
docstr_tok: ["UMAP","the","featurized","nodes","or","edges","data",",","or","pass","in","your","own","X",",","y","(","optional",")","dataframes","of","values","Example",">",">",">","import","graphistry",">",">",">","g","=","graphistry.nodes","(","pd.DataFrame","(","{","'node","'",":","[","0,1,2","]",",","'data","'",":","[","1,2,3","]",",","'meta","'",":","[","'","a","'",",","'","b","'",",","'","c","'","]","}",")",")",">",">",">","g2","=","g.umap","(","n_components=3",",","spread=1.0",",","min_dist=0.1",",","n_neighbors=12",",","negative_sample_rate=5",",","local_connectivity=1",",","repulsion_strength=1.0",",","metric='euclidean","'",",","suffix=","''",",","play=0",",","encode_position=True",",","encode_weight=True",",","dbscan=False",",","engine='auto","'",",","feature_engine='auto","'",",","inplace=False",",","memoize=True",",","verbose=False",")",">",">",">","g2.plot","(",")","Parameters",":","X",":","either","a","dataframe","ndarray","of","features",",","or","column","names","to","featurize",":","y",":","either","an","dataframe","ndarray","of","targets",",","or","column","names","to","featurize","targets",":","kind",":","`","nodes","`","or","`","edges","`","or","None",".","If","None",",","expects","explicit","X",",","y","(","optional",")","matrices",",","and","will","Not","associate","them","to","nodes","or","edges",".","If","X",",","y","(","optional",")","is","given",",","with","kind","=","[","nodes",",","edges","]",",","it","will","associate","new","matrices","to","nodes","or","edges","attributes",".",":","scale",":","multiplicative","scale","for","pruning","weighted","edge","DataFrame","gotten","from","UMAP",",","between","[","0",",","..",")","with","high","end","meaning","keep","all","edges",":","n_neighbors",":","UMAP","number","of","nearest","neighbors","to","include","for","UMAP","connectivity",",","lower","makes","more","compact","layouts",".","Minimum","2",":","min_dist",":","UMAP","float","between","0","and","1",",","lower","makes","more","compact","layouts",".",":","spread",":","UMAP","spread","of","values","for","relaxation",":","local_connectivity",":","UMAP","connectivity","parameter",":","repulsion_strength",":","UMAP","repulsion","strength",":","negative_sample_rate",":","UMAP","negative","sampling","rate",":","n_components",":","number","of","components","in","the","UMAP","projection",",","default","2",":","metric",":","UMAP","metric",",","default","'euclidean","'",".","see","(","UMAP-LEARN",")","[","https",":","\/\/umap-learn.readthedocs.io\/","en\/latest\/parameters.html","]","documentation","for","more",".",":","suffix",":","optional","suffix","to","add","to","x",",","y","attributes","of","umap",".",":","play",":","Graphistry","play","parameter",",","default","0",",","how","much","to","evolve","the","network","during","clustering",".","0","preserves","the","original","UMAP","layout",".",":","encode_weight",":","if","True",",","will","set","new","edges_df","from","implicit","UMAP",",","default","True",".",":","encode_position",":","whether","to","set","default","plotting","bindings","--","positions","x",",","y","from","umap","for",".plot","(",")",",","default","True",":","dbscan",":","whether","to","run","DBSCAN","on","the","UMAP","embedding",",","default","False",".",":","engine",":","selects","which","engine","to","use","to","calculate","UMAP",":","default","``","auto","''","will","use","cuML","if","available",",","otherwise","UMAP-LEARN",".",":","feature_engine",":","How","to","encode","data","(","``","none","''",",","``","auto","''",",","``","pandas","''",",","``","dirty_cat","''",",","``","torch","''",")",":","inplace",":","bool","=","False",",","whether","to","modify","the","current","object",",","default","False",".","when","False",",","returns","a","new","object",",","useful","for","chaining","in","a","functional","paradigm",".",":","memoize",":","whether","to","memoize","the","results","of","this","method",",","default","True",".",":","verbose",":","whether","to","print","out","extra","information",",","default","False",".",":","return",":","self",",","with","attributes","set","with","new","data"]
code: def umap(
      self,
      X: XSymbolic = None,
      y: YSymbolic = None,
      kind: str = "nodes",
      scale: float = 1.0,
      n_neighbors: int = 12,
      min_dist: float = 0.1,
      spread: float = 0.5,
      local_connectivity: int = 1,
      repulsion_strength: float = 1,
      negative_sample_rate: int = 5,
      n_components: int = 2,
      metric: str = "euclidean",
      suffix: str = "",
      play: Optional[int] = 0,
      encode_position: bool = True,
      encode_weight: bool = True,
      dbscan: bool = False,
      engine: UMAPEngine = "auto",
      feature_engine: str = "auto",
      inplace: bool = False,
      memoize: bool = True,
      verbose: bool = False,
      **featurize_kwargs,
  ):
      """UMAP the featurized nodes or edges data, or pass in your own X, y (optional) dataframes of values
  
      Example
  
      >>> import graphistry
      >>> g = graphistry.nodes(pd.DataFrame({'node': [0,1,2], 'data': [1,2,3], 'meta': ['a', 'b', 'c']}))
      >>> g2 = g.umap(n_components=3, spread=1.0, min_dist=0.1, n_neighbors=12, negative_sample_rate=5, local_connectivity=1, repulsion_strength=1.0, metric='euclidean', suffix='', play=0, encode_position=True, encode_weight=True, dbscan=False, engine='auto', feature_engine='auto', inplace=False, memoize=True, verbose=False)
      >>> g2.plot()
  
      Parameters
  
          :X: either a dataframe ndarray of features, or column names to featurize
          :y: either an dataframe ndarray of targets, or column names to featurize
                  targets
          :kind: `nodes` or `edges` or None.
                  If None, expects explicit X, y (optional) matrices,
                  and will Not associate them to nodes or edges.
                  If X, y (optional) is given, with kind = [nodes, edges],
                  it will associate new matrices to nodes or edges attributes.
          :scale: multiplicative scale for pruning weighted edge DataFrame
                  gotten from UMAP, between [0, ..) with high end meaning keep
                  all edges
          :n_neighbors: UMAP number of nearest neighbors to include for
                  UMAP connectivity, lower makes more compact layouts. Minimum 2
          :min_dist: UMAP float between 0 and 1, lower makes more compact
                  layouts.
          :spread: UMAP spread of values for relaxation
          :local_connectivity: UMAP connectivity parameter
          :repulsion_strength: UMAP repulsion strength
          :negative_sample_rate: UMAP negative sampling rate
          :n_components: number of components in the UMAP projection,
                  default 2
          :metric: UMAP metric, default 'euclidean'.
                  see (UMAP-LEARN)[https://umap-learn.readthedocs.io/
                  en/latest/parameters.html] documentation for more.
          :suffix: optional suffix to add to x, y attributes of umap.
          :play: Graphistry play parameter, default 0, how much to evolve
                  the network during clustering. 0 preserves the original UMAP layout.
          :encode_weight: if True, will set new edges_df from
                  implicit UMAP, default True.
          :encode_position: whether to set default plotting bindings
                  -- positions x,y from umap for .plot(), default True
          :dbscan: whether to run DBSCAN on the UMAP embedding, default False.
          :engine: selects which engine to use to calculate UMAP:
                  default "auto" will use cuML if available, otherwise UMAP-LEARN.
          :feature_engine: How to encode data
                  ("none", "auto", "pandas", "dirty_cat", "torch")
          :inplace: bool = False, whether to modify the current object, default False.
                  when False, returns a new object, useful for chaining in a functional paradigm.
          :memoize: whether to memoize the results of this method,
                  default True.
          :verbose: whether to print out extra information, default False.
  
      :return: self, with attributes set with new data
      """
      if engine == UMAP_LEARN:
          assert_imported()
      elif engine == CUML:
          assert_imported_cuml()
  
      umap_kwargs = dict(
          n_components=n_components,
          metric=metric,
          n_neighbors=n_neighbors,
          min_dist=min_dist,
          spread=spread,
          local_connectivity=local_connectivity,
          repulsion_strength=repulsion_strength,
          negative_sample_rate=negative_sample_rate,
          engine=engine,
          suffix=suffix,
      )
      logger.debug("umap_kwargs: %s", umap_kwargs)
  
      # temporary until we have full cudf support in feature_utils.py
      has_cudf, _, cudf = lazy_cudf_import_has_dependancy()
  
      if has_cudf:
          flag_nodes_cudf = isinstance(self._nodes, cudf.DataFrame)
          flag_edges_cudf = isinstance(self._edges, cudf.DataFrame)
  
          if flag_nodes_cudf or flag_edges_cudf:
              res = self
              if flag_nodes_cudf:
                  res._nodes = res._nodes.to_pandas()
              if flag_edges_cudf:
                  res._edges = res._edges.to_pandas()
              if (X is not None) or (y is not None):
                  res = res.umap(X=X, y=y, kind=kind, **umap_kwargs)  # type: ignore
              else:
                  res = res.umap(X=self._nodes, y=self._edges, kind=kind, **umap_kwargs)  # type: ignore
              return res
  
      if inplace:
          res = self
      else:
          res = self.bind()
  
      res = res.umap_lazy_init(res, verbose=verbose, **umap_kwargs)  # type: ignore
  
      logger.debug("umap input X :: %s", X)
      logger.debug("umap input y :: %s", y)
  
      featurize_kwargs = self._set_features(
          res,
          X,
          y,
          kind,
          feature_engine,
          {**featurize_kwargs, "memoize": memoize},
      )
  
      if kind == "nodes":
          index = res._nodes.index
          if res._node is None:
              logger.debug("-Writing new node name")
              res = res.nodes(  # type: ignore
                  res._nodes.reset_index(drop=True)
                  .reset_index()
                  .rename(columns={"index": config.IMPLICIT_NODE_ID}),
                  config.IMPLICIT_NODE_ID,
              )
              res._nodes.index = index
  
          nodes = res._nodes[res._node].values
  
          logger.debug(
              "propagating with featurize_kwargs: %s", featurize_kwargs
          )
          (
              X_,
              y_,
              res,
          ) = res._featurize_or_get_nodes_dataframe_if_X_is_None(  # type: ignore
              **featurize_kwargs
          )
  
          logger.debug("umap X_: %s", X_)
          logger.debug("umap y_: %s", y_)
          logger.debug("data is type :: %s", (type(X_)))
          if isinstance(X_, pd.DataFrame):
              index_to_nodes_dict = dict(zip(range(len(nodes)), nodes))
          elif "cudf.core.dataframe" in str(getmodule(X_)):
              index_to_nodes_dict = nodes  # {}?
  
          # add the safe coercion here
          X_, y_ = make_safe_gpu_dataframes(X_, y_, res.engine)  # type: ignore
  
          res = res._process_umap(
              res,
              X_,
              y_,
              kind,
              memoize,
              featurize_kwargs,
              verbose,
              **umap_kwargs,
          )
  
          res._weighted_adjacency_nodes = res._weighted_adjacency
          if res._xy is None:
              raise RuntimeError("This should not happen")
          res._node_embedding = res._xy
          # TODO user-guidable edge merge policies like upsert?
          res._weighted_edges_df_from_nodes = (
              prune_weighted_edges_df_and_relabel_nodes(
                  res._weighted_edges_df,  # type: ignore
                  scale=scale,
                  index_to_nodes_dict=index_to_nodes_dict,
              )
          )
      elif kind == "edges":
          logger.debug(
              "propagating with featurize_kwargs: %s", featurize_kwargs
          )
          (
              X_,
              y_,
              res,
          ) = res._featurize_or_get_edges_dataframe_if_X_is_None(  # type: ignore
              **featurize_kwargs
          )
  
          # add the safe coercion here
          X_, y_ = make_safe_gpu_dataframes(X_, y_, res.engine)  # type: ignore
  
          res = res._process_umap(
              res,
              X_,
              y_,
              kind,
              memoize,
              featurize_kwargs,
              **umap_kwargs,
          )
          res._weighted_adjacency_edges = res._weighted_adjacency
          if res._xy is None:
              raise RuntimeError("This should not happen")
          res._edge_embedding = res._xy
          res._weighted_edges_df_from_edges = (
              prune_weighted_edges_df_and_relabel_nodes(
                  res._weighted_edges_df,  # type: ignore
                  scale=scale,
                  index_to_nodes_dict=None,
              )
          )
      elif kind is None:
          logger.warning(
              "kind should be one of `nodes` or `edges` unless"
              "you are passing explicit matrices"
          )
          if X is not None and isinstance(X, pd.DataFrame) or "":
              logger.info("New Matrix `X` passed in for UMAP-ing")
              xy = res._umap_fit_transform(X, y, verbose=verbose)
              res._xy = xy
              res._weighted_edges_df = (
                  prune_weighted_edges_df_and_relabel_nodes(
                      res._weighted_edges_df, scale=scale
                  )
              )
              logger.info(  # noqa: E501
                  "Reduced Coordinates are stored in `._xy` attribute and "  # noqa: E501
                  "pruned weighted_edge_df in `._weighted_edges_df` attribute"  # noqa: E501
              )
          else:
              logger.error(
                  "If `kind` is `None`, `X` and optionally `y`"
                  "must be given."
              )
      else:
          raise ValueError(
              f"`kind` needs to be one of `nodes`, `edges`, `None`, got {kind}"  # noqa: E501
          )
      res = res._bind_xy_from_umap(
          res, kind, encode_position, encode_weight, play
      )  # noqa: E501
  
      if res.engine == CUML and is_legacy_cuml():  # type: ignore
          res = res.prune_self_edges()
  
      if dbscan:
          res = res.dbscan(min_dist=min_dist, kind=kind, fit_umap_embedding=True, verbose=verbose)  # type: ignore
  
      if not inplace:
          return res
  
imports: import copy
  from time import time
  from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Union
  from inspect import getmodule
  import pandas
  from .None import constants
  from .constants import CUML, UMAP_LEARN
  from .feature_utils import FeatureMixin, Literal, XSymbolic, YSymbolic, prune_weighted_edges_df_and_relabel_nodes, resolve_feature_engine
  from .PlotterBase import Plottable, WeakValueDictionary
  from .util import check_set_memoize
  import logging
label_desc: Use image node_id 11 for calling the UMAPMixin obj's underlying member method code with example usage: obj.umap(X, y, kind, scale, n_neighbors, min_dist, spread, local_connectivity, repulsion_strength, negative_sample_rate, n_components, metric, suffix, play, encode_position, encode_weight, dbscan, engine, feature_engine, inplace, memoize, verbose) and returns: res, res