Source code for phenotypic.plotting._image_plots

"""Standalone replacements for the removed ``Image.plot`` diagnostics."""

from __future__ import annotations

from dataclasses import replace
from typing import Any, Callable

from pydantic import BaseModel, ConfigDict

from phenotypic.abc_.plotting import PlotImage


def _diagnostics_figure(
    name: str,
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """Copy figure metadata while changing diagnostics to a call-time subject."""
    from phenotypic._core._image_parts.plot_accessor._diagnostics_plotter import (
        DiagnosticsPlotter,
    )

    source = getattr(DiagnosticsPlotter, name).__figure_spec__

    def decorate(method: Callable[..., Any]) -> Callable[..., Any]:
        method.__figure_spec__ = replace(  # type: ignore[attr-defined]
            source,
            method=method,
            wants_subject=True,
            subject_param="subject",
        )
        return method

    return decorate


[docs] class PlotDiagnostics(BaseModel, PlotImage): """Build image-quality diagnostics from a weakly bound call-time image.""" model_config = ConfigDict(extra="forbid") def _render_diagnostic( self, subject: Any, name: str, **controls: Any ) -> Any: """Render through a short-lived legacy helper without retaining it.""" from phenotypic._core._image_parts.plot_accessor._diagnostics_plotter import ( DiagnosticsPlotter, ) if subject is None: raise TypeError("PlotDiagnostics requires an Image subject") return getattr(DiagnosticsPlotter(subject), name)(**controls)
[docs] @_diagnostics_figure("fig_intensity_histogram") def fig_intensity_histogram(self, subject: Any, **controls: Any) -> Any: return self._render_diagnostic( subject, "fig_intensity_histogram", **controls )
[docs] @_diagnostics_figure("fig_noise_autocorrelation") def fig_noise_autocorrelation(self, subject: Any, **controls: Any) -> Any: return self._render_diagnostic( subject, "fig_noise_autocorrelation", **controls )
[docs] @_diagnostics_figure("fig_power_spectral_density") def fig_power_spectral_density(self, subject: Any, **controls: Any) -> Any: return self._render_diagnostic( subject, "fig_power_spectral_density", **controls )
[docs] @_diagnostics_figure("fig_detection_matrix") def fig_detection_matrix(self, subject: Any, **controls: Any) -> Any: return self._render_diagnostic(subject, "fig_detection_matrix", **controls)
[docs] @_diagnostics_figure("fig_local_contrast_map") def fig_local_contrast_map(self, subject: Any, **controls: Any) -> Any: return self._render_diagnostic( subject, "fig_local_contrast_map", **controls )
[docs] @_diagnostics_figure("fig_contrast_metrics") def fig_contrast_metrics(self, subject: Any, **controls: Any) -> Any: return self._render_diagnostic(subject, "fig_contrast_metrics", **controls)
[docs] @_diagnostics_figure("fig_gradient_magnitude") def fig_gradient_magnitude(self, subject: Any, **controls: Any) -> Any: return self._render_diagnostic( subject, "fig_gradient_magnitude", **controls )
[docs] @_diagnostics_figure("fig_orientation_coherence") def fig_orientation_coherence(self, subject: Any, **controls: Any) -> Any: return self._render_diagnostic( subject, "fig_orientation_coherence", **controls )
[docs] @_diagnostics_figure("fig_ridge_response") def fig_ridge_response(self, subject: Any, **controls: Any) -> Any: return self._render_diagnostic(subject, "fig_ridge_response", **controls)
[docs] @_diagnostics_figure("fig_background_estimate") def fig_background_estimate(self, subject: Any, **controls: Any) -> Any: return self._render_diagnostic( subject, "fig_background_estimate", **controls )
[docs] @_diagnostics_figure("fig_local_variance") def fig_local_variance(self, subject: Any, **controls: Any) -> Any: return self._render_diagnostic(subject, "fig_local_variance", **controls)
[docs] @_diagnostics_figure("fig_quality_summary") def fig_quality_summary(self, subject: Any, **controls: Any) -> Any: return self._render_diagnostic(subject, "fig_quality_summary", **controls)
[docs] class PlotDetectModes(BaseModel, PlotImage): """Compare every registered detection mode for a supplied image.""" model_config = ConfigDict(extra="forbid")
[docs] def inspect( self, subject: Any = None, *, for_save: bool = False, **overrides: Any, ) -> Any: del for_save from phenotypic._core._image_parts.plot_accessor._detect_modes_plotter import ( DetectModesPlotter, ) if subject is None: raise TypeError("PlotDetectModes.inspect requires an Image subject") return DetectModesPlotter(subject).inspect(**overrides)
[docs] def report(self, subject: Any = None, **overrides: Any) -> Any: from phenotypic._core._image_parts.plot_accessor._detect_modes_plotter import ( DetectModesPlotter, ) if subject is None: raise TypeError("PlotDetectModes.report requires an Image subject") return DetectModesPlotter(subject).report(**overrides)
__all__ = ["PlotDetectModes", "PlotDiagnostics"]