docs: def _metadata_fetch(self, metadata_fields, label=None):
          """Takes a list of metadata fields, some of which can contain taxon names or taxon IDs, and
          returns a DataFrame with transformed data that can be used for plotting.
  
          Parameters
          ----------
          metadata_fields : `list` of `string`
              A list of metadata fields, taxon names, or taxon IDs to fetch and transform for display.
          label : `string` or `callable`, optional
              A metadata field (or function) used to label each analysis. If passing a function, a
              dict containing the metadata for each analysis is passed as the first and only
              positional argument. The callable function must return a string.
  
              If this argument is not given, and "Label" is in `metadata_fields`, "Label" will be set
              to the filename associated with an analysis.
  
          Notes
          -----
          Taxon names and IDs are transformed into the relative abundances of those taxa within their
          own rank. For example, 'Bacteroides' will return the relative abundances of 'Bacteroides'
          among all taxa of rank genus. Taxon IDs are stored as strings in `ClassificationsDataFrame`
          and are coerced to strings if integers are given.
  
          Metadata fields are returned as is, from the `self.metadata` DataFrame. If multiple metadata
          fields are specified in a tuple, their values are joined as strings separated by underscore.
          Multiple metadata fields in a tuple must both be categorical. That is, a numerical field and
          boolean can not be joined, or the result would be something like '87.4_True'.
  
          The 'Label' field name is transformed to '_display_name'. This lets us label points in plots
          by the name generated for each sample in `SampleCollection._collate_metadata`.
  
          Returns
          -------
          `pandas.DataFrame`
              Columns are renamed (if applicable) metadata fields and rows are `Classifications.id`.
              Elements are transformed values. Not all metadata fields will have been renamed, but will
              be present in the below `dict` nonetheless.
          `dict`
              Keys are metadata fields and values are renamed metadata fields. This can be used to map
              metadata fields which were passed to this function, to prettier names. For example, if
              'bacteroid' is passed, it will be matched with the Bacteroides genus and renamed to
              'Bacteroides (816)', which includes its taxon ID.
          """
          import pandas as pd
  
          help_metadata = ", ".join(self.metadata.keys())
          magic_metadata = pd.DataFrame({"classification_id": self._results.index}).set_index(
              "classification_id"
          )
  
          # if user passed label kwarg but didn't put "Label" in the fields, assume the user wants
          # that field added
          if label is not None and "Label" not in metadata_fields:
              metadata_fields.append("Label")
  
          # if we magically rename fields, keep track
          magic_fields = {}
  
          for f in set([f for f in metadata_fields if f]):
              if isinstance(f, tuple):
                  # joined categorical metadata
                  for field in f:
                      if field not in self.metadata:
                          raise OneCodexException(
                              "Field {} not found. Choose from: {}".format(field, help_metadata)
                          )
  
                      if not (
                          pd.api.types.is_bool_dtype(self.metadata[field])
                          or pd.api.types.is_categorical_dtype(self.metadata[field])  # noqa
                          or pd.api.types.is_object_dtype(self.metadata[field])  # noqa
                      ):
                          raise OneCodexException(
                              "When specifying multiple metadata fields, all must be categorical"
                          )
  
                  # concatenate the columns together with underscores
                  composite_field = "_".join(f)
                  magic_metadata[composite_field] = ""
                  magic_metadata[composite_field] = (
                      magic_metadata[composite_field]
                      .str.cat([self.metadata[field].astype(str) for field in f], sep="_")
                      .str.lstrip("_")
                  )
                  magic_fields[f] = composite_field
              else:
                  str_f = str(f)
  
                  if str_f == "Label":
                      magic_metadata[str_f] = self.metadata["filename"]
                      magic_fields[f] = str_f
  
                      if isinstance(label, six.string_types):
                          if label in self.metadata.columns:
                              magic_metadata[str_f] = self.metadata[label]
                          else:
                              raise OneCodexException(
                                  "Label field {} not found. Choose from: {}".format(
                                      label, help_metadata
                                  )
                              )
                      elif callable(label):
                          for classification_id, metadata in self.metadata.to_dict(
                              orient="index"
                          ).items():
                              c_id_label = label(metadata)
  
                              if not isinstance(c_id_label, six.string_types):
                                  raise OneCodexException(
                                      "Expected string from label function, got: {}".format(
                                          type(c_id_label).__name__
                                      )
                                  )
  
                              magic_metadata.loc[classification_id, "Label"] = c_id_label
                      elif label is not None:
                          raise OneCodexException(
                              "Expected string or callable for label, got: {}".format(
                                  type(label).__name__
                              )
                          )
                  elif str_f in self.metadata:
                      # exactly matches existing metadata field
                      magic_metadata[f] = self.metadata[str_f]
                      magic_fields[f] = str_f
                  elif str_f in self._results.keys():
                      # is a tax_id
                      tax_name = self.taxonomy["name"][str_f]
  
                      # report within-rank abundance
                      df = self.to_df(rank=self.taxonomy["rank"][str_f])
  
                      renamed_field = "{} ({})".format(tax_name, str_f)
                      magic_metadata[renamed_field] = df[str_f]
                      magic_fields[f] = renamed_field
                  else:
                      # try to match it up with a taxon name
                      hits = []
  
                      # don't both searching if the query is really short
                      if len(str_f) > 4:
                          for tax_id, tax_name in zip(self.taxonomy.index, self.taxonomy["name"]):
                              # if it's an exact match, use that and skip the rest
                              if str_f.lower() == tax_name.lower():
                                  hits = [(tax_id, tax_name)]
                                  break
                              # otherwise, keep trying to match
                              elif str_f.lower() in tax_name.lower():
                                  hits.append((tax_id, tax_name))
  
                          # take the hit with the lowest tax_id
                          hits = sorted(hits, key=lambda x: int(x[0]))
  
                      if hits:
                          # report within-rank abundance
                          df = self.to_df(rank=self.taxonomy["rank"][hits[0][0]])
  
                          renamed_field = "{} ({})".format(hits[0][1], hits[0][0])
                          magic_metadata[renamed_field] = df[hits[0][0]]
                          magic_fields[f] = renamed_field
                      else:
                          # matched nothing
                          raise OneCodexException(
                              "Field or taxon {} not found. Choose from: {}".format(
                                  str_f, help_metadata
                              )
                          )
  
          return magic_metadata, magic_fields