code: def _to_marginal(side: str, size, layer: LayerSpec) -> LayerSpec:
      if side not in ["l", "r", "t", "b"]:
          raise ValueError(
              "Invalid 'side' value: {}. Valid values: 'l','r','t','b'.".format(
                  side
              )
          )
  
      if size is not None:
          if not 0.01 <= size <= 0.95:
              raise ValueError(
                  "Invalid 'size' value: {}. Should be in range [0.01..0.95].".format(
                      size
                  )
              )
  
      layer_copy = LayerSpec.duplicate(layer)
      marginal_options = dict(
          marginal=True, margin_side=side, margin_size=size
      )
  
      layer_props = layer_copy.props()
      layer_props.update(marginal_options)
  
      layer_kind = None
      stat = layer_props.get("stat")
      if stat is not None:
          if stat == "bin":
              layer_kind = "histogram"
          elif stat == "ydensity":
              layer_kind = "violin"
          elif stat in ("density", "boxplot", "boxplot_outlier"):
              layer_kind = stat
      else:
          geom = layer_props.get("geom")
          if geom in (
              "histogram",
              "boxplot",
              "violin",
              "density",
              "freqpoly",
          ):
              layer_kind = geom
  
      auto_settings = {}
  
      # choose a proper orientation
      if side in ("l", "r") and layer_kind in (
          "histogram",
          "density",
          "freqpoly",
      ):
          auto_settings["orientation"] = "y"
  
      if layer_kind in ("boxplot", "boxplot_outlier", "violin"):
          if side in ("l", "r"):
              auto_settings["x"] = 0
          elif side in ("t", "b"):
              auto_settings["y"] = 0
              auto_settings["orientation"] = "y"
  
      # Update layer's options with auto-generated and try not to override user-defined options.
      filtered = {k: v for k, v in layer_props.items() if v is not None}
      layer_props.update({**auto_settings, **filtered})
  
      # For 'histogram' set mapping of x or y to '..density..' for compatibility with 'density' geom.
      if layer_kind == "histogram":
          if side in ("l", "r"):
              added_mapping = {"x": "..density.."}
          elif side in ("t", "b"):
              added_mapping = {"y": "..density.."}
  
          aes_feature_spec = layer_props.get("mapping")
          mappings = (
              aes_feature_spec.props()
              if isinstance(aes_feature_spec, FeatureSpec)
              else {}
          )
          filtered_mappings = {
              k: v for k, v in mappings.items() if v is not None
          }
          updated_mappings = {**added_mapping, **filtered_mappings}
          updated_aes_feature_spec = FeatureSpec(
              "mapping", name=None, **updated_mappings
          )
          layer_props["mapping"] = updated_aes_feature_spec
  
      return layer_copy
  
imports: from .core import FeatureSpec, LayerSpec, DummySpec, FeatureSpecArray
label_desc: Use image node_id 3 for calling a global function with example usage: _to_marginal(side, size, layer) and returns: layer_copy