Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Plotting functions for model exploration and diagnostics.

All plot functions accept a fitted model instance and return matplotlib Figure objects.

Post-estimation plots (require .fit()): plot_params: Coefficient forest plot with CIs plot_resid: Residual diagnostic panels (QQ, fitted vs residuals) plot_predict: Prediction plots with confidence bands plot_explore: Marginal effects visualization plot_ranef: Random effects caterpillar plot (mixed models) plot_resamples: Bootstrap/permutation distribution plots plot_compare: Model comparison visualization plot_profile: Profile likelihood plots (mixed models) plot_vif: Variance inflation factor bar plot

plot_design: Design matrix heatmap plot_design: Design matrix heatmap plot_relationships: Variable relationship scatter matrix

Attributes:

NameTypeDescription
BOSSANOVA_STYLEdict[str, Any]

Functions:

NameDescription
compute_figsizeCompute figure size based on number of items.
compute_grid_figsizeCompute figure size for grid/subplot layouts.
extract_paramsExtract parameter estimates from a fitted model.
extract_residualsExtract residual diagnostics from a fitted model.
get_model_fittedExtract fitted values from model, supporting both APIs.
get_model_formulaExtract formula string from model, supporting both old and new API.
get_model_paramsExtract parameter estimates from model, supporting both APIs.
get_model_residualsExtract residuals from model, supporting both APIs.
get_model_responseExtract response variable name from model, supporting both APIs.
is_unified_modelCheck if model is the new unified model() class (or proxy).
plot_compareCompare coefficients across multiple fitted models.
plot_designPlot design matrix as an annotated heatmap.
plot_explorePlot marginal estimated effects.
plot_paramsPlot fixed effect estimates as a forest plot.
plot_predictPlot marginal predictions across a predictor’s range.
plot_profilePlot profile likelihood curves.
plot_ranefPlot random effects as a caterpillar plot.
plot_relationshipsPlot pairwise relationships between response and predictors.
plot_resamplesPlot distribution of resampled statistics.
plot_residPlot residual diagnostics as a faceted grid.
plot_vifPlot VIF diagnostics as correlation heatmap.

Modules:

NameDescription
compareMulti-model coefficient comparison forest plot.
coreCore utilities for bossanova visualization.
core_dataData extraction utilities for bossanova visualizations.
core_protocolsModel protocol and model-data extraction utilities.
core_sizingFigure sizing utilities for bossanova visualizations.
core_vizPlot helper utilities, label formatting, type inference, and FacetGrid support.
designDesign matrix structure visualization.
helpersShared helper utilities for bossanova visualization modules.
memMarginal effects visualization for bossanova models.
mem_forestForest-style plots for slopes and contrasts.
paramsParameter forest plot.
predictPrediction plots for bossanova models.
profileProfile likelihood visualization.
ranefRandom effects caterpillar plot.
relationshipsPairwise relationship scatter plot matrix.
resamplesBootstrap and permutation distribution visualization.
residResidual diagnostic plots.
vifVIF and multicollinearity visualization.

Attributes

BOSSANOVA_STYLE

BOSSANOVA_STYLE: dict[str, Any] = {'point_size': 80, 'point_marker': 'o', 'point_edgecolor': 'white', 'point_linewidth': 0.5, 'line_width': 1.5, 'capsize': 0, 'ci_alpha': 0.3, 'ref_line_color': '#888888', 'ref_line_style': '--', 'ref_line_width': 1.0, 'font_size': 10, 'title_size': 12, 'label_size': 10, 'palette': 'tab10', 'grid_alpha': 0.3, 'grid_style': '-', 'heatmap_cell_size': 0.7, 'heatmap_min_size': 3.5, 'heatmap_max_width': 10.0, 'heatmap_max_height': 12.0, 'heatmap_colorbar_pad': 0.12}

Functions

compute_figsize

compute_figsize(n_items: int, orientation: Literal['horizontal', 'vertical'] = 'horizontal', item_size: float = 0.4, min_size: float = 3.0, max_size: float = 12.0, base_width: float = 8.0, max_label_len: int = 0) -> tuple[float, float]

Compute figure size based on number of items.

Creates readable plots for 15-20 parameters by default. Clamps dimensions to prevent too-small or too-large figures.

Parameters:

NameTypeDescriptionDefault
n_itemsintNumber of items (parameters, groups, etc.) to display.required
orientationLiteral[‘horizontal’, ‘vertical’]Plot orientation. - “horizontal”: Items on y-axis (forest plot style). - “vertical”: Items on x-axis (bar chart style).‘horizontal’
item_sizefloatInches per item. Default 0.4 works well for forest plots.0.4
min_sizefloatMinimum dimension in inches.3.0
max_sizefloatMaximum dimension in inches.12.0
base_widthfloatBase width for horizontal orientation (height for vertical).8.0
max_label_lenintLongest label character count. For horizontal (forest) plots, increases base_width when labels exceed 12 chars.0

Returns:

TypeDescription
tuple[float, float]Tuple of (width, height) in inches.

Examples:

compute_figsize(15)  # 15 parameters
# (8.0, 6.0)
compute_figsize(30)  # Clamped to max
# (8.0, 12.0)

compute_grid_figsize

compute_grid_figsize(n_rows: int, n_cols: int, cell_width: float = 4.0, cell_height: float = 3.5) -> tuple[float, float]

Compute figure size for grid/subplot layouts.

Parameters:

NameTypeDescriptionDefault
n_rowsintNumber of subplot rows.required
n_colsintNumber of subplot columns.required
cell_widthfloatWidth per cell in inches.4.0
cell_heightfloatHeight per cell in inches.3.5

Returns:

TypeDescription
tuple[float, float]Tuple of (width, height) in inches.

Examples:

compute_grid_figsize(2, 2)  # 2x2 diagnostic grid
# (8.0, 7.0)

extract_params

extract_params(model: Any, which: Literal['fixef', 'ranef', 'all'] = 'fixef', include_intercept: bool = False, effect_sizes: bool = False, group: str | None = None, term: str | None = None) -> pl.DataFrame

Extract parameter estimates from a fitted model.

Returns a standardized DataFrame suitable for forest plot visualization. Supports both old BaseModel and new unified model() class.

Parameters:

NameTypeDescriptionDefault
modelAnyFitted bossanova model (lm, glm, lmer, glmer, or unified model()).required
whichLiteral[‘fixef’, ‘ranef’, ‘all’]Which parameters to extract. - “fixef”: Fixed effects only (default). - “ranef”: Random effects (lmer/glmer only). - “all”: Both fixed and random effects.‘fixef’
include_interceptboolInclude intercept term for fixed effects.False
effect_sizesboolReturn effect sizes (Cohen’s d) instead of raw estimates.False
groupstr | NoneFor ranef, which grouping factor (None = all).None
termstr | NoneFor ranef, which RE term (None = all).None

Returns:

TypeDescription
DataFrameDataFrame with columns: - term: Parameter name - estimate: Point estimate - se: Standard error - ci_lower: Lower confidence bound - ci_upper: Upper confidence bound - p_value: P-value (if available) - group_factor: Grouping factor name (for ranef) - re_term: Random effect term name (for ranef)

Examples:

Old API (BaseModel)::

model = lm("mpg ~ wt + hp", data=mtcars).fit()
df = extract_params(model)

New API (unified model())::

m = model("mpg ~ wt + hp", mtcars).fit()
df = extract_params(m)

extract_residuals

extract_residuals(model: Any, residual_type: str | None = None) -> dict[str, np.ndarray]

Extract residual diagnostics from a fitted model.

Supports both old BaseModel and new unified model() class.

Parameters:

NameTypeDescriptionDefault
modelAnyFitted bossanova model (lm, glm, lmer, glmer, or unified model()).required
residual_typestr | NoneType of residuals. If None, uses model default. - “response”: Raw residuals (y - fitted) - “pearson”: Pearson residuals - “deviance”: Deviance residuals (GLM)None

Returns:

TypeDescription
dict[str, ndarray]Dictionary with: - fitted: Fitted values - residuals: Residual values - std_resid: Standardized residuals - leverage: Hat/leverage values - cooksd: Cook’s distance

Examples:

Old API (BaseModel)::

model = lm("mpg ~ wt + hp", data=mtcars).fit()
diag = extract_residuals(model)

New API (unified model())::

m = model("mpg ~ wt + hp", mtcars).fit()
diag = extract_residuals(m)

get_model_fitted

get_model_fitted(model: Any) -> np.ndarray

Extract fitted values from model, supporting both APIs.

Parameters:

NameTypeDescriptionDefault
modelAnyA fitted bossanova model.required

Returns:

TypeDescription
ndarrayArray of fitted values.

get_model_formula

get_model_formula(model: Any) -> str

Extract formula string from model, supporting both old and new API.

Parameters:

NameTypeDescriptionDefault
modelAnyA bossanova model (BaseModel or unified model()).required

Returns:

TypeDescription
strFormula string.

get_model_params

get_model_params(model: Any) -> pl.DataFrame

Extract parameter estimates from model, supporting both APIs.

Parameters:

NameTypeDescriptionDefault
modelAnyA fitted bossanova model (or ModelResult proxy).required

Returns:

TypeDescription
DataFrameDataFrame with term, estimate, and optional inference columns.

get_model_residuals

get_model_residuals(model: Any) -> np.ndarray

Extract residuals from model, supporting both APIs.

Parameters:

NameTypeDescriptionDefault
modelAnyA fitted bossanova model.required

Returns:

TypeDescription
ndarrayArray of residual values.

get_model_response

get_model_response(model: Any) -> str

Extract response variable name from model, supporting both APIs.

Parameters:

NameTypeDescriptionDefault
modelAnyA bossanova model (BaseModel or unified model()).required

Returns:

TypeDescription
strResponse variable name.

is_unified_model

is_unified_model(model: Any) -> bool

Check if model is the new unified model() class (or proxy).

Parameters:

NameTypeDescriptionDefault
modelAnyA bossanova model or ModelResult proxy.required

Returns:

TypeDescription
boolTrue if model is the new unified model() class or a proxy wrapping one.

plot_compare

plot_compare(models: list['Any'], *, names: list[str] | None = None, terms: list[str] | None = None, include_intercept: bool = False, sort: Literal['none', 'magnitude', 'alpha'] = 'none', prettify: bool = False, height: float = 0.5, aspect: float = 2.0, col_wrap: int | None = None, palette: str | None = None) -> sns.FacetGrid

Compare coefficients across multiple fitted models.

Creates a forest plot showing coefficient estimates and confidence intervals for each model, with dodged points on a shared y-axis. Useful for:

Parameters:

NameTypeDescriptionDefault
modelslist[‘Any’]List of fitted bossanova models to compare.required
nameslist[str] | NoneLabels for each model. If None, uses “Model 1”, “Model 2”, etc.None
termslist[str] | NoneTerms to include. If None, uses all common terms across models. Terms not present in a model are shown as missing.None
include_interceptboolInclude intercept term (default False).False
sortLiteral[‘none’, ‘magnitude’, ‘alpha’]How to sort terms on y-axis. - “none”: Original order from first model (default). - “magnitude”: Sort by absolute value of first model’s estimates. - “alpha”: Alphabetical order.‘none’
prettifyboolConvert term names to human-readable labels (e.g., “wt_hp_ratio” → “Wt Hp Ratio”). Default False.False
heightfloatHeight per term in inches (default 0.5).0.5
aspectfloatAspect ratio (default 2.0).2.0
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the plot.

Examples:

::

from bossanova import model, viz, load_dataset
mtcars = load_dataset("mtcars")
m1 = model("mpg ~ wt + hp", mtcars).fit()
m2 = model("mpg ~ wt + hp + cyl", mtcars).fit()
m3 = model("mpg ~ wt * hp", mtcars).fit()

# Compare all three models
viz.plot_compare([m1, m2, m3],
                 names=["Base", "+cyl", "Interaction"])

# Compare specific terms
viz.plot_compare([m1, m2, m3], terms=["wt", "hp"])

See Also: plot_params: Fixed effects forest plot for a single model.

plot_design

plot_design(model: BaseModel, *, max_rows: int | None = 20, annotate_terms: bool = True, show_contrast_info: bool = True, prettify: bool = False, cmap: str | None = None, height: float = _DESIGN_DEFAULT_HEIGHT, aspect: float = _DESIGN_DEFAULT_ASPECT) -> sns.FacetGrid

Plot design matrix as an annotated heatmap.

Visualizes the structure of the model’s design matrix with:

Works on unfitted models since the design matrix is built at initialization.

Parameters:

NameTypeDescriptionDefault
modelmodelA bossanova model. Can be fitted or unfitted.required
max_rowsint | NoneMaximum number of rows to display. If None, shows all rows. Large datasets are subsampled evenly for readability.20
annotate_termsboolShow term grouping brackets above the heatmap.True
show_contrast_infoboolShow reference level annotations for categorical terms.True
prettifyboolConvert term names to human-readable labels (e.g., “wt_hp_ratio” -> “Wt Hp Ratio”). Default False.False
cmapstr | NoneMatplotlib colormap name. If None (default), uses "gray" (grayscale). Pass "viridis" for a perceptually-uniform alternative, or any valid matplotlib colormap name.None
heightfloatFigure height in inches. When both height and aspect are at their defaults, sizing adapts to the design matrix dimensions._DESIGN_DEFAULT_HEIGHT
aspectfloatWidth-to-height ratio. When both height and aspect are at their defaults, sizing adapts to the design matrix dimensions._DESIGN_DEFAULT_ASPECT

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the plot.

Examples:

from bossanova import model, load_dataset
cars = load_dataset("mtcars")
m = model("mpg ~ factor(cyl) + wt + wt:cyl", cars)
# Works before fitting
m.plot_design()
# Also works after fitting
m.fit().plot_design()

plot_explore

plot_explore(model: 'Any', specs: str, *, hue: str | None = None, col: str | None = None, row: str | None = None, effect_scale: Literal['link', 'response'] = 'response', conf_int: float = 0.95, prettify: bool = False, height: float = 4.0, aspect: float = 1.2, palette: str | None = None, col_wrap: int | None = None, show_pvalue: bool = False, ref_line: float | None = None, precomputed_emm: pl.DataFrame | None = None) -> sns.FacetGrid

Plot marginal estimated effects.

Dispatches to the appropriate plot type based on the result of model.explore(specs):

When precomputed_emm is provided, the function skips the model.explore().infer() call and uses the supplied DataFrame directly, inferring the plot type from column structure.

Parameters:

NameTypeDescriptionDefault
model‘Any’A fitted bossanova model.required
specsstrExplore formula, e.g. "treatment", "x", "pairwise(treatment)", "x ~ z".required
huestr | NoneColor encoding variable for grouping (dodged on same plot). Auto-detected from conditioning columns when None.None
colstr | NoneColumn faceting variable.None
rowstr | NoneRow faceting variable.None
effect_scaleLiteral[‘link’, ‘response’]"link" or "response" (default). Matches model.explore(effect_scale=...).‘response’
conf_intfloatConfidence level (default 0.95).0.95
prettifyboolConvert axis labels to human-readable format.False
heightfloatHeight of each facet in inches.4.0
aspectfloatAspect ratio of each facet.1.2
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None
col_wrapint | NoneNumber of columns before wrapping facets to a new row. Only used when col is set.None
show_pvalueboolAdd significance stars (for contrasts/slopes).False
ref_linefloat | NoneReference line position. Auto-set to 0 for contrasts/slopes if not specified.None
precomputed_emmDataFrame | NonePre-computed effects DataFrame (from model.effects). Skips explore().infer().None

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the plot.

Examples:

::

from bossanova import model, viz, load_dataset
mtcars = load_dataset("mtcars")
m = model("mpg ~ factor(cyl) + wt + hp", mtcars).fit()

# Categorical EMMs
m.explore("cyl").infer()
m.plot_explore("cyl")

# Continuous slope
m.explore("wt").infer()
m.plot_explore("wt")

# Pairwise contrasts (forest plot)
m.explore("pairwise(cyl)").infer()
m.plot_explore("pairwise(cyl)")

# Crossed: slopes at multiple levels
m.explore("wt ~ cyl").infer()
m.plot_explore("wt ~ cyl")

See Also: plot_predict: Marginal predictions across predictor range. plot_params: Fixed effects forest plot.

plot_params

plot_params(model: 'Any', *, include_intercept: bool = False, effect_sizes: bool = False, sort: bool | Literal['ascending', 'descending'] = False, show_values: bool = False, show_pvalue: bool = False, ref_line: float = 0.0, prettify: bool = False, height: float = 0.4, aspect: float = 2.5, col_wrap: int | None = None, palette: str | None = None) -> sns.FacetGrid

Plot fixed effect estimates as a forest plot.

Creates a horizontal dot-whisker plot showing parameter estimates with confidence intervals. Uses Seaborn FacetGrid for consistent styling.

Parameters:

NameTypeDescriptionDefault
model‘Any’A fitted bossanova model.required
include_interceptboolInclude intercept term.False
effect_sizesboolPlot Cohen’s d instead of raw estimates. Available measures depend on family (see :func:extract_fixef).False
sortbool | Literal[‘ascending’, ‘descending’]Sort parameters by estimate magnitude. - False: Keep original order. - True or “descending”: Largest to smallest. - “ascending”: Smallest to largest.False
show_valuesboolAnnotate points with estimate values.False
show_pvalueboolAdd significance stars based on p-values.False
ref_linefloatPosition of reference line (default 0.0).0.0
prettifyboolConvert term names to human-readable labels (e.g., “wt_hp_ratio” → “Wt Hp Ratio”). Default False.False
heightfloatHeight per parameter in inches (default 0.4).0.4
aspectfloatAspect ratio (default 2.5).2.5
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the plot.

Examples:

::

from bossanova import model, viz, load_dataset
mtcars = load_dataset("mtcars")
m = model("mpg ~ wt + hp + cyl", mtcars).fit()
viz.plot_params(m)

# After inference for p-values
m.infer()
viz.plot_params(m, show_pvalue=True)

See Also: plot_ranef: Random effects caterpillar plot for mixed models.

plot_predict

plot_predict(model: 'Any', term: str, *, hue: str | None = None, col: str | None = None, row: str | None = None, at: dict | None = None, units: Literal['link', 'data'] = 'data', n_points: int = 50, interval: Literal['confidence', 'prediction'] | None = 'confidence', conf_int: float = 0.95, show_data: bool = False, show_rug: bool = False, show_blups: bool = False, groups: list[str] | None = None, prettify: bool = False, height: float = 4.0, aspect: float = 1.2, col_wrap: int | None = None, palette: str | None = None) -> sns.FacetGrid

Plot marginal predictions across a predictor’s range.

Creates a visualization of model predictions varying one predictor while holding others at reference values (means for continuous, reference level for categorical).

Accepts either a bare column name or an explore-style formula::

plot_predict(m, "age")              # bare column
plot_predict(m, "age ~ sex")        # hue by sex
plot_predict(m, "age ~ sex@Female") # pin sex=Female
plot_predict(m, "age@range(5)")     # 5-point grid
plot_predict(m, "age@[25,50,75]")   # explicit grid values

Contrast formulas (pairwise(), Drug[A - B]) are not supported — use :func:plot_explore for those.

Parameters:

NameTypeDescriptionDefault
model‘Any’A fitted bossanova model.required
termstrThe predictor variable to vary, or an explore-style formula string. Can be continuous or categorical.required
huestr | NoneColumn name for color encoding (creates separate lines per level).None
colstr | NoneColumn name for faceting into columns.None
rowstr | NoneColumn name for faceting into rows.None
atdict | NoneDictionary of predictor values to hold fixed. E.g., at={"age": 30} holds age at 30.None
unitsLiteral[‘link’, ‘data’]Units for predictions. - “data”: Back-transformed predictions (default). - “link”: Predictions on link scale (GLM/GLMER).‘data’
n_pointsintNumber of points for continuous predictors.50
intervalLiteral[‘confidence’, ‘prediction’] | NoneType of interval to show. - “confidence”: Confidence interval for mean prediction. - “prediction”: Prediction interval (wider, includes residual var). - None: No interval.‘confidence’
conf_intfloatConfidence level (default 0.95).0.95
show_databoolOverlay actual data points on the plot.False
show_rugboolAdd rug plot showing observed data distribution.False
show_blupsboolFor mixed models, show group-specific BLUP lines in addition to the population-average fixed effects line.False
groupslist[str] | NoneFor mixed models with show_blups=True, which group levels to show. If None, shows all groups (can be crowded for many groups).None
prettifyboolConvert axis labels to human-readable format (e.g., “wt_hp_ratio” → “Wt Hp Ratio”). Default False.False
heightfloatHeight of each facet in inches.4.0
aspectfloatAspect ratio of each facet.1.2
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the plot.

Examples:

::

from bossanova import model, viz, load_dataset
mtcars = load_dataset("mtcars")

# Simple predictions
m = model("mpg ~ wt + hp", mtcars).fit()
viz.plot_predict(m, "wt")

# Interaction visualization with hue
m = model("mpg ~ wt * cyl", mtcars).fit()
viz.plot_predict(m, "wt", hue="cyl")

# Mixed model (inferred from formula)
sleep = load_dataset("sleepstudy")
m = model("Reaction ~ Days + (Days|Subject)", sleep).fit()
viz.plot_predict(m, "Days", show_blups=True)

See Also: plot_explore: Marginal effects/means visualization.

plot_profile

plot_profile(profile: ProfileState, param: str | None = None, *, height: float = 4.0, aspect: float = 1.2, prettify: bool = False, palette: str | None = None) -> sns.FacetGrid

Plot profile likelihood curves.

Parameters:

NameTypeDescriptionDefault
profileProfileStateProfileState from profile_likelihood().required
paramstr | NoneSpecific parameter to plot, or None for all parameters.None
heightfloatHeight of each panel in inches.4.0
aspectfloatWidth-to-height ratio of each panel.1.2
prettifyboolApply human-readable formatting to parameter names in axis labels and titles.False
palettestr | NoneColor palette name for the profile curves. Each parameter gets a distinct color from the cycle. Default uses BOSSANOVA_STYLE palette.None

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing zeta vs parameter plot(s).

plot_ranef

plot_ranef(model: 'Any', *, group: str | None = None, term: str | None = None, col: str | None = None, show: int | list[str] | Literal['all', 'top', 'bottom', 'quartile'] = 'all', sort: bool | Literal['ascending', 'descending'] = False, show_values: bool = False, ref_line: float = 0.0, prettify: bool = False, height: float = 4.0, aspect: float = 1.0, col_wrap: int | None = None, palette: str | None = None) -> sns.FacetGrid

Plot random effects as a caterpillar plot.

Creates a horizontal dot-whisker plot showing random effect estimates (BLUPs) for each group level. Supports faceting by random effect term.

Parameters:

NameTypeDescriptionDefault
model‘Any’A fitted mixed-effects model.required
groupstr | NoneWhich grouping factor to show. None shows first grouping factor.None
termstr | NoneWhich random effect term to show (e.g., “Intercept”, “Days”). None shows all terms with faceting.None
colstr | NoneColumn faceting variable. If None and multiple RE terms exist, facets by term.None
showint | list[str] | Literal[‘all’, ‘top’, ‘bottom’, ‘quartile’]Which group levels to display. - “all”: Show all levels (default). - int: First N levels in model order. - list[str]: Specific level names. - “top”: Top quartile by magnitude. - “bottom”: Bottom quartile by magnitude. - “quartile”: Top + bottom quartiles (most extreme).‘all’
sortbool | Literal[‘ascending’, ‘descending’]Sort levels by estimate magnitude. - False: Keep original order. - True or “descending”: Largest to smallest. - “ascending”: Smallest to largest.False
show_valuesboolAnnotate points with estimate values.False
ref_linefloatPosition of reference line (default 0.0).0.0
prettifyboolConvert term names to human-readable labels (e.g., “slope_days” → “Slope Days”). Default False.False
heightfloatHeight of each facet in inches.4.0
aspectfloatAspect ratio of each facet.1.0
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the plot.

Examples:

from bossanova import model, viz, load_dataset
sleep = load_dataset("sleepstudy")
m = model("Reaction ~ Days + (Days|Subject)", sleep).fit()

# All RE terms, faceted
viz.plot_ranef(m)

# Just intercepts
viz.plot_ranef(m, term="Intercept")

# Extreme levels only
viz.plot_ranef(m, show="quartile", sort=True)

See Also: plot_params: Fixed effects forest plot. plot_predict: Marginal predictions with BLUPs overlay.

plot_relationships

plot_relationships(model: BaseModel, *, show_vif: bool = True, prettify: bool = False, height: float = 1.5, aspect: float = 1.0, palette: str | None = None) -> sns.PairGrid

Plot pairwise relationships between response and predictors.

Creates a scatter plot matrix showing:

Works on unfitted models since the design matrix is built at initialization.

Parameters:

NameTypeDescriptionDefault
modelmodelA bossanova model. Can be fitted or unfitted.required
show_vifboolWhether to display VIF statistics above the plot.True
prettifyboolConvert variable names to human-readable labels (e.g., “wt_hp_ratio” → “Wt Hp Ratio”). Default False.False
heightfloatHeight of each facet in inches.1.5
aspectfloatAspect ratio of each facet.1.0
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None

Returns:

TypeDescription
PairGridSeaborn PairGrid containing the plot.

Note: This function returns a PairGrid. To access the underlying Figure, use g.figure. Migration from previous API: fig = model.plot_relationships()g = model.plot_relationships(); fig = g.figure

Examples:

from bossanova import model, load_dataset
cars = load_dataset("mtcars")
m = model("mpg ~ wt + hp + disp", cars)
m.plot_relationships()  # Shows y and all predictors

plot_resamples

plot_resamples(model: 'Any', *, which: Literal['params', 'mee', 'effects'] = 'params', include_intercept: bool = False, terms: list[str] | None = None, prettify: bool = False, height: float = 3.0, aspect: float = 1.2, col_wrap: int = 4, palette: str | None = None, show_ci: bool = True, show_pvalue: bool = True, fill: bool = True) -> sns.FacetGrid

Plot distribution of resampled statistics.

Visualizes bootstrap coefficient distributions or permutation null distributions. Requires save_resamples=True (default for n<=5000) during infer().

Parameters:

NameTypeDescriptionDefault
model‘Any’A fitted bossanova model with resampling results.required
whichLiteral[‘params’, ‘mee’, ‘effects’]What to plot: - “params”: Model coefficients (from boot_samples_ or perm_samples_) - “mee”: Marginal effects (from boot_mee_samples_)‘params’
include_interceptboolInclude intercept in coefficient plots.False
termslist[str] | NoneSubset of terms to plot. If None, plot all.None
prettifyboolConvert term names to human-readable labels (e.g., “wt_hp_ratio” → “Wt Hp Ratio”). Default False.False
heightfloatHeight of each facet in inches.3.0
aspectfloatAspect ratio of each facet (width = height * aspect).1.2
col_wrapintNumber of columns before wrapping.4
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None
show_ciboolFor bootstrap, shade confidence interval region.True
show_pvalueboolFor permutation, annotate p-value.True
fillboolFill under density curve.True

Returns:

TypeDescription
FacetGridSeaborn FacetGrid with one facet per parameter.

Examples:

from bossanova import model, viz, load_dataset
mtcars = load_dataset("mtcars")
m = model("mpg ~ wt + hp", mtcars).fit()

# Bootstrap distributions (auto-saved for n<=5000)
m.infer(how="boot", n=999)
viz.plot_resamples(m)

# Permutation null distributions
m.infer(how="perm", n=999)
viz.plot_resamples(m)

# MEE bootstrap
m.mee("wt").infer(how="boot", n=999)
viz.plot_resamples(m, which="mee")

See Also: plot_params: Forest plot of parameter estimates.

plot_resid

plot_resid(model: 'Any', *, which: list[int] | Literal['all'] = 'all', residual_type: Literal['response', 'pearson', 'deviance'] | None = None, lowess: bool = True, label_outliers: int | float = 3, height: float = 3.5, aspect: float = 1.0, col_wrap: int = 2, palette: str | None = None, prettify: bool = False) -> sns.FacetGrid

Plot residual diagnostics as a faceted grid.

Creates a diagnostic plot grid similar to R’s plot(lm_model):

  1. Residuals vs Fitted: Check linearity and heteroscedasticity. Points should be randomly scattered around 0.

  2. Q-Q Plot: Check normality of residuals. Points should follow the diagonal line.

  3. Scale-Location: Check homoscedasticity (constant variance). Points should be randomly scattered with constant spread.

  4. Residuals vs Leverage: Identify influential observations. Points outside Cook’s D contours may be influential.

Parameters:

NameTypeDescriptionDefault
model‘Any’A fitted bossanova model.required
whichlist[int] | Literal[‘all’]Which panels to show. - “all”: All 4 panels (default). - List of integers [1,2,3,4]: Specific panels.‘all’
residual_typeLiteral[‘response’, ‘pearson’, ‘deviance’] | NoneType of residuals to use. - None: Auto-select based on model type. - “response”: Raw residuals (y - fitted). - “pearson”: Pearson residuals. - “deviance”: Deviance residuals (GLM/GLMER).None
lowessboolAdd lowess smoothing line to applicable panels.True
label_outliersint | floatLabel points with standardized residuals exceeding this threshold. Set to 0 to disable.3
heightfloatHeight of each facet in inches.3.5
aspectfloatAspect ratio of each facet.1.0
col_wrapintNumber of columns before wrapping.2
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None
prettifyboolReserved for API consistency. Currently a no-op since panel labels are fixed diagnostic names.False

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the diagnostic panels.

Examples:

::

from bossanova import model, viz, load_dataset
mtcars = load_dataset("mtcars")
m = model("mpg ~ wt + hp", mtcars).fit()
viz.plot_resid(m)

# Show only Q-Q plot
viz.plot_resid(m, which=[2])

# GLM with deviance residuals
m = model("am ~ wt + hp", mtcars, family="binomial").fit()
viz.plot_resid(m, residual_type="deviance")

Note: This function returns a FacetGrid. To access the underlying Figure, use g.figure. Migration from previous API: fig = model.plot_resid()g = model.plot_resid(); fig = g.figure

plot_vif

plot_vif(model: BaseModel, *, cmap: str | None = None, height: float = 4.0, aspect: float = 1.0, prettify: bool = False) -> sns.FacetGrid

Plot VIF diagnostics as correlation heatmap.

Visualizes multicollinearity in the design matrix:

VIF interpretation:

Works on unfitted models since the design matrix is built at initialization.

For pairwise scatter plots including the response variable, use plot_relationships() instead.

Parameters:

NameTypeDescriptionDefault
modelmodelA bossanova model. Can be fitted or unfitted.required
cmapstr | NoneMatplotlib colormap name. Default “coolwarm”.None
heightfloatFigure height in inches. Default 4.0.4.0
aspectfloatWidth-to-height ratio. Default 1.0 (square heatmap).1.0
prettifyboolConvert column names to human-readable labels (e.g., “wt_hp_ratio” -> “Wt Hp Ratio”). Default False.False

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the plot.

Examples:

from bossanova import model, load_dataset
cars = load_dataset("mtcars")
m = model("mpg ~ wt + hp + disp", cars)
m.plot_vif()  # Correlation heatmap with VIF stats
m.plot_vif(prettify=True)  # With prettified labels

Modules

compare

Multi-model coefficient comparison forest plot.

Functions:

NameDescription
plot_compareCompare coefficients across multiple fitted models.

Attributes

Classes

Functions

plot_compare
plot_compare(models: list['Any'], *, names: list[str] | None = None, terms: list[str] | None = None, include_intercept: bool = False, sort: Literal['none', 'magnitude', 'alpha'] = 'none', prettify: bool = False, height: float = 0.5, aspect: float = 2.0, col_wrap: int | None = None, palette: str | None = None) -> sns.FacetGrid

Compare coefficients across multiple fitted models.

Creates a forest plot showing coefficient estimates and confidence intervals for each model, with dodged points on a shared y-axis. Useful for:

Parameters:

NameTypeDescriptionDefault
modelslist[‘Any’]List of fitted bossanova models to compare.required
nameslist[str] | NoneLabels for each model. If None, uses “Model 1”, “Model 2”, etc.None
termslist[str] | NoneTerms to include. If None, uses all common terms across models. Terms not present in a model are shown as missing.None
include_interceptboolInclude intercept term (default False).False
sortLiteral[‘none’, ‘magnitude’, ‘alpha’]How to sort terms on y-axis. - “none”: Original order from first model (default). - “magnitude”: Sort by absolute value of first model’s estimates. - “alpha”: Alphabetical order.‘none’
prettifyboolConvert term names to human-readable labels (e.g., “wt_hp_ratio” → “Wt Hp Ratio”). Default False.False
heightfloatHeight per term in inches (default 0.5).0.5
aspectfloatAspect ratio (default 2.0).2.0
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the plot.

Examples:

::

from bossanova import model, viz, load_dataset
mtcars = load_dataset("mtcars")
m1 = model("mpg ~ wt + hp", mtcars).fit()
m2 = model("mpg ~ wt + hp + cyl", mtcars).fit()
m3 = model("mpg ~ wt * hp", mtcars).fit()

# Compare all three models
viz.plot_compare([m1, m2, m3],
                 names=["Base", "+cyl", "Interaction"])

# Compare specific terms
viz.plot_compare([m1, m2, m3], terms=["wt", "hp"])

See Also: plot_params: Fixed effects forest plot for a single model.

core

Core utilities for bossanova visualization.

This module re-exports shared infrastructure from split sub-modules:

All public names remain importable from core.

Classes:

NameDescription
ModelProtocolProtocol for model objects that can be visualized.

Functions:

NameDescription
add_ref_lineAdd reference line to axes.
build_facetgrid_kwargsBuild standardized kwargs dict for FacetGrid/relplot/catplot.
coerce_to_column_dtypeCoerce user-provided values to match a data column’s dtype.
compute_figsizeCompute figure size based on number of items.
compute_grid_figsizeCompute figure size for grid/subplot layouts.
compute_heatmap_figsizeCompute figure size for heatmaps (VIF, design, correlation).
create_multi_panelCreate a multi-panel FacetGrid for matplotlib-native plots.
create_single_panelCreate a single-panel FacetGrid for matplotlib-native plots.
extract_fixefExtract fixed effects from model.
extract_paramsExtract parameter estimates from a fitted model.
extract_ranefExtract random effects from mixed model.
extract_residualsExtract residual diagnostics from a fitted model.
finalize_facetgridApply standard styling and layout to a FacetGrid.
format_display_labelTruncate label for tick display, preserving transform structure.
format_display_labelsStrip transforms + prettify + truncate + deduplicate labels for display.
format_pvalue_annotationFormat p-value for plot annotation.
get_model_fittedExtract fitted values from model, supporting both APIs.
get_model_formulaExtract formula string from model, supporting both old and new API.
get_model_paramsExtract parameter estimates from model, supporting both APIs.
get_model_residualsExtract residuals from model, supporting both APIs.
get_model_responseExtract response variable name from model, supporting both APIs.
is_categoricalCheck if a term is categorical.
is_unified_modelCheck if model is the new unified model() class (or proxy).
prettify_labelConvert column/term name to human-readable label.
prettify_labelsPrettify a list of labels.
setup_axSet up matplotlib axes, creating figure if needed.
strip_transform_wrapperStrip transform wrapper(s) from a term name, keeping the inner variable.

Attributes:

NameTypeDescription
BOSSANOVA_STYLEdict[str, Any]

Attributes

BOSSANOVA_STYLE
BOSSANOVA_STYLE: dict[str, Any] = {'point_size': 80, 'point_marker': 'o', 'point_edgecolor': 'white', 'point_linewidth': 0.5, 'line_width': 1.5, 'capsize': 0, 'ci_alpha': 0.3, 'ref_line_color': '#888888', 'ref_line_style': '--', 'ref_line_width': 1.0, 'font_size': 10, 'title_size': 12, 'label_size': 10, 'palette': 'tab10', 'grid_alpha': 0.3, 'grid_style': '-', 'heatmap_cell_size': 0.7, 'heatmap_min_size': 3.5, 'heatmap_max_width': 10.0, 'heatmap_max_height': 12.0, 'heatmap_colorbar_pad': 0.12}

Classes

ModelProtocol

Bases: Protocol

Protocol for model objects that can be visualized.

This protocol defines the minimal interface required for visualization functions, supporting both old BaseModel and new unified model() class.

Attributes:

NameTypeDescription
dataDataFrameThe model’s data.
Attributes
data
data: pl.DataFrame

The model’s data.

Functions

add_ref_line
add_ref_line(ax: 'Axes', value: float = 0.0, orientation: Literal['horizontal', 'vertical'] = 'vertical') -> None

Add reference line to axes.

Parameters:

NameTypeDescriptionDefault
ax‘Axes’Matplotlib axes.required
valuefloatPosition of reference line.0.0
orientationLiteral[‘horizontal’, ‘vertical’]Line orientation.‘vertical’
build_facetgrid_kwargs
build_facetgrid_kwargs(data: pl.DataFrame, height: float, aspect: float, col_wrap: int | None = None, hue: str | None = None, col: str | None = None, row: str | None = None, palette: str | None = None, sharex: bool = True, sharey: bool = True) -> dict[str, Any]

Build standardized kwargs dict for FacetGrid/relplot/catplot.

Creates a kwargs dictionary with consistent parameter handling for seaborn grid-based plotting functions.

Parameters:

NameTypeDescriptionDefault
dataDataFramePolars DataFrame to plot (passed directly to seaborn).required
heightfloatHeight of each facet in inches.required
aspectfloatAspect ratio of each facet (width = height * aspect).required
col_wrapint | NoneWrap column facets after this many columns. Ignored if row is set.None
huestr | NoneVariable name for color grouping.None
colstr | NoneVariable name for column faceting.None
rowstr | NoneVariable name for row faceting.None
palettestr | NoneColor palette name (uses BOSSANOVA_STYLE default if hue set but no palette).None
sharexboolShare x-axis across facets.True
shareyboolShare y-axis across facets.True

Returns:

TypeDescription
dict[str, Any]Dictionary of kwargs ready for sns.FacetGrid, relplot, or catplot.

Examples:

kwargs = build_facetgrid_kwargs(df, height=4.0, aspect=1.2, col="group")
g = sns.FacetGrid(**kwargs)
coerce_to_column_dtype
coerce_to_column_dtype(values: list[Any], data: pl.DataFrame, column: str) -> list[Any]

Coerce user-provided values to match a data column’s dtype.

Handles type mismatches between user input (often strings) and actual column types (integers, floats, categoricals). This enables user-friendly APIs where users can write groups=["308", "309"] even when the column contains integers.

Parameters:

NameTypeDescriptionDefault
valueslist[Any]User-provided values to coerce.required
dataDataFrameDataFrame containing the target column.required
columnstrColumn name to match dtype against.required

Returns:

TypeDescription
list[Any]Values coerced to match the column dtype. Returns original values
list[Any]if coercion fails or dtype is not recognized.

Examples:

# Integer column with string input
df = pl.DataFrame({"id": [1, 2, 3]})
coerce_to_column_dtype(["1", "2"], df, "id")
# [1, 2]

# Float column
df = pl.DataFrame({"value": [1.0, 2.0]})
coerce_to_column_dtype(["1.5", 2], df, "value")
# [1.5, 2.0]

# String column (no change needed)
df = pl.DataFrame({"name": ["a", "b"]})
coerce_to_column_dtype([1, 2], df, "name")
# ["1", "2"]
compute_figsize
compute_figsize(n_items: int, orientation: Literal['horizontal', 'vertical'] = 'horizontal', item_size: float = 0.4, min_size: float = 3.0, max_size: float = 12.0, base_width: float = 8.0, max_label_len: int = 0) -> tuple[float, float]

Compute figure size based on number of items.

Creates readable plots for 15-20 parameters by default. Clamps dimensions to prevent too-small or too-large figures.

Parameters:

NameTypeDescriptionDefault
n_itemsintNumber of items (parameters, groups, etc.) to display.required
orientationLiteral[‘horizontal’, ‘vertical’]Plot orientation. - “horizontal”: Items on y-axis (forest plot style). - “vertical”: Items on x-axis (bar chart style).‘horizontal’
item_sizefloatInches per item. Default 0.4 works well for forest plots.0.4
min_sizefloatMinimum dimension in inches.3.0
max_sizefloatMaximum dimension in inches.12.0
base_widthfloatBase width for horizontal orientation (height for vertical).8.0
max_label_lenintLongest label character count. For horizontal (forest) plots, increases base_width when labels exceed 12 chars.0

Returns:

TypeDescription
tuple[float, float]Tuple of (width, height) in inches.

Examples:

compute_figsize(15)  # 15 parameters
# (8.0, 6.0)
compute_figsize(30)  # Clamped to max
# (8.0, 12.0)
compute_grid_figsize
compute_grid_figsize(n_rows: int, n_cols: int, cell_width: float = 4.0, cell_height: float = 3.5) -> tuple[float, float]

Compute figure size for grid/subplot layouts.

Parameters:

NameTypeDescriptionDefault
n_rowsintNumber of subplot rows.required
n_colsintNumber of subplot columns.required
cell_widthfloatWidth per cell in inches.4.0
cell_heightfloatHeight per cell in inches.3.5

Returns:

TypeDescription
tuple[float, float]Tuple of (width, height) in inches.

Examples:

compute_grid_figsize(2, 2)  # 2x2 diagnostic grid
# (8.0, 7.0)
compute_heatmap_figsize
compute_heatmap_figsize(n_rows: int, n_cols: int, *, cell_size: float | None = None, include_colorbar: bool = True, annotation_lines: int = 0, annotation_height: float = 0.18, max_label_len: int = 0) -> tuple[float, float]

Compute figure size for heatmaps (VIF, design, correlation).

Uses rectangular scaling (not square) to prevent oversized plots when there are few items but annotation text above.

Parameters:

NameTypeDescriptionDefault
n_rowsintNumber of heatmap rows.required
n_colsintNumber of heatmap columns.required
cell_sizefloat | NoneSize per cell in inches (uses style default if None).None
include_colorbarboolReserve space for colorbar.True
annotation_linesintNumber of text lines above the heatmap.0
annotation_heightfloatHeight per annotation line in inches.0.18
max_label_lenintLongest tick-label character count. Reserves extra height for rotated x-tick labels when labels are long.0

Returns:

TypeDescription
tuple[float, float]Tuple of (width, height) in inches.

Examples:

compute_heatmap_figsize(3, 3)  # 3x3 correlation matrix
# (2.35, 3.2)
compute_heatmap_figsize(3, 3, annotation_lines=3)  # With VIF text
# (2.35, 3.74)
compute_heatmap_figsize(10, 10)  # Larger matrix
# (7.84, 8.1)
create_multi_panel
create_multi_panel(n_panels: int, *, col_wrap: int = 3, height: float = 4.0, aspect: float = 1.0) -> tuple[Any, list[Any]]

Create a multi-panel FacetGrid for matplotlib-native plots.

Parameters:

NameTypeDescriptionDefault
n_panelsintNumber of panels to create.required
col_wrapintNumber of columns before wrapping.3
heightfloatHeight of each panel in inches.4.0
aspectfloatAspect ratio of each panel.1.0

Returns:

TypeDescription
AnyTuple of (FacetGrid, list[Axes]) where each Axes is ready for
list[Any]direct matplotlib drawing.
create_single_panel
create_single_panel(figsize: tuple[float, float]) -> tuple[Any, Any]

Create a single-panel FacetGrid for matplotlib-native plots.

Wraps a plain matplotlib axes in a FacetGrid so that all plot functions return a consistent type.

Parameters:

NameTypeDescriptionDefault
figsizetuple[float, float]Desired (width, height) in inches.required

Returns:

TypeDescription
AnyTuple of (FacetGrid, Axes) where the FacetGrid wraps a single
Anypanel and the Axes is ready for direct matplotlib drawing.
extract_fixef
extract_fixef(model: Any, include_intercept: bool = False, effect_sizes: bool = False) -> pl.DataFrame

Extract fixed effects from model.

Parameters:

NameTypeDescriptionDefault
modelAnyA fitted bossanova model.required
include_interceptboolWhether to include the intercept term.False
effect_sizesboolWhether to return Cohen’s d instead of raw estimates. Available effect size measures depend on model family:
- Gaussian (LM/LMER): Cohen’s d, semi-partial r, eta-squared. - Binomial (GLM/GLMER): odds ratio, semi-partial r, eta-squared. Cohen’s d is unavailable (no residual SD). - Other GLM families: semi-partial r, eta-squared. Cohen’s d is unavailable (no residual SD).
Unavailable measures are returned as None columns.
False

Returns:

TypeDescription
DataFrameDataFrame with standard columns: term, estimate, se, ci_lower,
DataFrameci_upper, p_value.
extract_params
extract_params(model: Any, which: Literal['fixef', 'ranef', 'all'] = 'fixef', include_intercept: bool = False, effect_sizes: bool = False, group: str | None = None, term: str | None = None) -> pl.DataFrame

Extract parameter estimates from a fitted model.

Returns a standardized DataFrame suitable for forest plot visualization. Supports both old BaseModel and new unified model() class.

Parameters:

NameTypeDescriptionDefault
modelAnyFitted bossanova model (lm, glm, lmer, glmer, or unified model()).required
whichLiteral[‘fixef’, ‘ranef’, ‘all’]Which parameters to extract. - “fixef”: Fixed effects only (default). - “ranef”: Random effects (lmer/glmer only). - “all”: Both fixed and random effects.‘fixef’
include_interceptboolInclude intercept term for fixed effects.False
effect_sizesboolReturn effect sizes (Cohen’s d) instead of raw estimates.False
groupstr | NoneFor ranef, which grouping factor (None = all).None
termstr | NoneFor ranef, which RE term (None = all).None

Returns:

TypeDescription
DataFrameDataFrame with columns: - term: Parameter name - estimate: Point estimate - se: Standard error - ci_lower: Lower confidence bound - ci_upper: Upper confidence bound - p_value: P-value (if available) - group_factor: Grouping factor name (for ranef) - re_term: Random effect term name (for ranef)

Examples:

Old API (BaseModel)::

model = lm("mpg ~ wt + hp", data=mtcars).fit()
df = extract_params(model)

New API (unified model())::

m = model("mpg ~ wt + hp", mtcars).fit()
df = extract_params(m)
extract_ranef
extract_ranef(model: Any, group: str | None = None, term: str | None = None) -> pl.DataFrame

Extract random effects from mixed model.

Supports both old BaseModel (.varying) and new unified model() (.is_mixed).

Parameters:

NameTypeDescriptionDefault
modelAnyA fitted mixed-effects bossanova model.required
groupstr | NoneFilter to a specific grouping factor (None = all).None
termstr | NoneFilter to a specific random effect term (None = all).None

Returns:

TypeDescription
DataFrameDataFrame in long format with columns: term, estimate, se,
DataFrameci_lower, ci_upper, p_value, group_factor, re_term.
extract_residuals
extract_residuals(model: Any, residual_type: str | None = None) -> dict[str, np.ndarray]

Extract residual diagnostics from a fitted model.

Supports both old BaseModel and new unified model() class.

Parameters:

NameTypeDescriptionDefault
modelAnyFitted bossanova model (lm, glm, lmer, glmer, or unified model()).required
residual_typestr | NoneType of residuals. If None, uses model default. - “response”: Raw residuals (y - fitted) - “pearson”: Pearson residuals - “deviance”: Deviance residuals (GLM)None

Returns:

TypeDescription
dict[str, ndarray]Dictionary with: - fitted: Fitted values - residuals: Residual values - std_resid: Standardized residuals - leverage: Hat/leverage values - cooksd: Cook’s distance

Examples:

Old API (BaseModel)::

model = lm("mpg ~ wt + hp", data=mtcars).fit()
diag = extract_residuals(model)

New API (unified model())::

m = model("mpg ~ wt + hp", mtcars).fit()
diag = extract_residuals(m)
finalize_facetgrid
finalize_facetgrid(g: Any, title: str | None = None, xlabel: str | None = None, ylabel: str | None = None) -> Any

Apply standard styling and layout to a FacetGrid.

Applies consistent bossanova styling: despine, tight_layout, and title.

Parameters:

NameTypeDescriptionDefault
gAnySeaborn FacetGrid or PairGrid object.required
titlestr | NoneOptional title to add above the plot.None
xlabelstr | NoneOptional x-axis label.None
ylabelstr | NoneOptional y-axis label.None

Returns:

TypeDescription
AnyThe same FacetGrid/PairGrid object (for chaining).

Examples:

g = sns.FacetGrid(df, col="group")
g.map_dataframe(my_plot_func)
finalize_facetgrid(g, title="My Plot", xlabel="X", ylabel="Y")
format_display_label
format_display_label(label: str, max_chars: int = 25) -> str

Truncate label for tick display, preserving transform structure.

Handles long labels from transformed variables (e.g., center(reaction_time_ms)) by truncating while keeping the transform wrapper visible.

Parameters:

NameTypeDescriptionDefault
labelstrLabel string (raw or prettified).required
max_charsintMaximum character length. Labels within this limit are returned unchanged.25

Returns:

TypeDescription
strLabel truncated to fit within max_chars, with ellipsis if needed.

Examples:

format_display_label("center(reaction_time_ms)", 20)
# "center(reaction_t…)"
format_display_label("short", 25)
# "short"
format_display_labels
format_display_labels(labels: list[str], *, max_chars: int = 25, prettify: bool = False, strip_transforms: bool = True) -> list[str]

Strip transforms + prettify + truncate + deduplicate labels for display.

Unified entry point for tick-label formatting. Applies transform stripping (by default), optional prettification, truncation, and deduplication in sequence.

Parameters:

NameTypeDescriptionDefault
labelslist[str]Raw column or term names.required
max_charsintMaximum character length per label.25
prettifyboolApply prettify_label before truncation.False
strip_transformsboolRemove transform wrappers (e.g. center(x)x) before other formatting. Default True.True

Returns:

TypeDescription
list[str]List of display-ready label strings. If truncation creates
list[str]duplicates, numeric suffixes are appended.

Examples:

format_display_labels(["wt", "hp"], prettify=True)
# ["Wt", "Hp"]
format_display_labels(["center(x)", "scale(y)"])
# ["x", "y"]
format_display_labels(
    ["center(long_variable_name)", "scale(long_variable_name)"],
    max_chars=20,
    strip_transforms=False,
)
# ["center(long_varia…)", "scale(long_variab…)"]
format_pvalue_annotation
format_pvalue_annotation(p: float) -> str

Format p-value for plot annotation.

Parameters:

NameTypeDescriptionDefault
pfloatP-value.required

Returns:

TypeDescription
strFormatted string with significance stars.
get_model_fitted
get_model_fitted(model: Any) -> np.ndarray

Extract fitted values from model, supporting both APIs.

Parameters:

NameTypeDescriptionDefault
modelAnyA fitted bossanova model.required

Returns:

TypeDescription
ndarrayArray of fitted values.
get_model_formula
get_model_formula(model: Any) -> str

Extract formula string from model, supporting both old and new API.

Parameters:

NameTypeDescriptionDefault
modelAnyA bossanova model (BaseModel or unified model()).required

Returns:

TypeDescription
strFormula string.
get_model_params
get_model_params(model: Any) -> pl.DataFrame

Extract parameter estimates from model, supporting both APIs.

Parameters:

NameTypeDescriptionDefault
modelAnyA fitted bossanova model (or ModelResult proxy).required

Returns:

TypeDescription
DataFrameDataFrame with term, estimate, and optional inference columns.
get_model_residuals
get_model_residuals(model: Any) -> np.ndarray

Extract residuals from model, supporting both APIs.

Parameters:

NameTypeDescriptionDefault
modelAnyA fitted bossanova model.required

Returns:

TypeDescription
ndarrayArray of residual values.
get_model_response
get_model_response(model: Any) -> str

Extract response variable name from model, supporting both APIs.

Parameters:

NameTypeDescriptionDefault
modelAnyA bossanova model (BaseModel or unified model()).required

Returns:

TypeDescription
strResponse variable name.
is_categorical
is_categorical(data: pl.DataFrame, term: str) -> bool

Check if a term is categorical.

A term is considered categorical if:

Parameters:

NameTypeDescriptionDefault
dataDataFramePolars DataFrame containing the term.required
termstrColumn name to check.required

Returns:

TypeDescription
boolTrue if the term is categorical.

Examples:

is_categorical(df, "species")  # String column -> True
is_categorical(df, "cyl")      # 3 unique ints -> True
is_categorical(df, "mpg")      # Many unique floats -> False
is_unified_model
is_unified_model(model: Any) -> bool

Check if model is the new unified model() class (or proxy).

Parameters:

NameTypeDescriptionDefault
modelAnyA bossanova model or ModelResult proxy.required

Returns:

TypeDescription
boolTrue if model is the new unified model() class or a proxy wrapping one.
prettify_label
prettify_label(label: str) -> str

Convert column/term name to human-readable label.

Transformations applied:

Parameters:

NameTypeDescriptionDefault
labelstrRaw column or term name.required

Returns:

TypeDescription
strPrettified label string.

Examples:

prettify_label("wt_hp_ratio")  # "Wt Hp Ratio"
prettify_label("log_income")   # "Log Income"
prettify_label("wt:hp")        # "wt x hp"
prettify_label("Income")       # "Income" (preserved)
prettify_label("hp")           # "Hp"
prettify_label("center(reaction_time)")  # "center(Reaction Time)"
prettify_labels
prettify_labels(labels: list[str]) -> list[str]

Prettify a list of labels.

Parameters:

NameTypeDescriptionDefault
labelslist[str]List of raw column or term names.required

Returns:

TypeDescription
list[str]List of prettified label strings.

Examples:

prettify_labels(["wt", "hp", "wt:hp"])
# ["Wt", "Hp", "wt x hp"]
setup_ax
setup_ax(ax: 'Axes | None', figsize: tuple[float, float] | None = None) -> 'tuple[Figure, Axes]'

Set up matplotlib axes, creating figure if needed.

Parameters:

NameTypeDescriptionDefault
ax‘Axes | None’Existing axes or None to create new figure.required
figsizetuple[float, float] | NoneFigure size if creating new figure.None

Returns:

TypeDescription
‘tuple[Figure, Axes]’Tuple of (figure, axes).
strip_transform_wrapper
strip_transform_wrapper(label: str) -> str

Strip transform wrapper(s) from a term name, keeping the inner variable.

Recursively removes outer transform calls to expose the original variable name used in the data.

Parameters:

NameTypeDescriptionDefault
labelstrTerm name, possibly wrapped in transforms.required

Returns:

TypeDescription
strThe innermost variable name with transforms removed.

Examples:

strip_transform_wrapper("center(reaction_time)")  # "reaction_time"
strip_transform_wrapper("scale(log(income))")     # "income"
strip_transform_wrapper("poly(x, 2).1")           # "x.1"
strip_transform_wrapper("wt")                     # "wt"
strip_transform_wrapper("cyl[6]")                 # "cyl[6]"
strip_transform_wrapper("center(x):wt")           # "x:wt"

core_data

Data extraction utilities for bossanova visualizations.

Provides functions to extract standardized parameter, residual, and random-effect DataFrames from fitted models (both legacy and unified API).

Functions:

NameDescription
extract_fixefExtract fixed effects from model.
extract_paramsExtract parameter estimates from a fitted model.
extract_ranefExtract random effects from mixed model.
extract_residualsExtract residual diagnostics from a fitted model.

Classes

Functions

extract_fixef
extract_fixef(model: Any, include_intercept: bool = False, effect_sizes: bool = False) -> pl.DataFrame

Extract fixed effects from model.

Parameters:

NameTypeDescriptionDefault
modelAnyA fitted bossanova model.required
include_interceptboolWhether to include the intercept term.False
effect_sizesboolWhether to return Cohen’s d instead of raw estimates. Available effect size measures depend on model family:
- Gaussian (LM/LMER): Cohen’s d, semi-partial r, eta-squared. - Binomial (GLM/GLMER): odds ratio, semi-partial r, eta-squared. Cohen’s d is unavailable (no residual SD). - Other GLM families: semi-partial r, eta-squared. Cohen’s d is unavailable (no residual SD).
Unavailable measures are returned as None columns.
False

Returns:

TypeDescription
DataFrameDataFrame with standard columns: term, estimate, se, ci_lower,
DataFrameci_upper, p_value.
extract_params
extract_params(model: Any, which: Literal['fixef', 'ranef', 'all'] = 'fixef', include_intercept: bool = False, effect_sizes: bool = False, group: str | None = None, term: str | None = None) -> pl.DataFrame

Extract parameter estimates from a fitted model.

Returns a standardized DataFrame suitable for forest plot visualization. Supports both old BaseModel and new unified model() class.

Parameters:

NameTypeDescriptionDefault
modelAnyFitted bossanova model (lm, glm, lmer, glmer, or unified model()).required
whichLiteral[‘fixef’, ‘ranef’, ‘all’]Which parameters to extract. - “fixef”: Fixed effects only (default). - “ranef”: Random effects (lmer/glmer only). - “all”: Both fixed and random effects.‘fixef’
include_interceptboolInclude intercept term for fixed effects.False
effect_sizesboolReturn effect sizes (Cohen’s d) instead of raw estimates.False
groupstr | NoneFor ranef, which grouping factor (None = all).None
termstr | NoneFor ranef, which RE term (None = all).None

Returns:

TypeDescription
DataFrameDataFrame with columns: - term: Parameter name - estimate: Point estimate - se: Standard error - ci_lower: Lower confidence bound - ci_upper: Upper confidence bound - p_value: P-value (if available) - group_factor: Grouping factor name (for ranef) - re_term: Random effect term name (for ranef)

Examples:

Old API (BaseModel)::

model = lm("mpg ~ wt + hp", data=mtcars).fit()
df = extract_params(model)

New API (unified model())::

m = model("mpg ~ wt + hp", mtcars).fit()
df = extract_params(m)
extract_ranef
extract_ranef(model: Any, group: str | None = None, term: str | None = None) -> pl.DataFrame

Extract random effects from mixed model.

Supports both old BaseModel (.varying) and new unified model() (.is_mixed).

Parameters:

NameTypeDescriptionDefault
modelAnyA fitted mixed-effects bossanova model.required
groupstr | NoneFilter to a specific grouping factor (None = all).None
termstr | NoneFilter to a specific random effect term (None = all).None

Returns:

TypeDescription
DataFrameDataFrame in long format with columns: term, estimate, se,
DataFrameci_lower, ci_upper, p_value, group_factor, re_term.
extract_residuals
extract_residuals(model: Any, residual_type: str | None = None) -> dict[str, np.ndarray]

Extract residual diagnostics from a fitted model.

Supports both old BaseModel and new unified model() class.

Parameters:

NameTypeDescriptionDefault
modelAnyFitted bossanova model (lm, glm, lmer, glmer, or unified model()).required
residual_typestr | NoneType of residuals. If None, uses model default. - “response”: Raw residuals (y - fitted) - “pearson”: Pearson residuals - “deviance”: Deviance residuals (GLM)None

Returns:

TypeDescription
dict[str, ndarray]Dictionary with: - fitted: Fitted values - residuals: Residual values - std_resid: Standardized residuals - leverage: Hat/leverage values - cooksd: Cook’s distance

Examples:

Old API (BaseModel)::

model = lm("mpg ~ wt + hp", data=mtcars).fit()
diag = extract_residuals(model)

New API (unified model())::

m = model("mpg ~ wt + hp", mtcars).fit()
diag = extract_residuals(m)

core_protocols

Model protocol and model-data extraction utilities.

Provides a unified interface for extracting data from both the legacy BaseModel API and the new unified model() class.

Classes:

NameDescription
ModelProtocolProtocol for model objects that can be visualized.

Functions:

NameDescription
get_model_fittedExtract fitted values from model, supporting both APIs.
get_model_formulaExtract formula string from model, supporting both old and new API.
get_model_paramsExtract parameter estimates from model, supporting both APIs.
get_model_residualsExtract residuals from model, supporting both APIs.
get_model_responseExtract response variable name from model, supporting both APIs.
is_unified_modelCheck if model is the new unified model() class (or proxy).

Classes

ModelProtocol

Bases: Protocol

Protocol for model objects that can be visualized.

This protocol defines the minimal interface required for visualization functions, supporting both old BaseModel and new unified model() class.

Attributes:

NameTypeDescription
dataDataFrameThe model’s data.
Attributes
data
data: pl.DataFrame

The model’s data.

Functions

get_model_fitted
get_model_fitted(model: Any) -> np.ndarray

Extract fitted values from model, supporting both APIs.

Parameters:

NameTypeDescriptionDefault
modelAnyA fitted bossanova model.required

Returns:

TypeDescription
ndarrayArray of fitted values.
get_model_formula
get_model_formula(model: Any) -> str

Extract formula string from model, supporting both old and new API.

Parameters:

NameTypeDescriptionDefault
modelAnyA bossanova model (BaseModel or unified model()).required

Returns:

TypeDescription
strFormula string.
get_model_params
get_model_params(model: Any) -> pl.DataFrame

Extract parameter estimates from model, supporting both APIs.

Parameters:

NameTypeDescriptionDefault
modelAnyA fitted bossanova model (or ModelResult proxy).required

Returns:

TypeDescription
DataFrameDataFrame with term, estimate, and optional inference columns.
get_model_residuals
get_model_residuals(model: Any) -> np.ndarray

Extract residuals from model, supporting both APIs.

Parameters:

NameTypeDescriptionDefault
modelAnyA fitted bossanova model.required

Returns:

TypeDescription
ndarrayArray of residual values.
get_model_response
get_model_response(model: Any) -> str

Extract response variable name from model, supporting both APIs.

Parameters:

NameTypeDescriptionDefault
modelAnyA bossanova model (BaseModel or unified model()).required

Returns:

TypeDescription
strResponse variable name.
is_unified_model
is_unified_model(model: Any) -> bool

Check if model is the new unified model() class (or proxy).

Parameters:

NameTypeDescriptionDefault
modelAnyA bossanova model or ModelResult proxy.required

Returns:

TypeDescription
boolTrue if model is the new unified model() class or a proxy wrapping one.

core_sizing

Figure sizing utilities for bossanova visualizations.

Provides functions to compute figure dimensions based on item counts and layout configurations.

Functions:

NameDescription
compute_figsizeCompute figure size based on number of items.
compute_grid_figsizeCompute figure size for grid/subplot layouts.
compute_heatmap_figsizeCompute figure size for heatmaps (VIF, design, correlation).

Attributes:

NameTypeDescription
BOSSANOVA_STYLEdict[str, Any]

Attributes

BOSSANOVA_STYLE
BOSSANOVA_STYLE: dict[str, Any] = {'point_size': 80, 'point_marker': 'o', 'point_edgecolor': 'white', 'point_linewidth': 0.5, 'line_width': 1.5, 'capsize': 0, 'ci_alpha': 0.3, 'ref_line_color': '#888888', 'ref_line_style': '--', 'ref_line_width': 1.0, 'font_size': 10, 'title_size': 12, 'label_size': 10, 'palette': 'tab10', 'grid_alpha': 0.3, 'grid_style': '-', 'heatmap_cell_size': 0.7, 'heatmap_min_size': 3.5, 'heatmap_max_width': 10.0, 'heatmap_max_height': 12.0, 'heatmap_colorbar_pad': 0.12}

Functions

compute_figsize
compute_figsize(n_items: int, orientation: Literal['horizontal', 'vertical'] = 'horizontal', item_size: float = 0.4, min_size: float = 3.0, max_size: float = 12.0, base_width: float = 8.0, max_label_len: int = 0) -> tuple[float, float]

Compute figure size based on number of items.

Creates readable plots for 15-20 parameters by default. Clamps dimensions to prevent too-small or too-large figures.

Parameters:

NameTypeDescriptionDefault
n_itemsintNumber of items (parameters, groups, etc.) to display.required
orientationLiteral[‘horizontal’, ‘vertical’]Plot orientation. - “horizontal”: Items on y-axis (forest plot style). - “vertical”: Items on x-axis (bar chart style).‘horizontal’
item_sizefloatInches per item. Default 0.4 works well for forest plots.0.4
min_sizefloatMinimum dimension in inches.3.0
max_sizefloatMaximum dimension in inches.12.0
base_widthfloatBase width for horizontal orientation (height for vertical).8.0
max_label_lenintLongest label character count. For horizontal (forest) plots, increases base_width when labels exceed 12 chars.0

Returns:

TypeDescription
tuple[float, float]Tuple of (width, height) in inches.

Examples:

compute_figsize(15)  # 15 parameters
# (8.0, 6.0)
compute_figsize(30)  # Clamped to max
# (8.0, 12.0)
compute_grid_figsize
compute_grid_figsize(n_rows: int, n_cols: int, cell_width: float = 4.0, cell_height: float = 3.5) -> tuple[float, float]

Compute figure size for grid/subplot layouts.

Parameters:

NameTypeDescriptionDefault
n_rowsintNumber of subplot rows.required
n_colsintNumber of subplot columns.required
cell_widthfloatWidth per cell in inches.4.0
cell_heightfloatHeight per cell in inches.3.5

Returns:

TypeDescription
tuple[float, float]Tuple of (width, height) in inches.

Examples:

compute_grid_figsize(2, 2)  # 2x2 diagnostic grid
# (8.0, 7.0)
compute_heatmap_figsize
compute_heatmap_figsize(n_rows: int, n_cols: int, *, cell_size: float | None = None, include_colorbar: bool = True, annotation_lines: int = 0, annotation_height: float = 0.18, max_label_len: int = 0) -> tuple[float, float]

Compute figure size for heatmaps (VIF, design, correlation).

Uses rectangular scaling (not square) to prevent oversized plots when there are few items but annotation text above.

Parameters:

NameTypeDescriptionDefault
n_rowsintNumber of heatmap rows.required
n_colsintNumber of heatmap columns.required
cell_sizefloat | NoneSize per cell in inches (uses style default if None).None
include_colorbarboolReserve space for colorbar.True
annotation_linesintNumber of text lines above the heatmap.0
annotation_heightfloatHeight per annotation line in inches.0.18
max_label_lenintLongest tick-label character count. Reserves extra height for rotated x-tick labels when labels are long.0

Returns:

TypeDescription
tuple[float, float]Tuple of (width, height) in inches.

Examples:

compute_heatmap_figsize(3, 3)  # 3x3 correlation matrix
# (2.35, 3.2)
compute_heatmap_figsize(3, 3, annotation_lines=3)  # With VIF text
# (2.35, 3.74)
compute_heatmap_figsize(10, 10)  # Larger matrix
# (7.84, 8.1)

core_viz

Plot helper utilities, label formatting, type inference, and FacetGrid support.

Provides low-level helpers used by individual plot modules:

Functions:

NameDescription
add_ref_lineAdd reference line to axes.
build_facetgrid_kwargsBuild standardized kwargs dict for FacetGrid/relplot/catplot.
coerce_to_column_dtypeCoerce user-provided values to match a data column’s dtype.
create_multi_panelCreate a multi-panel FacetGrid for matplotlib-native plots.
create_single_panelCreate a single-panel FacetGrid for matplotlib-native plots.
finalize_facetgridApply standard styling and layout to a FacetGrid.
format_display_labelTruncate label for tick display, preserving transform structure.
format_display_labelsStrip transforms + prettify + truncate + deduplicate labels for display.
format_pvalue_annotationFormat p-value for plot annotation.
is_categoricalCheck if a term is categorical.
prettify_labelConvert column/term name to human-readable label.
prettify_labelsPrettify a list of labels.
setup_axSet up matplotlib axes, creating figure if needed.
strip_transform_wrapperStrip transform wrapper(s) from a term name, keeping the inner variable.

Attributes

Functions

add_ref_line
add_ref_line(ax: 'Axes', value: float = 0.0, orientation: Literal['horizontal', 'vertical'] = 'vertical') -> None

Add reference line to axes.

Parameters:

NameTypeDescriptionDefault
ax‘Axes’Matplotlib axes.required
valuefloatPosition of reference line.0.0
orientationLiteral[‘horizontal’, ‘vertical’]Line orientation.‘vertical’
build_facetgrid_kwargs
build_facetgrid_kwargs(data: pl.DataFrame, height: float, aspect: float, col_wrap: int | None = None, hue: str | None = None, col: str | None = None, row: str | None = None, palette: str | None = None, sharex: bool = True, sharey: bool = True) -> dict[str, Any]

Build standardized kwargs dict for FacetGrid/relplot/catplot.

Creates a kwargs dictionary with consistent parameter handling for seaborn grid-based plotting functions.

Parameters:

NameTypeDescriptionDefault
dataDataFramePolars DataFrame to plot (passed directly to seaborn).required
heightfloatHeight of each facet in inches.required
aspectfloatAspect ratio of each facet (width = height * aspect).required
col_wrapint | NoneWrap column facets after this many columns. Ignored if row is set.None
huestr | NoneVariable name for color grouping.None
colstr | NoneVariable name for column faceting.None
rowstr | NoneVariable name for row faceting.None
palettestr | NoneColor palette name (uses BOSSANOVA_STYLE default if hue set but no palette).None
sharexboolShare x-axis across facets.True
shareyboolShare y-axis across facets.True

Returns:

TypeDescription
dict[str, Any]Dictionary of kwargs ready for sns.FacetGrid, relplot, or catplot.

Examples:

kwargs = build_facetgrid_kwargs(df, height=4.0, aspect=1.2, col="group")
g = sns.FacetGrid(**kwargs)
coerce_to_column_dtype
coerce_to_column_dtype(values: list[Any], data: pl.DataFrame, column: str) -> list[Any]

Coerce user-provided values to match a data column’s dtype.

Handles type mismatches between user input (often strings) and actual column types (integers, floats, categoricals). This enables user-friendly APIs where users can write groups=["308", "309"] even when the column contains integers.

Parameters:

NameTypeDescriptionDefault
valueslist[Any]User-provided values to coerce.required
dataDataFrameDataFrame containing the target column.required
columnstrColumn name to match dtype against.required

Returns:

TypeDescription
list[Any]Values coerced to match the column dtype. Returns original values
list[Any]if coercion fails or dtype is not recognized.

Examples:

# Integer column with string input
df = pl.DataFrame({"id": [1, 2, 3]})
coerce_to_column_dtype(["1", "2"], df, "id")
# [1, 2]

# Float column
df = pl.DataFrame({"value": [1.0, 2.0]})
coerce_to_column_dtype(["1.5", 2], df, "value")
# [1.5, 2.0]

# String column (no change needed)
df = pl.DataFrame({"name": ["a", "b"]})
coerce_to_column_dtype([1, 2], df, "name")
# ["1", "2"]
create_multi_panel
create_multi_panel(n_panels: int, *, col_wrap: int = 3, height: float = 4.0, aspect: float = 1.0) -> tuple[Any, list[Any]]

Create a multi-panel FacetGrid for matplotlib-native plots.

Parameters:

NameTypeDescriptionDefault
n_panelsintNumber of panels to create.required
col_wrapintNumber of columns before wrapping.3
heightfloatHeight of each panel in inches.4.0
aspectfloatAspect ratio of each panel.1.0

Returns:

TypeDescription
AnyTuple of (FacetGrid, list[Axes]) where each Axes is ready for
list[Any]direct matplotlib drawing.
create_single_panel
create_single_panel(figsize: tuple[float, float]) -> tuple[Any, Any]

Create a single-panel FacetGrid for matplotlib-native plots.

Wraps a plain matplotlib axes in a FacetGrid so that all plot functions return a consistent type.

Parameters:

NameTypeDescriptionDefault
figsizetuple[float, float]Desired (width, height) in inches.required

Returns:

TypeDescription
AnyTuple of (FacetGrid, Axes) where the FacetGrid wraps a single
Anypanel and the Axes is ready for direct matplotlib drawing.
finalize_facetgrid
finalize_facetgrid(g: Any, title: str | None = None, xlabel: str | None = None, ylabel: str | None = None) -> Any

Apply standard styling and layout to a FacetGrid.

Applies consistent bossanova styling: despine, tight_layout, and title.

Parameters:

NameTypeDescriptionDefault
gAnySeaborn FacetGrid or PairGrid object.required
titlestr | NoneOptional title to add above the plot.None
xlabelstr | NoneOptional x-axis label.None
ylabelstr | NoneOptional y-axis label.None

Returns:

TypeDescription
AnyThe same FacetGrid/PairGrid object (for chaining).

Examples:

g = sns.FacetGrid(df, col="group")
g.map_dataframe(my_plot_func)
finalize_facetgrid(g, title="My Plot", xlabel="X", ylabel="Y")
format_display_label
format_display_label(label: str, max_chars: int = 25) -> str

Truncate label for tick display, preserving transform structure.

Handles long labels from transformed variables (e.g., center(reaction_time_ms)) by truncating while keeping the transform wrapper visible.

Parameters:

NameTypeDescriptionDefault
labelstrLabel string (raw or prettified).required
max_charsintMaximum character length. Labels within this limit are returned unchanged.25

Returns:

TypeDescription
strLabel truncated to fit within max_chars, with ellipsis if needed.

Examples:

format_display_label("center(reaction_time_ms)", 20)
# "center(reaction_t…)"
format_display_label("short", 25)
# "short"
format_display_labels
format_display_labels(labels: list[str], *, max_chars: int = 25, prettify: bool = False, strip_transforms: bool = True) -> list[str]

Strip transforms + prettify + truncate + deduplicate labels for display.

Unified entry point for tick-label formatting. Applies transform stripping (by default), optional prettification, truncation, and deduplication in sequence.

Parameters:

NameTypeDescriptionDefault
labelslist[str]Raw column or term names.required
max_charsintMaximum character length per label.25
prettifyboolApply prettify_label before truncation.False
strip_transformsboolRemove transform wrappers (e.g. center(x)x) before other formatting. Default True.True

Returns:

TypeDescription
list[str]List of display-ready label strings. If truncation creates
list[str]duplicates, numeric suffixes are appended.

Examples:

format_display_labels(["wt", "hp"], prettify=True)
# ["Wt", "Hp"]
format_display_labels(["center(x)", "scale(y)"])
# ["x", "y"]
format_display_labels(
    ["center(long_variable_name)", "scale(long_variable_name)"],
    max_chars=20,
    strip_transforms=False,
)
# ["center(long_varia…)", "scale(long_variab…)"]
format_pvalue_annotation
format_pvalue_annotation(p: float) -> str

Format p-value for plot annotation.

Parameters:

NameTypeDescriptionDefault
pfloatP-value.required

Returns:

TypeDescription
strFormatted string with significance stars.
is_categorical
is_categorical(data: pl.DataFrame, term: str) -> bool

Check if a term is categorical.

A term is considered categorical if:

Parameters:

NameTypeDescriptionDefault
dataDataFramePolars DataFrame containing the term.required
termstrColumn name to check.required

Returns:

TypeDescription
boolTrue if the term is categorical.

Examples:

is_categorical(df, "species")  # String column -> True
is_categorical(df, "cyl")      # 3 unique ints -> True
is_categorical(df, "mpg")      # Many unique floats -> False
prettify_label
prettify_label(label: str) -> str

Convert column/term name to human-readable label.

Transformations applied:

Parameters:

NameTypeDescriptionDefault
labelstrRaw column or term name.required

Returns:

TypeDescription
strPrettified label string.

Examples:

prettify_label("wt_hp_ratio")  # "Wt Hp Ratio"
prettify_label("log_income")   # "Log Income"
prettify_label("wt:hp")        # "wt x hp"
prettify_label("Income")       # "Income" (preserved)
prettify_label("hp")           # "Hp"
prettify_label("center(reaction_time)")  # "center(Reaction Time)"
prettify_labels
prettify_labels(labels: list[str]) -> list[str]

Prettify a list of labels.

Parameters:

NameTypeDescriptionDefault
labelslist[str]List of raw column or term names.required

Returns:

TypeDescription
list[str]List of prettified label strings.

Examples:

prettify_labels(["wt", "hp", "wt:hp"])
# ["Wt", "Hp", "wt x hp"]
setup_ax
setup_ax(ax: 'Axes | None', figsize: tuple[float, float] | None = None) -> 'tuple[Figure, Axes]'

Set up matplotlib axes, creating figure if needed.

Parameters:

NameTypeDescriptionDefault
ax‘Axes | None’Existing axes or None to create new figure.required
figsizetuple[float, float] | NoneFigure size if creating new figure.None

Returns:

TypeDescription
‘tuple[Figure, Axes]’Tuple of (figure, axes).
strip_transform_wrapper
strip_transform_wrapper(label: str) -> str

Strip transform wrapper(s) from a term name, keeping the inner variable.

Recursively removes outer transform calls to expose the original variable name used in the data.

Parameters:

NameTypeDescriptionDefault
labelstrTerm name, possibly wrapped in transforms.required

Returns:

TypeDescription
strThe innermost variable name with transforms removed.

Examples:

strip_transform_wrapper("center(reaction_time)")  # "reaction_time"
strip_transform_wrapper("scale(log(income))")     # "income"
strip_transform_wrapper("poly(x, 2).1")           # "x.1"
strip_transform_wrapper("wt")                     # "wt"
strip_transform_wrapper("cyl[6]")                 # "cyl[6]"
strip_transform_wrapper("center(x):wt")           # "x:wt"

design

Design matrix structure visualization.

Functions:

NameDescription
plot_designPlot design matrix as an annotated heatmap.

Attributes

Classes

Functions

plot_design
plot_design(model: BaseModel, *, max_rows: int | None = 20, annotate_terms: bool = True, show_contrast_info: bool = True, prettify: bool = False, cmap: str | None = None, height: float = _DESIGN_DEFAULT_HEIGHT, aspect: float = _DESIGN_DEFAULT_ASPECT) -> sns.FacetGrid

Plot design matrix as an annotated heatmap.

Visualizes the structure of the model’s design matrix with:

Works on unfitted models since the design matrix is built at initialization.

Parameters:

NameTypeDescriptionDefault
modelmodelA bossanova model. Can be fitted or unfitted.required
max_rowsint | NoneMaximum number of rows to display. If None, shows all rows. Large datasets are subsampled evenly for readability.20
annotate_termsboolShow term grouping brackets above the heatmap.True
show_contrast_infoboolShow reference level annotations for categorical terms.True
prettifyboolConvert term names to human-readable labels (e.g., “wt_hp_ratio” -> “Wt Hp Ratio”). Default False.False
cmapstr | NoneMatplotlib colormap name. If None (default), uses "gray" (grayscale). Pass "viridis" for a perceptually-uniform alternative, or any valid matplotlib colormap name.None
heightfloatFigure height in inches. When both height and aspect are at their defaults, sizing adapts to the design matrix dimensions._DESIGN_DEFAULT_HEIGHT
aspectfloatWidth-to-height ratio. When both height and aspect are at their defaults, sizing adapts to the design matrix dimensions._DESIGN_DEFAULT_ASPECT

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the plot.

Examples:

from bossanova import model, load_dataset
cars = load_dataset("mtcars")
m = model("mpg ~ factor(cyl) + wt + wt:cyl", cars)
# Works before fitting
m.plot_design()
# Also works after fitting
m.fit().plot_design()

helpers

Shared helper utilities for bossanova visualization modules.

This module consolidates helper functions used across multiple viz modules (fit.py, predict.py, etc.) to eliminate duplication.

Functions:

NameDescription
detect_ci_columnsDetect CI bound column names in a DataFrame.
fill_ci_bandRender sorted CI bands on a matplotlib axes.
get_grouping_factorsGet grouping factor column names for mixed models.
is_mixed_modelCheck if model is a mixed-effects model.

Classes

Functions

detect_ci_columns
detect_ci_columns(columns: 'Sequence[str]') -> tuple[str, str] | None

Detect CI bound column names in a DataFrame.

Checks for ci_lower/ci_upper (preferred) falling back to lwr/upr (legacy). Returns None if neither pair is present.

Parameters:

NameTypeDescriptionDefault
columns‘Sequence[str]’Column names to search (e.g., df.columns).required

Returns:

TypeDescription
tuple[str, str] | NoneTuple of (lower_col, upper_col) column names, or None
tuple[str, str] | Noneif no CI columns are found.
fill_ci_band
fill_ci_band(ax: 'Axes', x: np.ndarray, lower: np.ndarray, upper: np.ndarray, hue_values: np.ndarray | None = None, colors: dict['Any', 'Any'] | None = None, default_color: str = 'C0', fill_kws: dict[str, 'Any'] | None = None) -> None

Render sorted CI bands on a matplotlib axes.

Shared rendering core for CI bands. Sorts data along x, then calls ax.fill_between() once per hue level (or once if no hue).

Parameters:

NameTypeDescriptionDefault
ax‘Axes’Matplotlib axes to draw on.required
xndarrayX-axis values, shape (n,).required
lowerndarrayLower CI bound values, shape (n,).required
upperndarrayUpper CI bound values, shape (n,).required
hue_valuesndarray | NonePer-observation hue labels, shape (n,). Pass None for single-color rendering.None
colorsdict[‘Any’, ‘Any’] | NoneMapping from hue level to matplotlib color. Required when hue_values is not None. Determines both which levels to draw and their colors.None
default_colorstrColor to use when hue_values is None. Defaults to "C0".‘C0’
fill_kwsdict[str, ‘Any’] | NoneAdditional keyword arguments forwarded to ax.fill_between().None
get_grouping_factors
get_grouping_factors(model: 'Any') -> list[str]

Get grouping factor column names for mixed models.

Extracts the names of grouping variables (e.g., Subject from (1|Subject)) from a fitted mixed model. Returns an empty list for fixed-effects-only models.

Supports both the legacy API (lmer/glmer with _group_names) and the unified model() class (via random_terms property).

Parameters:

NameTypeDescriptionDefault
model‘Any’A bossanova model object (any API variant).required

Returns:

TypeDescription
list[str]List of grouping factor column names, in the order they appear
list[str]in the formula. Empty list for non-mixed models.
is_mixed_model
is_mixed_model(model: 'Any') -> bool

Check if model is a mixed-effects model.

Supports both the legacy API (lmer/glmer classes) and the unified model() class.

Parameters:

NameTypeDescriptionDefault
model‘Any’A bossanova model object (any API variant).required

Returns:

TypeDescription
boolTrue if the model contains random/varying effects.

mem

Marginal effects visualization for bossanova models.

This module provides plot_explore() for visualizing marginal estimated effects (MEEs) from model.explore() output. Supports three result types:

The slopes and contrasts drawing logic lives in mem_forest.py.

Functions:

NameDescription
plot_explorePlot marginal estimated effects.

Attributes

Classes

Functions

plot_explore
plot_explore(model: 'Any', specs: str, *, hue: str | None = None, col: str | None = None, row: str | None = None, effect_scale: Literal['link', 'response'] = 'response', conf_int: float = 0.95, prettify: bool = False, height: float = 4.0, aspect: float = 1.2, palette: str | None = None, col_wrap: int | None = None, show_pvalue: bool = False, ref_line: float | None = None, precomputed_emm: pl.DataFrame | None = None) -> sns.FacetGrid

Plot marginal estimated effects.

Dispatches to the appropriate plot type based on the result of model.explore(specs):

When precomputed_emm is provided, the function skips the model.explore().infer() call and uses the supplied DataFrame directly, inferring the plot type from column structure.

Parameters:

NameTypeDescriptionDefault
model‘Any’A fitted bossanova model.required
specsstrExplore formula, e.g. "treatment", "x", "pairwise(treatment)", "x ~ z".required
huestr | NoneColor encoding variable for grouping (dodged on same plot). Auto-detected from conditioning columns when None.None
colstr | NoneColumn faceting variable.None
rowstr | NoneRow faceting variable.None
effect_scaleLiteral[‘link’, ‘response’]"link" or "response" (default). Matches model.explore(effect_scale=...).‘response’
conf_intfloatConfidence level (default 0.95).0.95
prettifyboolConvert axis labels to human-readable format.False
heightfloatHeight of each facet in inches.4.0
aspectfloatAspect ratio of each facet.1.2
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None
col_wrapint | NoneNumber of columns before wrapping facets to a new row. Only used when col is set.None
show_pvalueboolAdd significance stars (for contrasts/slopes).False
ref_linefloat | NoneReference line position. Auto-set to 0 for contrasts/slopes if not specified.None
precomputed_emmDataFrame | NonePre-computed effects DataFrame (from model.effects). Skips explore().infer().None

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the plot.

Examples:

::

from bossanova import model, viz, load_dataset
mtcars = load_dataset("mtcars")
m = model("mpg ~ factor(cyl) + wt + hp", mtcars).fit()

# Categorical EMMs
m.explore("cyl").infer()
m.plot_explore("cyl")

# Continuous slope
m.explore("wt").infer()
m.plot_explore("wt")

# Pairwise contrasts (forest plot)
m.explore("pairwise(cyl)").infer()
m.plot_explore("pairwise(cyl)")

# Crossed: slopes at multiple levels
m.explore("wt ~ cyl").infer()
m.plot_explore("wt ~ cyl")

See Also: plot_predict: Marginal predictions across predictor range. plot_params: Fixed effects forest plot.

mem_forest

Forest-style plots for slopes and contrasts.

Provides _plot_slopes and _plot_contrasts used by plot_explore() in mem.py. Separated to keep each file under 800 lines.

Classes

Functions

params

Parameter forest plot.

Functions:

NameDescription
plot_paramsPlot fixed effect estimates as a forest plot.

Attributes

Classes

Functions

plot_params
plot_params(model: 'Any', *, include_intercept: bool = False, effect_sizes: bool = False, sort: bool | Literal['ascending', 'descending'] = False, show_values: bool = False, show_pvalue: bool = False, ref_line: float = 0.0, prettify: bool = False, height: float = 0.4, aspect: float = 2.5, col_wrap: int | None = None, palette: str | None = None) -> sns.FacetGrid

Plot fixed effect estimates as a forest plot.

Creates a horizontal dot-whisker plot showing parameter estimates with confidence intervals. Uses Seaborn FacetGrid for consistent styling.

Parameters:

NameTypeDescriptionDefault
model‘Any’A fitted bossanova model.required
include_interceptboolInclude intercept term.False
effect_sizesboolPlot Cohen’s d instead of raw estimates. Available measures depend on family (see :func:extract_fixef).False
sortbool | Literal[‘ascending’, ‘descending’]Sort parameters by estimate magnitude. - False: Keep original order. - True or “descending”: Largest to smallest. - “ascending”: Smallest to largest.False
show_valuesboolAnnotate points with estimate values.False
show_pvalueboolAdd significance stars based on p-values.False
ref_linefloatPosition of reference line (default 0.0).0.0
prettifyboolConvert term names to human-readable labels (e.g., “wt_hp_ratio” → “Wt Hp Ratio”). Default False.False
heightfloatHeight per parameter in inches (default 0.4).0.4
aspectfloatAspect ratio (default 2.5).2.5
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the plot.

Examples:

::

from bossanova import model, viz, load_dataset
mtcars = load_dataset("mtcars")
m = model("mpg ~ wt + hp + cyl", mtcars).fit()
viz.plot_params(m)

# After inference for p-values
m.infer()
viz.plot_params(m, show_pvalue=True)

See Also: plot_ranef: Random effects caterpillar plot for mixed models.

predict

Prediction plots for bossanova models.

This module provides plot_predict() for visualizing marginal predictions across the range of a predictor variable.

Functions:

NameDescription
plot_predictPlot marginal predictions across a predictor’s range.

Attributes

Classes

Functions

plot_predict
plot_predict(model: 'Any', term: str, *, hue: str | None = None, col: str | None = None, row: str | None = None, at: dict | None = None, units: Literal['link', 'data'] = 'data', n_points: int = 50, interval: Literal['confidence', 'prediction'] | None = 'confidence', conf_int: float = 0.95, show_data: bool = False, show_rug: bool = False, show_blups: bool = False, groups: list[str] | None = None, prettify: bool = False, height: float = 4.0, aspect: float = 1.2, col_wrap: int | None = None, palette: str | None = None) -> sns.FacetGrid

Plot marginal predictions across a predictor’s range.

Creates a visualization of model predictions varying one predictor while holding others at reference values (means for continuous, reference level for categorical).

Accepts either a bare column name or an explore-style formula::

plot_predict(m, "age")              # bare column
plot_predict(m, "age ~ sex")        # hue by sex
plot_predict(m, "age ~ sex@Female") # pin sex=Female
plot_predict(m, "age@range(5)")     # 5-point grid
plot_predict(m, "age@[25,50,75]")   # explicit grid values

Contrast formulas (pairwise(), Drug[A - B]) are not supported — use :func:plot_explore for those.

Parameters:

NameTypeDescriptionDefault
model‘Any’A fitted bossanova model.required
termstrThe predictor variable to vary, or an explore-style formula string. Can be continuous or categorical.required
huestr | NoneColumn name for color encoding (creates separate lines per level).None
colstr | NoneColumn name for faceting into columns.None
rowstr | NoneColumn name for faceting into rows.None
atdict | NoneDictionary of predictor values to hold fixed. E.g., at={"age": 30} holds age at 30.None
unitsLiteral[‘link’, ‘data’]Units for predictions. - “data”: Back-transformed predictions (default). - “link”: Predictions on link scale (GLM/GLMER).‘data’
n_pointsintNumber of points for continuous predictors.50
intervalLiteral[‘confidence’, ‘prediction’] | NoneType of interval to show. - “confidence”: Confidence interval for mean prediction. - “prediction”: Prediction interval (wider, includes residual var). - None: No interval.‘confidence’
conf_intfloatConfidence level (default 0.95).0.95
show_databoolOverlay actual data points on the plot.False
show_rugboolAdd rug plot showing observed data distribution.False
show_blupsboolFor mixed models, show group-specific BLUP lines in addition to the population-average fixed effects line.False
groupslist[str] | NoneFor mixed models with show_blups=True, which group levels to show. If None, shows all groups (can be crowded for many groups).None
prettifyboolConvert axis labels to human-readable format (e.g., “wt_hp_ratio” → “Wt Hp Ratio”). Default False.False
heightfloatHeight of each facet in inches.4.0
aspectfloatAspect ratio of each facet.1.2
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the plot.

Examples:

::

from bossanova import model, viz, load_dataset
mtcars = load_dataset("mtcars")

# Simple predictions
m = model("mpg ~ wt + hp", mtcars).fit()
viz.plot_predict(m, "wt")

# Interaction visualization with hue
m = model("mpg ~ wt * cyl", mtcars).fit()
viz.plot_predict(m, "wt", hue="cyl")

# Mixed model (inferred from formula)
sleep = load_dataset("sleepstudy")
m = model("Reaction ~ Days + (Days|Subject)", sleep).fit()
viz.plot_predict(m, "Days", show_blups=True)

See Also: plot_explore: Marginal effects/means visualization.

profile

Profile likelihood visualization.

Pure function operating on ProfileState containers.

Functions:

NameDescription
plot_profilePlot profile likelihood curves.

Attributes

Classes

Functions

plot_profile
plot_profile(profile: ProfileState, param: str | None = None, *, height: float = 4.0, aspect: float = 1.2, prettify: bool = False, palette: str | None = None) -> sns.FacetGrid

Plot profile likelihood curves.

Parameters:

NameTypeDescriptionDefault
profileProfileStateProfileState from profile_likelihood().required
paramstr | NoneSpecific parameter to plot, or None for all parameters.None
heightfloatHeight of each panel in inches.4.0
aspectfloatWidth-to-height ratio of each panel.1.2
prettifyboolApply human-readable formatting to parameter names in axis labels and titles.False
palettestr | NoneColor palette name for the profile curves. Each parameter gets a distinct color from the cycle. Default uses BOSSANOVA_STYLE palette.None

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing zeta vs parameter plot(s).

ranef

Random effects caterpillar plot.

Functions:

NameDescription
plot_ranefPlot random effects as a caterpillar plot.

Attributes

Classes

Functions

plot_ranef
plot_ranef(model: 'Any', *, group: str | None = None, term: str | None = None, col: str | None = None, show: int | list[str] | Literal['all', 'top', 'bottom', 'quartile'] = 'all', sort: bool | Literal['ascending', 'descending'] = False, show_values: bool = False, ref_line: float = 0.0, prettify: bool = False, height: float = 4.0, aspect: float = 1.0, col_wrap: int | None = None, palette: str | None = None) -> sns.FacetGrid

Plot random effects as a caterpillar plot.

Creates a horizontal dot-whisker plot showing random effect estimates (BLUPs) for each group level. Supports faceting by random effect term.

Parameters:

NameTypeDescriptionDefault
model‘Any’A fitted mixed-effects model.required
groupstr | NoneWhich grouping factor to show. None shows first grouping factor.None
termstr | NoneWhich random effect term to show (e.g., “Intercept”, “Days”). None shows all terms with faceting.None
colstr | NoneColumn faceting variable. If None and multiple RE terms exist, facets by term.None
showint | list[str] | Literal[‘all’, ‘top’, ‘bottom’, ‘quartile’]Which group levels to display. - “all”: Show all levels (default). - int: First N levels in model order. - list[str]: Specific level names. - “top”: Top quartile by magnitude. - “bottom”: Bottom quartile by magnitude. - “quartile”: Top + bottom quartiles (most extreme).‘all’
sortbool | Literal[‘ascending’, ‘descending’]Sort levels by estimate magnitude. - False: Keep original order. - True or “descending”: Largest to smallest. - “ascending”: Smallest to largest.False
show_valuesboolAnnotate points with estimate values.False
ref_linefloatPosition of reference line (default 0.0).0.0
prettifyboolConvert term names to human-readable labels (e.g., “slope_days” → “Slope Days”). Default False.False
heightfloatHeight of each facet in inches.4.0
aspectfloatAspect ratio of each facet.1.0
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the plot.

Examples:

from bossanova import model, viz, load_dataset
sleep = load_dataset("sleepstudy")
m = model("Reaction ~ Days + (Days|Subject)", sleep).fit()

# All RE terms, faceted
viz.plot_ranef(m)

# Just intercepts
viz.plot_ranef(m, term="Intercept")

# Extreme levels only
viz.plot_ranef(m, show="quartile", sort=True)

See Also: plot_params: Fixed effects forest plot. plot_predict: Marginal predictions with BLUPs overlay.

relationships

Pairwise relationship scatter plot matrix.

Functions:

NameDescription
plot_relationshipsPlot pairwise relationships between response and predictors.

Attributes

Classes

Functions

plot_relationships
plot_relationships(model: BaseModel, *, show_vif: bool = True, prettify: bool = False, height: float = 1.5, aspect: float = 1.0, palette: str | None = None) -> sns.PairGrid

Plot pairwise relationships between response and predictors.

Creates a scatter plot matrix showing:

Works on unfitted models since the design matrix is built at initialization.

Parameters:

NameTypeDescriptionDefault
modelmodelA bossanova model. Can be fitted or unfitted.required
show_vifboolWhether to display VIF statistics above the plot.True
prettifyboolConvert variable names to human-readable labels (e.g., “wt_hp_ratio” → “Wt Hp Ratio”). Default False.False
heightfloatHeight of each facet in inches.1.5
aspectfloatAspect ratio of each facet.1.0
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None

Returns:

TypeDescription
PairGridSeaborn PairGrid containing the plot.

Note: This function returns a PairGrid. To access the underlying Figure, use g.figure. Migration from previous API: fig = model.plot_relationships()g = model.plot_relationships(); fig = g.figure

Examples:

from bossanova import model, load_dataset
cars = load_dataset("mtcars")
m = model("mpg ~ wt + hp + disp", cars)
m.plot_relationships()  # Shows y and all predictors

resamples

Bootstrap and permutation distribution visualization.

Functions:

NameDescription
plot_resamplesPlot distribution of resampled statistics.

Attributes

Classes

Functions

plot_resamples
plot_resamples(model: 'Any', *, which: Literal['params', 'mee', 'effects'] = 'params', include_intercept: bool = False, terms: list[str] | None = None, prettify: bool = False, height: float = 3.0, aspect: float = 1.2, col_wrap: int = 4, palette: str | None = None, show_ci: bool = True, show_pvalue: bool = True, fill: bool = True) -> sns.FacetGrid

Plot distribution of resampled statistics.

Visualizes bootstrap coefficient distributions or permutation null distributions. Requires save_resamples=True (default for n<=5000) during infer().

Parameters:

NameTypeDescriptionDefault
model‘Any’A fitted bossanova model with resampling results.required
whichLiteral[‘params’, ‘mee’, ‘effects’]What to plot: - “params”: Model coefficients (from boot_samples_ or perm_samples_) - “mee”: Marginal effects (from boot_mee_samples_)‘params’
include_interceptboolInclude intercept in coefficient plots.False
termslist[str] | NoneSubset of terms to plot. If None, plot all.None
prettifyboolConvert term names to human-readable labels (e.g., “wt_hp_ratio” → “Wt Hp Ratio”). Default False.False
heightfloatHeight of each facet in inches.3.0
aspectfloatAspect ratio of each facet (width = height * aspect).1.2
col_wrapintNumber of columns before wrapping.4
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None
show_ciboolFor bootstrap, shade confidence interval region.True
show_pvalueboolFor permutation, annotate p-value.True
fillboolFill under density curve.True

Returns:

TypeDescription
FacetGridSeaborn FacetGrid with one facet per parameter.

Examples:

from bossanova import model, viz, load_dataset
mtcars = load_dataset("mtcars")
m = model("mpg ~ wt + hp", mtcars).fit()

# Bootstrap distributions (auto-saved for n<=5000)
m.infer(how="boot", n=999)
viz.plot_resamples(m)

# Permutation null distributions
m.infer(how="perm", n=999)
viz.plot_resamples(m)

# MEE bootstrap
m.mee("wt").infer(how="boot", n=999)
viz.plot_resamples(m, which="mee")

See Also: plot_params: Forest plot of parameter estimates.

resid

Residual diagnostic plots.

Functions:

NameDescription
plot_residPlot residual diagnostics as a faceted grid.

Attributes

Classes

Functions

plot_resid
plot_resid(model: 'Any', *, which: list[int] | Literal['all'] = 'all', residual_type: Literal['response', 'pearson', 'deviance'] | None = None, lowess: bool = True, label_outliers: int | float = 3, height: float = 3.5, aspect: float = 1.0, col_wrap: int = 2, palette: str | None = None, prettify: bool = False) -> sns.FacetGrid

Plot residual diagnostics as a faceted grid.

Creates a diagnostic plot grid similar to R’s plot(lm_model):

  1. Residuals vs Fitted: Check linearity and heteroscedasticity. Points should be randomly scattered around 0.

  2. Q-Q Plot: Check normality of residuals. Points should follow the diagonal line.

  3. Scale-Location: Check homoscedasticity (constant variance). Points should be randomly scattered with constant spread.

  4. Residuals vs Leverage: Identify influential observations. Points outside Cook’s D contours may be influential.

Parameters:

NameTypeDescriptionDefault
model‘Any’A fitted bossanova model.required
whichlist[int] | Literal[‘all’]Which panels to show. - “all”: All 4 panels (default). - List of integers [1,2,3,4]: Specific panels.‘all’
residual_typeLiteral[‘response’, ‘pearson’, ‘deviance’] | NoneType of residuals to use. - None: Auto-select based on model type. - “response”: Raw residuals (y - fitted). - “pearson”: Pearson residuals. - “deviance”: Deviance residuals (GLM/GLMER).None
lowessboolAdd lowess smoothing line to applicable panels.True
label_outliersint | floatLabel points with standardized residuals exceeding this threshold. Set to 0 to disable.3
heightfloatHeight of each facet in inches.3.5
aspectfloatAspect ratio of each facet.1.0
col_wrapintNumber of columns before wrapping.2
palettestr | NoneColor palette name (default: BOSSANOVA_STYLE palette).None
prettifyboolReserved for API consistency. Currently a no-op since panel labels are fixed diagnostic names.False

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the diagnostic panels.

Examples:

::

from bossanova import model, viz, load_dataset
mtcars = load_dataset("mtcars")
m = model("mpg ~ wt + hp", mtcars).fit()
viz.plot_resid(m)

# Show only Q-Q plot
viz.plot_resid(m, which=[2])

# GLM with deviance residuals
m = model("am ~ wt + hp", mtcars, family="binomial").fit()
viz.plot_resid(m, residual_type="deviance")

Note: This function returns a FacetGrid. To access the underlying Figure, use g.figure. Migration from previous API: fig = model.plot_resid()g = model.plot_resid(); fig = g.figure

vif

VIF and multicollinearity visualization.

Functions:

NameDescription
plot_vifPlot VIF diagnostics as correlation heatmap.

Attributes

Classes

Functions

plot_vif
plot_vif(model: BaseModel, *, cmap: str | None = None, height: float = 4.0, aspect: float = 1.0, prettify: bool = False) -> sns.FacetGrid

Plot VIF diagnostics as correlation heatmap.

Visualizes multicollinearity in the design matrix:

VIF interpretation:

Works on unfitted models since the design matrix is built at initialization.

For pairwise scatter plots including the response variable, use plot_relationships() instead.

Parameters:

NameTypeDescriptionDefault
modelmodelA bossanova model. Can be fitted or unfitted.required
cmapstr | NoneMatplotlib colormap name. Default “coolwarm”.None
heightfloatFigure height in inches. Default 4.0.4.0
aspectfloatWidth-to-height ratio. Default 1.0 (square heatmap).1.0
prettifyboolConvert column names to human-readable labels (e.g., “wt_hp_ratio” -> “Wt Hp Ratio”). Default False.False

Returns:

TypeDescription
FacetGridSeaborn FacetGrid containing the plot.

Examples:

from bossanova import model, load_dataset
cars = load_dataset("mtcars")
m = model("mpg ~ wt + hp + disp", cars)
m.plot_vif()  # Correlation heatmap with VIF stats
m.plot_vif(prettify=True)  # With prettified labels