code: def ggmarginal(
      sides: str, *, size=None, layer: LayerSpec
  ) -> FeatureSpec:
      """
      Convert a given geometry layer to a marginal layer.
      You can add one or more marginal layers to a plot to create a marginal plot.
  
      Parameters
      ----------
      sides : str
          A string specifying which sides of the plot the marginal layer will appear on.
          It should be set to a string containing any of "trbl", for top, right, bottom, and left.
      size : number or list of numbers, default=0.1
          Size of marginal geometry (width or height, depending on the margin side) as a fraction of the entire
          plotting area of the plot.
          The value should be in range [0.01..0.95].
      layer : `LayerSpec`
          A marginal geometry layer.
          The result of calling of the `geom_xxx()` / `stat_xxx()` function.
          Marginal plot works best with `density`,`histogram`,`boxplot`,`violin` and `freqpoly` geometry layers.
  
      Returns
      -------
      `FeatureSpec`
          An object specifying a marginal geometry layer or a list of marginal geometry layers.
  
      Notes
      -----
      A marginal plot is a scatterplot (sometimes a 2D density plot or other bivariate plot) that has histograms,
      boxplots, or other distribution visualization layers in the margins of the x- and y-axes.
  
      Examples
      --------
      .. jupyter-execute::
          :linenos:
          :emphasize-lines: 24
  
          import numpy as np
          from lets_plot import *
          from lets_plot.mapping import as_discrete
          LetsPlot.setup_html()
          LetsPlot.set_theme(theme_light())
  
          np.random.seed(0)
  
          cov0=[[1, -.8],
               [-.8, 1]]
          cov1=[[ 10, .1],
                 [.1, .1]]
  
          x0, y0 = np.random.multivariate_normal(mean=[-2,0], cov=cov0, size=200).T
          x1, y1 = np.random.multivariate_normal(mean=[0,1], cov=cov1, size=200).T
  
          data = dict(
              x = np.concatenate((x0,x1)),
              y = np.concatenate((y0,y1)),
              c = ["A"]*200 + ["B"]*200
          )
  
          p = ggplot(data, aes("x", "y", color="c", fill="c")) + geom_point()
          p + ggmarginal("tr", layer=geom_density(alpha=0.3, show_legend=False))
  
      """
  
      if not isinstance(sides, str):
          raise TypeError("'sides' must be a string.")
      if not 0 < len(sides) <= 4:
          raise ValueError(
              "'sides' must be a string containing 1 to 4 chars: 'l','r','t','b'."
          )
  
      # Recursive call when layer is sum of geoms
      if isinstance(layer, FeatureSpecArray):
          result = DummySpec()
          for sublayer in layer.elements():
              result += ggmarginal(sides, size=size, layer=sublayer)
          return result
  
      if not isinstance(layer, LayerSpec):
          raise TypeError(
              "Invalid 'layer' type: {}".format(type(layer))
          )
  
      result = DummySpec()
  
      for i in range(len(sides)):
          side = sides[i]
          margin_size = _to_size(size, i)
          marginal_layer = _to_marginal(side, margin_size, layer)
          result = result + marginal_layer
  
      return result
  
imports: from .core import FeatureSpec, LayerSpec, DummySpec, FeatureSpecArray
label_desc: Use image node_id 1 for calling a global function with example usage: ggmarginal(sides) and returns: result, result