# Path: onecodex/exceptions.py
# class OneCodexException(Exception):
#     pass
# 
# class PlottingException(OneCodexException):
#     """User-facing plotting error for cases when the user may take action to resolve the issue."""
# 
#     pass
# 
# Path: onecodex/lib/enums.py
# class AbundanceMetric(BaseEnum):
#     Abundance = "abundance"
#     AbundanceWChildren = "abundance_w_children"
# 
# class Rank(BaseEnum):
#     """Python does not allow extending enums so we have to repeat the ranks."""
# 
#     Superkingdom = "superkingdom"
#     Kingdom = "kingdom"
#     Phylum = "phylum"
#     Class = "class"
#     Order = "order"
#     Family = "family"
#     Genus = "genus"
#     Species = "species"
#     Auto = "auto"
# 
# class Metric(BaseEnum):
#     Auto = "auto"
#     Readcount = "readcount"
#     ReadcountWChildren = "readcount_w_children"
#     Abundance = "abundance"
#     AbundanceWChildren = "abundance_w_children"
# 
#     @property
#     def dtype(self):
#         if self == Metric.Readcount or self == Metric.ReadcountWChildren:
#             return int
#         elif self == Metric.Abundance or self == Metric.AbundanceWChildren:
#             return float
#         else:
#             raise ValueError("Metric {} does not have an associated dtype.".format(self))
# 
# Path: onecodex/viz/_primitives.py
# def interleave_palette(domain, palette="ocx"):
#     from onecodex.viz import DEFAULT_PALETTES
# 
#     if palette in DEFAULT_PALETTES:
#         colors = DEFAULT_PALETTES[palette]
#     elif isinstance(palette, list):
#         colors = palette
#     else:
#         raise OneCodexException("A valid palette name or list of colors must be passed")
# 
#     n_rows = len(set(domain))
#     if n_rows == 0:
#         return []
# 
#     # We do some shuffling to optimize the range of colours with our own palette
#     if palette == "ocx":
#         hues, shades = 6, 4
# 
#         # Calculate how many shades to show of each hue
#         period = min(ceil(n_rows / hues), shades)
# 
#         # Save the darkest hue for last
#         offset = 0
#         if period < shades:
#             offset = 1
# 
#         # Generate a sub-palette with each hue, at each shade
#         sub_palettes = [colors[ix::shades] for ix in range(offset, period + offset)]
# 
#         # Interleave the sub-palettes so the individuals colors are ordered by hue, then shade
#         colors = list(chain.from_iterable(zip(*sub_palettes)))
# 
#     # Repeat the palette to extend it to the length of the domain
#     extended_palette = colors * (n_rows // len(colors)) + colors[: n_rows % len(colors)]
# 
#     return extended_palette
# 
# def prepare_props(title=None, height=None, width=None):
#     """Prepare key plotting kwargs for passing to Altair, which d/n like None values."""
#     props = {}
#     if title:
#         props["title"] = title  # None gets rendered as `None`
#     if height:
#         props["height"] = height  # None violates Vega JSON Schema
#     if width:
#         props["width"] = width  # None violates Vega JSON Schema
#     return props
# 
# def sort_helper(sort, values):
#     """Return a sorted list of values for the Altair chart axes."""
#     sort_order = None
# 
#     if callable(sort):
#         values = list(set(values))
#         sort_order = sort(values)
#     elif isinstance(sort, list):
#         if set(sort) != set(values):
#             raise OneCodexException("sort_x must have the same items as your dataset.")
#         sort_order = sort
#     elif sort:
#         raise OneCodexException(
#             "Please pass either a sorted list of values matching the axis labels \
#             or a function that returns a sorted list of labels"
#         )
# 
#     return sort_order
# 
# def get_base_classification_url():
#     return os.environ.get("ONE_CODEX_API_BASE", "https://app.onecodex.com") + "/classification/"


from onecodex.exceptions import OneCodexException, PlottingException
from onecodex.lib.enums import AbundanceMetric, Rank, Metric
from onecodex.viz._primitives import (
    interleave_palette,
    prepare_props,
    sort_helper,
    get_base_classification_url,
)
        import altair as alt
            plot is hovered over, the value of the metadata associated with that sample will be
            displayed in a modal.
        haxis : `string`, optional
            The metadata field (or tuple containing multiple categorical fields) used to group
            samples together.
        legend: `string`, optional
            Title for color scale. Defaults to the metric used to generate the plot, e.g.
            readcount_w_children or abundance.
        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.
        sort_x : `list` or `callable`, optional
            Either a list of sorted labels or a function that will be called with a list of x-axis labels
            as the only argument, and must return the same list in a user-specified order.
        include_no_level : `bool`, optional
            Whether or not a row should be plotted for taxa that do not have a designated parent at `rank`.

        Examples
        --------
        Plot a bargraph of the top 10 most abundant genera

        >>> plot_bargraph(rank='genus', top_n=10)
        """
        # Deferred imports

        if rank is None:
            raise OneCodexException("Please specify a rank or 'auto' to choose automatically")

        if not (threshold or top_n):

# Path: onecodex/exceptions.py
# class OneCodexException(Exception):
#     pass
# 
# class PlottingException(OneCodexException):
#     """User-facing plotting error for cases when the user may take action to resolve the issue."""
# 
#     pass
# 
# Path: onecodex/lib/enums.py
# class AbundanceMetric(BaseEnum):
#     Abundance = "abundance"
#     AbundanceWChildren = "abundance_w_children"
# 
# class Rank(BaseEnum):
#     """Python does not allow extending enums so we have to repeat the ranks."""
# 
#     Superkingdom = "superkingdom"
#     Kingdom = "kingdom"
#     Phylum = "phylum"
#     Class = "class"
#     Order = "order"
#     Family = "family"
#     Genus = "genus"
#     Species = "species"
#     Auto = "auto"
# 
# class Metric(BaseEnum):
#     Auto = "auto"
#     Readcount = "readcount"
#     ReadcountWChildren = "readcount_w_children"
#     Abundance = "abundance"
#     AbundanceWChildren = "abundance_w_children"
# 
#     @property
#     def dtype(self):
#         if self == Metric.Readcount or self == Metric.ReadcountWChildren:
#             return int
#         elif self == Metric.Abundance or self == Metric.AbundanceWChildren:
#             return float
#         else:
#             raise ValueError("Metric {} does not have an associated dtype.".format(self))
# 
# Path: onecodex/viz/_primitives.py
# def interleave_palette(domain, palette="ocx"):
#     from onecodex.viz import DEFAULT_PALETTES
# 
#     if palette in DEFAULT_PALETTES:
#         colors = DEFAULT_PALETTES[palette]
#     elif isinstance(palette, list):
#         colors = palette
#     else:
#         raise OneCodexException("A valid palette name or list of colors must be passed")
# 
#     n_rows = len(set(domain))
#     if n_rows == 0:
#         return []
# 
#     # We do some shuffling to optimize the range of colours with our own palette
#     if palette == "ocx":
#         hues, shades = 6, 4
# 
#         # Calculate how many shades to show of each hue
#         period = min(ceil(n_rows / hues), shades)
# 
#         # Save the darkest hue for last
#         offset = 0
#         if period < shades:
#             offset = 1
# 
#         # Generate a sub-palette with each hue, at each shade
#         sub_palettes = [colors[ix::shades] for ix in range(offset, period + offset)]
# 
#         # Interleave the sub-palettes so the individuals colors are ordered by hue, then shade
#         colors = list(chain.from_iterable(zip(*sub_palettes)))
# 
#     # Repeat the palette to extend it to the length of the domain
#     extended_palette = colors * (n_rows // len(colors)) + colors[: n_rows % len(colors)]
# 
#     return extended_palette
# 
# def prepare_props(title=None, height=None, width=None):
#     """Prepare key plotting kwargs for passing to Altair, which d/n like None values."""
#     props = {}
#     if title:
#         props["title"] = title  # None gets rendered as `None`
#     if height:
#         props["height"] = height  # None violates Vega JSON Schema
#     if width:
#         props["width"] = width  # None violates Vega JSON Schema
#     return props
# 
# def sort_helper(sort, values):
#     """Return a sorted list of values for the Altair chart axes."""
#     sort_order = None
# 
#     if callable(sort):
#         values = list(set(values))
#         sort_order = sort(values)
#     elif isinstance(sort, list):
#         if set(sort) != set(values):
#             raise OneCodexException("sort_x must have the same items as your dataset.")
#         sort_order = sort
#     elif sort:
#         raise OneCodexException(
#             "Please pass either a sorted list of values matching the axis labels \
#             or a function that returns a sorted list of labels"
#         )
# 
#     return sort_order
# 
# def get_base_classification_url():
#     return os.environ.get("ONE_CODEX_API_BASE", "https://app.onecodex.com") + "/classification/"


# Path: onecodex/viz/_bargraph.py
from onecodex.exceptions import OneCodexException, PlottingException
from onecodex.lib.enums import AbundanceMetric, Rank, Metric
from onecodex.viz._primitives import (
    interleave_palette,
    prepare_props,
    sort_helper,
    get_base_classification_url,
)
        import altair as alt

            plot is hovered over, the value of the metadata associated with that sample will be
            displayed in a modal.
        haxis : `string`, optional
            The metadata field (or tuple containing multiple categorical fields) used to group
            samples together.
        legend: `string`, optional
            Title for color scale. Defaults to the metric used to generate the plot, e.g.
            readcount_w_children or abundance.
        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.
        sort_x : `list` or `callable`, optional
            Either a list of sorted labels or a function that will be called with a list of x-axis labels
            as the only argument, and must return the same list in a user-specified order.
        include_no_level : `bool`, optional
            Whether or not a row should be plotted for taxa that do not have a designated parent at `rank`.

        Examples
        --------
        Plot a bargraph of the top 10 most abundant genera

        >>> plot_bargraph(rank='genus', top_n=10)
        """
        # Deferred imports

        if rank is None:
            raise OneCodexException("Please specify a rank or 'auto' to choose automatically")

        if not (threshold or top_n):

            raise OneCodexException("Please specify at least one of: threshold, top_n")