cantuccio.core module

core.py

Core plotting logic.

corner(samples, …) -> (fig, axes)

cantuccio.core.cornerplot(samples, columns=None, weights=None, truths=None, plot_delta=False, periodic=None, credible_interval=0.9, statistic='median', diag_mode='kde', offdiag_mode='hexbin+kde', labels=None, colors=None, contour_levels=(0.68, 0.9), title_format=None, fig=None, axes=None, kde_kwargs=None, offdiag_kwargs=None, truth_kwargs=None, legend_kwargs=None, n_ticks=4, xlabelpad=4.0, ylabelpad=2.0, hspace=0.1, wspace=0.1, stylefile=None, savepath=None)[source]

Custom corner plot with KDE marginals and 2D contours/hexbin/histograms.

Parameters:
  • samples (dict[str, ndarray] | ndarray | list[dict[str, ndarray] | ndarray]) – A single chain or a list of chains, where each dict maps parameter names to samples. If np.ndarrays are provided instead of dictionaries, the parameters will be labelled as \(\theta_i\).

  • columns (list[str] | None, default: None) – List of parameter names to include in the plot. If None, all keys from the first chain will be used.

  • weights (ndarray | list[ndarray] | None, default: None) – A single array of weights or a list of arrays of weights corresponding to the chains. If None, samples will be treated as unweighted.

  • truths (dict | ndarray | None, default: None) – Dictionary or array mapping parameter names to their true values. If provided, these will be overplotted as lines on the plot. If a numpy array is provided, it will be matched to the parameters in order of columns.

  • plot_delta (bool, default: False) – If True, plot the difference between the samples and the truths (i.e., Δ = samples - truths) instead of the raw samples. Requires truths to be provided.

  • credible_interval (float, default: 0.9) – Credible interval level for shading the 1D KDE plots on the diagonal.

  • statistic (str, default: 'median') – Statistic to compute for the titles on the diagonal panels. Options are “median” or “hdi”. The latter follows the ChainConsumer implementation. Refer to the get_credible_interval_median() and get_credible_interval_hdi() for details.

  • diag_mode (str, default: 'kde') – Mode for the 1D distributions on the diagonal panels. Options are: - “kde”: Kernel density estimates - “hist”: Histograms

  • offdiag_mode (str, default: 'hexbin+kde') – Mode for the off-diagonal panels. Options are: - “hist”: 2D histogram - “hexbin”: Hexagonal binning - “contour”: Filled contour plot of the KDE - “kde”: Non-filled contour plot of the KDE - “hist+kde”: 2D histogram with KDE contours overlaid - “hexbin+kde”: Hexagonal binning with KDE contours overlaid - “contour+kde”: Filled contour plot with KDE contours overlaid

  • labels (str | list[str] | None, default: None) – Label(s) for the chain(s) to be used in the legend. If a single string is provided and multiple chains are given, the same label will be used for all chains.

  • colors (list[str] | None, default: None) – List of colors for the chains. If not provided, default colors will be used.

  • contour_levels (tuple[float, ...], default: (0.68, 0.9)) – Levels for the 2D contour plots, specified as fractions of the total probability mass (e.g., 0.68 for 68% credible region).

  • periodic (dict[str, tuple[float, float]] | None, default: None) – Dictionary mapping parameter names to their wrapped domain boundaries (e.g., {“phi”: (0, 2 * np.pi)} for an angle parameter). If provided, the KDE contours and 1D marginal regions correctly integrate mathematically over boundaries to fold and wrap inside this topology. We recommend providing the periodic bounds only for parameters that wrap within the range of the samples.

  • title_format (str | None, default: None) – Format string for the titles on the diagonal panels. If provided, the median and credible interval will be included in the title for each parameter. The format string should be suitable for formatting the median and interval widths, e.g. “.2f” for 2 decimal places.

  • fig (Figure | None, default: None) – Matplotlib Figure object to use for the plot. If None, a new figure will be created.

  • axes (ndarray | None, default: None) – Array of matplotlib Axes objects to use for the plot. If None, a new set of axes will be created. The shape of the axes array should match the number of parameters (n_dim x n_dim).

  • kde_kwargs (dict | None, default: None) – Keyword arguments for the KDE estimation. If not provided, defaults will be used (e.g., bandwidth method “silverman” and FFT-based KDE). Supported keys include: - “bandwidth”: Bandwidth method for KDE (“scott”, “silverman”, or a scalar factor). - “fast”: If True, use FFT-based KDE through the KDEpy package for faster computation on large datasets. If False, use the standard Gaussian KDE estimator. Default is False. - “num_1d”: Number of points to evaluate the 1D KDE on. Default is 512. - “num_2d”: Number of points per dimension to evaluate the 2D KDE on. Default is 80.

  • offdiag_kwargs (dict | None, default: None) – Keyword arguments for the off-diagonal plots (histogram, hexbin, contour).

  • truth_kwargs (dict | None, default: None) – Keyword arguments for the truth lines.

  • legend_kwargs (dict | None, default: None) – Keyword arguments for the legend.

  • n_ticks (int, default: 4) – Number of ticks to show on each axis.

  • xlabelpad (float | None, default: 4.0) – Padding for x-axis labels. If None, the default Matplotlib padding will be used.

  • ylabelpad (float | None, default: 2.0) – Padding for y-axis labels. If None, the default Matplotlib padding will be used.

  • hspace (float, default 0.1) – Height space between subplots.

  • wspace (float, default 0.1) – Width space between subplots.

  • stylefile (str | None, default: None) – Path to a Matplotlib style file to use for the plot. If None, a default style file included with the package will be used.

  • savepath (str | None, default: None) – Path to save the figure. If None, the figure will not be saved.

Return type:

tuple[Figure, ndarray]

cantuccio.core.cov_ellipse(mean, cov, ax, num_std=1.0, **kwargs)[source]

Plot a covariance ellipse using eigendecomposition. Code from the https://github.com/mikekatz04/Eryn package.

The ellipse axes are aligned with the eigenvectors of the covariance matrix, and scaled by sqrt(eigenvalue) * num_std.

Parameters:
  • mean (ndarray) – Center of the ellipse (mean_x, mean_y).

  • cov (ndarray) – 2x2 covariance matrix.

  • ax (Axes) – Axes object on which to plot the ellipse.

  • num_std (int, default: 1.0) – Number of standard deviations for ellipse radius. Default is 1.0.

  • **kwargs – Additional keyword arguments passed to matplotlib.patches.Ellipse.

Returns:

The covariance ellipse added to the axes.

Return type:

matplotlib.patches.Ellipse

cantuccio.core.get_credible_interval(data, level, weights=None)[source]

Return (lower, median, upper) for a highest-density credible interval. Standalone function for users who want to compute credible intervals without going through the kde estimation. This is not used internally by the cornerplot() method.

Parameters:
  • data (ndarray) – 1D array of samples.

  • level (float) – Credible interval level, e.g. 0.90 for a 90% credible interval.

  • weights (ndarray | None, default: None) – 1D array of weights corresponding to the samples.

Returns:

A tuple containing the lower bound, median, and upper bound of the credible interval.

Return type:

tuple[float, float, float]

cantuccio.core.get_credible_interval_hdi(x, pdf, level)[source]

Return (lower, center, upper) for the highest-density credible interval.

Routine adapted from the ChainConsumer package: https://samreay.github.io/ChainConsumer/, doi:10.21105/joss.00045.

Parameters:
  • x (ndarray) – 1D array of samples.

  • pdf (ndarray) – 1D array of probability density values corresponding to the samples.

  • level (float) – Credible interval level, e.g. 0.90 for a 90% credible interval.

Returns:

A tuple containing the lower bound, center, and upper bound of the highest-density interval.

Return type:

tuple[float, float, float]

cantuccio.core.get_credible_interval_median(x, pdf, level)[source]

Return (lower, median, upper). The median is the value of x at which the cumulative distribution function (CDF) reaches 0.5, and the lower and upper bounds are the values of x at which the CDF reaches (1 - level) / 2 and 1 - (1 - level) / 2, respectively.

Parameters:
  • x (ndarray) – 1D array of samples.

  • pdf (ndarray) – 1D array of probability density values corresponding to the samples.

  • level (float) – Credible interval level, e.g. 0.90 for a 90% credible interval.

Returns:

A tuple containing the lower bound, median, and upper bound of the credible interval.

Return type:

tuple[float, float, float]

cantuccio.core.overlay_covariance(fig, covariance, means=None, levels=(0.68, 0.9), num_sigmas=[1, 2, 3], plot_1d=False, colors='k', linestyles=None, linewidths=None, alpha=0.7, label=None)[source]

Overlay covariance ellipses on corner plot axes. Useful for comparing the results of a Information Matrix analysis to MCMC results.

For 2D subplots, draws elliptical contours; for 1D diagonal plots, draws vertical lines either side of the mean.

There are two conventions for sizing the ellipse, controlled by which argument you pass:

  • levels (recommended for comparing against cornerplot()): each entry is a credible mass (e.g. 0.68), matching the contour_levels argument of cornerplot(). The ellipse is drawn at the radius that encloses that fraction of the 2D probability mass, and the 1D lines at the radius enclosing that fraction of the 1D mass. Because a 2D region and a 1D interval enclosing the same mass sit at different radii (\(\chi^2\) with 2 vs 1 degrees of freedom), this is the only way to make the overlay line up with the corner contours.

  • num_sigmas: each entry is a Mahalanobis radius in units of \(\sigma\) along the principal axes. Note that an n-\(\sigma\) ellipse encloses only \(1 - e^{-n^2/2}\) of the mass (e.g. 39% at 1 \(\sigma\)), not the 68% that n=1 encloses in 1D. Use this only if you specifically want fixed-radius ellipses. If levels is given it takes precedence over num_sigmas.

Parameters:
  • fig (Figure) – Figure object containing corner plot axes.

  • covariance (ndarray) – Covariance matrix from Fisher analysis, shape (n_params, n_params).

  • means (ndarray | None, default: None) – Mean values for each parameter. If None, uses origin (0, 0, …).

  • levels (tuple | None, default: (0.68, 0.9)) – Credible masses to plot (e.g., [0.68, 0.90]), matching cornerplot’s contour_levels. Takes precedence over num_sigmas.

  • num_sigmas (list, default: [1, 2, 3]) – Mahalanobis radii (in sigma) to plot (e.g., [1, 2, 3]). Default [1, 2, 3]. Ignored if levels is given.

  • plot_1d (bool, default: False) – Whether to plot 1D contours on diagonal plots. Default is False.

  • colors (list | str | None, default: 'k') – Colors for each level. Default is “k”.

  • linestyles (list | str | None, default: None) – Line styles for each level. If None, uses solid lines.

  • linewidths (list | float | None, default: None) – Line widths for each level. If None, uses default (1.5).

  • alpha (float, default: 0.7) – Transparency of contours. Default 0.7.

  • label (str, default: None) – Label for legend entry.

Returns:

The figure with overlaid contours.

Return type:

matplotlib.figure.Figure

cantuccio.core.overplot_lines(axes, lines, columns=None, marker=None, **kwargs)[source]

Overplot vertical and horizontal lines on a corner plot.

Parameters:
  • axes (ndarray) – Array of matplotlib axes objects.

  • lines (dict[str, float]) – Dictionary mapping parameter names to line positions.

  • columns (list[str] | None, default: None) – List of parameter names. If not provided, the keys of the lines dictionary will be used.

  • marker (str | None, default: None) – Marker style for the line plots. If not provided, lines will be plotted without markers.

  • **kwargs – Additional keyword arguments for the line plots.