code: def plot_surf_contours(
      surf_mesh,
      roi_map,
      axes=None,
      figure=None,
      levels=None,
      labels=None,
      colors=None,
      legend=False,
      cmap="tab20",
      title=None,
      output_file=None,
      **kwargs,
  ):
      """Plot contours of ROIs on a surface, \
      optionally over a statistical map.
  
      Parameters
      ----------
      surf_mesh : str or list of two numpy.ndarray
          Surface :term:`mesh` geometry, can be a file (valid formats are
          .gii or Freesurfer specific files such as .orig, .pial,
          .sphere, .white, .inflated) or
          a list of two Numpy arrays, the first containing the x-y-z coordinates
          of the :term:`mesh` :term:`vertices<vertex>`,
          the second containing the indices (into coords)
          of the :term:`mesh` :term:`faces`.
  
      roi_map : str or numpy.ndarray or list of numpy.ndarray
          ROI map to be displayed on the surface mesh, can be a file
          (valid formats are .gii, .mgz, .nii, .nii.gz, or Freesurfer specific
          files such as .annot or .label), or
          a Numpy array with a value for each :term:`vertex` of the surf_mesh.
          The value at each :term:`vertex` one inside the ROI
          and zero inside ROI,
          or an integer giving the label number for atlases.
  
      axes : instance of matplotlib axes, None, optional
          The axes instance to plot to. The projection must be '3d' (e.g.,
          `figure, axes = plt.subplots(subplot_kw={'projection': '3d'})`,
          where axes should be passed.).
          If None, uses axes from figure if available, else creates new axes.
      %(figure)s
      levels : list of integers, or None, optional
          A list of indices of the regions that are to be outlined.
          Every index needs to correspond to one index in roi_map.
          If None, all regions in roi_map are used.
  
      labels : list of strings or None, or None, optional
          A list of labels for the individual regions of interest.
          Provide None as list entry to skip showing the label of that region.
          If None no labels are used.
  
      colors : list of matplotlib color names or RGBA values, or None, optional
          Colors to be used.
  
      legend : boolean,  optional, default=False
          Whether to plot a legend of region's labels.
      %(cmap)s
          Default='tab20'.
      %(title)s
      %(output_file)s
  
      See Also
      --------
      nilearn.datasets.fetch_surf_fsaverage : For surface data object to be
          used as background map for this plotting function.
  
      nilearn.plotting.plot_surf_stat_map : for plotting statistical maps on
          brain surfaces.
  
      nilearn.surface.vol_to_surf : For info on the generation of surfaces.
  
      """
      if figure is None and axes is None:
          figure = plot_surf(surf_mesh, **kwargs)
          axes = figure.axes[0]
      if figure is None:
          figure = axes.get_figure()
      if axes is None:
          axes = figure.axes[0]
      if axes.name != "3d":
          raise ValueError("Axes must be 3D.")
      # test if axes contains Poly3DCollection, if not initialize surface
      if not axes.collections or not isinstance(
          axes.collections[0], Poly3DCollection
      ):
          _ = plot_surf(surf_mesh, axes=axes, **kwargs)
  
      coords, faces = load_surf_mesh(surf_mesh)
      roi = load_surf_data(roi_map)
      if levels is None:
          levels = np.unique(roi_map)
      if colors is None:
          n_levels = len(levels)
          vmax = n_levels
          cmap = plt.get_cmap(cmap)
          norm = Normalize(vmin=0, vmax=vmax)
          colors = [cmap(norm(color_i)) for color_i in range(vmax)]
      else:
          try:
              colors = [to_rgba(color, alpha=1.0) for color in colors]
          except ValueError:
              raise ValueError(
                  "All elements of colors need to be either a"
                  " matplotlib color string or RGBA values."
              )
  
      if labels is None:
          labels = [None] * len(levels)
      if not (len(levels) == len(labels) == len(colors)):
          raise ValueError(
              "Levels, labels, and colors "
              "argument need to be either the same length or None."
          )
  
      patch_list = []
      for level, color, label in zip(levels, colors, labels):
          roi_indices = np.where(roi == level)[0]
          faces_outside = _get_faces_on_edge(faces, roi_indices)
          # Fix: Matplotlib version 3.3.2 to 3.3.3
          # Attribute _facecolors3d changed to _facecolor3d in
          # matplotlib version 3.3.3
          if compare_version(mpl.__version__, "<", "3.3.3"):
              axes.collections[0]._facecolors3d[faces_outside] = color
              if axes.collections[0]._edgecolors3d.size == 0:
                  axes.collections[0].set_edgecolor(
                      axes.collections[0]._facecolors3d
                  )
              axes.collections[0]._edgecolors3d[faces_outside] = color
          else:
              axes.collections[0]._facecolor3d[faces_outside] = color
              if axes.collections[0]._edgecolor3d.size == 0:
                  axes.collections[0].set_edgecolor(
                      axes.collections[0]._facecolor3d
                  )
              axes.collections[0]._edgecolor3d[faces_outside] = color
          if label and legend:
              patch_list.append(Patch(color=color, label=label))
      # plot legend only if indicated and labels provided
      if legend and np.any([lbl is not None for lbl in labels]):
          figure.legend(handles=patch_list)
          # if legends, then move title to the left
      if title is None and hasattr(figure._suptitle, "_text"):
          title = figure._suptitle._text
      if title:
          axes.set_title(title)
      # save figure if output file is given
      if output_file is not None:
          figure.savefig(output_file)
          plt.close(figure)
      else:
          return figure
  
imports: import itertools
  import math
  from collections.abc import Sequence
  from warnings import warn
  import matplotlib
  import matplotlib.pyplot
  import numpy
  from matplotlib import gridspec
  from matplotlib.cm import ScalarMappable
  from matplotlib.colorbar import make_axes
  from matplotlib.colors import LinearSegmentedColormap, Normalize, to_rgba
  from matplotlib.patches import Patch
  from mpl_toolkits.mplot3d.art3d import Poly3DCollection
  from nilearn import image, surface
  from nilearn._utils import check_niimg_3d, compare_version, fill_doc
  from nilearn._utils.helpers import is_kaleido_installed, is_plotly_installed
  from nilearn.plotting.cm import cold_hot, mix_colormaps
  from nilearn.plotting.displays._slicers import _get_cbar_ticks
  from nilearn.plotting.html_surface import get_vertexcolor
  from nilearn.plotting.img_plotting import get_colorbar_and_data_ranges
  from nilearn.plotting.js_plotting_utils import colorscale
  from nilearn.surface import load_surf_data, load_surf_mesh, vol_to_surf
  from nilearn.surface.surface import check_mesh
label_desc: Use image node_id 20 for calling a global function with example usage: plot_surf_contours(surf_mesh, roi_map, axes, figure, levels, labels, colors, legend, cmap, title, output_file) and returns: figure