QQPlot#

class chemotools.plotting.QQPlot(residuals: ndarray, *, target_index: int = 0, annotations: list[str] | None = None, label: str = 'Residuals', color: str = '#008BFB', add_reference_line: bool = True, add_confidence_band: bool | float | None = None)[source]

Bases: BasePlot

Quantile-Quantile plot to assess if residuals follow a normal distribution.

This class creates Q-Q plots comparing the quantiles of residuals against theoretical quantiles from a normal distribution. Points falling on the diagonal line indicate normality, while deviations suggest non-normality.

Parameters:
  • residuals (np.ndarray) – Residual values with shape (n_samples,) for univariate or (n_samples, n_targets) for multivariate regression.

  • target_index (int, optional) – For multivariate residuals, which target to plot (default: 0). Ignored if residuals is 1D.

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

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

  • color (str, optional) – Color for the points (default: “#008BFB”).

  • add_reference_line (bool, optional) – Whether to add the diagonal reference line (default: True).

  • add_confidence_band (bool or float, optional) –

    Whether to add confidence bands around the reference line.

    • If True: uses 95% confidence band

    • If float: uses specified confidence level (0 < level < 1)

    • If False or None: no bands (default: None)

Raises:

ValueError – If residuals have invalid shapes.

Examples

Basic Q-Q plot:

>>> residuals = y_true - y_pred
>>> plot = QQPlot(residuals)
>>> fig = plot.show(title="Q-Q Plot of Residuals")

With confidence bands:

>>> plot = QQPlot(residuals, add_confidence_band=0.95)
>>> fig = plot.show(title="Q-Q Plot with 95% Confidence Band")

Multiple datasets compared:

>>> fig, axes = plt.subplots(1, 2, figsize=(12, 5))
>>> QQPlot(train_residuals, label="Train").render(axes[0])
>>> QQPlot(test_residuals, label="Test").render(axes[1])
>>> plt.show()

Multivariate regression - plot specific target:

>>> residuals = y_true - y_pred  # shape (n_samples, n_targets)
>>> plot = QQPlot(residuals, target_index=1)
>>> fig = plot.show(title="Q-Q Plot for Target 2")

With outlier annotations:

>>> outlier_indices = [5, 23, 47]
>>> annotations = [f"S{i}" if i in outlier_indices else "" for i in range(len(residuals))]
>>> plot = QQPlot(residuals, annotations=annotations)
>>> fig = plot.show(title="Q-Q Plot with Outliers")

Notes

The Q-Q plot compares: - X-axis: Theoretical quantiles from standard normal distribution N(0,1) - Y-axis: Sample quantiles (standardized residuals)

Points should fall approximately on the diagonal line y=x if residuals are normally distributed. Common patterns: - S-curve: Heavy or light tails - Points above line: Right skew - Points below line: Left skew

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 QQ 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 existing or new axes.

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

  • 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 (min, max).

  • ylim (tuple[float, float], optional) – Y-axis limits (min, max).

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

Returns:

The Figure and Axes objects containing the plot.

Return type:

tuple[Figure, Axes]