Source code for visualization_toolkit.helpers.plotly.charts.core.shading

from dataclasses import dataclass
from datetime import date, datetime
from typing import Literal

from plotly import graph_objects as go

from visualization_toolkit.helpers.plotly.colors import resolve_color
from visualization_toolkit.helpers.plotly.theme import (
    SHADE_OPACITY,
    SHADE_LINE_WIDTH,
    COLORS,
)


@dataclass
class BaseShadingMixin:
    start: int | float | date | datetime
    end: int | float | date | datetime
    color: str = COLORS["light-grey"][400]

    def __post_init__(self):
        if self.start >= self.end:
            raise ValueError("start must be less than the end value")

    @property
    def resolved_color(self):
        return resolve_color(self.color)


@dataclass
class ShadeX(BaseShadingMixin):
    """
    Add a shaded rectangle region that spans vertically on the chart
    between the ``start`` and ``end`` values on the x-axis.

    :param start: The starting value where the shaded region begins on the x-axis.
    :param end: The ending value where the shaded region ends on the x-axis.
    :param color: Fill color of the shaded region. Defaults to light-grey.

    Examples
    ^^^^^^^^^^^^^
    .. code-block:: python
        :caption: Example of creating a chart with shaded vertical areas. Note that the start and end values correspond to the x-axis.

        from visualization_toolkit.helpers.plotly import chart, axis, series, annotation, shade_x

        fig = chart(
            df,
            x_axis=axis(
                column_name="year",
                label="Year",
            ),
            chart_series=[
                series(
                    column_name="lifeExp",
                    category_column_name="country",
                    location="y1",
                ),
            ],
            y1_axis=axis(
                label="Life Expectancy",
                axis_type="number",
            ),
            shaded_regions=[
                shade_x(start=1950, end=1955, color="green"),
                shade_x(start=1970, end=1975, color="red"),
            ],
        )

        display(fig)

    """

    def add_to_figure(self, fig: go.Figure):
        fig.add_vrect(
            x0=self.start,
            x1=self.end,
            fillcolor=self.resolved_color,
            opacity=SHADE_OPACITY,
            layer="below",
            line_width=SHADE_LINE_WIDTH,
        )


[docs] shade_x = ShadeX
@dataclass class ShadeY(BaseShadingMixin): """ Add a shaded rectangle region that spans horizontally on the chart between the ``start`` and ``end`` values on the y-axis. :param start: The starting value where the shaded region begins on the y-axis. :param end: The ending value where the shaded region ends on the y-axis. :param color: Fill color of the shaded region. Defaults to light-grey. Examples ^^^^^^^^^^^^^ .. code-block:: python :caption: Example of creating a chart with shaded horizontal areas. Note that the start and end values correspond to the y-axis. from visualization_toolkit.helpers.plotly import chart, axis, series, annotation, shade_y fig = chart( df, x_axis=axis( column_name="year", label="Year", ), chart_series=[ series( column_name="lifeExp", category_column_name="country", location="y1", ), ], y1_axis=axis( label="Life Expectancy", axis_type="number", ), shaded_regions=[ shade_y(start=50, end=55, color="green"), shade_y(start=70, end=75, color="red"), ], ) display(fig) """ location: Literal["y1", "y2"] = "y1" def add_to_figure(self, fig: go.Figure): fig.add_hrect( y0=self.start, y1=self.end, fillcolor=self.resolved_color, opacity=SHADE_OPACITY, layer="below", line_width=SHADE_LINE_WIDTH, secondary_y=self.location == "y2", )
[docs] shade_y = ShadeY