class_docstr: Shallow Decision Tree (low depth).
  
  Currently wrapper around DecisionTreeClassifier or DecisionTreeRegressor in scikit-learn.
  To keep the tree shallow, max depth is defaulted to 3.
  
  https://github.com/scikit-learn/scikit-learn
class_docstr_tok: ["Shallow","Decision","Tree","(","low","depth",")",".","Currently","wrapper","around","DecisionTreeClassifier","or","DecisionTreeRegressor","in","scikit-learn",".","To","keep","the","tree","shallow",",","max","depth","is","defaulted","to","3.","https",":","\/\/github.com\/scikit-learn\/scikit-learn"]
docstr: Adapted from:
  https://github.com/scikit-learn/scikit-learn/blob/79bdc8f711d0af225ed6be9fdb708cea9f98a910/sklearn/tree/export.py
docstr_tok: ["Adapted","from",":","https",":","\/\/github.com\/scikit-learn\/scikit-learn\/blob\/79bdc8f711d0af225ed6be9fdb708cea9f98a910\/sklearn\/tree\/export.py"]
code: def _graph_from_tree(self, tree, feature_names=None, max_depth=None):
      """Adapted from:
      https://github.com/scikit-learn/scikit-learn/blob/79bdc8f711d0af225ed6be9fdb708cea9f98a910/sklearn/tree/export.py
      """
      tree_ = tree.tree_
      nodes = []
      edges = []
      max_samples = self.n_samples_
      counter = {"node": 0}
  
      # i is the element in the tree_ to create a dict for
      def recur(i, depth=0):
          if max_depth is not None and depth > max_depth:
              return None
          if i == _tree.TREE_LEAF:
              return None
  
          feature = int(tree_.feature[i])
          threshold = float(tree_.threshold[i])
  
          if feature == _tree.TREE_UNDEFINED:
              feature = None
              threshold = None
              value = [
                  list(map(int, x)) for x in tree_.value[i].tolist()
              ]
          else:
              value = [
                  list(map(int, x)) for x in tree_.value[i].tolist()
              ]
              if feature_names is not None:
                  feature = feature_names[feature]
  
          counter["node"] += 1
          node_id = str(counter["node"])
          if is_classifier(self):
              value_str = "# Obs: "
          else:
              value_str = "E[Y]: "
  
          if feature is not None and threshold is not None:
              value_str += ", ".join([str(v) for v in value[0]])
              label_str = "{0} <= {1:.2f}\n{2}".format(
                  feature, threshold, value_str
              )
          else:
              value_str += ", ".join([str(v) for v in value[0]])
              label_str = "Impurity: {0:.2f}\n{1}".format(
                  tree_.impurity[i], value_str
              )
  
          nodes.append(
              {
                  "data": {
                      "id": node_id,
                      "label": label_str,
                      "feature": feature,
                  }
              }
          )
          left = recur(tree_.children_left[i], depth + 1)
          right = recur(tree_.children_right[i], depth + 1)
          if left is not None:
              data_left = {
                  "data": {
                      "source": node_id,
                      "target": left["node_id"],
                      "edge_weight": left["n_node_samples"]
                      / max_samples
                      * 15,
                  }
              }
              edges.append(data_left)
  
          if right is not None:
              data_right = {
                  "data": {
                      "source": node_id,
                      "target": right["node_id"],
                      "edge_weight": right["n_node_samples"]
                      / max_samples
                      * 15,
                  }
              }
              edges.append(data_right)
  
          return {
              "node_id": node_id,
              "feature": feature,
              "threshold": threshold,
              "impurity": float(tree_.impurity[i]),
              "n_node_samples": int(tree_.n_node_samples[i]),
              "left": left,
              "right": right,
              "value": value,
          }
  
      recur(0)
      return nodes, edges
  
imports: from ..api.base import ExplainerMixin, ExplanationMixin
  from ..utils._explanation import gen_name_from_class, gen_local_selector, gen_global_selector, gen_perf_dicts
  from sklearn.base import ClassifierMixin, RegressorMixin
  from sklearn.tree import DecisionTreeClassifier
  from sklearn.tree import DecisionTreeRegressor
  from sklearn.base import is_classifier
  from sklearn.utils.validation import check_is_fitted
  import numpy
  from abc import abstractmethod
  from sklearn.tree import _tree
  from copy import deepcopy
  from ..utils._clean_x import preclean_X
  from ..utils._clean_simple import clean_dimensions, typify_classification
  from ..utils._unify_data import unify_data
  import logging
label_desc: Use image node_id 7 for calling the BaseShallowDecisionTree obj's underlying member method code with example usage: obj._graph_from_tree(tree, feature_names, max_depth) and returns: nodes,  edges, dict, None, None