code: def _ctreeviz_univar(
      shadow_tree,
      fontsize,
      ticks_fontsize,
      fontname,
      nbins,
      gtype,
      show,
      colors,
      feature,
      figsize,
      ax,
  ):
      if ax is None:
          if figsize:
              fig, ax = plt.subplots(figsize=figsize)
          else:
              fig, ax = plt.subplots()
  
      featidx = shadow_tree.feature_names.index(feature)
      X_train = shadow_tree.X_train
      y_train = shadow_tree.y_train
      colors = adjust_colors(colors)
      n_classes = shadow_tree.nclasses()
      overall_feature_range = (
          np.min(X_train[:, featidx]),
          np.max(X_train[:, featidx]),
      )
      class_values = shadow_tree.classes()
      color_values = colors["classes"][n_classes]
      color_map = {
          v: color_values[i] for i, v in enumerate(class_values)
      }
      X_colors = [color_map[cl] for cl in class_values]
  
      # if np.numeric(X_train[:,featidx])
      if not is_numeric(X_train[:, featidx]):
          raise ValueError(
              f"ctree_feature_space only supports numeric feature spaces"
          )
  
      _format_axes(
          ax,
          shadow_tree.feature_names[featidx],
          "Count" if gtype == "barstacked" else None,
          colors,
          fontsize,
          fontname,
          ticks_fontsize=ticks_fontsize,
          grid=False,
      )
  
      X_hist = [X_train[y_train == cl, featidx] for cl in class_values]
  
      if gtype == "barstacked":
          bins = np.linspace(
              start=overall_feature_range[0],
              stop=overall_feature_range[1],
              num=nbins,
              endpoint=True,
          )
          hist, bins, barcontainers = ax.hist(
              X_hist,
              color=X_colors,
              align="mid",
              histtype="barstacked",
              bins=bins,
              label=shadow_tree.class_names,
          )
  
          for patch in barcontainers:
              for rect in patch.patches:
                  rect.set_linewidth(0.5)
                  rect.set_edgecolor(colors["rect_edge"])
          ax.set_xlim(*overall_feature_range)
          ax.set_xticks(overall_feature_range)
          ax.set_yticks([0, max([max(h) for h in hist])])
      elif gtype == "strip":
          # user should pass in short and wide fig
          ax.spines["left"].set_visible(False)
          ax.yaxis.set_visible(False)
          sigma = 0.013
          mu = 0.08
          class_step = 0.08
          dot_w = 20
          ax.set_ylim(0, mu + n_classes * class_step)
          for i, bucket in enumerate(X_hist):
              y_noise = np.random.normal(
                  mu + i * class_step, sigma, size=len(bucket)
              )
              ax.scatter(
                  bucket,
                  y_noise,
                  alpha=colors["scatter_marker_alpha"],
                  marker="o",
                  s=dot_w,
                  c=color_map[i],
                  edgecolors=colors["scatter_edge"],
                  lw=0.3,
              )
      else:
          raise ValueError(f"Unrecognized gtype = {gtype}!")
  
      splits = [
          node.split()
          for node in shadow_tree.internal
          if node.feature() == featidx
      ]
      splits = sorted(splits)
  
      if (
          "preds" in show
      ):  # this gets the horiz bars showing prediction region
          pred_box_height = 0.07 * (ax.get_ylim()[1] - ax.get_ylim()[0])
          bins = [ax.get_xlim()[0]] + splits + [ax.get_xlim()[1]]
          for i in range(len(bins) - 1):
              left = bins[i]
              right = bins[i + 1]
              inrange = y_train[(X_train >= left) & (X_train <= right)]
              if len(inrange) == 0:
                  continue
              values, counts = np.unique(inrange, return_counts=True)
              pred = values[np.argmax(counts)]
              rect = patches.Rectangle(
                  (left, -2 * pred_box_height),
                  (right - left),
                  pred_box_height,
                  linewidth=0.3,
                  edgecolor=colors["edge"],
                  facecolor=color_map[pred],
              )
              ax.add_patch(rect)
  
      if "legend" in show:
          add_classifier_legend(
              ax,
              shadow_tree.class_names,
              class_values,
              color_map,
              shadow_tree.target_name,
              colors,
              fontname=fontname,
          )
  
      if "title" in show:
          accur = shadow_tree.get_score()
          title = f"Classifier Tree Depth {shadow_tree.get_max_depth()}, Training Accuracy={accur * 100:.2f}%"
          ax.set_title(title, fontsize=fontsize, color=colors["title"])
  
      if "splits" in show:
          split_heights = [*ax.get_ylim()]
          for split in splits:
              ax.plot(
                  [split, split],
                  split_heights,
                  "--",
                  color=colors["split_line"],
                  linewidth=1,
              )
  
imports: import os
  import tempfile
  from typing import Mapping, List, Callable
  import matplotlib
  import matplotlib.patches
  import matplotlib.pyplot
  import numpy
  import pandas
  from colour import Color, rgb2hex
  from sklearn import tree
  from dtreeviz.colors import adjust_colors
  from dtreeviz.interpretation import explain_prediction_plain_english, explain_prediction_sklearn_default
  from dtreeviz.models.shadow_decision_tree import ShadowDecTree
  from dtreeviz.models.shadow_decision_tree import ShadowDecTreeNode
  from dtreeviz.utils import myround, DTreeVizRender, add_classifier_legend, _format_axes, _draw_wedge, _set_wedge_ticks, tessellate, is_numeric
label_desc: Use image node_id 11 for calling a global function with example usage: _ctreeviz_univar(shadow_tree, fontsize, ticks_fontsize, fontname, nbins, gtype, show, colors, feature, figsize, ax) without return types