code: def plotly_xgboost_trees(
      xgboost_preds_df,
      highlight_tree=None,
      y=None,
      round=2,
      pos_label=1,
      target="",
      units="",
      higher_is_better=True,
  ):
      """Generate a plot showing the prediction of every single tree inside an XGBoost model
  
      Args:
          xgboost_preds_df (pd.DataFrame): generated with get_xgboost_preds_df(...)
          highlight_tree (int, optional): DecisionTree to highlight in graph. Defaults to None.
          y (np.ndarray, optional): Target values. Defaults to None.
          round (int, optional): Apply rounding to floats. Defaults to 2.
          pos_label (int, optional): For RandomForestClassifier: Class label
              to generate graph for. Defaults to 1.
          target (str, optional): Description of target variable. Defaults to "".
          units (str, optional): Units of target variable. Defaults to "".
          higher_is_better (bool, optional): up is green, down is red. If False then
              flip the colors.
  
      Returns:
          Plotly fig
      """
  
      xgboost_preds_df["color"] = "blue"
      xgboost_preds_df.loc[0, "color"] = "yellow"
      if highlight_tree is not None:
          xgboost_preds_df.loc[highlight_tree + 1, "color"] = "red"
  
      trees = xgboost_preds_df.tree.values[1:]
      colors = xgboost_preds_df.color.values[1:]
  
      is_classifier = (
          True if "pred_proba" in xgboost_preds_df.columns else False
      )
  
      colors = xgboost_preds_df.color.values
      if is_classifier:
          final_prediction = xgboost_preds_df.pred_proba.values[-1]
          base_prediction = xgboost_preds_df.pred_proba.values[0]
          preds = xgboost_preds_df.pred_proba.values[1:]
          bases = xgboost_preds_df.pred_proba.values[:-1]
          diffs = xgboost_preds_df.pred_proba_diff.values[1:]
  
          texts = [
              f"tree no {t}:<br>change = {100*d:.{round}f}%<br> click for detailed info"
              for (t, d) in zip(trees, diffs)
          ]
          texts.insert(
              0,
              f"Base prediction: <br>proba = {100*base_prediction:.{round}f}%",
          )
          texts.append(
              f"Final Prediction: <br>proba = {100*final_prediction:.{round}f}%"
          )
      else:
          final_prediction = xgboost_preds_df.pred.values[-1]
          base_prediction = xgboost_preds_df.pred.values[0]
          preds = xgboost_preds_df.pred.values[1:]
          bases = xgboost_preds_df.pred.values[:-1]
          diffs = xgboost_preds_df.pred_diff.values[1:]
  
          texts = [
              f"tree no {t}:<br>change = {d:.{round}f}<br> click for detailed info"
              for (t, d) in zip(trees, diffs)
          ]
          texts.insert(
              0,
              f"Base prediction: <br>pred = {base_prediction:.{round}f}",
          )
          texts.append(
              f"Final Prediction: <br>pred = {final_prediction:.{round}f}"
          )
  
      green_fill, green_line = (
          "rgba(50, 200, 50, 1.0)",
          "rgba(40, 160, 50, 1.0)",
      )
      yellow_fill, yellow_line = (
          "rgba(230, 230, 30, 1.0)",
          "rgba(190, 190, 30, 1.0)",
      )
      blue_fill, blue_line = (
          "rgba(55, 128, 191, 0.7)",
          "rgba(55, 128, 191, 1.0)",
      )
      red_fill, red_line = (
          "rgba(219, 64, 82, 0.7)",
          "rgba(219, 64, 82, 1.0)",
      )
  
      if higher_is_better:
          fill_color_up, line_color_up = green_fill, green_line
          fill_color_down, line_color_down = red_fill, red_line
      else:
          fill_color_up, line_color_up = red_fill, red_line
          fill_color_down, line_color_down = green_fill, green_line
  
      fill_colors = [
          fill_color_up if diff > 0 else fill_color_down
          for diff in diffs
      ]
      line_colors = [
          line_color_up if diff > 0 else line_color_down
          for diff in diffs
      ]
  
      fill_colors.insert(0, yellow_fill)
      line_colors.insert(0, yellow_line)
  
      fill_colors.append(blue_fill)
      line_colors.append(blue_line)
  
      trees = np.append(trees, len(trees))
      trees = np.insert(trees, 0, -1)
      bases = np.insert(bases, 0, 0)
      bases = np.append(bases, 0)
      diffs = np.insert(diffs, 0, base_prediction)
      diffs = np.append(diffs, final_prediction)
  
      trace0 = go.Bar(
          x=trees,
          y=bases,
          hoverinfo="skip",
          name="",
          showlegend=False,
          marker=dict(color="rgba(1,1,1, 0.0)"),
      )
  
      trace1 = go.Bar(
          x=trees,
          y=diffs,
          text=texts,
          name="",
          hoverinfo="text",
          showlegend=False,
          marker=dict(
              color=fill_colors,
              line=dict(
                  color=line_colors,
                  width=2,
              ),
          ),
      )
  
      if target:
          title = (
              f"Individual xgboost decision trees predicting {target}"
          )
          yaxis_title = (
              f"Predicted {target} {f'({units})' if units else ''}"
          )
      else:
          title = f"Individual xgboost decision trees"
          yaxis_title = (
              f"Predicted outcome ({units})"
              if units
              else "Predicted outcome"
          )
  
      layout = go.Layout(
          title=title,
          barmode="stack",
          plot_bgcolor="#fff",
          yaxis=dict(title=yaxis_title),
          xaxis=dict(title="decision trees"),
      )
  
      fig = go.Figure(data=[trace0, trace1], layout=layout)
  
      shapes = []
      annotations = []
  
      if y is not None:
          shapes.append(
              dict(
                  type="line",
                  xref="x",
                  yref="y",
                  x0=trees.min(),
                  x1=trees.max(),
                  y0=y,
                  y1=y,
                  line=dict(color="black", width=4, dash="dashdot"),
              )
          )
          annotations.append(
              go.layout.Annotation(
                  x=0.75 * trees.max(),
                  y=y,
                  text=f"Observed={y}",
                  bgcolor="white",
              )
          )
  
      fig.update_layout(shapes=shapes)
      fig.update_layout(annotations=annotations)
      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 21 for calling a global function with example usage: plotly_xgboost_trees(xgboost_preds_df, highlight_tree, y, round, pos_label, target, units, higher_is_better) and returns: fig