Skip to content

Core objects

Types and coercion helpers used across all plotting functions to normalize SHAP values, interaction values, and enums.

Explanation dataclass

Explanation(
    values: FloatArray,
    base_values: FloatArray,
    feature_names: tuple[str, ...],
    data: FloatArray | None = None,
)

Normalized SHAP explanation used internally by every plot builder.

All arrays are stored two-dimensionally as (n_samples, n_features) so plot code never has to special-case single instances.

Attributes:

Name Type Description
values FloatArray

SHAP values, shape (n_samples, n_features).

base_values FloatArray

Model expected value per sample, shape (n_samples,).

feature_names tuple[str, ...]

Feature labels, length n_features.

data FloatArray | None

Original feature values aligned with values, or None when the caller only provided SHAP values.

n_samples property

n_samples: int

Number of explained instances.

n_features property

n_features: int

Number of features.

is_single property

is_single: bool

Whether the explanation describes a single instance.

__post_init__

__post_init__() -> None

Validate array shapes are mutually consistent.

Source code in src/shaply/explanation.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
def __post_init__(self) -> None:
    """Validate array shapes are mutually consistent."""
    if self.values.ndim != 2:
        msg = f"values must be 2D (n_samples, n_features), got shape {self.values.shape}"
        raise ValueError(msg)
    n_samples, n_features = self.values.shape
    if self.base_values.shape != (n_samples,):
        msg = f"base_values must have shape ({n_samples},), got {self.base_values.shape}"
        raise ValueError(msg)
    if len(self.feature_names) != n_features:
        msg = f"feature_names must have length {n_features}, got {len(self.feature_names)}"
        raise ValueError(msg)
    if self.data is not None and self.data.shape != self.values.shape:
        msg = f"data must match values shape {self.values.shape}, got {self.data.shape}"
        raise ValueError(msg)

mean_abs

mean_abs() -> FloatArray

Mean absolute SHAP value per feature (global importance).

Source code in src/shaply/explanation.py
94
95
96
def mean_abs(self) -> FloatArray:
    """Mean absolute SHAP value per feature (global importance)."""
    return np.abs(self.values).mean(axis=0)

select_sample

select_sample(index: int) -> Explanation

Return a single-sample explanation for index.

Source code in src/shaply/explanation.py
 98
 99
100
101
102
103
104
105
def select_sample(self, index: int) -> Explanation:
    """Return a single-sample explanation for ``index``."""
    return Explanation(
        values=self.values[index : index + 1],
        base_values=self.base_values[index : index + 1],
        feature_names=self.feature_names,
        data=None if self.data is None else self.data[index : index + 1],
    )

to_explanation

to_explanation(
    values: ExplanationLike | ArrayLike | object,
    *,
    base_values: object = None,
    data: ArrayLike | None = None,
    feature_names: Sequence[str] | None = None,
    output_index: int | None = None,
) -> Explanation

Coerce supported inputs into an :class:Explanation.

Parameters:

Name Type Description Default
values ExplanationLike | ArrayLike | object

A shap.Explanation-like object, a numpy array of SHAP values, or a :class:pandas.DataFrame whose columns are feature names.

required
base_values object

Model expected value(s). Scalar or per-sample. Defaults to zeros. Ignored when values already carries base values.

None
data ArrayLike | None

Original feature values aligned with the SHAP values.

None
feature_names Sequence[str] | None

Feature labels. Inferred from a DataFrame or generated when omitted.

None
output_index int | None

Class index to select when values holds multi-output SHAP values.

None

Returns:

Type Description
Explanation

The normalized internal representation.

Raises:

Type Description
ValueError

If the provided arrays have inconsistent or unsupported shapes.

Source code in src/shaply/explanation.py
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
def to_explanation(
    values: ExplanationLike | npt.ArrayLike | object,
    *,
    base_values: object = None,
    data: npt.ArrayLike | None = None,
    feature_names: Sequence[str] | None = None,
    output_index: int | None = None,
) -> Explanation:
    """Coerce supported inputs into an :class:`Explanation`.

    Parameters
    ----------
    values
        A ``shap.Explanation``-like object, a numpy array of SHAP values, or a
        :class:`pandas.DataFrame` whose columns are feature names.
    base_values
        Model expected value(s). Scalar or per-sample. Defaults to zeros.
        Ignored when ``values`` already carries base values.
    data
        Original feature values aligned with the SHAP values.
    feature_names
        Feature labels. Inferred from a DataFrame or generated when omitted.
    output_index
        Class index to select when ``values`` holds multi-output SHAP values.

    Returns
    -------
    Explanation
        The normalized internal representation.

    Raises
    ------
    ValueError
        If the provided arrays have inconsistent or unsupported shapes.
    """
    if isinstance(values, ExplanationLike) and not isinstance(values, np.ndarray):
        return _from_explanation_like(values, output_index=output_index)

    frame_names, frame_values = _maybe_dataframe(values)
    if frame_values is not None:
        values_arr = frame_values
        if feature_names is None:
            feature_names = frame_names
    else:
        values_arr = np.asarray(values, dtype=np.float64)

    values_arr = _as_2d(_select_output(values_arr, output_index))
    n_samples, n_features = values_arr.shape

    resolved_names = (
        _default_feature_names(n_features)
        if feature_names is None
        else tuple(str(name) for name in feature_names)
    )

    data_arr = None if data is None else _as_2d(np.asarray(data, dtype=np.float64))
    base_arr = _coerce_base_values(base_values, n_samples)

    return Explanation(
        values=values_arr,
        base_values=base_arr,
        feature_names=resolved_names,
        data=data_arr,
    )

InteractionValues dataclass

InteractionValues(
    values: FloatArray, feature_names: tuple[str, ...]
)

Normalized SHAP interaction tensor used by the interaction heatmap.

Attributes:

Name Type Description
values FloatArray

Interaction values, shape (n_samples, n_features, n_features).

feature_names tuple[str, ...]

Feature labels, length n_features.

n_features property

n_features: int

Number of features.

__post_init__

__post_init__() -> None

Validate the tensor is a stack of square interaction matrices.

Source code in src/shaply/interaction.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def __post_init__(self) -> None:
    """Validate the tensor is a stack of square interaction matrices."""
    if self.values.ndim != 3 or self.values.shape[1] != self.values.shape[2]:
        msg = (
            "interaction values must have shape (n_samples, n_features, n_features), "
            f"got {self.values.shape}"
        )
        raise ValueError(msg)
    if len(self.feature_names) != self.values.shape[1]:
        msg = (
            f"feature_names must have length {self.values.shape[1]}, "
            f"got {len(self.feature_names)}"
        )
        raise ValueError(msg)

mean_abs_matrix

mean_abs_matrix() -> FloatArray

Mean absolute interaction per feature pair, shape (n_features, n_features).

Source code in src/shaply/interaction.py
60
61
62
def mean_abs_matrix(self) -> FloatArray:
    """Mean absolute interaction per feature pair, shape ``(n_features, n_features)``."""
    return np.abs(self.values).mean(axis=0)

to_interaction_values

to_interaction_values(
    values: ArrayLike | object,
    *,
    feature_names: Sequence[str] | None = None,
) -> InteractionValues

Coerce an interaction tensor (or .values-carrying object) into a model.

Parameters:

Name Type Description Default
values ArrayLike | object

A (n_samples, n_features, n_features) array, or an object exposing such an array as .values (and optionally .feature_names).

required
feature_names Sequence[str] | None

Feature labels; inferred from the object or generated when omitted.

None

Returns:

Type Description
InteractionValues

The normalized internal representation.

Source code in src/shaply/interaction.py
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
def to_interaction_values(
    values: npt.ArrayLike | object,
    *,
    feature_names: Sequence[str] | None = None,
) -> InteractionValues:
    """Coerce an interaction tensor (or ``.values``-carrying object) into a model.

    Parameters
    ----------
    values
        A ``(n_samples, n_features, n_features)`` array, or an object exposing
        such an array as ``.values`` (and optionally ``.feature_names``).
    feature_names
        Feature labels; inferred from the object or generated when omitted.

    Returns
    -------
    InteractionValues
        The normalized internal representation.
    """
    raw = getattr(values, "values", values)
    array = np.asarray(raw, dtype=np.float64)

    if feature_names is None:
        obj_names = getattr(values, "feature_names", None)
        feature_names = None if obj_names is None else [str(name) for name in obj_names]

    n_features = array.shape[1] if array.ndim == 3 else 0
    resolved = (
        tuple(f"Feature {i}" for i in range(n_features))
        if feature_names is None
        else tuple(str(name) for name in feature_names)
    )
    return InteractionValues(values=array, feature_names=resolved)

ColorScale

Bases: StrEnum

Named color scales available for continuous encodings.

RED_BLUE reproduces the canonical SHAP diverging scheme (blue for low feature values, red for high).

FeatureOrdering

Bases: StrEnum

Strategy used to order features along the categorical axis of a plot.

Attributes:

Name Type Description
IMPORTANCE

Order by mean absolute SHAP value (most important first).

MAX_ABSOLUTE

Order by the single largest absolute SHAP value across samples.

ORIGINAL

Keep the order of feature_names as provided.

ALPHABETICAL

Order features alphabetically by name.

PlotType

Bases: StrEnum

Kind of SHAP figure that shaply can render.