code: def _scale_translate(fig, scale_x, scale_y, translate_x, translate_y):
      """
      Scale a figure and translate it to sub-region of the original
      figure canvas.
  
      Note: If the input figure has a title, this title is converted into an
      annotation and scaled along with the rest of the figure.
  
      Note: This function mutates the input fig dict
  
      Note: This function assumes that the normalize_subplot_ids function has
      already been run on the figure, so that all layout subplot properties in
      use are explicitly present in the figure's layout.
  
      Parameters
      ----------
      fig: dict
          A plotly figure dict
      scale_x: float
          Factor by which to scale the figure in the x-direction. This will
          typically be a value < 1.  E.g. a value of 0.5 will cause the
          resulting figure to be half as wide as the original.
      scale_y: float
          Factor by which to scale the figure in the y-direction. This will
          typically be a value < 1
      translate_x: float
          Factor by which to translate the scaled figure in the x-direction in
          normalized coordinates.
      translate_y: float
          Factor by which to translate the scaled figure in the x-direction in
          normalized coordinates.
      """
      data = fig.setdefault("data", [])
      layout = fig.setdefault("layout", {})
  
      def scale_translate_x(x):
          return [
              min(x[0] * scale_x + translate_x, 1),
              min(x[1] * scale_x + translate_x, 1),
          ]
  
      def scale_translate_y(y):
          return [
              min(y[0] * scale_y + translate_y, 1),
              min(y[1] * scale_y + translate_y, 1),
          ]
  
      def perform_scale_translate(obj):
          domain = obj.setdefault("domain", {})
          x = domain.get("x", [0, 1])
          y = domain.get("y", [0, 1])
  
          domain["x"] = scale_translate_x(x)
          domain["y"] = scale_translate_y(y)
  
      # Scale/translate traces
      for trace in data:
          trace_type = trace.get("type", "scatter")
          if trace_type in _domain_trace_types:
              perform_scale_translate(trace)
  
      # Scale/translate subplot containers
      for prop in layout:
          for subplot_type in _subplot_types:
              if prop.startswith(subplot_type):
                  perform_scale_translate(layout[prop])
  
      for prop in layout:
          if prop.startswith("xaxis"):
              xaxis = layout[prop]
              x_domain = xaxis.get("domain", [0, 1])
              xaxis["domain"] = scale_translate_x(x_domain)
          elif prop.startswith("yaxis"):
              yaxis = layout[prop]
              y_domain = yaxis.get("domain", [0, 1])
              yaxis["domain"] = scale_translate_y(y_domain)
  
      # convert title to annotation
      # This way the annotation will be scaled with the reset of the figure
      annotations = layout.get("annotations", [])
  
      title = layout.pop("title", None)
      if title:
          titlefont = layout.pop("titlefont", {})
          title_fontsize = titlefont.get("size", 17)
          min_fontsize = 12
          titlefont["size"] = round(
              min_fontsize + (title_fontsize - min_fontsize) * scale_x
          )
  
          annotations.append(
              {
                  "text": title,
                  "showarrow": False,
                  "xref": "paper",
                  "yref": "paper",
                  "x": 0.5,
                  "y": 1.01,
                  "xanchor": "center",
                  "yanchor": "bottom",
                  "font": titlefont,
              }
          )
          layout["annotations"] = annotations
  
      # annotations
      for obj in layout.get("annotations", []):
          if obj.get("xref", None) == "paper":
              obj["x"] = obj.get("x", 0.5) * scale_x + translate_x
          if obj.get("yref", None) == "paper":
              obj["y"] = obj.get("y", 0.5) * scale_y + translate_y
  
      # shapes
      for obj in layout.get("shapes", []):
          if obj.get("xref", None) == "paper":
              obj["x0"] = obj.get("x0", 0.25) * scale_x + translate_x
              obj["x1"] = obj.get("x1", 0.75) * scale_x + translate_x
          if obj.get("yref", None) == "paper":
              obj["y0"] = obj.get("y0", 0.25) * scale_y + translate_y
              obj["y1"] = obj.get("y1", 0.75) * scale_y + translate_y
  
      # images
      for obj in layout.get("images", []):
          if obj.get("xref", None) == "paper":
              obj["x"] = obj.get("x", 0.5) * scale_x + translate_x
              obj["sizex"] = obj.get("sizex", 0) * scale_x
          if obj.get("yref", None) == "paper":
              obj["y"] = obj.get("y", 0.5) * scale_y + translate_y
              obj["sizey"] = obj.get("sizey", 0) * scale_y
  
file_path: holoviews/holoviews/plotting/plotly/util.py
imports: import copy
  import re
  import numpy
  from plotly import colors
  from ...core.util import isfinite, max_range
  from ..util import color_intervals, process_cmap
label_desc: Use image node_id 7 for calling a global function with example usage: _scale_translate(fig, scale_x, scale_y, translate_x, translate_y) and returns: list, list