Skip to content

plotting

pycatdap.plotting

v0.2 compatibility shim for the legacy pycatdap.plotting import path.

The canonical path for visualization in v0.3+ is pycatdap.plot (with backend dispatch) or pycatdap.plot.matplotlib (direct).

This shim re-exports the matplotlib backend functions so that existing v0.2 user code continues to work without modification:

from pycatdap.plotting import mosaic_plot # still works from pycatdap.plot.matplotlib import mosaic_plot # canonical from pycatdap.plot import mosaic_plot # backend dispatcher

This shim is preserved through v1.0. v1.0 will add a DeprecationWarning on use, and v2.0 may remove this module.

aic_comparison_plot

aic_comparison_plot(
    result: Catdap1Result | Catdap2Result,
    response: str | None = None,
    ax: Axes | None = None,
    **kwargs: Any,
) -> Axes

Horizontal bar chart of ΔAIC values per explanatory variable.

Parameters:

Name Type Description Default
result Catdap1Result or Catdap2Result

Analysis result.

required
response str or None

Response variable name. Required for Catdap1Result when multiple responses are present. Ignored for Catdap2Result.

None
ax Axes or None

Matplotlib axes. Created if None.

None
**kwargs Any

Passed to :meth:Axes.barh.

{}

Returns:

Type Description
Axes
Source code in src/pycatdap/plot/matplotlib.py
def aic_comparison_plot(
    result: Catdap1Result | Catdap2Result,
    response: str | None = None,
    ax: Axes | None = None,
    **kwargs: Any,
) -> Axes:
    """Horizontal bar chart of ΔAIC values per explanatory variable.

    Parameters
    ----------
    result : Catdap1Result or Catdap2Result
        Analysis result.
    response : str or None
        Response variable name.  Required for ``Catdap1Result`` when
        multiple responses are present.  Ignored for ``Catdap2Result``.
    ax : Axes or None
        Matplotlib axes.  Created if ``None``.
    **kwargs
        Passed to :meth:`Axes.barh`.

    Returns
    -------
    Axes
    """
    plt = _import_matplotlib()

    from pycatdap.catdap1 import Catdap1Result

    if isinstance(result, Catdap1Result):
        if response is None:
            response = str(result.aic.index[0])
        aic_row = result.aic.loc[response].dropna()
        variables = list(aic_row.index)
        values = list(aic_row.values)
    else:
        variables = list(result.aic["variable"])
        values = list(result.aic["aic"])

    if ax is None:
        _fig: Figure
        _fig, ax = plt.subplots()

    colors = ["tab:green" if v < 0 else "tab:red" for v in values]
    ax.barh(variables, values, color=colors, **kwargs)
    ax.set_xlabel("ΔAIC")
    ax.set_title(f"AIC Comparison (response: {response})")
    ax.axvline(0, color="black", linewidth=0.8)
    return ax

barplot_twoway

barplot_twoway(
    table: DataFrame, ax: Axes | None = None, **kwargs: Any
) -> Axes

Stacked proportional bar chart for a two-way frequency table.

Parameters:

Name Type Description Default
table DataFrame

Cross-frequency table (e.g. from result.tway_tables).

required
ax Axes or None

Matplotlib axes. Created if None.

None
**kwargs Any

Passed to :meth:DataFrame.plot.bar.

{}

Returns:

Type Description
Axes
Source code in src/pycatdap/plot/matplotlib.py
def barplot_twoway(
    table: pd.DataFrame,
    ax: Axes | None = None,
    **kwargs: Any,
) -> Axes:
    """Stacked proportional bar chart for a two-way frequency table.

    Parameters
    ----------
    table : DataFrame
        Cross-frequency table (e.g. from ``result.tway_tables``).
    ax : Axes or None
        Matplotlib axes.  Created if ``None``.
    **kwargs
        Passed to :meth:`DataFrame.plot.bar`.

    Returns
    -------
    Axes
    """
    plt = _import_matplotlib()

    proportions = table.div(table.sum(axis=0), axis=1).T

    if ax is None:
        _fig: Figure
        _fig, ax = plt.subplots()

    proportions.plot.bar(stacked=True, ax=ax, **kwargs)
    ax.set_ylabel("Proportion")
    ax.legend(title=str(table.index.name))
    return ax

mosaic_plot

mosaic_plot(
    table: DataFrame, ax: Axes | None = None, **kwargs: Any
) -> Axes

Mosaic plot for a two-way frequency table.

Uses statsmodels.graphics.mosaicplot if available, otherwise falls back to a proportional rectangle plot with matplotlib.

Parameters:

Name Type Description Default
table DataFrame

Cross-frequency table.

required
ax Axes or None

Matplotlib axes. Created if None.

None
**kwargs Any

Passed to the underlying plot function.

{}

Returns:

Type Description
Axes
Source code in src/pycatdap/plot/matplotlib.py
def mosaic_plot(
    table: pd.DataFrame,
    ax: Axes | None = None,
    **kwargs: Any,
) -> Axes:
    """Mosaic plot for a two-way frequency table.

    Uses ``statsmodels.graphics.mosaicplot`` if available, otherwise
    falls back to a proportional rectangle plot with matplotlib.

    Parameters
    ----------
    table : DataFrame
        Cross-frequency table.
    ax : Axes or None
        Matplotlib axes.  Created if ``None``.
    **kwargs
        Passed to the underlying plot function.

    Returns
    -------
    Axes
    """
    plt = _import_matplotlib()

    if ax is None:
        _fig: Figure
        _fig, ax = plt.subplots()

    # Flatten table to dict for statsmodels mosaic
    try:
        import statsmodels.graphics.mosaicplot as _sm

        sm_mosaic = _sm.mosaic

        data_dict: dict[tuple[str, str], float] = {}
        for row_label in table.index:
            for col_label in table.columns:
                data_dict[(str(row_label), str(col_label))] = float(
                    table.loc[row_label, col_label]
                )
        sm_mosaic(data_dict, ax=ax, **kwargs)
    except ImportError:
        # Fallback: simple proportional rectangles
        _draw_simple_mosaic(table, ax)

    ax.set_title("Mosaic Plot")
    return ax