Skip to content

plot_autocorrelation

yohou.plotting.diagnostics.plot_autocorrelation(df, *, columns=None, max_lags=None, confidence_level=0.95, show_confidence=True, groups=None, facet_by='member', facet_n_cols=2, color_palette=None, show_legend=True, title=None, x_label=None, y_label=None, width=None, height=None, color='#2563EB')

Plot autocorrelation function (ACF) for time series.

Shows correlation between the series and its lagged values at different time lags. Useful for identifying periodic patterns and determining appropriate MA order.

Parameters

Name Type Description Default
df DataFrame

Input DataFrame with 'time' column and numeric columns.

required
columns str | list[str] | None

Column(s) to analyze. If None, uses all numeric columns except 'time'.

None
max_lags int | None

Maximum number of lags to compute. If None, uses min(len(df)//2, 40).

None
confidence_level float

Confidence level for confidence bands (e.g. 0.95 for 95%).

0.95
show_confidence bool

Whether to show confidence bands.

True
groups list[str] | None

Panel group prefixes to plot.

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

Faceting axis for panel data. "group" creates one subplot per group, "member" one per member. None disables faceting. Ignored for non-panel data.

"member"
facet_n_cols int

Number of columns in facet grid.

2
color_palette list[str] | None

Custom color palette (one color per column).

None
show_legend bool

Whether to show the legend.

True
title str | None

Plot title.

None
x_label str | None

X-axis label.

None
y_label str | None

Y-axis label.

None
width int | None

Plot width in pixels.

None
height int | None

Plot height in pixels.

None
color str

Bar color for single-column plots (ignored when color_palette is set).

"#2563EB"

Returns

Type Description
Figure

Plotly figure object.

Examples

>>> import polars as pl
>>> from yohou.plotting import plot_autocorrelation
>>> # Create sample time series
>>> df = pl.DataFrame({
...     "time": pl.date_range(pl.date(2020, 1, 1), pl.date(2020, 12, 31), "1d", eager=True),
...     "y": [100 + i % 30 for i in range(366)],
... })
>>> # Plot ACF
>>> fig = plot_autocorrelation(df, columns="y", max_lags=20)
>>> len(fig.data) > 0
True

See Also

plot_partial_autocorrelation : Plot partial autocorrelation function. plot_correlation_heatmap : Plot correlation matrix.

Source Code

Show/Hide source
def plot_autocorrelation(
    df: pl.DataFrame,
    *,
    columns: str | list[str] | None = None,
    max_lags: int | None = None,
    confidence_level: float = 0.95,
    show_confidence: bool = True,
    groups: list[str] | None = None,
    facet_by: Literal["group", "member"] | None = "member",
    facet_n_cols: int = 2,
    color_palette: list[str] | None = None,
    show_legend: bool = True,
    title: str | None = None,
    x_label: str | None = None,
    y_label: str | None = None,
    width: int | None = None,
    height: int | None = None,
    color: str = "#2563EB",
) -> go.Figure:
    """Plot autocorrelation function (ACF) for time series.

    Shows correlation between the series and its lagged values at different time lags.
    Useful for identifying periodic patterns and determining appropriate MA order.

    Parameters
    ----------
    df : pl.DataFrame
        Input DataFrame with 'time' column and numeric columns.
    columns : str | list[str] | None, default=None
        Column(s) to analyze. If None, uses all numeric columns except 'time'.
    max_lags : int | None, default=None
        Maximum number of lags to compute. If None, uses min(len(df)//2, 40).
    confidence_level : float, default=0.95
        Confidence level for confidence bands (e.g. ``0.95`` for 95%).
    show_confidence : bool, default=True
        Whether to show confidence bands.
    groups : list[str] | None, default=None
        Panel group prefixes to plot.
    facet_by : Literal["group", "member"] | None, default="member"
        Faceting axis for panel data.  ``"group"`` creates one subplot per
        group, ``"member"`` one per member.  ``None`` disables faceting.
        Ignored for non-panel data.
    facet_n_cols : int, default=2
        Number of columns in facet grid.
    color_palette : list[str] | None, default=None
        Custom color palette (one color per column).
    show_legend : bool, default=True
        Whether to show the legend.
    title : str | None, default=None
        Plot title.
    x_label : str | None, default=None
        X-axis label.
    y_label : str | None, default=None
        Y-axis label.
    width : int | None, default=None
        Plot width in pixels.
    height : int | None, default=None
        Plot height in pixels.
    color : str, default="#2563EB"
        Bar color for single-column plots (ignored when color_palette is set).

    Returns
    -------
    go.Figure
        Plotly figure object.

    Examples
    --------
    >>> import polars as pl
    >>> from yohou.plotting import plot_autocorrelation

    >>> # Create sample time series
    >>> df = pl.DataFrame({
    ...     "time": pl.date_range(pl.date(2020, 1, 1), pl.date(2020, 12, 31), "1d", eager=True),
    ...     "y": [100 + i % 30 for i in range(366)],
    ... })

    >>> # Plot ACF
    >>> fig = plot_autocorrelation(df, columns="y", max_lags=20)
    >>> len(fig.data) > 0
    True

    See Also
    --------
    [`plot_partial_autocorrelation`][yohou.plotting.plot_partial_autocorrelation] : Plot partial autocorrelation function.
    [`plot_correlation_heatmap`][yohou.plotting.plot_correlation_heatmap] : Plot correlation matrix.
    """
    # Validate inputs
    validate_plotting_data(df, min_rows=2)
    validate_plotting_params(width=width, height=height)

    if _auto_detect_panel(df) and groups is None and columns is None:
        groups = []

    if groups is not None:
        _panel_cols = resolve_panel_columns(df, groups, columns)
        _color_mgr = PanelColorManager(color_palette)
        _acf_legend = LegendTracker()

        def _render_acf(ctx: RenderContext) -> None:
            """Render autocorrelation bar chart with confidence bands for a single column."""
            base = [c for c in ctx.sub_df.columns if c != "time"][0]
            member = _member_name(base)
            _bc = _color_mgr.get_color(member)
            series = ctx.sub_df[base].drop_nulls()
            n_s = len(series)
            _ml = max_lags if max_lags is not None else min(n_s // 2, 40)
            acf_vals = _compute_acf_values(series, _ml)
            ctx.fig.add_trace(
                go.Bar(
                    x=list(range(_ml + 1)),
                    y=acf_vals,
                    marker={"color": _bc},
                    legendgroup=ctx.display_name,
                    showlegend=_acf_legend.should_show(ctx.display_name),
                    name=ctx.display_name,
                    hovertemplate=_make_hovertemplate(ctx.display_name, "Lag", "ACF", decimals=3),
                ),
                row=ctx.row,
                col=ctx.col,
            )
            if show_confidence:
                ci = norm.ppf(1 - (1 - confidence_level) / 2) / math.sqrt(n_s)
                _add_confidence_bands(
                    ctx.fig, list(range(_ml + 1)), [ci] * (_ml + 1), [-ci] * (_ml + 1), row=ctx.row, col=ctx.col
                )

        effective_facet_by = facet_by or "member"
        fig = facet_figure(
            df,
            _render_acf,
            groups=groups,
            columns=columns,
            facet_by=effective_facet_by,
            facet_n_cols=facet_n_cols,
            title=title or "Autocorrelation (ACF)",
            x_label=x_label or "Lag",
            y_label=y_label or "ACF",
            width=width,
            height=height,
            shared_xaxes=False,
        )
        fig.update_layout(showlegend=show_legend)
        return fig

    # Non-panel case: column-mode facet_figure
    plot_columns = validate_plotting_data(df, columns=columns, exclude=["time"])
    _colors = resolve_color_palette(color_palette, len(plot_columns))
    _col_colors = dict(zip(plot_columns, _colors, strict=False))
    _default_bar_color = color  # fallback single-column color

    n = len(df)
    if max_lags is None:
        max_lags = min(n // 2, 40)

    def _render_acf(ctx: RenderContext) -> None:
        """Render ACF bars for one column into a subplot."""
        base = ctx.display_name
        _bar_color = _col_colors[base] if color_palette is not None else _default_bar_color
        series = ctx.sub_df[base].drop_nulls()
        n_series = len(series)
        acf_values = _compute_acf_values(series, max_lags)
        ctx.fig.add_trace(
            go.Bar(
                x=list(range(max_lags + 1)),
                y=acf_values,
                name=base,
                marker={"color": _bar_color},
                hovertemplate=_make_hovertemplate(base, "Lag", "ACF", decimals=3),
            ),
            row=ctx.row,
            col=ctx.col,
        )
        if show_confidence:
            ci = norm.ppf(1 - (1 - confidence_level) / 2) / math.sqrt(n_series)
            _add_confidence_bands(
                ctx.fig,
                list(range(max_lags + 1)),
                [ci] * (max_lags + 1),
                [-ci] * (max_lags + 1),
                row=ctx.row,
                col=ctx.col,
            )

    fig = facet_figure(
        df,
        _render_acf,
        columns=plot_columns,
        facet_n_cols=facet_n_cols,
        title=title or "Autocorrelation (ACF)",
        x_label=x_label or "Lag",
        y_label=y_label or "Autocorrelation",
        width=width,
        height=height,
        shared_xaxes=False,
    )
    fig.update_layout(showlegend=show_legend)

    return fig

Tutorials

The following example notebooks use this component:

  • Seasonal Analysis


    Visualization

    Seasonal overlays, subseasonal structure, ACF/PACF correlation patterns, and STL decomposition for monthly, quarterly, and long-cycle datasets.

    View · Open in marimo