display#

hydromodpy.display is the solver-agnostic figure layer. It wraps matplotlib through a registered catalog of named figures consumable from Run.plot, hmp display, and the [display] TOML section.

Sub-modules#

  • display/figure.pyFigureSpec dataclass, Figure Protocol, and BaseFigure ABC. Concrete figures inherit from BaseFigure and decorate themselves with @register.

  • display/catalog.py – registry, register decorator, get(name), list_figures(), names().

  • display/figures/ – one module per named figure. Auto-discovery through pkgutil.iter_modules in display/figures/__init__.py.

  • display/geo/ – shared geographic plotting helpers (basemaps, CRS-aware axes, scalebar, north arrow).

  • display/overview/ – composed overview report rendering used by the [overview] workflow.

  • display/report_blocks/ – shared static HTML block primitives used by block-based reports. It owns the generic dataclasses, renderer, level navigation, per-block level switches, relative artifact links, and missing-figure placeholders.

  • display/catchment_report/ – generic watershed report pipeline driven by hmp report catchment and rendered through display/report_blocks.

  • display/config.pyDisplayConfig Pydantic model for the [display] TOML section.

  • display/theme.py – shared style / colormap selection.

Block HTML Reports#

display/report_blocks is the common renderer for static reports composed from reusable blocks. The key contract is that workflow code builds ReportBlock objects, while the shared renderer writes the HTML page. Domain-specific report modules should keep their scientific logic in their own blocks.py files and call:

  • write_report_page(...) for one static page;

  • write_report_page_with_block_variants(...) for a page where each block can switch between compact, standard and audit detail.

The renderer is currently used by overview reporting, site-selection review reports, the catchment report pipeline, and the network/transient calibration diagnostic page.

Figure inventory (33 today)#

Spatial: piezometric_map, recharge_map, seepage_map, concentration_map, side_by_side_map, difference_map, cross_section, hydrographic_network, hydrographic_network_comparison, simulated_active_network, watershed_id_card, residuals.

Time series: hydrograph, hydrograph_sim_obs, piezo_timeseries_sim_obs, duration_curve, seasonal_boxplot, recession, ensemble_band.

Balance: water_budget.

Calibration: calibration_convergence, calibration_landscape, calibration_objective_surface, calibration_pairplot, calibration_posterior, calibration_trace.

Hydrochemistry: piper_diagram, schoeller_diagram, stiff_diagram.

Particle / scatter: particle_tracks, scatter_one_to_one.

Figure contract#

@dataclass(frozen=True)
class FigureSpec:
    name: str
    title: str
    kind: str                     # "spatial" | "timeseries" | "balance" | "calibration" | ...
    required_fields: tuple[str, ...]
    required_tables: tuple[str, ...]
    default_figsize: tuple[float, float]


class BaseFigure(ABC):
    """Implements plot() boilerplate (subplots + render + save)."""
    spec: ClassVar[FigureSpec]

    @abstractmethod
    def render(self, sim: Run, ax: Axes, **opts) -> Axes: ...

The @register decorator places the class in the global registry keyed by spec.name.

Key public symbols#

  • hydromodpy.display.{get, list_figures, names}

  • hydromodpy.display.figure.{FigureSpec, BaseFigure}

  • hydromodpy.display.catalog.register

  • hydromodpy.display.theme.plot_params

  • hydromodpy.display.config.DisplayConfig

  • hydromodpy.display.report_blocks.{ReportBlock, ReportMetric, ReportFigure, ReportTable, ReportLink}

  • hydromodpy.display.report_blocks.{write_report_page, write_report_page_with_block_variants}

Layer-matrix neighbours#

  • Allowed targets: core, schema, results, display.

  • Allowed sources: analysis, reporting, workflow, project and cli.

  • display must not import data, simulation, solver, calibration. Reach data through Run (run.field, run.timeseries, run.budget).

See also#