morphospace_plot#

ktch.plot.morphospace_plot(data: Any | None = None, *, x: str | npt.ArrayLike | None = None, y: str | npt.ArrayLike | None = None, hue: str | npt.ArrayLike | None = None, reducer: Any | None = None, reducer_inverse_transform: Callable[[np.ndarray], np.ndarray] | None = None, n_components: int | None = None, descriptor: Any | None = None, descriptor_inverse_transform: Callable[[np.ndarray], np.ndarray] | None = None, components: tuple[int, int] = (0, 1), shape_type: str = 'auto', render_fn: Callable[..., None] | None = None, n_dim: int | None = None, links: Sequence[Sequence[int]] | None = None, n_shapes: int = 5, shape_scale: float = 1.0, shape_color: str = 'lightgray', shape_alpha: float = 0.7, palette: str | Sequence | None = None, hue_order: Sequence | None = None, scatter_kw: dict[str, Any] | None = None, ax: object | None = None, **render_kw: Any) object[source]#

Scatter plot of specimens in morphospace with shape insets.

Draws a scatter plot of scores from dimension reduction (reducer) and overlays reconstructed shapes at a regular grid of positions in the low-dimensional space.

The function uses the same two-stage inverse transform pipeline as shape_variation_plot(): scores -> [reducer_inverse_transform] -> coefficients -> [descriptor_inverse_transform] -> shape coordinates.

This function calls fig.canvas.draw() internally to compute accurate pixel positions for inset axes. Inset positions are fixed at draw time and will not automatically update if the figure is later resized or saved at a different DPI. For best results, set the final figure size before calling this function.

Parameters:
dataDataFrame, optional

DataFrame containing scores and metadata. If provided, x, y, hue refer to column names.

xstr or array-like, optional

Horizontal axis values (column name or array).

ystr or array-like, optional

Vertical axis values (column name or array).

huestr or array-like, optional

Grouping variable for scatter coloring.

reducerfitted estimator, optional

Convenience parameter. Extracts reducer_inverse_transform via .inverse_transform and n_components via .n_components_ (fallback to .n_components).

reducer_inverse_transformcallable, optional

Overrides reducer.inverse_transform.

n_componentsint, optional

Overrides reducer.n_components_.

descriptorfitted estimator, optional

Convenience parameter. Extracts descriptor_inverse_transform via .inverse_transform.

descriptor_inverse_transformcallable, optional

Overrides descriptor.inverse_transform.

componentstuple of (int, int)

0-indexed component indices for (horizontal, vertical) axes.

shape_typestr

Shape rendering type. One of "auto", "curve_2d", "curve_3d", "surface_3d", "landmarks_2d", "landmarks_3d".

render_fncallable, optional

Custom renderer (coords, ax, **kw) -> None.

n_dimint, optional

Spatial dimensionality (for GPA identity case).

linkssequence of sequence of int, optional

Landmark link pairs.

n_shapesint

Number of shapes along each axis (total: n_shapes * n_shapes).

shape_scalefloat

Scale factor for inset shape size.

shape_colorstr

Color for reconstructed shapes.

shape_alphafloat

Transparency for reconstructed shapes.

palettestr or sequence, optional

Forwarded to sns.scatterplot.

hue_ordersequence, optional

Forwarded to sns.scatterplot.

scatter_kwdict, optional

Additional kwargs forwarded to sns.scatterplot.

axmatplotlib.axes.Axes, optional

Pre-existing axes. If None, creates new figure and axes.

**render_kw

Forwarded to the shape renderer.

Returns:
axmatplotlib.axes.Axes

The main scatter plot axes.

Raises:
ImportError

If matplotlib or seaborn are not installed.

ValueError

If required parameters cannot be resolved.

See also

shape_variation_plot

Shape grid along component axes.

explained_variance_ratio_plot

Scree plot of explained variance.

Notes

When shape_type="auto" (the default), the type is inferred from the output of the descriptor inverse transform:

  • 4-D array -> "surface_3d"

  • 3-D array with last dimension 2 -> "curve_2d"

  • 3-D array with last dimension 3 -> "curve_3d"

  • No descriptor (identity / GPA case) with n_dim=2 -> "landmarks_2d"

  • No descriptor (identity / GPA case) with n_dim=3 -> "landmarks_3d"

For 3-D arrays with shape[-1] == 3, auto-detection chooses "curve_3d". If the data represents landmarks, specify shape_type="landmarks_3d" explicitly.

3-D shape types ("surface_3d", "curve_3d", "landmarks_3d") use matplotlib 3-D projection for each inset, which is significantly slower. For 3-D surfaces (e.g., SHA), consider using n_shapes <= 3 and reducing surface resolution via a descriptor_inverse_transform wrapper.

Examples

>>> from ktch.plot import morphospace_plot
>>> ax = morphospace_plot(
...     data=df_pca,
...     x="PC1", y="PC2", hue="genus",
...     reducer=pca,
...     descriptor=efa,
...     palette="Paired",
...     n_shapes=5,
...     shape_scale=0.8,
... )