code: def color_map(lookup, color_stops, default_color="rgb(122,122,122)"):
      """Return an rgb color value interpolated from given color_stops;
      assumes colors in color_stops provided as strings of form 'rgb(RRR,GGG,BBB)'
      or in hex: '#RRGGBB'
      """
      # if no color_stops, use default color
      if len(color_stops) == 0:
          return default_color
  
      # dictionary to lookup color from match-type color_stops
      match_map = dict((x, y) for (x, y) in color_stops)
  
      # if lookup matches stop exactly, return corresponding color (first priority)
      # (includes non-numeric color_stop "keys" for finding color by match)
      if lookup in match_map.keys():
          return match_map.get(lookup)
  
      # if lookup value numeric, map color by interpolating from color scale
      if isinstance(lookup, (int, float, complex)):
          # try ordering stops
          try:
              stops, colors = zip(*sorted(color_stops))
  
          # if not all stops are numeric, attempt looking up as if categorical stops
          except TypeError:
              return match_map.get(lookup, default_color)
  
          # for interpolation, all stops must be numeric
          if not all(
              isinstance(x, (int, float, complex)) for x in stops
          ):
              return default_color
  
          # check if lookup value in stops bounds
          if float(lookup) <= stops[0]:
              return colors[0]
  
          elif float(lookup) >= stops[-1]:
              return colors[-1]
  
          # check if lookup value matches any stop value
          elif float(lookup) in stops:
              return colors[stops.index(lookup)]
  
          # interpolation required
          else:
              rgb_tuples = [
                  Color(rgb_tuple_from_str(x)) for x in colors
              ]
  
              # identify bounding color stop values
              lower = max([stops[0]] + [x for x in stops if x < lookup])
              upper = min(
                  [stops[-1]] + [x for x in stops if x > lookup]
              )
  
              # colors from bounding stops
              lower_color = rgb_tuples[stops.index(lower)]
              upper_color = rgb_tuples[stops.index(upper)]
  
              # generate color scale for mapping lookup value to interpolated color
              scale = Scale(Color(lower_color), Color(upper_color))
  
              # compute linear "relative distance" from lower bound color to upper bound color
              distance = (lookup - lower) / (upper - lower)
  
              # return string representing rgb color value
              return scale(distance).to_string().replace(", ", ",")
  
      # default color value catch-all
      return default_color
  
imports: import base64
  import codecs
  import datetime
  from io import BytesIO
  import json
  import re
  from chroma import Color, Scale
  from colour import Color
  import geojson
  from matplotlib.image import imsave
  import requests
  from .colors import color_ramps, common_html_colors
  from .errors import SourceDataError, DateConversionError
label_desc: Use image node_id 12 for calling a global function with example usage: color_map(lookup, color_stops, default_color) and returns: default_color, default_color, match_map, default_color, colors, match_map, colors, colors, scale