code: def decision_boundaries(
      model,
      X: np.ndarray,
      y: np.ndarray,
      ntiles=50,
      tile_fraction=0.9,
      binary_threshold=0.5,
      show=[
          "instances",
          "boundaries",
          "probabilities",
          "misclassified",
          "legend",
      ],
      feature_names=None,
      target_name=None,
      class_names=None,
      markers=None,
      boundary_marker="o",
      boundary_markersize=0.8,
      fontsize=9,
      fontname="Arial",
      dot_w=25,
      yshift=0.08,
      sigma=0.013,
      colors: dict = None,
      ranges: Tuple = None,
      figsize: Tuple = None,
      ax=None,
  ) -> None:
      """
      Two-variable case:
      Draw a tiled grid over a 2D classifier feature space where each tile is colored by
      the coordinate probabilities or coordinate predicted class. The X,y instances
      are drawn on top of the tiling. The decision boundaries are indicated
      by dots in between the classes. You can specify a threshold for the binary
      classification case. Misclassified instances are highlighted.
  
      One-variable case:
      Draw a strip plot over a 1D feature space, one strip per class. A narrow rectangle
      along the bottom indicates a color combined probabilities from all classes. The
      color associated with the most likely class will dominate the probabilities rectangle.
      Misclassified instances are highlighted. Decision boundaries, where the predicted
      class shifts from one to another, are indicated by vertical dashed lines.
  
      TODO: assumes classes are contiguous and 0..k-1
  
      :param model: an sklearn or Keras classifier model or any other model that can answer
                    method predict_proba(X)
      :param X: A 1- or 2-column dataframe or numpy array with the one or two features to plot
      :param y: The target column with integers indicating the true instance classes;
                currently these must be contiguous 0..k-1 for k classes.
      :param ntiles: How many tiles to draw across the x1, x2 feature space
      :param tile_fraction: A value between 0..1 indicating how much of a tile
                            should be colored; e.g., .9 indicates the tile should leave
                            10% whitespace around the colored portion.
      :param boundary_marker: The marker symbol from matplotlib to use for the boundary;
                              default is a circle 'o'.
      :param boundary_markersize: The boundary marker size; default is .8
      :param feature_names: A list of strings indicating the one or two X variable names.
                            If None, no axes labels are showing
      :param target_name: If showing legend, this is the title of the legend box.
      :param class_names: If showing legend, these are the class names in the legend box
      :param show: Which elements to show, includes elements from
                   ['instances','boundaries','probabilities','misclassified','legend']
      :param markers: By default, just small circles are shown for each X instance, but
                      if not None, this is a list of matplotlib marker strings like ['X','s'].
      :param fontsize: Font size for tick labels and axis labels
      :param fontname: The font name for  tick labels and axis labels
      :param colors: A dictionary with adjustments to the colors
      :param dot_w: How wide should the circles be when drawing the instances
      :param yshift: For univariate case. If you'd like to play around with the strip plot,
                     this variable shifts the class clusters; a shifted zero puts them on
                     top of each other.
      :param sigma:  For univariate case. The standard deviation of the noise added to make
                     the strip plot.
      :param ranges: Tuple for ranges of plot. One range per input dimension also specified as tuple,
                     e.g. ((10, 100), (500, 600)).
                     Ranges of plot are determined by min, max of X vector if not specified.
      :param figsize: optional (width, height) in inches for the entire plot
      :param ax: An optional matplotlib "axes" upon which this method should draw. If you
                 send in your own figure, it should be wide but not tall like shape 4,1
      """
      if isinstance(X, pd.DataFrame):
          X = X.values
      if isinstance(y, pd.Series):
          y = y.values
  
      if class_names is not None and np.max(y) >= len(class_names):
          raise ValueError(
              f"Target label values (for now) must be 0..{len(class_names)-1} for n={len(class_names)} labels"
          )
  
      if model.__class__.__module__.startswith(
          "tensorflow.python.keras"
      ) or model.__class__.__module__.startswith("keras"):
          if not (
              hasattr(model, "predict")
              and callable(getattr(model, "predict"))
          ):
              raise ValueError(
                  "Keras model argument must implement method `predict()`"
              )
      elif not (
          hasattr(model, "predict_proba")
          and callable(getattr(model, "predict_proba"))
      ):
          raise ValueError(
              "model argument must implement method `predict_proba()`"
          )
  
      if len(X.shape) == 1 or (len(X.shape) == 2 and X.shape[1] == 1):
          decision_boundaries_univar(
              model=model,
              x=X,
              y=y,
              ntiles=ntiles,
              binary_threshold=binary_threshold,
              show=show,
              feature_name=feature_names[0]
              if feature_names is not None
              else None,
              target_name=target_name,
              class_names=class_names,
              markers=markers,
              fontsize=fontsize,
              fontname=fontname,
              dot_w=dot_w,
              sigma=sigma,
              yshift=yshift,
              colors=colors,
              figsize=figsize,
              ax=ax,
          )
      elif len(X.shape) == 2 and X.shape[1] == 2:
          decision_boundaries_bivar(
              model=model,
              X=X,
              y=y,
              ntiles=ntiles,
              tile_fraction=tile_fraction,
              binary_threshold=binary_threshold,
              show=show,
              feature_names=feature_names,
              target_name=target_name,
              class_names=class_names,
              markers=markers,
              boundary_marker=boundary_marker,
              boundary_markersize=boundary_markersize,
              fontsize=fontsize,
              fontname=fontname,
              dot_w=dot_w,
              colors=colors,
              ranges=ranges,
              figsize=figsize,
              ax=ax,
          )
      else:
          raise ValueError(f"Expecting 2D data not {X.shape}")
  
file_path: dtreeviz/dtreeviz/classifiers.py
imports: from typing import Tuple
  import matplotlib.pyplot
  import numpy
  import pandas
  from PIL import ImageColor
  from colour import Color
  from matplotlib import patches
  from matplotlib.collections import PatchCollection
  from dtreeviz import utils
  from dtreeviz.colors import adjust_colors
  from dtreeviz.utils import add_classifier_legend, _format_axes
label_desc: Use image node_id 1 for calling a global function with example usage: decision_boundaries(model, X, y, ntiles, tile_fraction, binary_threshold, show, feature_names, target_name, class_names, markers, boundary_marker, boundary_markersize, fontsize, fontname, dot_w, yshift, sigma, colors, ranges, figsize, ax) without return types