docs: def create_figure(
      *,
      width="single",
      nrows=1,
      cols=[1],
      margin=1.,
      hspace=0.25,
      wspace=0.25,
      cbar_width=0.25,
      aspects=[],
      default_aspect=1
  ):
      """Re-parameterization of matplotlib figure creation tools, exposing convenient variables.
  
      Figures are defined primarily by their width. Height is defined by the
      aspect ratios of the subplots contained within. hspace, wspace, and
      cbar_width are defined in inches, making it easier to make consistent
      plots. Margins are enforced to be equal around the entire plot, starting
      from the edges of the subplots.
  
      Parameters
      ----------
      width : {'single', 'double', 'dissertation'} or float (optional)
          The total width of the generated figure. Can be given in inches
          directly, or can be specified using keys. Default is 'single' (6.5
          inches).
      nrows : int (optional)
          The number of subplot rows in the figure. Default is 1.
      cols : list (optional)
          A list of numbers, defining the number and width-ratios of the
          figure columns. May also contain the special string 'cbar', defining
          a column as a colorbar-containing column. Default is [1].
      margin : float (optional)
          Margin in inches. Margin is applied evenly around the figure, starting
          from the subplot boundaries (so that ticks and labels appear in the
          margin). Default is 1.
      hspace : float (optional)
          The 'height space' (space seperating two subplots vertically), in
          inches. Default is 0.25.
      wspace : float (optional)
          The 'width space' (space seperating two subplots horizontally), in
          inches. Default is 0.25.
      cbar_width : float (optional)
          The width of the colorbar in inches. Default is 0.25.
      aspects : list of lists (optional)
          Define the aspect ratio of individual subplots. List of lists, each
          sub-ist having the format [[row, col], aspect]. The figure will expand
          vertically to acomidate the defined aspect ratio. Aspects are V/H so
          aspects larger than 1 will be taller than wide and vice-versa for
          aspects smaller than 1. You may only define the aspect for one subplot
          in each row. If no aspect is defined for a particular row, the leftmost
          subplot will have an aspect of ``default_aspect``. Default is given by
          default_aspect kwarg.
      default_aspect : number (optional)
          Default aspect of left-most column, if no aspect is defined for a
          given row.
  
      Returns
      -------
      tuple
          (WrightTools.artists.Figure, WrightTools.artists.GridSpec). GridSpec
          contains SubplotSpec objects that can have axes placed into them.
          The SubplotSpec objects can be accessed through indexing: [row, col].
          Slicing works, for example ``cax = plt.subplot(gs[:, -1])``. See
          matplotlib gridspec__ documentation for more information.
  
          __ http://matplotlib.org/users/gridspec.html#gridspec-and-subplotspec
  
  
      Notes
      -----
      To ensure the margins work as expected, save the fig with
      the same margins (``pad_inches``) as specified in this function. Common
      savefig call:
      ``plt.savefig(plt.savefig(output_path, dpi=300, transparent=True,
      pad_inches=1))``
  
      See Also
      --------
      wt.artists.plot_margins
          Plot lines to visualize the figure edges, margins, and centers. For
          debug and design purposes.
      wt.artists.subplots_adjust
          Enforce margins for figure generated elsewhere.
  
      """
      # get width
      if width == "double":
          figure_width = 14.
      elif width == "single":
          figure_width = 6.5
      elif width == "dissertation":
          figure_width = 13.
      else:
          figure_width = float(width)
      # check if aspect constraints are valid
      rows_in_aspects = [item[0][0] for item in aspects]
      if not len(rows_in_aspects) == len(set(rows_in_aspects)):
          raise Exception("can only specify aspect for one plot in each row")
      # get width avalible to subplots (not including colorbars)
      total_subplot_width = figure_width - 2 * margin
      total_subplot_width -= (len(cols) - 1) * wspace  # whitespace in width
      total_subplot_width -= cols.count("cbar") * cbar_width  # colorbar width
      # converters
  
      def in_to_mpl(inches, total, n):
          return (inches * n) / (total - inches * n + inches)
  
      def mpl_to_in(mpl, total, n):
          return (total / (n + mpl * (n - 1))) * mpl
  
      # calculate column widths, width_ratio
      subplot_ratios = np.array([i for i in cols if not i == "cbar"], dtype=np.float)
      subplot_ratios /= sum(subplot_ratios)
      subplot_widths = total_subplot_width * subplot_ratios
      width_ratios = []
      cols_idxs = []
      i = 0
      for col in cols:
          if not col == "cbar":
              width_ratios.append(subplot_widths[i])
              cols_idxs.append(i)
              i += 1
          else:
              width_ratios.append(cbar_width)
              cols_idxs.append(np.nan)
      # calculate figure height, height_ratios, figure height
      subplot_heights = []
      for row_index in range(nrows):
          if row_index in rows_in_aspects:
              aspect = aspects[rows_in_aspects.index(row_index)][1]
              col_index = aspects[rows_in_aspects.index(row_index)][0][1]
              height = subplot_widths[col_index] * aspect
              subplot_heights.append(height)
          else:
              # make the leftmost (zero indexed) plot square as default
              subplot_heights.append(subplot_widths[0] * default_aspect)
      height_ratios = subplot_heights
      figure_height = sum(subplot_heights)
      figure_height += (nrows - 1) * hspace
      figure_height += 2 * margin
      # make figure
      fig = plt.figure(figsize=[figure_width, figure_height], FigureClass=Figure)
      # get hspace, wspace in relative units
      hspace = in_to_mpl(hspace, figure_height - 2 * margin, nrows)
      wspace = in_to_mpl(wspace, figure_width - 2 * margin, len(cols))
      # make gridpsec
      gs = GridSpec(
          nrows,
          len(cols),
          hspace=hspace,
          wspace=wspace,
          width_ratios=width_ratios,
          height_ratios=height_ratios,
      )
      # finish
      subplots_adjust(fig, inches=margin)
      return fig, gs