docs: def boxplot(df, category, quantity, category_type="N", title=None, xlabel=None, ylabel=None):
      """Plot a simple boxplot using Altair.
  
      Parameters
      ----------
      df : `pandas.DataFrame`
          Contains columns matching 'category' and 'quantity' labels, at a minimum.
      category : `string`
          The name of the column in df used to group values on the horizontal axis.
      quantity : `string`
          The name of the columm in df of values to plot on the vertical axis. Must be numerical.
      category_type : {'N', 'O', 'T'}, optional
          Nominal, ordinal, or time values can be used as categories. Quantitative (Q) values look weird.
      title : `string`, optional
          Text label at the top of the plot.
      xlabel : `string`, optional
          Text label along the horizontal axis.
      ylabel : `string`, optional
          Text label along the vertical axis.
  
      Returns
      -------
      `altair.Chart`
      """
      # must be one of Nominal, Ordinal, Time per altair
      if category_type not in ("N", "O", "T"):
          raise OneCodexException("If specifying category_type, must be N, O, or T")
  
      # adapted from https://altair-viz.github.io/gallery/boxplot_max_min.html
      lower_box = "q1({}):Q".format(quantity)
      lower_whisker = "min({}):Q".format(quantity)
      upper_box = "q3({}):Q".format(quantity)
      upper_whisker = "max({}):Q".format(quantity)
  
      if category_type == "T":
          x_format = "hoursminutes({}):{}".format(category, category_type)
      else:
          x_format = "{}:{}".format(category, category_type)
  
      lower_plot = (
          alt.Chart(df)
          .mark_rule()
          .encode(y=alt.Y(lower_whisker, axis=alt.Axis(title=ylabel)), y2=lower_box, x=x_format)
      )
  
      middle_plot = alt.Chart(df).mark_bar(size=35).encode(y=lower_box, y2=upper_box, x=x_format)
  
      upper_plot = alt.Chart(df).mark_rule().encode(y=upper_whisker, y2=upper_box, x=x_format)
  
      middle_tick = (
          alt.Chart(df)
          .mark_tick(color="black", size=35)
          .encode(
              y="median({}):Q".format(quantity),
              x=alt.X(x_format, axis=alt.Axis(title=xlabel), scale=alt.Scale(rangeStep=45)),
              tooltip="median({}):Q".format(quantity),
          )
      )
  
      chart = lower_plot + middle_plot + upper_plot + middle_tick
  
      if title:
          chart = chart.properties(title=title)
  
      return chart