code: def plotly_confusion_matrix(
      cm, labels=None, percentage=True, normalize="all"
  ):
      """Generates Plotly fig confusion matrix
  
      Args:
          cm (np.ndarray): generated by sklearn.metrics.confusion_matrix(y_true, preds)
          labels (List[str], optional): List of labels for classes. Defaults to None.
          percentage (bool, optional): Display percentages on top of the counts.
              Defaults to True.
          normalize ({‘observed’, ‘pred’, ‘all’}): normalizes confusion matrix over
              the true (rows), predicted (columns) conditions or all the population.
              Defaults to 'all'.
  
      Returns:
          Plotly fig
      """
  
      if normalize not in ["observed", "pred", "all"]:
          raise ValueError(
              "Error! parameters normalize must be one of {'observed', 'pred', 'all'} !"
          )
  
      with np.errstate(all="ignore"):
          if normalize == "all":
              cm_normalized = np.round(100 * cm / cm.sum(), 1)
          elif normalize == "observed":
              cm_normalized = np.round(
                  100 * cm / cm.sum(axis=1, keepdims=True), 1
              )
          elif normalize == "pred":
              cm_normalized = np.round(
                  100 * cm / cm.sum(axis=0, keepdims=True), 1
              )
  
          cm_normalized = np.nan_to_num(cm_normalized)
  
      if labels is None:
          labels = [str(i) for i in range(cm.shape[0])]
  
      zmax = 130  # to keep the text readable at 100% accuracy
  
      data = [
          go.Heatmap(
              z=cm_normalized,
              x=[f" {lab}" for lab in labels],
              y=[f" {lab}" for lab in labels],
              hoverinfo="skip",
              zmin=0,
              zmax=zmax,
              colorscale="Blues",
              showscale=False,
          )
      ]
  
      layout = go.Layout(
          title="Confusion Matrix",
          xaxis=dict(
              title="predicted",
              constrain="domain",
              tickmode="array",
              showgrid=False,
              tickvals=[f" {lab}" for lab in labels],
              ticktext=[f" {lab}" for lab in labels],
          ),
          yaxis=dict(
              title=dict(text="observed", standoff=20),
              autorange="reversed",
              side="left",
              scaleanchor="x",
              scaleratio=1,
              showgrid=False,
              tickmode="array",
              tickvals=[f" {lab}" for lab in labels],
              ticktext=[f" {lab}" for lab in labels],
          ),
          plot_bgcolor="#fff",
      )
      fig = go.Figure(data, layout)
      annotations = []
      for x in range(cm.shape[0]):
          for y in range(cm.shape[1]):
              top_text = (
                  f"{cm_normalized[x, y]}%"
                  if percentage
                  else f"{cm[x, y]}"
              )
              bottom_text = (
                  f"{cm_normalized[x, y]}%"
                  if not percentage
                  else f"{cm[x, y]}"
              )
              annotations.extend(
                  [
                      go.layout.Annotation(
                          x=fig.data[0].x[y],
                          y=fig.data[0].y[x],
                          text=top_text,
                          showarrow=False,
                          font=dict(size=20),
                      ),
                      go.layout.Annotation(
                          x=fig.data[0].x[y],
                          y=fig.data[0].y[x],
                          text=f" <br> <br> <br>({bottom_text})",
                          showarrow=False,
                          font=dict(size=12),
                      ),
                  ]
              )
      longest_label = max([len(label) for label in labels])
      fig.update_layout(annotations=annotations)
      fig.update_layout(
          margin=dict(t=40, b=40, l=longest_label * 7, r=40)
      )
      return fig
  
imports: import warnings
  import numpy
  import pandas
  from pandas.api.types import is_numeric_dtype
  import plotly.graph_objs
  from plotly.subplots import make_subplots
  from sklearn.metrics import classification_report, confusion_matrix, precision_recall_curve, roc_curve, roc_auc_score, average_precision_score
  from .explainer_methods import matching_cols, safe_isinstance
label_desc: Use image node_id 11 for calling a global function with example usage: plotly_confusion_matrix(cm, labels, percentage, normalize) and returns: fig