Skip to content

facet_figure

yohou.plotting._utils.facet_figure(df, render_fn, *, groups=None, columns=None, column_groups=None, facet_by='member', facet_n_cols=2, title=None, x_label=None, y_label=None, width=None, height=None, row_height=300, shared_xaxes=True, subplot_v_spacing=None, subplot_h_spacing=None, resampler=None)

Create a faceted subplot figure for panel or column data.

When groups is provided the function facets by panel group/member (existing behaviour). When groups is None the function facets by column: each column (or column group) becomes one subplot.

Parameters

Name Type Description Default
df DataFrame

Input DataFrame with a "time" column.

required
render_fn Callable[[RenderContext], None]

Callback receiving a RenderContext for each trace.

required
groups list[str] | None

Group prefixes to include (None means non-panel mode).

None
columns str | list[str] | None

For panel mode: member names to include within selected groups. For non-panel mode: column names to facet on. Mutually exclusive with column_groups in non-panel mode.

None
column_groups dict[str, list[str]] | None

Non-panel only. Maps a facet name (subplot title) to a list of columns that should be available in RenderContext.sub_df. Mutually exclusive with columns in non-panel mode. Example: {"sales": ["sales_proba_low", "sales_proba_high"]}.

None
facet_by Literal['group', 'member']

Faceting axis (panel mode only).

  • "member" - one subplot per unique member; groups are overlaid within each subplot (cross-entity comparison).
  • "group" - one subplot per group; members are overlaid within each subplot (within-entity analysis).
"member"
facet_n_cols int

Number of columns in the facet grid.

2
title str | None

Figure title.

None
x_label str | None

X-axis label.

None
y_label str | None

Y-axis label.

None
width int | None

Figure width in pixels.

None
height int | None

Figure height in pixels. Defaults to row_height * n_rows.

None
row_height int

Height per facet row when height is None.

300
shared_xaxes bool

Share x-axes across all subplots.

True
subplot_v_spacing float | None

Vertical spacing between subplots.

None
subplot_h_spacing float | None

Horizontal spacing between subplots.

None
resampler bool | Literal['widget'] | None

Resampler mode.

None

Returns

Type Description
Figure

Plotly figure with faceted subplots.

Examples

>>> import polars as pl
>>> from yohou.plotting._utils import facet_figure, RenderContext, LegendTracker
>>> df = pl.DataFrame({
...     "time": [1, 2, 3],
...     "sales__a": [10, 20, 30],
...     "sales__b": [15, 25, 35],
... })
>>> tracker = LegendTracker()
>>> def render(ctx: RenderContext) -> None:
...     ctx.fig.add_scatter(
...         x=ctx.sub_df["time"],
...         y=ctx.sub_df[ctx.display_name],
...         name=ctx.display_name,
...         row=ctx.row,
...         col=ctx.col,
...     )
>>> fig = facet_figure(df, render)
>>> len(fig.data) > 0
True

See Also

[RenderContext][yohou.plotting._utils.RenderContext] : Typed context passed to the render callback. resolve_panel_columns : Resolve which panel columns to plot.

Source Code

Show/Hide source
def facet_figure(
    df: pl.DataFrame,
    render_fn: Callable[[RenderContext], None],
    *,
    groups: list[str] | None = None,
    columns: str | list[str] | None = None,
    column_groups: dict[str, list[str]] | None = None,
    facet_by: Literal["group", "member"] = "member",
    facet_n_cols: int = 2,
    title: str | None = None,
    x_label: str | None = None,
    y_label: str | None = None,
    width: int | None = None,
    height: int | None = None,
    row_height: int = 300,
    shared_xaxes: bool = True,
    subplot_v_spacing: float | None = None,
    subplot_h_spacing: float | None = None,
    resampler: bool | Literal["widget"] | None = None,
) -> go.Figure:
    """Create a faceted subplot figure for panel or column data.

    When *groups* is provided the function facets by panel
    group/member (existing behaviour).  When *groups* is
    ``None`` the function facets by **column**: each column (or column
    group) becomes one subplot.

    Parameters
    ----------
    df : pl.DataFrame
        Input DataFrame with a ``"time"`` column.
    render_fn : Callable[[RenderContext], None]
        Callback receiving a `RenderContext` for each trace.
    groups : list[str] | None, default=None
        Group prefixes to include (``None`` means non-panel mode).
    columns : str | list[str] | None, default=None
        For panel mode: member names to include within selected groups.
        For non-panel mode: column names to facet on.  Mutually
        exclusive with *column_groups* in non-panel mode.
    column_groups : dict[str, list[str]] | None, default=None
        Non-panel only.  Maps a facet name (subplot title) to a list
        of columns that should be available in ``RenderContext.sub_df``.
        Mutually exclusive with *columns* in non-panel mode.  Example:
        ``{"sales": ["sales_proba_low", "sales_proba_high"]}``.
    facet_by : Literal["group", "member"], default="member"
        Faceting axis (panel mode only).

        - ``"member"`` - one subplot per unique member; groups are
          overlaid within each subplot (cross-entity comparison).
        - ``"group"`` - one subplot per group; members are overlaid
          within each subplot (within-entity analysis).
    facet_n_cols : int, default=2
        Number of columns in the facet grid.
    title : str | None, default=None
        Figure title.
    x_label : str | None, default=None
        X-axis label.
    y_label : str | None, default=None
        Y-axis label.
    width : int | None, default=None
        Figure width in pixels.
    height : int | None, default=None
        Figure height in pixels.  Defaults to ``row_height * n_rows``.
    row_height : int, default=300
        Height per facet row when *height* is ``None``.
    shared_xaxes : bool, default=True
        Share x-axes across all subplots.
    subplot_v_spacing : float | None, default=None
        Vertical spacing between subplots.
    subplot_h_spacing : float | None, default=None
        Horizontal spacing between subplots.
    resampler : bool | Literal["widget"] | None, default=None
        Resampler mode.

    Returns
    -------
    go.Figure
        Plotly figure with faceted subplots.

    Examples
    --------
    >>> import polars as pl
    >>> from yohou.plotting._utils import facet_figure, RenderContext, LegendTracker
    >>> df = pl.DataFrame({
    ...     "time": [1, 2, 3],
    ...     "sales__a": [10, 20, 30],
    ...     "sales__b": [15, 25, 35],
    ... })
    >>> tracker = LegendTracker()
    >>> def render(ctx: RenderContext) -> None:
    ...     ctx.fig.add_scatter(
    ...         x=ctx.sub_df["time"],
    ...         y=ctx.sub_df[ctx.display_name],
    ...         name=ctx.display_name,
    ...         row=ctx.row,
    ...         col=ctx.col,
    ...     )
    >>> fig = facet_figure(df, render)
    >>> len(fig.data) > 0
    True

    See Also
    --------
    [`RenderContext`][yohou.plotting._utils.RenderContext] : Typed context passed to the render callback.
    [`resolve_panel_columns`][yohou.plotting._utils.resolve_panel_columns] : Resolve which panel columns to plot.
    """
    if groups is not None:
        return _facet_figure_panel(
            df,
            render_fn,
            groups=groups,
            columns=columns,
            facet_by=facet_by,
            facet_n_cols=facet_n_cols,
            title=title,
            x_label=x_label,
            y_label=y_label,
            width=width,
            height=height,
            row_height=row_height,
            shared_xaxes=shared_xaxes,
            subplot_v_spacing=subplot_v_spacing,
            subplot_h_spacing=subplot_h_spacing,
            resampler=resampler,
        )

    return _facet_figure_columns(
        df,
        render_fn,
        columns=columns,
        column_groups=column_groups,
        facet_n_cols=facet_n_cols,
        title=title,
        x_label=x_label,
        y_label=y_label,
        width=width,
        height=height,
        row_height=row_height,
        shared_xaxes=shared_xaxes,
        subplot_v_spacing=subplot_v_spacing,
        subplot_h_spacing=subplot_h_spacing,
        resampler=resampler,
    )