code: def plot_metric_scores(
      fobject, other_objects, title=None, verbose=True
  ):
      data = (
          fobject._subgroup_confusion_matrix_metrics_object.to_vertical_DataFrame()
      )
      data["label"] = np.repeat(fobject.label, data.shape[0]).astype(
          "U"
      )
      n = 1
      if other_objects is not None:
          basic_checks.check_other_fairness_objects(
              fobject, other_objects
          )
          for other_obj in other_objects:
              other_data = (
                  other_obj._subgroup_confusion_matrix_metrics_object.to_vertical_DataFrame()
              )
              other_data["label"] = np.repeat(
                  other_obj.label, other_data.shape[0]
              ).astype("U")
              data = pd.concat([data, other_data])
              n += 1
  
      # metric choosing and name change
      data = data.loc[
          data.metric.isin(["TPR", "PPV", "STP", "ACC", "FPR"])
      ]
      data.loc[data.metric == "TPR", "metric"] = "TPR    TP/(TP + FN)"
      data.loc[
          data.metric == "ACC", "metric"
      ] = "ACC   (TP + TN)/(TP + FP + TN + FN)"
      data.loc[data.metric == "PPV", "metric"] = "PPV    TP/(TP + FP)"
      data.loc[data.metric == "FPR", "metric"] = "FPR    FP/(FP + TN)"
      data.loc[
          data.metric == "STP", "metric"
      ] = "STP   (TP + FP)/(TP + FP + TN + FN)"
  
      # for x axis
      min_score = min(data.score)
      max_score = max(data.score)
  
      # subgroup y-axis value creation
      n_ticks = len(data.label.unique())
      tick_values = np.linspace(0, 1, n_ticks + 2)[1:-1]
  
      privileged_data = data.loc[data.subgroup == fobject.privileged]
      data = data.loc[data.subgroup != fobject.privileged]
  
      subgroup_tick_dict = {}
      label_tick_dict = {}
      for i in range(len(data.subgroup.unique())):
          subgroup = data.subgroup.unique()[i]
          subgroup_tick_dict[subgroup] = i
  
      for i in range(len(data.label.unique())):
          label = data.label.unique()[i]
          label_tick_dict[label] = tick_values[i]
  
      data["subgroup_numeric"] = [
          subgroup_tick_dict.get(sub) for sub in data.subgroup
      ]
      data = data.reset_index(drop=True)
      data.subgroup_numeric = data.subgroup_numeric + pd.Series(
          [label_tick_dict.get(lab) for lab in data.label]
      )
  
      # drwhy colors
      colors = _theme.get_default_colors(
          len(data.label.unique()), "line"
      )
  
      # fig creation
      fig = px.scatter(
          data,
          x="score",
          y="subgroup_numeric",
          color="label",
          color_discrete_sequence=colors,
          facet_col="metric",
          facet_col_wrap=1,
          custom_data=["subgroup", "label"],
      )
  
      fig.update_traces(
          hovertemplate="<br>".join(
              [
                  "<b>%{customdata[1]}</b><br>"
                  "Subgroup: %{customdata[0]}",
                  "Score: %{x}" "<extra></extra>",
              ]
          )
      )
  
      # point size
      fig.update_traces(mode="markers", marker_size=7)
  
      # axis ticks
      fig.update_xaxes(tickvals=np.arange(0, 1.01, 0.1))
  
      # cols and ref dicts are dependent on the arrangement of metrics and labels
      color_dict = {}
      k = 0
      for label in data.label.unique():
          color_dict[label] = colors[k]
          k += 1
  
      refs = ["y", "y2", "y3", "y4", "y5"]
      refs_dict = {}
      j = 1
      for metric in data.metric.unique():
          refs_dict[metric] = refs[len(refs) - j]
          j += 1
      # add lines
      lines_nan = False
  
      for metric in data.metric.unique():
          for label in data.label.unique():
              x = float(
                  privileged_data.loc[
                      (privileged_data.metric == metric)
                      & (privileged_data.label == label),
                      :,
                  ].score
              )
              if np.isnan(x):
                  lines_nan = True
                  continue
              # lines
              for subgroup in data.subgroup.unique():
                  y = float(
                      data.loc[
                          (data.metric == metric)
                          & (data.label == label)
                          & (data.subgroup == subgroup)
                      ].subgroup_numeric
                  )
                  # horizontal
  
                  x0 = float(
                      data.loc[
                          (data.metric == metric)
                          & (data.label == label)
                          & (data.subgroup == subgroup)
                      ].score
                  )
  
                  if np.isnan(x0):
                      lines_nan = True
                      continue
  
                  fig.add_shape(
                      type="line",
                      xref="x",
                      yref=refs_dict.get(metric),
                      x0=x0,
                      x1=x,
                      y0=y,
                      y1=y,
                      line=dict(color=color_dict.get(label), width=1),
                  )
              # vertical
              fig.add_shape(
                  type="line",
                  xref="x",
                  yref=refs_dict.get(metric),
                  x0=x,
                  x1=x,
                  y0=0,
                  y1=np.ceil(max(data.subgroup_numeric)),
                  line=dict(color=color_dict.get(label), width=2),
              )
  
      # theme and appearance
      if title is None:
          title = "Metric Scores"
  
      fig.update_layout(utils._fairness_theme(title))
  
      fig.for_each_annotation(
          lambda a: a.update(
              text=a.text.replace("metric=", ""),
              xanchor="left",
              x=0.05,
              font={"size": 15},
          )
      )
  
      # disable all y grids and
      # delete y axis names [fixed] number of refs
      for i in ["", "2", "3", "4", "5"]:
          fig.update_layout(
              {
                  "yaxis" + i + "_showgrid": False,
                  "yaxis" + i + "_zeroline": False,
              }
          )
          if i != "3":
              fig.update_layout({"yaxis" + i + "_title_text": ""})
  
      # names on y axis - each subgroup in middle of integers - 0.5, 1.5 ,...
      subgroup_tick_dict_updated = {}
      for sub, val in subgroup_tick_dict.items():
          subgroup_tick_dict_updated[sub] = val + 0.5
  
      # centers axis values
      fig.update_yaxes(
          tickvals=list(subgroup_tick_dict_updated.values()),
          ticktext=list(subgroup_tick_dict_updated.keys()),
          range=[
              -1 / 20 * len(subgroup_tick_dict),
              len(subgroup_tick_dict)
              + 1 / 20 * len(subgroup_tick_dict),
          ],
      )
  
      # delete y axis names [fixed] number of refs
      for i in ["", "2", "4", "5"]:
          fig.update_layout({"yaxis" + i + "_title_text": ""})
  
      fig.update_layout({"yaxis3_title_text": "subgroup"})
  
      # fixes rare bug where axis are in center and blank fields on left and right
      fig.update_xaxes(range=[min_score - 0.05, max_score + 0.05])
      fig.update_yaxes(showgrid=False, zeroline=False)
  
      # inform about nan's
      if lines_nan:
          data_joined = pd.concat([privileged_data, data])
          nan_labels = set(
              data_joined.label[np.isnan(data_joined.score)]
          )
  
          helper.verbose_cat(
              f"\nFound NaN's while plotting metric_scores in models : {nan_labels}\n"
              f"It is advisable to check 'metric_scores' attribute of the GroupFairnessClassification",
              verbose=verbose,
          )
  
      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 4 for calling a global function with example usage: plot_metric_scores(fobject, other_objects, title, verbose) and returns: fig