code: def _plot_evoked_topo(
      evoked,
      layout=None,
      layout_scale=0.945,
      color=None,
      border="none",
      ylim=None,
      scalings=None,
      title=None,
      proj=False,
      vline=(0.0,),
      hline=(0.0,),
      fig_facecolor="k",
      fig_background=None,
      axis_facecolor="k",
      font_color="w",
      merge_channels=False,
      legend=True,
      axes=None,
      exclude="bads",
      show=True,
      noise_cov=None,
  ):
      """Plot 2D topography of evoked responses.
  
      Clicking on the plot of an individual sensor opens a new figure showing
      the evoked response for the selected sensor.
  
      Parameters
      ----------
      evoked : list of Evoked | Evoked
          The evoked response to plot.
      layout : instance of Layout | None
          Layout instance specifying sensor positions (does not need to
          be specified for Neuromag data). If possible, the correct layout is
          inferred from the data.
      layout_scale : float
          Scaling factor for adjusting the relative size of the layout
          on the canvas.
      color : list of color objects | color object | None
          Everything matplotlib accepts to specify colors. If not list-like,
          the color specified will be repeated. If None, colors are
          automatically drawn.
      border : str
          Matplotlib borders style to be used for each sensor plot.
      ylim : dict | None
          ylim for plots (after scaling has been applied). The value
          determines the upper and lower subplot limits. e.g.
          ylim = dict(eeg=[-20, 20]). Valid keys are eeg, mag, grad. If None,
          the ylim parameter for each channel type is determined by the minimum
          and maximum peak.
      scalings : dict | None
          The scalings of the channel types to be applied for plotting. If None,`
          defaults to ``dict(eeg=1e6, grad=1e13, mag=1e15)``.
      title : str
          Title of the figure.
      proj : bool | 'interactive'
          If true SSP projections are applied before display. If 'interactive',
          a check box for reversible selection of SSP projection vectors will
          be shown.
      vline : list of floats | None
          The values at which to show a vertical line.
      hline : list of floats | None
          The values at which to show a horizontal line.
      fig_facecolor : color
          The figure face color. Defaults to black.
      fig_background : None | array
          A background image for the figure. This must be a valid input to
          `matplotlib.pyplot.imshow`. Defaults to None.
      axis_facecolor : color
          The face color to be used for each sensor plot. Defaults to black.
      font_color : color
          The color of text in the colorbar and title. Defaults to white.
      merge_channels : bool
          Whether to use RMS value of gradiometer pairs. Only works for Neuromag
          data. Defaults to False.
      legend : bool | int | string | tuple
          If True, create a legend based on evoked.comment. If False, disable the
          legend. Otherwise, the legend is created and the parameter value is
          passed as the location parameter to the matplotlib legend call. It can
          be an integer (e.g. 0 corresponds to upper right corner of the plot),
          a string (e.g. 'upper right'), or a tuple (x, y coordinates of the
          lower left corner of the legend in the axes coordinate system).
          See matplotlib documentation for more details.
      axes : instance of matplotlib Axes | None
          Axes to plot into. If None, axes will be created.
      noise_cov : instance of Covariance | str | None
          Noise covariance used to whiten the data while plotting.
          Whitened data channels names are shown in italic.
          Can be a string to load a covariance from disk.
      exclude : list of str | 'bads'
          Channels names to exclude from being shown. If 'bads', the
          bad channels are excluded. By default, exclude is set to 'bads'.
      show : bool
          Show figure if True.
  
          .. versionadded:: 0.16.0
  
      Returns
      -------
      fig : instance of matplotlib.figure.Figure
          Images of evoked responses at sensor locations
      """
      import matplotlib.pyplot as plt
  
      from ..channels.layout import (
          _merge_ch_data,
          _pair_grad_sensors,
          find_layout,
      )
      from ..cov import whiten_evoked
  
      if type(evoked) not in (tuple, list):
          evoked = [evoked]
  
      noise_cov = _check_cov(noise_cov, evoked[0].info)
      if noise_cov is not None:
          evoked = [whiten_evoked(e, noise_cov) for e in evoked]
      else:
          evoked = [e.copy() for e in evoked]
      info = evoked[0].info
      ch_names = evoked[0].ch_names
      scalings = _handle_default("scalings", scalings)
      if not all(e.ch_names == ch_names for e in evoked):
          raise ValueError("All evoked.picks must be the same")
      ch_names = _clean_names(ch_names)
      if merge_channels:
          picks = _pair_grad_sensors(
              info, topomap_coords=False, exclude=exclude
          )
          chs = list()
          for pick in picks[::2]:
              ch = info["chs"][pick]
              ch["ch_name"] = ch["ch_name"][:-1] + "X"
              chs.append(ch)
          with info._unlock(update_redundant=True, check_after=True):
              info["chs"] = chs
              info["bads"] = list()  # Bads handled by pair_grad_sensors
          new_picks = list()
          for e in evoked:
              data, _ = _merge_ch_data(e.data[picks], "grad", [])
              if noise_cov is None:
                  data *= scalings["grad"]
              e.data = data
              new_picks.append(range(len(data)))
          picks = new_picks
          types_used = ["grad"]
          unit = (
              _handle_default("units")["grad"]
              if noise_cov is None
              else "NA"
          )
          y_label = "RMS amplitude (%s)" % unit
  
      if layout is None:
          layout = find_layout(info, exclude=exclude)
  
      if not merge_channels:
          # XXX. at the moment we are committed to 1- / 2-sensor-types layouts
          chs_in_layout = [
              ch_name for ch_name in ch_names if ch_name in layout.names
          ]
          types_used = [
              channel_type(info, ch_names.index(ch))
              for ch in chs_in_layout
          ]
          # Using dict conversion to remove duplicates
          types_used = list(dict.fromkeys(types_used))
          # remove possible reference meg channels
          types_used = [
              types_used
              for types_used in types_used
              if types_used != "ref_meg"
          ]
          # one check for all vendors
          is_meg = (
              len([x for x in types_used if x in ["mag", "grad"]]) > 0
          )
          is_nirs = (
              len(
                  [
                      x
                      for x in types_used
                      if x
                      in (
                          "hbo",
                          "hbr",
                          "fnirs_cw_amplitude",
                          "fnirs_od",
                      )
                  ]
              )
              > 0
          )
          if is_meg:
              types_used = list(types_used)[
                  ::-1
              ]  # -> restore kwarg order
              picks = [
                  pick_types(
                      info, meg=kk, ref_meg=False, exclude=exclude
                  )
                  for kk in types_used
              ]
          elif is_nirs:
              types_used = list(types_used)[
                  ::-1
              ]  # -> restore kwarg order
              picks = [
                  pick_types(
                      info, fnirs=kk, ref_meg=False, exclude=exclude
                  )
                  for kk in types_used
              ]
          else:
              types_used_kwargs = {t: True for t in types_used}
              picks = [
                  pick_types(
                      info,
                      meg=False,
                      exclude=exclude,
                      **types_used_kwargs,
                  )
              ]
          assert isinstance(picks, list) and len(types_used) == len(
              picks
          )
  
          if noise_cov is None:
              for e in evoked:
                  for pick, ch_type in zip(picks, types_used):
                      e.data[pick] *= scalings[ch_type]
  
          if proj is True and all(e.proj is not True for e in evoked):
              evoked = [e.apply_proj() for e in evoked]
          elif proj == "interactive":  # let it fail early.
              for e in evoked:
                  _check_delayed_ssp(e)
          # Y labels for picked plots must be reconstructed
          y_label = list()
          for ch_idx in range(len(chs_in_layout)):
              if noise_cov is None:
                  unit = _handle_default("units")[
                      channel_type(info, ch_idx)
                  ]
              else:
                  unit = "NA"
              y_label.append("Amplitude (%s)" % unit)
  
      if ylim is None:
          # find minima and maxima over all evoked data for each channel pick
          ymaxes = np.array(
              [max((e.data[t]).max() for e in evoked) for t in picks]
          )
          ymins = np.array(
              [min((e.data[t]).min() for e in evoked) for t in picks]
          )
  
          ylim_ = (ymins, ymaxes)
      elif isinstance(ylim, dict):
          ylim_ = _handle_default("ylim", ylim)
          ylim_ = [ylim_[kk] for kk in types_used]
          # extra unpack to avoid bug #1700
          if len(ylim_) == 1:
              ylim_ = ylim_[0]
          else:
              ylim_ = [np.array(yl) for yl in ylim_]
              # Transposing to avoid Zipping confusion
              if is_meg or is_nirs:
                  ylim_ = list(map(list, zip(*ylim_)))
      else:
          raise TypeError(
              "ylim must be None or a dict. Got %s." % type(ylim)
          )
  
      data = [e.data for e in evoked]
      comments = [e.comment for e in evoked]
      times = [e.times for e in evoked]
  
      show_func = partial(
          _plot_timeseries_unified,
          data=data,
          color=color,
          times=times,
          vline=vline,
          hline=hline,
          hvline_color=font_color,
      )
      click_func = partial(
          _plot_timeseries,
          data=data,
          color=color,
          times=times,
          vline=vline,
          hline=hline,
          hvline_color=font_color,
          labels=comments,
      )
  
      time_min = min([t[0] for t in times])
      time_max = max([t[-1] for t in times])
      fig = _plot_topo(
          info=info,
          times=[time_min, time_max],
          show_func=show_func,
          click_func=click_func,
          layout=layout,
          colorbar=False,
          ylim=ylim_,
          cmap=None,
          layout_scale=layout_scale,
          border=border,
          fig_facecolor=fig_facecolor,
          font_color=font_color,
          axis_facecolor=axis_facecolor,
          title=title,
          x_label="Time (s)",
          y_label=y_label,
          unified=True,
          axes=axes,
      )
  
      add_background_image(fig, fig_background)
  
      if legend is not False:
          legend_loc = 0 if legend is True else legend
          labels = [
              e.comment if e.comment else "Unknown" for e in evoked
          ]
          handles = fig.axes[0].lines[: len(evoked)]
          legend = plt.legend(
              labels=labels,
              handles=handles,
              loc=legend_loc,
              prop={"size": 10},
          )
          legend.get_frame().set_facecolor(axis_facecolor)
          txts = legend.get_texts()
          for txt, col in zip(txts, color):
              txt.set_color(col)
  
      if proj == "interactive":
          for e in evoked:
              _check_delayed_ssp(e)
          params = dict(
              evokeds=evoked,
              times=times,
              plot_update_proj_callback=_plot_update_evoked_topo_proj,
              projs=evoked[0].info["projs"],
              fig=fig,
          )
          _draw_proj_checkbox(None, params)
  
      plt_show(show)
      return fig
  
imports: from copy import deepcopy
  from functools import partial
  import numpy
  from scipy import ndimage
  from .._fiff.pick import channel_type, pick_types
  from ..defaults import _handle_default
  from ..utils import Bunch, _check_option, _clean_names, _is_numeric, _to_rgb, fill_doc
  from .utils import DraggableColorbar, _check_cov, _check_delayed_ssp, _draw_proj_checkbox, _plot_masked_image, _setup_ax_spines, _setup_vmin_vmax, add_background_image, plt_show
label_desc: Use image node_id 14 for calling a global function with example usage: _plot_evoked_topo(evoked, layout, layout_scale, color, border, ylim, scalings, title, proj, vline, hline, fig_facecolor, fig_background, axis_facecolor, font_color, merge_channels, legend, axes, exclude, show, noise_cov) and returns: fig