code: def events(times, labels=None, base=None, height=None, ax=None, text_kw=None,
             **kwargs):
      '''Plot event times as a set of vertical lines
      Parameters
      ----------
      times : np.ndarray, shape=(n,)
          event times, in the format returned by
          :func:`mir_eval.io.load_events` or
          :func:`mir_eval.io.load_labeled_events`.
      labels : list, shape=(n,), optional
          event labels, in the format returned by
          :func:`mir_eval.io.load_labeled_events`.
      base : number
          The vertical position of the base of the line.
          By default, this will be the bottom of the plot.
      height : number
          The height of the lines.
          By default, this will be the top of the plot (minus `base`).
      ax : matplotlib.pyplot.axes
          An axis handle on which to draw the segmentation.
          If none is provided, a new set of axes is created.
      text_kw : dict
          If `labels` is provided, the properties of the text
          objects can be specified here.
          See `matplotlib.pyplot.Text` for valid parameters
      kwargs
          Additional keyword arguments to pass to
          `matplotlib.pyplot.vlines`.
      Returns
      -------
      ax : matplotlib.pyplot.axes._subplots.AxesSubplot
          A handle to the (possibly constructed) plot axes
      '''
      if text_kw is None:
          text_kw = dict()
      text_kw.setdefault('va', 'top')
      text_kw.setdefault('clip_on', True)
      text_kw.setdefault('bbox', dict(boxstyle='round', facecolor='white'))
      times = np.asarray(times)
      ax, new_axes = __get_axes(ax=ax)
      if new_axes:
          if base is None:
              base = 0
          if height is None:
              height = 1
          ax.set_ylim([base, height])
      else:
          if base is None:
              base = ax.get_ylim()[0]
          if height is None:
              height = ax.get_ylim()[1]
      cycler = ax._get_patches_for_fill.prop_cycler
      style = next(cycler).copy()
      style.update(kwargs)
      if 'colors' in style:
          style.pop('color', None)
      lines = ax.vlines(times, base, base + height, **style)
      if labels:
          for path, lab in zip(lines.get_paths(), labels):
              ax.annotate(lab,
                          xy=(path.vertices[0][0], height),
                          xycoords='data',
                          xytext=(8, -10), textcoords='offset points',
                          **text_kw)
      if new_axes:
          ax.set_yticks([])
      __expand_limits(ax, [base, base + height], which='y')
      if times.size:
          __expand_limits(ax, [times.min(), times.max()], which='x')
      return ax