code: def plotly_lift_curve(
      lift_curve_df,
      cutoff=None,
      percentage=False,
      add_wizard=True,
      round=2,
  ):
      """returns a lift plot for values
  
      Args:
          lift_curve_df (pd.DataFrame): generated with get_liftcurve_df(pred_proba, y)
          cutoff (float, optional): cutoff above which samples get classified as
              positive. Defaults to None.
          percentage (bool, optional): Display percentages instead of absolute
              numbers along axis. Defaults to False.
          add_wizard (bool, optional): Add a line indicating how a perfect model
              would perform ("the wizard"). Defaults to True
          round (int, optional): Rounding to apply to floats. Defaults to 2.
  
      Returns:
          Plotly fig
      """
  
      if percentage:
          model_text = [
              f"model selected {pos:.{round}f}% of all positives in first {i:.{round}f}% sampled<br>"
              + f"precision={precision:.{round}f}% positives in sample<br>"
              + f"lift={pos/exp:.{round}f}"
              for (i, pos, exp, precision) in zip(
                  lift_curve_df.index_percentage,
                  lift_curve_df.cumulative_percentage_pos,
                  lift_curve_df.random_cumulative_percentage_pos,
                  lift_curve_df.precision,
              )
          ]
  
          random_text = [
              f"random selected {exp:.{round}f}% of all positives in first {i:.{round}f}% sampled<br>"
              + f"precision={precision:.{round}f}% positives in sample"
              for (i, pos, exp, precision) in zip(
                  lift_curve_df.index_percentage,
                  lift_curve_df.cumulative_percentage_pos,
                  lift_curve_df.random_cumulative_percentage_pos,
                  lift_curve_df.random_precision,
              )
          ]
      else:
          model_text = [
              f"model selected {pos} positives out of {i}<br>"
              + f"precision={precision:.{round}f}<br>"
              + f"lift={pos/exp:.{round}f}"
              for (i, pos, exp, precision) in zip(
                  lift_curve_df["index"],
                  lift_curve_df.positives,
                  lift_curve_df.random_pos,
                  lift_curve_df.precision,
              )
          ]
          random_text = [
              f"random selected {int(exp)} positives out of {i}<br>"
              + f"precision={precision:.{round}f}"
              for (i, pos, exp, precision) in zip(
                  lift_curve_df["index"],
                  lift_curve_df.positives,
                  lift_curve_df.random_pos,
                  lift_curve_df.random_precision,
              )
          ]
  
      trace0 = go.Scatter(
          x=lift_curve_df["index_percentage"].values
          if percentage
          else lift_curve_df["index"],
          y=np.round(
              lift_curve_df.cumulative_percentage_pos.values, round
          )
          if percentage
          else np.round(lift_curve_df.positives.values, round),
          name="model",
          text=model_text,
          hoverinfo="text",
      )
  
      trace1 = go.Scatter(
          x=lift_curve_df["index_percentage"].values
          if percentage
          else lift_curve_df["index"],
          y=np.round(
              lift_curve_df.random_cumulative_percentage_pos.values,
              round,
          )
          if percentage
          else np.round(lift_curve_df.random_pos.values, round),
          name="random",
          text=random_text,
          hoverinfo="text",
      )
      if add_wizard:
          if percentage:
              trace2 = go.Scatter(
                  x=[0.0, lift_curve_df.random_precision[0], 100],
                  y=[0.0, 100, 100],
                  text=[
                      "0%, 0%",
                      f"{lift_curve_df.random_precision[0]:.2f}%, 100%",
                      "100, 100%",
                  ],
                  name="perfect",
                  hoverinfo="text",
              )
          else:
              trace2 = go.Scatter(
                  x=[
                      0.0,
                      lift_curve_df["positives"].max(),
                      lift_curve_df["index"].max(),
                  ],
                  y=[
                      0.0,
                      lift_curve_df["positives"].max(),
                      lift_curve_df["positives"].max(),
                  ],
                  name="perfect",
              )
  
          data = [trace2, trace0, trace1]
      else:
          data = [trace0, trace1]
  
      fig = go.Figure(data)
  
      fig.update_layout(
          title=dict(text="Lift curve", x=0.5, font=dict(size=18)),
          xaxis_title="Percentage sampled"
          if percentage
          else "Number sampled",
          yaxis_title="Percentage of positive"
          if percentage
          else "Number of positives",
          xaxis=dict(spikemode="across"),
          hovermode="x",
          plot_bgcolor="#fff",
      )
  
      fig.update_layout(legend=dict(xanchor="center", y=0.9, x=0.1))
      if percentage:
          fig.update_layout(xaxis=dict(range=[0, 100]))
      else:
          fig.update_layout(
              xaxis=dict(range=[0, lift_curve_df["index"].max()])
          )
  
      if cutoff is not None:
          # cutoff_idx = max(0, (np.abs(lift_curve_df.pred_proba - cutoff)).argmin() - 1)
          cutoff_idx = max(
              0,
              len(lift_curve_df[lift_curve_df.pred_proba >= cutoff])
              - 1,
          )
          if percentage:
              cutoff_x = lift_curve_df["index_percentage"].iloc[
                  cutoff_idx
              ]
          else:
              cutoff_x = lift_curve_df["index"].iloc[cutoff_idx]
  
          cutoff_n = lift_curve_df["index"].iloc[cutoff_idx]
          cutoff_pos = lift_curve_df["positives"].iloc[cutoff_idx]
          cutoff_random_pos = int(
              lift_curve_df["random_pos"].iloc[cutoff_idx]
          )
          cutoff_lift = np.round(
              lift_curve_df["positives"].iloc[cutoff_idx]
              / lift_curve_df.random_pos.iloc[cutoff_idx],
              1,
          )
          cutoff_precision = np.round(
              lift_curve_df["precision"].iloc[cutoff_idx], 2
          )
          cutoff_random_precision = np.round(
              lift_curve_df["random_precision"].iloc[cutoff_idx], 2
          )
  
          fig.update_layout(
              shapes=[
                  dict(
                      type="line",
                      xref="x",
                      yref="y",
                      x0=cutoff_x,
                      x1=cutoff_x,
                      y0=0,
                      y1=100.0
                      if percentage
                      else lift_curve_df.positives.max(),
                  )
              ]
          )
          fig.update_layout(
              annotations=[
                  go.layout.Annotation(
                      x=cutoff_x,
                      y=5,
                      yref="y",
                      text=f"cutoff={cutoff:.{round}f}",
                  ),
                  go.layout.Annotation(
                      x=0.5,
                      y=0.4,
                      text=f"Model: {cutoff_pos} out {cutoff_n} ({cutoff_precision:.{round}f}%)",
                      showarrow=False,
                      align="right",
                      xref="paper",
                      yref="paper",
                      xanchor="left",
                      yanchor="top",
                  ),
                  go.layout.Annotation(
                      x=0.5,
                      y=0.33,
                      text=f"Random: {cutoff_random_pos} out {cutoff_n} ({cutoff_random_precision:.{round}f}%)",
                      showarrow=False,
                      align="right",
                      xref="paper",
                      yref="paper",
                      xanchor="left",
                      yanchor="top",
                  ),
                  go.layout.Annotation(
                      x=0.5,
                      y=0.26,
                      text=f"Lift: {cutoff_lift}",
                      showarrow=False,
                      align="right",
                      xref="paper",
                      yref="paper",
                      xanchor="left",
                      yanchor="top",
                  ),
              ]
          )
      fig.update_layout(margin=dict(t=40, b=40, l=40, 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 5 for calling a global function with example usage: plotly_lift_curve(lift_curve_df, cutoff, percentage, add_wizard, round) and returns: fig