code: def plot_density(
      ax,
      x_range,
      v,
      kind="kde",
      bw_method=None,
      bins=50,
      fill=False,
      linecolor=None,
      clip_on=True,
      normalize=True,
      floc=None,
      **kwargs,
  ):
      """Draw a density plot given an axis, an array of values v and an array
      of x positions where to return the estimated density.
      """
      v = _remove_na(v)
      if len(v) == 0 or len(x_range) == 0:
          return
  
      if kind == "kde":
          try:
              gkde = gaussian_kde(v, bw_method=bw_method)
              y = gkde.evaluate(x_range)
          except ValueError:
              # Handle cases where there is no data in a group.
              y = np.zeros_like(x_range)
          except np.linalg.LinAlgError as e:
              # Handle singular matrix in kde computation.
              distinct_values = np.unique(v)
              if len(distinct_values) == 1:
                  # In case of a group with a single value val,
                  # that should have infinite density,
                  # return a δ(val)
                  val = distinct_values[0]
                  warnings.warn(
                      "The data contains a group with a single distinct value ({}) "
                      "having infinite probability density. "
                      "Consider using a different visualization.".format(
                          val
                      )
                  )
  
                  # Find index i of x_range
                  # such that x_range[i-1] < val ≤ x_range[i]
                  i = np.searchsorted(x_range, val)
  
                  y = np.zeros_like(x_range)
                  y[i] = 1
              else:
                  raise e
  
      elif kind == "lognorm":
          if floc is not None:
              lnparam = stats.lognorm.fit(v, loc=floc)
          else:
              lnparam = stats.lognorm.fit(v)
  
          lpdf = stats.lognorm.pdf(
              x_range, lnparam[0], lnparam[1], lnparam[2]
          )
          if normalize:
              y = lpdf / lpdf.sum()
          else:
              y = lpdf
      elif kind == "counts":
          y, bin_edges = np.histogram(
              v, bins=bins, range=(min(x_range), max(x_range))
          )
          # np.histogram returns the edges of the bins.
          # We compute here the middle of the bins.
          x_range = _moving_average(bin_edges, 2)
      elif kind == "normalized_counts":
          y, bin_edges = np.histogram(
              v,
              bins=bins,
              density=False,
              range=(min(x_range), max(x_range)),
          )
          # np.histogram returns the edges of the bins.
          # We compute here the middle of the bins.
          y = y / len(v)
          x_range = _moving_average(bin_edges, 2)
      elif kind == "values":
          # Warning: to use values and get a meaningful visualization,
          # x_range must also be manually set in the main function.
          y = v
          x_range = list(range(len(y)))
      else:
          raise NotImplementedError
  
      if fill:
          ax.fill_between(x_range, 0.0, y, clip_on=clip_on, **kwargs)
  
          # Hack to have a border at the bottom at the fill patch
          # (of the same color of the fill patch)
          # so that the fill reaches the same bottom margin as the edge lines
          # with y value = 0.0
          kw = kwargs
          kw["label"] = None
          ax.plot(x_range, [0.0] * len(x_range), clip_on=clip_on, **kw)
  
      if linecolor is not None:
          kwargs["color"] = linecolor
  
      # Remove the legend labels if we are plotting filled curve:
      # we only want one entry per group in the legend (if shown).
      if fill:
          kwargs["label"] = None
  
      ax.plot(x_range, y, clip_on=clip_on, **kwargs)
  
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 8 for calling a global function with example usage: plot_density(ax, x_range, v, kind, bw_method, bins, fill, linecolor, clip_on, normalize, floc) without return types