ScoresPlot#

class chemotools.plotting.ScoresPlot(scores: ndarray, *, components: tuple[int, int] = (0, 1), color_by: ndarray | None = None, annotations: list[str] | None = None, label: str = 'Data', color: str | None = None, colormap: str | None = None, confidence_ellipse: bool | float | None = None, color_mode: Literal['continuous', 'categorical'] | None = None, colorbar_label: str = 'Value')[source]

Bases: BasePlot, ColoringMixin

Simple, composable scores plot for a single dataset.

This class creates scatter plots of model scores (projections) for one dataset. Multiple datasets can be overlaid by using the render() method on shared axes.

Parameters:
  • scores (np.ndarray) – Score array with shape (n_samples, n_components).

  • components (tuple[int, int], optional) – Component indices to plot (default is (0, 1) for PC1 vs PC2). Uses 0-based indexing (e.g., (0, 1) plots PC1 vs PC2).

  • color_by (np.ndarray, optional) –

    Values for coloring samples. Can be either:

    • Continuous (numeric): shows colorbar (e.g., concentration, temperature)

    • Categorical (strings/classes): shows legend with discrete colors

  • annotations (list[str], optional) – Labels for annotating individual points.

  • label (str, optional) – Legend label for this dataset (default: “Data”).

  • color (str, optional) – Color for all points when color_by is None (default: auto-assigned).

  • colormap (str, optional) –

    Colormap name. Colorblind-friendly defaults:

    • ”tab10” for categorical data

    • ”viridis” for continuous data

  • confidence_ellipse (bool or float, optional) –

    Whether to draw a confidence ellipse around the data.

    • If True: draws 95% confidence ellipse

    • If float: draws ellipse at specified confidence level (e.g., 0.90, 0.99)

    • If False or None: no ellipse (default)

  • color_mode ({"continuous", "categorical"}, optional) – Explicitly specify coloring mode. If None (default), automatically detects based on dtype and unique values of color_by.

  • colorbar_label (str, optional) – Label for the colorbar when using continuous coloring. Default is “Value”. Only applies when color_by is continuous.

Raises:

ValueError – If components tuple contains invalid component indices.

Examples

Simple single dataset plot:

>>> plot = ScoresPlot(train_scores)
>>> fig = plot.show(title="PCA Scores")

Multiple datasets composed together:

>>> fig, ax = plt.subplots()
>>> ScoresPlot(train_scores, label="Train", color="blue").render(ax)
>>> ScoresPlot(test_scores, label="Test", color="red").render(ax)
>>> ax.legend()
>>> plt.show()

With categorical coloring:

>>> plot = ScoresPlot(train_scores, color_by=train_classes)
>>> fig = plot.show(title="Scores by Class")

With continuous coloring:

>>> plot = ScoresPlot(train_scores, color_by=concentrations, colormap='viridis')
>>> fig = plot.show(title="Scores by Concentration")

Custom components and labels:

>>> plot = ScoresPlot(scores, components=(1, 2))
>>> fig = plot.show(
...     title="PC2 vs PC3",
...     xlabel="Second Component",
...     ylabel="Third Component"
... )

With annotations:

>>> annotations = [f"S{i}" if i in outliers else "" for i in range(len(scores))]
>>> plot = ScoresPlot(scores, annotations=annotations)
>>> fig = plot.show(title="Annotated Scores")

With confidence ellipse:

>>> plot = ScoresPlot(train_scores, confidence_ellipse=True)
>>> fig = plot.show(title="Scores with 95% Confidence Ellipse")
>>> plot = ScoresPlot(train_scores, confidence_ellipse=0.99, color="blue")
>>> fig = plot.show(title="Scores with 99% Confidence Ellipse")

Attributes

color_by

is_categorical

colormap

colorbar_label

show(*, figsize: Tuple[float, float] | None = None, title: str | None = None, xlabel: str | None = None, ylabel: str | None = None, xlim: Tuple[float, float] | None = None, ylim: Tuple[float, float] | None = None, **kwargs: Any) Figure[source]

Create and return a complete figure with the scores plot.

This method handles figure creation and then delegates to render().

Parameters:
  • figsize (tuple[float, float], optional) – Figure size in inches (width, height).

  • title (str, optional) – Figure title.

  • xlabel (str, optional) – Custom x-axis label. If None, uses existing label or default.

  • ylabel (str, optional) – Custom y-axis label. If None, uses existing label or default.

  • xlim (tuple[float, float], optional) – X-axis limits as (xmin, xmax).

  • ylim (tuple[float, float], optional) – Y-axis limits as (ymin, ymax).

  • **kwargs (Any) – Additional keyword arguments passed to the render() method.

Returns:

The matplotlib Figure object containing the plot.

Return type:

Figure

render(ax: Axes | None = None, *, xlabel: str | None = None, ylabel: str | None = None, xlim: tuple[float, float] | None = None, ylim: tuple[float, float] | None = None, **kwargs: Any) tuple[Figure, Axes][source]

Render the plot on the given axes or create new ones.

Use this method to compose multiple plots on the same axes.

Parameters:
  • ax (Axes, optional) – Matplotlib axes to plot on. If None, creates new figure and axes.

  • xlabel (str, optional) – Custom x-axis label. If None, uses existing label or defaults to “PC{comp1+1}”.

  • ylabel (str, optional) – Custom y-axis label. If None, uses existing label or defaults to “PC{comp2+1}”.

  • xlim (tuple[float, float], optional) – X-axis limits as (xmin, xmax).

  • ylim (tuple[float, float], optional) – Y-axis limits as (ymin, ymax).

  • **kwargs (Any) – Additional keyword arguments passed to ax.scatter().

Returns:

  • fig (Figure) – The matplotlib Figure object.

  • ax (Axes) – The matplotlib Axes object with the rendered plot.

Examples

Compose multiple datasets:

>>> fig, ax = plt.subplots()
>>> ScoresPlot(train_scores, label="Train").render(ax)
>>> ScoresPlot(test_scores, label="Test").render(ax)
>>> ax.set_xlabel("PC1")
>>> ax.set_ylabel("PC2")
>>> ax.legend()
>>> plt.show()