def get_cached_colour(element, orbital, colours=None, cache=None):
    """Get a colour for a particular elemental and orbital combination.

    If the element is not specified in the colours dictionary, the cache is
    checked. If this element-orbital combination has not been chached before,
    a new colour is drawn from the current matplotlib colour cycle and cached.

    The default cache is sumo.plotting.colour_cache. To reset this cache, use
    ``sumo.plotting.colour_cache.clear()``.

    Args:
        element (:obj:`str`): The element.
        orbital (:obj:`str`): The orbital.
        colours (:obj:`dict`, optional): Use custom colours for specific
            element and orbital combinations. Specified as a :obj:`dict` of
            :obj:`dict` of the colours. For example::

                {
                    'Sn': {'s': 'r', 'p': 'b'},
                    'O': {'s': '#000000'}
                }

            The colour can be a hex code, series of rgb value, or any other
            format supported by matplotlib.
        cache (:obj:`dict`, optional): Cache of colour values already
            assigned. The format is the same as the custom colours dict. If
            None, the module-level cache ``sumo.plotting.colour_cache`` is
            used.

    Returns:
        tuple: (colour, cache)
    """

    if cache is None:
        cache = colour_cache

    def _get_colour_with_cache(element, orbital, cache, colour_series):
        """Return cached colour if available, or fetch and cache from cycle"""
        from itertools import chain
        if element in cache and orbital in cache[element]:
            return cache[element][orbital], cache
        else:
            # Iterate through colours to find one which is unused
            for colour in colour_series:
                # Iterate through cache to check if colour already used
                if colour not in chain(*[[col for _, col in orb.items()]
                                         for _, orb in cache.items()]):
                    break
            else:
                raise Exception('Not enough colours available for orbitals! '
                                'Try a different theme.')

            if element not in cache:
                cache[element] = {}
            cache[element].update({orbital: colour})
            return colour, cache

    colour_series = matplotlib.rcParams['axes.prop_cycle'].by_key()['color']

    if isinstance(colours, configparser.ConfigParser):
        try:
            return colours.get(element, orbital), cache
        except(configparser.NoSectionError, configparser.NoOptionError):
            return _get_colour_with_cache(element, orbital,
                                          cache, colour_series)

    elif isinstance(colours, dict):
        try:
            return colours[element][orbital]
        except KeyError:
            return _get_colour_with_cache(element, orbital,
                                          cache, colour_series)

    elif colours is None:
        return _get_colour_with_cache(element, orbital, cache, colour_series)

    else:
        raise TypeError('Argument "colours" should be dict, '
                        'ConfigParser or None.')
Get a colour for a particular elemental and orbital combination.

    If the element is not specified in the colours dictionary, the cache is
    checked. If this element-orbital combination has not been chached before,
    a new colour is drawn from the current matplotlib colour cycle and cached.

    The default cache is sumo.plotting.colour_cache. To reset this cache, use
    ``sumo.plotting.colour_cache.clear()``.

    Args:
        element (:obj:`str`): The element.
        orbital (:obj:`str`): The orbital.
        colours (:obj:`dict`, optional): Use custom colours for specific
            element and orbital combinations. Specified as a :obj:`dict` of
            :obj:`dict` of the colours. For example::

                {
                    'Sn': {'s': 'r', 'p': 'b'},
                    'O': {'s': '#000000'}
                }

            The colour can be a hex code, series of rgb value, or any other
            format supported by matplotlib.
        cache (:obj:`dict`, optional): Cache of colour values already
            assigned. The format is the same as the custom colours dict. If
            None, the module-level cache ``sumo.plotting.colour_cache`` is
            used.

    Returns:
        tuple: (colour, cache)