code: def axis_spanning_shape_annotation(
      annotation, shape_type, shape_args, kwargs
  ):
      """
      annotation: a go.layout.Annotation object, a dict describing an annotation, or None
      shape_type: one of 'vline', 'hline', 'vrect', 'hrect' and determines how the
                  x, y, xanchor, and yanchor values are set.
      shape_args: the parameters used to draw the shape, which are used to place the annotation
      kwargs:     a dictionary that was the kwargs of a
                  _process_multiple_axis_spanning_shapes spanning shapes call. Items in this
                  dict whose keys start with 'annotation_' will be extracted and the keys with
                  the 'annotation_' part stripped off will be used to assign properties of the
                  new annotation.
  
      Property precedence:
      The annotation's x, y, xanchor, and yanchor properties are set based on the
      shape_type argument. Each property already specified in the annotation or
      through kwargs will be left as is (not replaced by the value computed using
      shape_type). Note that the xref and yref properties will in general get
      overwritten if the result of this function is passed to an add_annotation
      called with the row and col parameters specified.
  
      Returns an annotation populated with fields based on the
      annotation_position, annotation_ prefixed kwargs or the original annotation
      passed in to this function.
      """
      # set properties based on annotation_ prefixed kwargs
      prefix = "annotation_"
      len_prefix = len(prefix)
      annotation_keys = list(
          filter(lambda k: k.startswith(prefix), kwargs.keys())
      )
      # If no annotation or annotation-key is specified, return None as we don't
      # want an annotation in this case
      if annotation is None and len(annotation_keys) == 0:
          return None
      # TODO: Would it be better if annotation were initialized to an instance of
      # go.layout.Annotation ?
      if annotation is None:
          annotation = dict()
      for k in annotation_keys:
          if k == "annotation_position":
              # don't set so that Annotation constructor doesn't complain
              continue
          subk = k[len_prefix:]
          annotation[subk] = kwargs[k]
      # set x, y, xanchor, yanchor based on shape_type and position
      annotation_position = None
      if "annotation_position" in kwargs.keys():
          annotation_position = kwargs["annotation_position"]
      if shape_type.endswith("line"):
          shape_dict = annotation_params_for_line(
              shape_type, shape_args, annotation_position
          )
      elif shape_type.endswith("rect"):
          shape_dict = annotation_params_for_rect(
              shape_type, shape_args, annotation_position
          )
      for k in shape_dict.keys():
          # only set property derived from annotation_position if it hasn't already been set
          # see above: this would be better as a go.layout.Annotation then the key
          # would be checked for validity here (otherwise it is checked later,
          # which I guess is ok too)
          if (k not in annotation) or (annotation[k] is None):
              annotation[k] = shape_dict[k]
      return annotation
  
file_path: catboost/contrib/python/plotly/py3/plotly/shapeannotation.py
label_desc: Use image node_id 9 for calling a global function with example usage: axis_spanning_shape_annotation(annotation, shape_type, shape_args, kwargs) and returns: annotation, None