code: def interact_multiple_pareto_frontier(
      frontier_lists: Dict[str, List[ParetoFrontierResults]],
      CI_level: float = DEFAULT_CI_LEVEL,
      show_parameterization_on_hover: bool = True,
  ) -> AxPlotConfig:
      """Plot a Pareto frontiers from a list of lists of NamedParetoFrontierResults
      objects that we want to compare.
  
      Args:
          frontier_lists (Dict[List[ParetoFrontierResults]]): A dictionary of multiple
              lists of Pareto frontier computation results to plot for comparison.
              Each list of ParetoFrontierResults contains a list of the results of
              the same pareto frontier but under different pairs of metrics.
              Different List[ParetoFrontierResults] must contain the the same pairs
              of metrics for this function to work.
          CI_level (float, optional): The confidence level, i.e. 0.95 (95%)
          show_parameterization_on_hover (bool, optional): If True, show the
              parameterization of the points on the frontier on hover.
  
      Returns:
          AEPlotConfig: The resulting Plotly plot definition.
  
      """
      if not frontier_lists:
          raise ValueError(
              "Must receive a non-empty list of pareto frontiers to plot."
          )
  
      # Check all the lists have the same length
      vals = frontier_lists.values()
      length = len(frontier_lists[next(iter(frontier_lists))])
      if not all(len(item) == length for item in vals):
          raise ValueError(
              "Not all lists in frontier_lists have the same length."
          )
  
      # Transform the frontier_lists to lists of frontiers where each list
      # corresponds to one pair of metrics with multiple frontiers
      list_of_frontiers = [
          dict(zip(frontier_lists.keys(), t))
          for t in zip(*frontier_lists.values())
      ]
      # Get the traces and shapes for plotting
      traces = []
      shapes = []
      for frontiers in list_of_frontiers:
          config = plot_multiple_pareto_frontiers(
              frontiers=frontiers,
              CI_level=CI_level,
              show_parameterization_on_hover=show_parameterization_on_hover,
          )
          for i in range(len(config.data["data"])):
              traces.append(config.data["data"][i])
          shapes.append(config.data["layout"].get("shapes", []))
  
      num_frontiers = len(frontier_lists)
      num_metric_pairs = len(list_of_frontiers)
      for i, trace in enumerate(traces):
          if (
              i < num_frontiers
          ):  # Only the traces for metric 1 v.s. metric 2 are initially set to visible
              trace["visible"] = True
          else:  # All other plot traces are not visible initially
              trace["visible"] = False
  
      dropdown = []
      for i, frontiers in enumerate(list_of_frontiers):
          # Only plot traces for the current pair of metrics are visible at a given time.
          visible = [False] * (num_metric_pairs * num_frontiers)
          for j in range(i * num_frontiers, (i + 1) * num_frontiers):
              visible[j] = True
          # Get the first frontier for reference of metric names
          first_frontier = list(frontiers.values())[0]
          rel_y = (
              first_frontier.primary_metric
              not in first_frontier.absolute_metrics
          )
          rel_x = (
              first_frontier.secondary_metric
              not in first_frontier.absolute_metrics
          )
          primary_metric = first_frontier.primary_metric
          secondary_metric = first_frontier.secondary_metric
          dropdown.append(
              {
                  "method": "update",
                  "args": [
                      {"visible": visible, "method": "restyle"},
                      {
                          "yaxis.title": primary_metric,
                          "xaxis.title": secondary_metric,
                          "yaxis.ticksuffix": "%" if rel_y else "",
                          "xaxis.ticksuffix": "%" if rel_x else "",
                          "shapes": shapes[i],
                      },
                  ],
                  "label": f"{primary_metric} vs {secondary_metric}",
              }
          )
  
      # Set initial layout arguments.
      initial_first_frontier = list(list_of_frontiers[0].values())[0]
      rel_x = (
          initial_first_frontier.secondary_metric
          not in initial_first_frontier.absolute_metrics
      )
      rel_y = (
          initial_first_frontier.primary_metric
          not in initial_first_frontier.absolute_metrics
      )
      secondary_metric = initial_first_frontier.secondary_metric
      primary_metric = initial_first_frontier.primary_metric
  
      layout = go.Layout(
          title="Pareto Frontier",
          xaxis={
              "title": secondary_metric,
              "ticksuffix": "%" if rel_x else "",
              "zeroline": True,
          },
          yaxis={
              "title": primary_metric,
              "ticksuffix": "%" if rel_y else "",
              "zeroline": True,
          },
          updatemenus=[
              {
                  "buttons": dropdown,
                  "x": 0.075,
                  "xanchor": "left",
                  "y": 1.1,
                  "yanchor": "middle",
              }
          ],
          hovermode="closest",
          legend={
              "orientation": "h",
              "yanchor": "top",
              "y": -0.20,
              "xanchor": "auto",
              "x": 0.075,
          },
          showlegend=True,
          width=750,
          height=550,
          margin=go.layout.Margin(
              pad=4, l=225, b=125, t=75
          ),  # noqa E741
          shapes=shapes[0],
      )
  
      fig = go.Figure(data=traces, layout=layout)
      return AxPlotConfig(data=fig, plot_type=AxPlotTypes.GENERIC)
  
imports: import warnings
  from typing import Dict, Iterable, List, Optional, Tuple, Union
  import numpy
  import pandas
  import plotly.graph_objs
  from ax.core.experiment import Experiment
  from ax.core.objective import MultiObjective
  from ax.core.optimization_config import MultiObjectiveOptimizationConfig, OptimizationConfig
  from ax.core.outcome_constraint import ObjectiveThreshold
  from ax.exceptions.core import UserInputError
  from ax.plot.base import AxPlotConfig, AxPlotTypes, CI_OPACITY, DECIMALS
  from ax.plot.color import COLORS, DISCRETE_COLOR_SCALE, rgba
  from ax.plot.helper import _format_CI, _format_dict, extend_range
  from ax.plot.pareto_utils import ParetoFrontierResults
  from ax.service.utils.best_point_mixin import BestPointMixin
  from ax.utils.common.typeutils import checked_cast, not_none
  from plotly import express
  from scipy.stats import norm
label_desc: Use image node_id 10 for calling a global function with example usage: interact_multiple_pareto_frontier(frontier_lists, CI_level, show_parameterization_on_hover) and returns: AxPlotConfig