code: def plot_contour_plotly(
      model: ModelBridge,
      param_x: str,
      param_y: str,
      metric_name: str,
      generator_runs_dict: TNullableGeneratorRunsDict = None,
      relative: bool = False,
      density: int = 50,
      slice_values: Optional[Dict[str, Any]] = None,
      lower_is_better: bool = False,
      fixed_features: Optional[ObservationFeatures] = None,
      trial_index: Optional[int] = None,
  ) -> go.Figure:
      """Plot predictions for a 2-d slice of the parameter space.
  
      Args:
          model: ModelBridge that contains model for predictions
          param_x: Name of parameter that will be sliced on x-axis
          param_y: Name of parameter that will be sliced on y-axis
          metric_name: Name of metric to plot
          generator_runs_dict: A dictionary {name: generator run} of generator runs
              whose arms will be plotted, if they lie in the slice.
          relative: Predictions relative to status quo
          density: Number of points along slice to evaluate predictions.
          slice_values: A dictionary {name: val} for the fixed values of the
              other parameters. If not provided, then the status quo values will
              be used if there is a status quo, otherwise the mean of numeric
              parameters or the mode of choice parameters.
          lower_is_better: Lower values for metric are better.
          fixed_features: An ObservationFeatures object containing the values of
              features (including non-parameter features like context) to be set
              in the slice.
  
      Returns:
          go.Figure: contour plot of objective vs. parameter values
      """
      if param_x == param_y:
          raise ValueError(
              "Please select different parameters for x- and y-dimensions."
          )
  
      if trial_index is not None:
          if slice_values is None:
              slice_values = {}
          slice_values["TRIAL_PARAM"] = str(trial_index)
  
      (
          data,
          f_plt,
          sd_plt,
          grid_x,
          grid_y,
          scales,
      ) = _get_contour_predictions(
          model=model,
          x_param_name=param_x,
          y_param_name=param_y,
          metric=metric_name,
          generator_runs_dict=generator_runs_dict,
          density=density,
          slice_values=slice_values,
          fixed_features=fixed_features,
      )
      config = {
          "arm_data": data,
          "blue_scale": BLUE_SCALE,
          "density": density,
          "f": f_plt,
          "green_scale": GREEN_SCALE,
          "green_pink_scale": GREEN_PINK_SCALE,
          "grid_x": grid_x,
          "grid_y": grid_y,
          "lower_is_better": lower_is_better,
          "metric": metric_name,
          "rel": relative,
          "sd": sd_plt,
          "xvar": param_x,
          "yvar": param_y,
          "x_is_log": scales["x"],
          "y_is_log": scales["y"],
      }
  
      config = AxPlotConfig(config, plot_type=AxPlotTypes.GENERIC).data
  
      traces = contour_config_to_trace(config)
  
      density = config["density"]
      grid_x = config["grid_x"]
      grid_y = config["grid_y"]
      lower_is_better = config["lower_is_better"]
      xvar = config["xvar"]
      yvar = config["yvar"]
  
      x_is_log = config["x_is_log"]
      y_is_log = config["y_is_log"]
  
      xrange = axis_range(grid_x, x_is_log)
      yrange = axis_range(grid_y, y_is_log)
  
      xtype = "log" if x_is_log else "linear"
      ytype = "log" if y_is_log else "linear"
  
      layout = {
          "title": metric_name,
          "annotations": [
              {
                  "font": {"size": 14},
                  "showarrow": False,
                  "text": "Mean",
                  "x": 0.25,
                  "xanchor": "center",
                  "xref": "paper",
                  "y": 1,
                  "yanchor": "bottom",
                  "yref": "paper",
              },
              {
                  "font": {"size": 14},
                  "showarrow": False,
                  "text": "Standard Error",
                  "x": 0.8,
                  "xanchor": "center",
                  "xref": "paper",
                  "y": 1,
                  "yanchor": "bottom",
                  "yref": "paper",
              },
          ],
          "autosize": False,
          "height": 450,
          "hovermode": "closest",
          "legend": {"orientation": "h", "x": 0, "y": -0.25},
          "margin": {"b": 100, "l": 35, "pad": 0, "r": 35, "t": 35},
          "width": 950,
          "xaxis": {
              "anchor": "y",
              "autorange": False,
              "domain": [0.05, 0.45],
              "exponentformat": "e",
              "range": xrange,
              "tickfont": {"size": 11},
              "tickmode": "auto",
              "title": xvar,
              "type": xtype,
          },
          "xaxis2": {
              "anchor": "y2",
              "autorange": False,
              "domain": [0.6, 1],
              "exponentformat": "e",
              "range": xrange,
              "tickfont": {"size": 11},
              "tickmode": "auto",
              "title": xvar,
              "type": xtype,
          },
          "yaxis": {
              "anchor": "x",
              "autorange": False,
              "domain": [0, 1],
              "exponentformat": "e",
              "range": yrange,
              "tickfont": {"size": 11},
              "tickmode": "auto",
              "title": yvar,
              "type": ytype,
          },
          "yaxis2": {
              "anchor": "x2",
              "autorange": False,
              "domain": [0, 1],
              "exponentformat": "e",
              "range": yrange,
              "tickfont": {"size": 11},
              "tickmode": "auto",
              "type": ytype,
          },
      }
  
      return go.Figure(data=traces, layout=layout)
  
file_path: Ax/ax/plot/contour.py
imports: import re
  from copy import deepcopy
  from typing import Any, Dict, Optional, Tuple
  import numpy
  import plotly.graph_objs
  from ax.core.observation import ObservationFeatures
  from ax.modelbridge.base import ModelBridge
  from ax.plot.base import AxPlotConfig, AxPlotTypes, PlotData
  from ax.plot.color import BLUE_SCALE, GREEN_PINK_SCALE, GREEN_SCALE
  from ax.plot.helper import axis_range, contour_config_to_trace, get_fixed_values, get_grid_for_parameter, get_plot_data, get_range_parameter, get_range_parameters, relativize_data, rgb, TNullableGeneratorRunsDict
label_desc: Use image node_id 3 for calling a global function with example usage: plot_contour_plotly(model, param_x, param_y, metric_name, generator_runs_dict, relative, density, slice_values, lower_is_better, fixed_features, trial_index) and returns: go