code: def silhouette_analysis_from_results(
      X,
      cluster_labels,
      metric="euclidean",
      figsize=None,
      cmap="nipy_spectral",
      text_fontsize="medium",
      ax=None,
  ):
      """
      Same as `silhouette_plot` but takes cluster_labels as input.
      Useful if you want to train the model yourself
  
      Notes
      -----
      .. versionadded:: 0.8.3
      """
      cluster_labels = np.asarray(cluster_labels)
  
      le = LabelEncoder()
      cluster_labels_encoded = le.fit_transform(cluster_labels)
  
      n_clusters = len(np.unique(cluster_labels))
  
      silhouette_avg = silhouette_score(
          X, cluster_labels, metric=metric
      )
  
      sample_silhouette_values = silhouette_samples(
          X, cluster_labels, metric=metric
      )
  
      if ax is None:
          _, ax = plt.subplots(1, 1, figsize=figsize)
  
      ax.set_xlim([-0.1, 1])
  
      if hasattr(X, "shape"):
          length = X.shape[0]
      else:
          length = len(X)
      ax.set_ylim([0, length + (n_clusters + 1) * 10 + 10])
  
      ax.set_xlabel(
          "Silhouette coefficient values", fontsize=text_fontsize
      )
      ax.set_ylabel("Cluster label", fontsize=text_fontsize)
  
      y_lower = 10
  
      for i in range(n_clusters):
          ax.set_title(
              f"Silhouette Analysis (n_clusters={n_clusters})",
              fontsize="large",
          )
  
          ith_cluster_silhouette_values = sample_silhouette_values[
              cluster_labels_encoded == i
          ]
  
          ith_cluster_silhouette_values.sort()
  
          size_cluster_i = ith_cluster_silhouette_values.shape[0]
          y_upper = y_lower + size_cluster_i
  
          color = plt.cm.get_cmap(cmap)(float(i) / n_clusters)
  
          ax.fill_betweenx(
              np.arange(y_lower, y_upper),
              0,
              ith_cluster_silhouette_values,
              facecolor=color,
              edgecolor=color,
              alpha=0.7,
          )
  
          ax.text(
              -0.05,
              y_lower + 0.5 * size_cluster_i,
              str(le.classes_[i]),
              fontsize=text_fontsize,
          )
  
          y_lower = y_upper + 10
  
      ax.axvline(
          x=silhouette_avg,
          color="red",
          linestyle="--",
          label="Silhouette score: {0:0.3f}".format(silhouette_avg),
      )
  
      ax.set_yticks([])  # Clear the y-axis labels / ticks
      ax.set_xticks(np.arange(-0.1, 1.0, 0.2))
  
      ax.tick_params(labelsize=text_fontsize)
      ax.legend(loc="best", fontsize=text_fontsize)
      return ax
  
file_path: sklearn-evaluation/src/sklearn_evaluation/plot/clustering.py
imports: import time
  import matplotlib.pyplot
  import numpy
  from sklearn.base import clone
  from sklearn.metrics import silhouette_samples, silhouette_score
  from sklearn.preprocessing import LabelEncoder
  from joblib import Parallel, delayed
  from sklearn_evaluation.telemetry import SKLearnEvaluationLogger
  from ploomber_core.exceptions import modify_exceptions
  from ploomber_core import deprecated
label_desc: Use image node_id 5 for calling a global function with example usage: silhouette_analysis_from_results(X, cluster_labels, metric, figsize, cmap, text_fontsize, ax) and returns: ax