class_docstr: Provides a marginal plot for provided data.
docstr: Explains data as visualizations.
  
  Args:
      X: Numpy array for X to explain.
      y: Numpy vector for y to explain.
      name: User-defined explanation name.
  
  Returns:
      An explanation object.
docstr_tok: ["Explains","data","as","visualizations",".","Args",":","X",":","Numpy","array","for","X","to","explain",".","y",":","Numpy","vector","for","y","to","explain",".","name",":","User-defined","explanation","name",".","Returns",":","An","explanation","object","."]
code: def explain_data(self, X, y, name=None):
      """Explains data as visualizations.
  
      Args:
          X: Numpy array for X to explain.
          y: Numpy vector for y to explain.
          name: User-defined explanation name.
  
      Returns:
          An explanation object.
      """
      if name is None:
          name = gen_name_from_class(self)
  
      y = clean_dimensions(y, "y")
      if y.ndim != 1:
          raise ValueError("y must be 1 dimensional")
  
      try:
          y = y.astype(np.float64, copy=False)
      except (TypeError, ValueError):
          # we get a TypeError whenever we have an np.object_ array and numpy attempts to call float(), but the
          # object doesn't have a __float__ function.  We get a ValueError when either a str object inside an
          # np.object_ array or when an np.unicode_ array attempts to convert a string to a float and fails
  
          y = typify_classification(y)
  
      X, n_samples = preclean_X(
          X, self.feature_names, self.feature_types, len(y)
      )
  
      X, feature_names, feature_types = unify_data(
          X, n_samples, self.feature_names, self.feature_types, False, 0
      )
  
      unique_val_counts = np.zeros(len(feature_names), dtype=np.int64)
      for col_idx in range(len(feature_names)):
          X_col = X[:, col_idx]
          unique_val_counts.itemset(col_idx, len(np.unique(X_col)))
  
      global_selector = gen_global_selector(
          len(feature_names),
          feature_names,
          feature_types,
          unique_val_counts,
          None,
      )
  
      counts, values = np.histogram(y, bins="doane")
      response_density_data_dict = {"names": values, "scores": counts}
      overall_dict = {
          "type": "hist",
          "density": response_density_data_dict,
          "X": X,
          "y": y,
      }
  
      # Sample down
      n_samples = (
          self.max_scatter_samples
          if len(y) > self.max_scatter_samples
          else len(y)
      )
      idx = np.random.choice(
          np.arange(len(y)), n_samples, replace=False
      )
      X_sample = X[idx, :]
      y_sample = y[idx]
      specific_dicts = []
      for feat_idx, feature_name in enumerate(feature_names):
          feature_type = feature_types[feat_idx]
          if feature_type == "continuous":
              counts, values = np.histogram(
                  X[:, feat_idx], bins="doane"
              )
              corr = pearsonr(X[:, feat_idx], y)[0]
          elif feature_type == "nominal" or feature_type == "ordinal":
              values, counts = np.unique(
                  X[:, feat_idx], return_counts=True
              )
              corr = None
          else:
              raise Exception(
                  "Cannot support type: {0}".format(feature_type)
              )
  
          feat_density_data_dict = {"names": values, "scores": counts}
          specific_dict = {
              "type": "marginal",
              "feature_density": feat_density_data_dict,
              "response_density": response_density_data_dict,
              "feature_samples": X_sample[:, feat_idx],
              "response_samples": y_sample,
              "correlation": corr,
          }
  
          specific_dicts.append(specific_dict)
  
      internal_obj = {
          "overall": overall_dict,
          "specific": specific_dicts,
      }
  
      return MarginalExplanation(
          "data",
          internal_obj,
          feature_names=feature_names,
          feature_types=feature_types,
          name=name,
          selector=global_selector,
      )
  
imports: from ..api.base import ExplainerMixin, ExplanationMixin
  from ..utils._explanation import gen_name_from_class, gen_global_selector
  import numpy
  from scipy.stats import pearsonr
  from ..utils._clean_x import preclean_X
  from ..utils._clean_simple import clean_dimensions, typify_classification
  from ..utils._unify_data import unify_data
label_desc: Use image node_id 2 for calling the Marginal obj's underlying member method code with example usage: obj.explain_data(X, y, name) and returns: MarginalExplanation