docstr: Generate the node content string
  Args:
      tree:      Tree class
      node_id:   int, Tree node id
      criterion: str or object, split criterion
  Returns: str, node content
docstr_tok: ["Generate","the","node","content","string","Args",":","tree",":","Tree","class","node_id",":","int",",","Tree","node","id","criterion",":","str","or","object",",","split","criterion","Returns",":","str",",","node","content"]
code: def node_to_str(
      self, tree: _tree.Tree, node_id: int, criterion: str or object
  ) -> str:
      """
      Generate the node content string
      Args:
          tree:      Tree class
          node_id:   int, Tree node id
          criterion: str or object, split criterion
      Returns: str, node content
      """
      if tree.n_outputs == 1:
          value = tree.value[node_id][0, :]
      else:
          value = tree.value[node_id]
  
      # Should labels be shown?
      labels = (
          self.label == "root" and node_id == 0
      ) or self.label == "all"
  
      characters = self.characters
      node_string = characters[-1]
  
      # Write node ID
      if self.node_ids:
          if labels:
              node_string += "node "
          node_string += characters[0] + str(node_id) + characters[4]
  
      # Write decision criteria
      if tree.children_left[node_id] != _tree.TREE_LEAF:
          # Always write node decision criteria, except for leaves
          if self.feature_names is not None:
              feature = self.feature_names[tree.feature[node_id]]
          else:
              feature = "X%s%s%s" % (
                  characters[1],
                  tree.feature[node_id],
                  characters[2],
              )
          node_string += "%s %s %s%s" % (
              feature,
              characters[3],
              round(tree.threshold[node_id], self.precision),
              characters[4],
          )
  
      # Write impurity
      if self.impurity:
          if not isinstance(criterion, str):
              criterion = "impurity"
          if labels:
              node_string += "%s = " % criterion
          node_string += (
              str(round(tree.impurity[node_id], self.precision))
              + characters[4]
          )
  
      # Write node sample count
      if labels:
          node_string += "samples = "
      if self.proportion:
          percent = (
              100.0
              * tree.n_node_samples[node_id]
              / float(tree.n_node_samples[0])
          )
          node_string += str(round(percent, 1)) + "%" + characters[4]
      else:
          node_string += (
              str(tree.n_node_samples[node_id]) + characters[4]
          )
  
      # Write the number of samples per treatment and control groups
      if self.groups_count:
          for group in self.treatment_groups:
              node_string += f"Group {group} = {self.causal_tree._groups_cnt[node_id][group]} "
      node_string += characters[4]
  
      # Write node class distribution / regression value
      if self.proportion and tree.n_classes[0] != 1:
          # For classification this will show the proportion of samples
          value = value / tree.weighted_n_node_samples[node_id]
      if labels:
          node_string += "value = "
      if tree.n_classes[0] == 1:
          # Regression
          value_text = np.around(value, self.precision)
      elif self.proportion:
          # Classification
          value_text = np.around(value, self.precision)
      elif np.all(np.equal(np.mod(value, 1), 0)):
          # Classification without floating-point weights
          value_text = value.astype(int)
      else:
          # Classification with floating-point weights
          value_text = np.around(value, self.precision)
      # Strip whitespace
      value_text = str(value_text.astype("S32")).replace("b'", "'")
      value_text = value_text.replace("' '", ", ").replace("'", "")
      if tree.n_classes[0] == 1 and tree.n_outputs == 1:
          value_text = value_text.replace("[", "").replace("]", "")
      value_text = value_text.replace("\n ", characters[4])
      node_string += value_text + characters[4]
  
      # Write node majority class
      if (
          self.class_names is not None
          and tree.n_classes[0] != 1
          and tree.n_outputs == 1
      ):
          # Only done for single-output classification trees
          if labels:
              node_string += "class = "
          if self.class_names is not True:
              class_name = self.class_names[np.argmax(value)]
          else:
              class_name = "y%s%s%s" % (
                  characters[1],
                  np.argmax(value),
                  characters[2],
              )
          node_string += class_name
  
      # Clean up any trailing newlines
      if node_string.endswith(characters[4]):
          node_string = node_string[: -len(characters[4])]
  
      return node_string + characters[5]
  
imports: from collections import defaultdict
  import matplotlib.pyplot
  import numpy
  import pydotplus
  import seaborn
  from sklearn.tree import _tree
  from sklearn.tree._export import _MPLTreeExporter, _color_brew
  from sklearn.utils.validation import check_is_fitted
  from .None import CausalTreeRegressor
  from .utils import get_tree_leaves_mask
label_desc: Use image node_id 2 for calling the _MPLCTreeExporter obj's underlying member method code with example usage: obj.node_to_str(tree, node_id, criterion) and returns: unknown