code: def plot_events(
      events,
      sfreq=None,
      first_samp=0,
      color=None,
      event_id=None,
      axes=None,
      equal_spacing=True,
      show=True,
      on_missing="raise",
      verbose=None,
  ):
      """Plot :term:`events` to get a visual display of the paradigm.
  
      Parameters
      ----------
      %(events)s
      sfreq : float | None
          The sample frequency. If None, data will be displayed in samples (not
          seconds).
      first_samp : int
          The index of the first sample. Recordings made on Neuromag systems
          number samples relative to the system start (not relative to the
          beginning of the recording). In such cases the ``raw.first_samp``
          attribute can be passed here. Default is 0.
      color : dict | None
          Dictionary of event_id integers as keys and colors as values. If None,
          colors are automatically drawn from a default list (cycled through if
          number of events longer than list of default colors). Color can be any
          valid :ref:`matplotlib color <matplotlib:colors_def>`.
      event_id : dict | None
          Dictionary of event labels (e.g. 'aud_l') as keys and their associated
          event_id values. Labels are used to plot a legend. If None, no legend
          is drawn.
      axes : instance of Axes
         The subplot handle.
      equal_spacing : bool
          Use equal spacing between events in y-axis.
      show : bool
          Show figure if True.
      %(on_missing_events)s
      %(verbose)s
  
      Returns
      -------
      fig : matplotlib.figure.Figure
          The figure object containing the plot.
  
      Notes
      -----
      .. versionadded:: 0.9.0
      """
      if sfreq is None:
          sfreq = 1.0
          xlabel = "Samples"
      else:
          xlabel = "Time (s)"
  
      events = np.asarray(events)
      if len(events) == 0:
          raise ValueError("No events in events array, cannot plot.")
      unique_events = np.unique(events[:, 2])
  
      if event_id is not None:
          # get labels and unique event ids from event_id dict,
          # sorted by value
          event_id_rev = {v: k for k, v in event_id.items()}
          conditions, unique_events_id = zip(
              *sorted(event_id.items(), key=lambda x: x[1])
          )
  
          keep = np.ones(len(unique_events_id), bool)
          for ii, this_event in enumerate(unique_events_id):
              if this_event not in unique_events:
                  msg = f"{this_event} from event_id is not present in events."
                  _on_missing(on_missing, msg)
                  keep[ii] = False
          conditions = [cond for cond, k in zip(conditions, keep) if k]
          unique_events_id = [
              id_ for id_, k in zip(unique_events_id, keep) if k
          ]
          if len(unique_events_id) == 0:
              raise RuntimeError("No usable event IDs found")
  
          for this_event in unique_events:
              if this_event not in unique_events_id:
                  warn(
                      "event %s missing from event_id will be ignored"
                      % this_event
                  )
  
      else:
          unique_events_id = unique_events
  
      color = _handle_event_colors(color, unique_events, event_id)
      import matplotlib.pyplot as plt
  
      fig = None
      if axes is None:
          fig = plt.figure(layout="constrained")
      ax = axes if axes else plt.gca()
  
      unique_events_id = np.array(unique_events_id)
      min_event = np.min(unique_events_id)
      max_event = np.max(unique_events_id)
      max_x = (
          events[np.isin(events[:, 2], unique_events_id), 0].max()
          - first_samp
      ) / sfreq
  
      handles, labels = list(), list()
      for idx, ev in enumerate(unique_events_id):
          ev_mask = events[:, 2] == ev
          count = ev_mask.sum()
          if count == 0:
              continue
          y = np.full(
              count, idx + 1 if equal_spacing else events[ev_mask, 2][0]
          )
          if event_id is not None:
              event_label = "%s (%s)" % (event_id_rev[ev], count)
          else:
              event_label = "N=%d" % (count,)
          labels.append(event_label)
          kwargs = {}
          if ev in color:
              kwargs["color"] = color[ev]
          handles.append(
              ax.plot(
                  (events[ev_mask, 0] - first_samp) / sfreq,
                  y,
                  ".",
                  clip_on=False,
                  **kwargs,
              )[0]
          )
  
      if equal_spacing:
          ax.set_ylim(0, unique_events_id.size + 1)
          ax.set_yticks(1 + np.arange(unique_events_id.size))
          ax.set_yticklabels(unique_events_id)
      else:
          ax.set_ylim([min_event - 1, max_event + 1])
  
      ax.set(xlabel=xlabel, ylabel="Event id", xlim=[0, max_x])
  
      ax.grid(True)
  
      fig = fig if fig is not None else plt.gcf()
      # reverse order so that the highest numbers are at the top
      # (match plot order)
      handles, labels = handles[::-1], labels[::-1]
      box = ax.get_position()
      factor = 0.8 if event_id is not None else 0.9
      ax.set_position([box.x0, box.y0, box.width * factor, box.height])
      ax.legend(
          handles,
          labels,
          loc="center left",
          bbox_to_anchor=(1, 0.5),
          fontsize="small",
      )
      fig.canvas.draw()
      plt_show(show)
      return fig
  
imports: import copy
  import io
  import os
  import os.path
  import warnings
  from collections import defaultdict
  from glob import glob
  from itertools import cycle
  from pathlib import Path
  import numpy
  from scipy.signal import filtfilt, freqz, group_delay, lfilter, sosfilt, sosfiltfilt
  from .._fiff.constants import FIFF
  from .._fiff.pick import _DATA_CH_TYPES_SPLIT, _picks_by_type, pick_channels, pick_info, pick_types
  from .._fiff.proj import make_projector
  from .._freesurfer import _check_mri, _mri_orientation, _read_mri_info, _reorient_image
  from ..defaults import DEFAULTS
  from ..filter import estimate_ringing_samples
  from ..fixes import _safe_svd
  from ..rank import compute_rank
  from ..surface import read_surface
  from ..transforms import _frame_to_str, apply_trans
  from ..utils import _check_option, _mask_to_onsets_offsets, _on_missing, _pl, fill_doc, get_subjects_dir, logger, verbose, warn
  from .utils import _figure_agg, _get_color_list, _prepare_trellis, _validate_type, plt_show
label_desc: Use image node_id 7 for calling a global function with example usage: plot_events(events, sfreq, first_samp, color, event_id, axes, equal_spacing, show, on_missing, verbose) and returns: fig