//  [python]
def plot_avg_coverage_vs_time(cov_df, time_units="m"):
  print(yellow("Generating plots ..."))
  cov_metrics = [
      SW_LINE_COVERAGE_LABEL, SW_REGION_COVERAGE_LABEL, HW_LINE_COVERAGE_LABEL
  ]
  axis_limits = _get_axis_limits()
  sns.set_theme(context="notebook", style="darkgrid")

  # create figure and subplot axes
  fig, axes = plt.subplots(len(cov_metrics),
                           len(TOPLEVELS),
                           sharex="col",
                           figsize=(10, 4))

  # plot coverage traces
  for row in range(len(axes)):
    # select portion of data corresponding to current COVERAGE METRIC
    sub_cov_df = cov_df[cov_df[COVERAGE_TYPE_LABEL] == cov_metrics[row]]
    for col in range(len(axes[row])):
      # select portion of data corresponding to current core
      plt_df = sub_cov_df[sub_cov_df[TOPLEVEL_LABEL] == TOPLEVELS[col]]
      # TODO(ttrippel): there has to be a better way to do the following:
      # plot legend only for the first subplot so we can extract the labels
      if row == 0 and col == 0:
        plot_legend = True
      else:
        plot_legend = False
      ax = sns.tsplot(data=plt_df,
                        time=TIME_LABEL,
                        value=COVERAGE_LABEL,
                        unit=GRAMMAR_LABEL,
                        ax=axes[row][col],
                        legend=plot_legend)
      ax.axhline(y=1.0, color='r', linestyle='-')
      # get legend info if we are plotting the first plot
      if plot_legend:
        lines = ax.get_lines()
        labels = _get_legend_labels(ax)

  # format each figure
  for row in range(len(axes)):
    for col in range(len(axes[row])):
      # get corresponding axis_limits
      if cov_metrics[row] == SW_LINE_COVERAGE_LABEL:
        ax_lims = axis_limits[TOPLEVELS[col]].kcov_limits
      elif cov_metrics[row] == SW_REGION_COVERAGE_LABEL:
        ax_lims = axis_limits[TOPLEVELS[col]].llvm_cov_limits
      else:
        ax_lims = axis_limits[TOPLEVELS[col]].vlt_cov_limits
      # format plot labels and axes
      subplot_title = "%s | %s" % (TOPLEVELS[col], cov_metrics[row])
      _format_plot(axes[row][col], ax_lims, time_units, subplot_title)
  plt.tight_layout()

  # set legend
  # isa_label_mapping = {
  # "constant-variable-never": "Const. Opcode | Variable Frame",
  # "constant-fixed-never": "Const. Opcode | Fixed Frame",
  # "mapped-variable-never": "Mapped Opcode | Variable Frame",
  # "mapped-fixed-never": "Mapped Opcode | Fixed Frame",
  # }
  isa_label_mapping = {
      "constant-variable-never": "Constant | Variable",
      "constant-fixed-never": "Constant | Fixed",
      "mapped-variable-never": "Mapped | Variable",
      "mapped-fixed-never": "Mapped | Fixed",
  }
  clean_labels = [isa_label_mapping[isa_label] for isa_label in labels]
  fig.legend(lines,
             clean_labels,
             fontsize=LEGEND_FONT_SIZE,
             title_fontsize=LEGEND_TITLE_FONT_SIZE,
             loc="upper center",
             ncol=4,
             borderaxespad=0.05,
             bbox_to_anchor=(0.5, 0.12),
             title=GRAMMAR_LABEL + " (Opcode Format | Frame Format)")
  plt.subplots_adjust(bottom=0.23, wspace=0.25, hspace=0.25)

  # adjust figure layout and save to file
  plt.savefig(PLOT_FILE_NAME, format=PLOT_FORMAT)
  print(green("Done."))
  print(LINE_SEP)