Source code for plotnine_extra.scales.scale_multi
"""
Multi-variable colour / fill scales.
``scale_colour_multi`` and ``scale_fill_multi`` are simplified
ports of ``ggh4x::scale_colour_multi`` / ``scale_fill_multi``.
They take a *dict* of palette assignments keyed by aesthetic
suffix and return a list of plotnine scale layers, so a single
``+ scale_colour_multi(...)`` adds several aesthetic-specific
colour scales at once.
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from plotnine import (
scale_color_gradientn,
scale_color_manual,
scale_fill_gradientn,
scale_fill_manual,
)
from ..palettes.palettes import _resolve_palette
if TYPE_CHECKING:
from typing import Mapping, Sequence
__all__ = (
"scale_colour_multi",
"scale_color_multi",
"scale_fill_multi",
"scale_listed",
)
def _build_scales(
palettes: "Mapping[str, str | Sequence[str]]",
aesthetic: str,
discrete: bool,
):
layers = []
if aesthetic == "color":
manual_cls = scale_color_manual
gradient_cls = scale_color_gradientn
else:
manual_cls = scale_fill_manual
gradient_cls = scale_fill_gradientn
for aes_name, pal in palettes.items():
cols = list(_resolve_palette(pal))
# plotnine's ``scale`` base class iterates
# ``aesthetics`` as a sequence, so passing a bare
# string splits it into individual characters. Always
# wrap in a list.
aesthetics = (
[aes_name] if isinstance(aes_name, str) else list(aes_name)
)
if discrete:
layers.append(
manual_cls(
values=cols,
aesthetics=aesthetics,
)
)
else:
layers.append(
gradient_cls(
colors=cols,
aesthetics=aesthetics,
)
)
return layers
[docs]
def scale_colour_multi(
palettes: "Mapping[str, str | Sequence[str]]",
discrete: bool = True,
):
"""
Build several colour scales for different aesthetics.
Parameters
----------
palettes : mapping
Maps aesthetic names (e.g. ``"colour"``,
``"colour_alt"``) to palette names or sequences of
colours.
discrete : bool, default True
If ``True`` use discrete (manual) scales; otherwise
continuous gradient scales.
Returns
-------
list
A list of plotnine scale objects ready to be added to
a ggplot via the ``+`` operator. Adding the list adds
each scale in turn.
"""
return _build_scales(palettes, aesthetic="color", discrete=discrete)
# Alias for the American spelling
scale_color_multi = scale_colour_multi
[docs]
def scale_fill_multi(
palettes: "Mapping[str, str | Sequence[str]]",
discrete: bool = True,
):
"""
Build several fill scales for different aesthetics.
See :func:`scale_colour_multi` for parameter docs.
"""
return _build_scales(palettes, aesthetic="fill", discrete=discrete)
[docs]
def scale_listed(
scales: "Sequence",
replaces: "Sequence[str] | None" = None,
):
"""
Combine several already-constructed scales into one list.
Parameters
----------
scales : sequence
Already-constructed plotnine scale objects.
replaces : sequence of str, optional
Aesthetic names that the listed scales should replace.
Currently informational; the function returns the
list as-is so it can be added to a ggplot in one go.
"""
return list(scales)