code: def plot_density(fobject, other_objects, title):
      data = pd.DataFrame(columns=["y", "y_hat", "subgroup", "model"])
      objects = [fobject]
      if other_objects is not None:
          for other_obj in other_objects:
              objects.append(other_obj)
      for obj in objects:
          for subgroup in np.unique(obj.protected):
              y, y_hat = (
                  obj.y[obj.protected == subgroup],
                  obj.y_hat[obj.protected == subgroup],
              )
              data_to_append = pd.DataFrame(
                  {
                      "y": y,
                      "y_hat": y_hat,
                      "subgroup": np.repeat(subgroup, len(y)),
                      "model": np.repeat(obj.label, len(y)),
                  }
              )
              data = pd.concat([data, data_to_append])
  
      fig = go.Figure()
  
      counter = 0
      for model in data.model.unique():
          for i, sub in enumerate(data.subgroup.unique()):
              counter += 1
              fig.add_trace(
                  go.Violin(
                      box_visible=True,
                      x=data.loc[
                          (data.subgroup == sub) & (data.model == model)
                      ].y_hat,
                      y0=sub + model,
                      name=sub,
                      fillcolor=_theme.get_default_colors(
                          len(data.subgroup.unique()), type="line"
                      )[i],
                      opacity=0.9,
                      line_color="black",
                      hoveron="points",
                  )
              )
  
      violins_in_model = int(counter / len(data.model.unique()))
      starter_violins = np.arange(0, counter, violins_in_model)
  
      fig.update_xaxes(title="prediction")
      fig.update_yaxes(
          title="model",
          tickvals=list((starter_violins + (violins_in_model - 1) / 2)),
          ticktext=list(data.model.unique()),
      )
  
      # hide doubling entries in legend
      legend_entries = set()
      for trace in fig["data"]:
          legend_entries.add(trace["name"])
  
      for trace in fig["data"]:
          if trace["name"] in legend_entries:
              legend_entries.remove(trace["name"])
          else:
              trace["showlegend"] = False
  
      if title is None:
          title = "Density plot"
      fig.update_layout(utils._fairness_theme(title))
      fig.update_traces(hovertemplate="outlier prediction: %{x:.3f}")
  
      return fig
  
imports: import numpy
  import pandas
  import plotly.express
  import plotly.graph_objects
  from plotly.subplots import make_subplots
  from .None import checks
  from .None import utils
  from .._basics import checks
  from .._basics.exceptions import ParameterCheckError
  from ...None import _theme
  from ..._explainer import helper
label_desc: Use image node_id 10 for calling a global function with example usage: plot_density(fobject, other_objects, title) and returns: fig