Interactive Web Viewer#
pyiwfm includes a browser-based interactive viewer for exploring IWFM models. The viewer is built with FastAPI on the backend and React + vtk.js + deck.gl on the frontend.
Quick Start#
Launch the viewer from the command line:
# Auto-detect model in current directory
pyiwfm viewer
# Specify model directory
pyiwfm viewer --model-dir /path/to/model
# Specify CRS for coordinate reprojection (optional)
pyiwfm viewer --model-dir /path/to/model --crs "+proj=utm +zone=10 +datum=NAD83 +units=us-ft +no_defs"
# Configure port (default: 8080)
pyiwfm viewer --model-dir /path/to/model --port 9000
Or launch from Python:
from pyiwfm.visualization.webapi.server import create_app
import uvicorn
app = create_app(model_dir="/path/to/model")
uvicorn.run(app, host="0.0.0.0", port=8080)
Model Auto-Detection#
The launcher automatically searches for IWFM input files:
Looks for
Preprocessor/*.inorPreProcessor_MAIN.INLooks for
Simulation/*.inorSimulation_MAIN.INExtracts model name from input files
Loads stream specification files if available
Missing components are handled gracefully:
No stratigraphy: 2D mesh only
No streams: stream layer omitted
No simulation results: static property display
Viewer Tabs#
The viewer provides six tabs, each focused on a different aspect of the model.
Overview#
Model summary and metadata including node/element counts, component availability, simulation time range, and coordinate reference system.
Mesh Quality Card:
The Overview tab includes a mesh quality summary card showing aggregate
statistics computed by compute_mesh_quality():
Element count breakdown (triangles vs quads)
Aspect ratio statistics (min, max, mean)
Skewness (mean)
Min/max angle across all elements
Count of poor-quality elements (aspect ratio > 5 or skewness > 0.8)
3D Mesh#
Interactive 3D rendering of the model mesh using vtk.js.
Controls:
Layer slider to filter which layer is displayed
Show all layers or a single layer
Opacity slider
Edge visibility toggle
Stream network overlay
Vertical exaggeration slider
Cross-Section:
Enable/disable slice plane
Select axis (X, Y, Z)
Position slider
Results Map#
2D map view using deck.gl and MapLibre GL for head contour visualization.
Features:
Head values displayed as color-coded elements
Timestep and layer selection
Head difference (change) between two timesteps
Drawdown mode: Select Color By: Drawdown to visualize drawdown relative to a reference timestep. A reference timestep slider appears, and a diverging color scale (blue = rising, red = falling) is applied. Supports pagination (
offset,limit,skip) for animation playback.Head statistics (min/max/mean/std per node across all timesteps)
Subsidence surface: When subsidence data is available, display subsidence values as a color-coded surface layer
Hydrograph locations displayed as markers (cached for fast response)
Click a hydrograph marker to view time series chart
Upload observed data (CSV, TSV, SMP, or other delimited text) for comparison overlay
Stream network overlay on map
Budgets#
Plotly-based charts for water budget time series.
Features:
Groundwater, stream, lake, root zone, and other budget types
Location and column selection
Monthly budget timestep support
Diagnostics#
Simulation diagnostics tab for analyzing convergence and errors. See Simulation Diagnostics for a detailed walkthrough.
Features:
Messages table: Paginated list of simulation messages with severity filtering (INFO, WARN, FATAL)
Convergence chart: Iteration counts per timestep plotted as a time series
Mass balance error chart: Per-component mass balance error over time
Summary statistics: Total warnings, errors, max iterations, average iterations, and total runtime
Z-Budgets#
Zone budget visualization, similar to the Budgets tab but organized by spatial zones defined in zone definition files.
Docker Deployment#
The viewer can be deployed using Docker:
# Build and run with Docker
docker run -p 8080:8080 -v /path/to/model:/model pyiwfm
# Or use docker-compose
docker-compose up --build
See DOCKER.md for full configuration including environment variables
(PORT, TITLE, MODE, MODEL_PATH).
Coordinate Reprojection#
The backend reprojects model coordinates to WGS84 for map display using
pyproj. Use the --crs flag to specify the model’s coordinate
reference system:
pyiwfm viewer --crs "+proj=utm +zone=10 +datum=NAD83 +units=us-ft +no_defs"
For C2VSimFG models, the CRS defaults to UTM Zone 10N, NAD83, US survey feet.
Data Export#
The viewer provides several data export endpoints:
CSV: Heads per node, budget time series, GW/stream hydrographs
Excel: Budget data as formatted
.xlsxworkbooks (one sheet per location with title lines, bold headers, unit conversion, and auto-fitted column widths) viaGET /api/budgets/{budget_type}/excelandGET /api/export/budget-excelGeoJSON: Mesh elements as downloadable GeoJSON
GeoPackage: Multi-layer GeoPackage with nodes, elements, streams, subregions, and model boundary via
GISExporterPlots: Publication-quality matplotlib figures (mesh, elements, streams, heads) as PNG or SVG with configurable size and DPI
Model Comparison#
Load a second IWFM model and compare it with the currently loaded model:
curl -X POST "http://localhost:8080/api/model/compare" \
-H "Content-Type: application/json" \
-d '{"preprocessor_file": "/path/to/other/Preprocessor.in"}'
Returns mesh and stratigraphy differences computed by ModelDiffer.
The comparison dialog in the web viewer allows you to:
Select a second model directory via a file path input
View side-by-side mesh differences (added/removed nodes and elements)
Compare stratigraphy layer structure changes
See summary metrics (node count diff, element count diff, area changes)
Report Export#
The viewer supports exporting diagnostic and summary reports:
HTML report:
GET /api/export/report?format=html— formatted HTML document with model summary, mesh quality, budget summaries, and diagnosticsJSON report:
GET /api/export/report?format=json— machine-readable JSON for programmatic consumption
These endpoints aggregate data from multiple sources into a single downloadable report suitable for review or archiving.
Performance#
The viewer includes optimizations for large models:
Lazy loading: Head data loaded on demand from HDF5
Caching: Node/element ID-to-index mappings, reprojected coordinates, and hydrograph locations computed once and cached in
ModelStateDrawdown pagination:
offset/limit/skipparameters for efficient frame-by-frame animation without loading all timesteps at onceVectorized computation: NumPy-based operations for sub-100ms response
Pre-built frontend: Static React SPA served directly by FastAPI
For C2VSimFG-scale models (~130,000 cells), the viewer remains interactive with these optimizations.
Frontend Development#
The React frontend source is in frontend/. To rebuild:
cd frontend
npm install
npm run build
This compiles TypeScript and builds the SPA to
src/pyiwfm/visualization/webapi/static/.
For development with hot reload:
cd frontend
npm run dev
The Vite dev server proxies /api requests to http://localhost:8080,
so the FastAPI backend must be running separately.