code: def scatterplot(  # noqa C901
      p,
      df,
      x,
      x_old,
      y,
      category,
      category_values,
      colormap,
      hovertool,
      hovertool_string,
      additional_columns,
      x_axis_type,
      xlabelname,
      ylabelname,
      **kwargs,
  ):
      """Adds a scatterplot to figure p for each data_col."""
  
      # Set standard size and linecolor of markers:
      if "size" not in kwargs:
          kwargs["size"] = 10
      if "line_color" not in kwargs:
          kwargs["line_color"] = "black"
  
      # Define source:
      source = ColumnDataSource(
          {"__x__values": x, "__x__values_original": x_old, "y": y}
      )
      for kwarg, value in kwargs.items():
          if value in df.columns:
              source.data[value] = df[value].values
      for add_col in additional_columns:
          source.data[add_col] = df[add_col].values
  
      # Define Colormapper for categorical scatterplot:
      if category is not None:
          category = str(category)
          source.data[category] = category_values
  
          # Make numerical categorical scatterplot:
          if check_type(category_values) == "numeric":
              kwargs["legend_label"] = category + " "
  
              # Define colormapper for numerical scatterplot:
              if colormap is None:
                  colormap = Inferno256
              elif isinstance(colormap, str):
                  if colormap in all_palettes:
                      colormap = all_palettes[colormap]
                      max_key = max(colormap.keys())
                      colormap = colormap[max_key]
                  else:
                      raise ValueError(
                          f"Could not find <colormap> with name {colormap}. The following predefined colormaps are supported (see also https://bokeh.pydata.org/en/latest/docs/reference/palettes.html ): {list(all_palettes.keys())}"
                      )
              elif isinstance(colormap, (list, tuple)):
                  pass
              else:
                  raise ValueError(
                      "<colormap> can onyl be None, a name of a colorpalette as string( see https://bokeh.pydata.org/en/latest/docs/reference/palettes.html ) or a list/tuple of colors."
                  )
  
              colormapper = LinearColorMapper(palette=colormap)
  
              # Set fill-color to colormapper:
              kwargs["fill_color"] = {
                  "field": category,
                  "transform": colormapper,
              }
  
              # Define Colorbar:
              colorbar_options = {
                  "color_mapper": colormapper,
                  "label_standoff": 0,
                  "border_line_color": None,
                  "location": (0, 0),
              }
              colorbar = ColorBar(**colorbar_options)
              p.add_layout(colorbar, "right")
  
              # Draw glyph:
              glyph = p.scatter(
                  x="__x__values", y="y", source=source, **kwargs
              )
  
              # Add Hovertool
              if hovertool:
                  my_hover = HoverTool(renderers=[glyph])
                  if hovertool_string is None:
                      if x_axis_type == "datetime":
                          my_hover.tooltips = [
                              (xlabelname, "@__x__values_original{%F}"),
                              (ylabelname, "@y"),
                          ]
                          my_hover.formatters = {
                              "@__x__values_original": "datetime"
                          }
                      else:
                          my_hover.tooltips = [
                              (xlabelname, "@__x__values_original"),
                              (ylabelname, "@y"),
                          ]
                      my_hover.tooltips.append(
                          (str(category), "@{%s}" % category)
                      )
                  else:
                      my_hover.tooltips = hovertool_string
                  p.add_tools(my_hover)
  
          # Make categorical scatterplot:
          elif check_type(category_values) == "object":
              # Define colormapper for categorical scatterplot:
              labels, categories = pd.factorize(category_values)
              colormap = get_colormap(colormap, len(categories))
  
              # Draw each category as separate glyph:
              x, y = source.data["__x__values"], source.data["y"]
              for cat, color in zip(categories, colormap):
                  # Define reduced source for this categorx:
                  x_cat = x[category_values == cat]
                  x_old_cat = x_old[category_values == cat]
                  y_cat = y[category_values == cat]
                  cat_cat = category_values[category_values == cat]
                  source = ColumnDataSource(
                      {
                          "__x__values": x_cat,
                          "__x__values_original": x_old_cat,
                          "y": y_cat,
                          "category": cat_cat,
                      }
                  )
                  for kwarg, value in kwargs.items():
                      if value in df.columns:
                          source.data[value] = df[value].values[
                              category_values == cat
                          ]
                  for add_col in additional_columns:
                      source.data[add_col] = df[add_col].values[
                          category_values == cat
                      ]
  
                  # Draw glyph:
                  glyph = p.scatter(
                      x="__x__values",
                      y="y",
                      legend_label=str(cat) + " ",
                      source=source,
                      color=color,
                      **kwargs,
                  )
  
                  # Add Hovertool
                  if hovertool:
                      my_hover = HoverTool(renderers=[glyph])
                      if hovertool_string is None:
                          if x_axis_type == "datetime":
                              my_hover.tooltips = [
                                  (
                                      xlabelname,
                                      "@__x__values_original{%F}",
                                  ),
                                  (ylabelname, "@y"),
                              ]
                              my_hover.formatters = {
                                  "@__x__values_original": "datetime"
                              }
                          else:
                              my_hover.tooltips = [
                                  (xlabelname, "@__x__values_original"),
                                  (ylabelname, "@y"),
                              ]
                          my_hover.tooltips.append(
                              (str(category), "@category")
                          )
                      else:
                          my_hover.tooltips = hovertool_string
                      p.add_tools(my_hover)
  
              if len(categories) > 5:
                  warnings.warn(
                      "There are more than 5 categories in the scatterplot. The legend might be crowded, to hide the axis you can pass 'legend=False' as an optional argument."
                  )
  
          else:
              raise ValueError(
                  "<category> is not supported with datetime objects. Consider casting the datetime objects to strings, which can be used as <category> values."
              )
  
      # Draw non-categorical plot:
      else:
          # Draw glyph:
          glyph = p.scatter(
              x="__x__values",
              y="y",
              source=source,
              legend_label="Hide/Show",
              **kwargs,
          )
  
          # Add Hovertool:
          if hovertool:
              my_hover = HoverTool(renderers=[glyph])
              if hovertool_string is None:
                  if x_axis_type == "datetime":
                      my_hover.tooltips = [
                          (xlabelname, "@__x__values_original{%F}"),
                          (ylabelname, "@y"),
                      ]
                      my_hover.formatters = {
                          "@__x__values_original": "datetime"
                      }
                  else:
                      my_hover.tooltips = [
                          (xlabelname, "@__x__values_original"),
                          (ylabelname, "@y"),
                      ]
              else:
                  my_hover.tooltips = hovertool_string
              p.add_tools(my_hover)
  
      return p
  
imports: import datetime
  import numbers
  import warnings
  from copy import deepcopy
  from typing import Iterable, List, Optional, Union
  import numpy
  import pandas
  from bokeh.layouts import column
  from bokeh.models import ColorBar, ColumnDataSource, DatetimeTickFormatter, FuncTickFormatter, HoverTool, LinearColorMapper, RangeTool
  from bokeh.models.ranges import Range1d
  from bokeh.palettes import Inferno256, all_palettes
  from bokeh.plotting import figure
  from bokeh.transform import cumsum, dodge
  from pandas.core.base import PandasObject
  from pandas.errors import ParserError
  from .base import embedded_html, set_fontsizes_of_figure, show
  from .geoplot import geoplot
  from .utils import _extract_additional_columns
label_desc: Use image node_id 10 for calling a global function with example usage: scatterplot(p, df, x, x_old, y, category, category_values, colormap, hovertool, hovertool_string, additional_columns, x_axis_type, xlabelname, ylabelname) and returns: p