code: def _get_batch_comparison_plot_data(
      observations: List[Observation],
      batch_x: int,
      batch_y: int,
      rel: bool = False,
      status_quo_name: Optional[str] = None,
  ) -> PlotData:
      """Compute PlotData for comparing repeated arms across trials.
  
      Args:
          observations: List of observations.
          batch_x: Batch for x-axis.
          batch_y: Batch for y-axis.
          rel: Whether to relativize data against status_quo arm.
          status_quo_name: Name of the status_quo arm.
  
      Returns:
          PlotData: a plot data object.
      """
      if rel and status_quo_name is None:
          raise ValueError(
              "Experiment status quo must be set for rel=True"
          )
      x_observations = {
          observation.arm_name: observation
          for observation in observations
          if observation.features.trial_index == batch_x
      }
      y_observations = {
          observation.arm_name: observation
          for observation in observations
          if observation.features.trial_index == batch_y
      }
  
      # Assume input is well formed and metric_names are consistent across observations
      metric_names = observations[0].data.metric_names
      insample_data: Dict[str, PlotInSampleArm] = {}
      for arm_name, x_observation in x_observations.items():
          # Restrict to arms present in both trials
          if arm_name not in y_observations:
              continue
  
          y_observation = y_observations[arm_name]
          arm_data = {
              "name": arm_name,
              "y": {},
              "se": {},
              "parameters": x_observation.features.parameters,
              "y_hat": {},
              "se_hat": {},
              "context_stratum": None,
          }
          for i, mname in enumerate(x_observation.data.metric_names):
              # pyre-fixme[16]: Optional type has no attribute `__setitem__`.
              arm_data["y"][mname] = x_observation.data.means[i]
              # pyre-fixme[16]: Item `None` of `Union[None, Dict[typing.Any,
              #  typing.Any], Dict[str, typing.Union[None, bool, float, int, str]], str]`
              #  has no attribute `__setitem__`.
              arm_data["se"][mname] = np.sqrt(
                  x_observation.data.covariance[i][i]
              )
          for i, mname in enumerate(y_observation.data.metric_names):
              # pyre-fixme[16]: Item `None` of `Union[None, Dict[typing.Any,
              #  typing.Any], Dict[str, typing.Union[None, bool, float, int, str]], str]`
              #  has no attribute `__setitem__`.
              arm_data["y_hat"][mname] = y_observation.data.means[i]
              # pyre-fixme[16]: Item `None` of `Union[None, Dict[typing.Any,
              #  typing.Any], Dict[str, typing.Union[None, bool, float, int, str]], str]`
              #  has no attribute `__setitem__`.
              arm_data["se_hat"][mname] = np.sqrt(
                  y_observation.data.covariance[i][i]
              )
          # Expected `str` for 2nd anonymous parameter to call `dict.__setitem__` but got
          # `Optional[str]`.
          # pyre-fixme[6]:
          insample_data[arm_name] = PlotInSampleArm(**arm_data)
  
      return PlotData(
          metrics=metric_names,
          in_sample=insample_data,
          out_of_sample=None,
          status_quo_name=status_quo_name,
      )
  
imports: from copy import deepcopy
  from typing import Any, Dict, List, Optional, Tuple
  import numpy
  import plotly.graph_objs
  from ax.core.batch_trial import BatchTrial
  from ax.core.data import Data
  from ax.core.experiment import Experiment
  from ax.core.multi_type_experiment import MultiTypeExperiment
  from ax.core.observation import Observation
  from ax.modelbridge.cross_validation import CVResult
  from ax.modelbridge.transforms.convert_metric_names import convert_mt_observations
  from ax.plot.base import AxPlotConfig, AxPlotTypes, PlotData, PlotInSampleArm, PlotMetric, Z
  from ax.plot.helper import compose_annotation
  from ax.plot.scatter import _error_scatter_data, _error_scatter_trace
  from ax.utils.common.typeutils import not_none
  from plotly import subplots
label_desc: Use image node_id 4 for calling a global function with example usage: _get_batch_comparison_plot_data(observations, batch_x, batch_y, rel, status_quo_name) and returns: PlotData