code: def joyplot(
      data,
      column=None,
      by=None,
      grid=False,
      xlabelsize=None,
      xrot=None,
      ylabelsize=None,
      yrot=None,
      ax=None,
      figsize=None,
      hist=False,
      bins=10,
      fade=False,
      ylim="max",
      fill=True,
      linecolor=None,
      overlap=1,
      background=None,
      labels=None,
      xlabels=True,
      ylabels=True,
      range_style="all",
      x_range=None,
      title=None,
      colormap=None,
      color=None,
      normalize=True,
      floc=None,
      **kwds,
  ):
      """
      Draw joyplot of a DataFrame, or appropriately nested collection,
      using matplotlib and pandas.
  
      A joyplot is a stack of vertically aligned density plots / histograms.
      By default, if 'data' is a DataFrame,
      this function will plot a density plot for each column.
  
      This wrapper method tries to convert whatever structure is given
      to a nested collection of lists with additional information
      on labels, and use the private _joyplot function to actually
      draw theh plot.
  
      Parameters
      ----------
      data : DataFrame, Series or nested collection
      column : string or sequence
          If passed, will be used to limit data to a subset of columns
      by : object, optional
          If passed, used to form separate plot groups
      grid : boolean, default True
          Whether to show axis grid lines
      labels : boolean or list, default True.
          If list, must be the same size of the de
      xlabelsize : int, default None
          If specified changes the x-axis label size
      xrot : float, default None
          rotation of x axis labels
      ylabelsize : int, default None
          If specified changes the y-axis label size
      yrot : float, default None
          rotation of y axis labels
      ax : matplotlib axes object, default None
      figsize : tuple
          The size of the figure to create in inches by default
      hist : boolean, default False
      bins : integer, default 10
          Number of histogram bins to be used
      color : color or colors to be used in the plots. It can be:
          a string or anything interpretable as color by matplotib;
          a list of colors. See docs / examples for more details.
      kwds : other plotting keyword arguments
          To be passed to hist/kde plot function
      """
  
      if column is not None:
          if not isinstance(column, (list, np.ndarray)):
              column = [column]
  
      def _grouped_df_to_standard(grouped, column):
          converted = []
          labels = []
          for i, (key, group) in enumerate(grouped):
              if column is not None:
                  group = group[column]
              labels.append(key)
              converted.append(
                  [
                      _remove_na(group[c])
                      for c in group.columns
                      if _is_numeric(group[c])
                  ]
              )
              if i == 0:
                  sublabels = [
                      col
                      for col in group.columns
                      if _is_numeric(group[col])
                  ]
          return converted, labels, sublabels
  
      #################################################################
      # GROUPED
      # - given a grouped DataFrame, a group by key, or a dict of dicts of Series/lists/arrays
      # - select the required columns/Series/lists/arrays
      # - convert to standard format: list of lists of non-null arrays
      #   + extra parameters (labels and sublabels)
      #################################################################
      if isinstance(data, DataFrameGroupBy):
          grouped = data
          converted, _labels, sublabels = _grouped_df_to_standard(
              grouped, column
          )
          if labels is None:
              labels = _labels
      elif by is not None and isinstance(data, DataFrame):
          grouped = data.groupby(by)
          if column is None:
              # Remove the groupby key. It's not automatically removed by pandas.
              column = list(data.columns)
              column.remove(by)
          converted, _labels, sublabels = _grouped_df_to_standard(
              grouped, column
          )
          if labels is None:
              labels = _labels
          # If there is at least an element which is not a list of lists.. go on.
      elif isinstance(data, dict) and all(
          isinstance(g, dict) for g in data.values()
      ):
          grouped = data
          if labels is None:
              labels = list(grouped.keys())
          converted = []
          for i, (key, group) in enumerate(grouped.items()):
              if column is not None:
                  converted.append(
                      [
                          _remove_na(g)
                          for k, g in group.items()
                          if _is_numeric(g) and k in column
                      ]
                  )
                  if i == 0:
                      sublabels = [
                          k for k, g in group.items() if _is_numeric(g)
                      ]
              else:
                  converted.append(
                      [
                          _remove_na(g)
                          for k, g in group.items()
                          if _is_numeric(g)
                      ]
                  )
                  if i == 0:
                      sublabels = [
                          k for k, g in group.items() if _is_numeric(g)
                      ]
      #################################################################
      # PLAIN:
      # - given a DataFrame or list/dict of Series/lists/arrays
      # - select the required columns/Series/lists/arrays
      # - convert to standard format: list of lists of non-null arrays + extra parameter (labels)
      #################################################################
      elif isinstance(data, DataFrame):
          if column is not None:
              data = data[column]
          converted = [
              [_remove_na(data[col])]
              for col in data.columns
              if _is_numeric(data[col])
          ]
          labels = [
              col for col in data.columns if _is_numeric(data[col])
          ]
          sublabels = None
      elif isinstance(data, dict):
          if column is not None:
              converted = [
                  [_remove_na(g)]
                  for k, g in data.items()
                  if _is_numeric(g) and k in column
              ]
              labels = [
                  k
                  for k, g in data.items()
                  if _is_numeric(g) and k in column
              ]
          else:
              converted = [
                  [_remove_na(g)]
                  for k, g in data.items()
                  if _is_numeric(g)
              ]
              labels = [k for k, g in data.items() if _is_numeric(g)]
          sublabels = None
      elif isinstance(data, list):
          if column is not None:
              converted = [
                  [_remove_na(g)]
                  for g in data
                  if _is_numeric(g) and i in column
              ]
          else:
              converted = [
                  [_remove_na(g)] for g in data if _is_numeric(g)
              ]
          if labels and len(labels) != len(converted):
              raise ValueError(
                  "The number of labels does not match the length of the list."
              )
  
          sublabels = None
      else:
          raise TypeError(
              "Unknown type for 'data': {!r}".format(type(data))
          )
  
      if ylabels is False:
          labels = None
  
      if all(len(subg) == 0 for g in converted for subg in g):
          raise ValueError(
              "No numeric values found. Joyplot requires at least a numeric column/group."
          )
  
      if any(len(subg) == 0 for g in converted for subg in g):
          warn("At least a column/group has no numeric values.")
  
      return _joyplot(
          converted,
          labels=labels,
          sublabels=sublabels,
          grid=grid,
          xlabelsize=xlabelsize,
          xrot=xrot,
          ylabelsize=ylabelsize,
          yrot=yrot,
          ax=ax,
          figsize=figsize,
          hist=hist,
          bins=bins,
          fade=fade,
          ylim=ylim,
          fill=fill,
          linecolor=linecolor,
          overlap=overlap,
          background=background,
          xlabels=xlabels,
          range_style=range_style,
          x_range=x_range,
          title=title,
          colormap=colormap,
          color=color,
          normalize=normalize,
          floc=floc,
          **kwds,
      )
  
file_path: joypy/joypy/joyplot.py
imports: import numpy
  from scipy.stats import gaussian_kde
  import scipy.stats
  import warnings
  from pandas import DataFrame, Series
  from pandas.core.dtypes.common import is_number
  from pandas.core.groupby import DataFrameGroupBy
  from matplotlib import pyplot
  from warnings import warn
label_desc: Use image node_id 7 for calling a global function with example usage: joyplot(data, column, by, grid, xlabelsize, xrot, ylabelsize, yrot, ax, figsize, hist, bins, fade, ylim, fill, linecolor, overlap, background, labels, xlabels, ylabels, range_style, x_range, title, colormap, color, normalize, floc) and returns: _joyplot, converted,  labels,  sublabels