code: def plotly_actual_vs_col(
      y,
      preds,
      col,
      col_name=None,
      idxs=None,
      round=2,
      points=True,
      winsor=0,
      na_fill=-999,
      units="",
      target="",
      index_name="index",
      cats_order=None,
  ):
      """Generates a residuals plot vs a particular feature column.
  
      Args:
          y (np.ndarray): array of actual target values
          preds (np.ndarray): array of predicted values
          col (pd.Series): series of values to be used as x-axis
          col_name (str, optional): feature name to display.
              Defaults to None, in which case col.name gets used.
          idxs (List[str], optional): str identifiers for each sample.
              Defaults to None.
          round (int, optional): Rounding to apply to floats. Defaults to 2.
          points (bool, optional): For categorical features display point cloud
              next to violin plots. Defaults to True.
          winsor (int, optional): Winsorize the outliers. Remove the top `winsor`
              percent highest and lowest values. Defaults to 0.
          na_fill (int, optional): Value used to fill missing values. Defaults to -999.
          index_name (str): identifier for idxs. Defaults to "index".
          cats_order (list, optional): list of categories to display. If None
              defaults to X_col.unique().tolist() so displays all categories.
  
  
      Returns:
          Plotly fig
      """
      if col_name is None:
          try:
              col_name = col.name
          except:
              col_name = "Feature"
  
      if idxs is not None:
          assert len(idxs) == len(preds)
          idxs = [str(idx) for idx in idxs]
      else:
          idxs = [str(i) for i in range(len(preds))]
  
      y_text = [
          f"{index_name}: {idx}<br>Observed {target}: {actual:.{round}f}<br>Prediction: {pred:.{round}f}"
          for idx, actual, pred in zip(idxs, y, preds)
      ]
  
      if not is_numeric_dtype(col):
          if cats_order is None:
              cats_order = sorted(col.unique().tolist())
          n_cats = len(cats_order)
  
          if points:
              fig = make_subplots(
                  rows=1,
                  cols=2 * n_cats,
                  column_widths=[3, 1] * n_cats,
                  shared_yaxes=True,
              )
              showscale = True
          else:
              fig = make_subplots(
                  rows=1, cols=n_cats, shared_yaxes=True
              )
  
          fig.update_yaxes(
              range=[
                  np.percentile(y, winsor),
                  np.percentile(y, 100 - winsor),
              ]
          )
  
          for i, cat in enumerate(cats_order):
              column = 1 + i * 2 if points else 1 + i
              fig.add_trace(
                  go.Violin(
                      x=col[col == cat],
                      y=y[col == cat],
                      name=cat,
                      box_visible=True,
                      meanline_visible=True,
                      showlegend=False,
                  ),
                  row=1,
                  col=column,
              )
              if points:
                  fig.add_trace(
                      go.Scattergl(
                          x=np.random.randn(len(col[col == cat])),
                          y=y[col == cat],
                          mode="markers",
                          showlegend=False,
                          text=[
                              t for t, b in zip(y_text, col == cat) if b
                          ],
                          hoverinfo="text",
                          marker=dict(
                              size=7, opacity=0.6, color="blue"
                          ),
                      ),
                      row=1,
                      col=column + 1,
                  )
  
          if points:
              for i in range(n_cats):
                  fig.update_xaxes(
                      showgrid=False,
                      zeroline=False,
                      visible=False,
                      row=1,
                      col=2 + i * 2,
                  )
                  fig.update_yaxes(
                      showgrid=False,
                      zeroline=False,
                      row=1,
                      col=2 + i * 2,
                  )
  
          fig.update_layout(
              title=f"Observed {target} vs {col_name}",
              yaxis=dict(
                  title=f"Observed {target} ({units})"
                  if units
                  else f"Observed {target}"
              ),
              hovermode="closest",
          )
          fig.update_layout(margin=dict(t=40, b=40, l=40, r=40))
          return fig
  
      else:
          col[col == na_fill] = np.nan
  
          trace0 = go.Scattergl(
              x=col,
              y=y,
              mode="markers",
              name="Observed",
              text=y_text,
              hoverinfo="text",
          )
  
          data = [trace0]
  
          layout = go.Layout(
              title=f"Observed {target} vs {col_name}",
              yaxis=dict(
                  title=f"Observed {target} ({units})"
                  if units
                  else f"Observed {target}"
              ),
              xaxis=dict(title=f"{col_name} value"),
              plot_bgcolor="#fff",
              hovermode="closest",
          )
  
          fig = go.Figure(data, layout)
          fig.update_yaxes(
              range=[
                  np.percentile(y, winsor),
                  np.percentile(y, 100 - winsor),
              ]
          )
          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 18 for calling a global function with example usage: plotly_actual_vs_col(y, preds, col, col_name, idxs, round, points, winsor, na_fill, units, target, index_name, cats_order) and returns: fig, fig