.. _visualization: ************* Visualization ************* TEEHR integrates with HoloViews/hvPlot and GeoViews for interactive visualization of timeseries and spatial data. This section demonstrates common visualization patterns for TEEHR evaluation results. .. note:: This section is under development. Additional examples and interactive visualizations will be added in future releases. Prerequisites ============= TEEHR includes visualization dependencies (installed with the main package): - **HoloViews/hvPlot**: Interactive plotting for timeseries data - **GeoViews**: Geographic visualization with Bokeh backend - **matplotlib**: Static plotting support .. code-block:: python import holoviews as hv import hvplot.pandas import geoviews as gv from bokeh.io import output_notebook # Enable notebook output hv.extension('bokeh') output_notebook() Basic Timeseries Plot ===================== Plot observed vs. simulated timeseries for a single location: .. code-block:: python import teehr import hvplot.pandas ev = teehr.LocalReadWriteEvaluation(dir_path="/path/to/evaluation") # Get joined timeseries for a specific location df = ev.joined_timeseries_view().filter( "primary_location_id = 'usgs-01184000'" ).to_pandas() # Plot primary (observed) vs secondary (simulated) plot = df.hvplot.line( x='value_time', y=['primary_value', 'secondary_value'], title='Streamflow: Observed vs. Simulated', xlabel='Time', ylabel='Streamflow (cfs)', legend='top', width=800, height=400 ) plot Forecast Timeseries ------------------- Plot ensemble forecast with spread: .. code-block:: python # Filter for forecast data with multiple members df = ev.secondary_timeseries.filter( "configuration_name = 'nwm30_medium_range'", "primary_location_id = 'usgs-01184000'" ).to_pandas() # Plot ensemble members plot = df.hvplot.line( x='value_time', y='value', by='reference_time', title='Ensemble Forecast', xlabel='Time', ylabel='Streamflow (cfs)', width=800, height=400 ) plot Basic Map ========= Display locations with attributes: .. code-block:: python import geoviews as gv import geoviews.tile_sources as gts gv.extension('bokeh') ev = teehr.LocalReadWriteEvaluation(dir_path="/path/to/evaluation") # Get locations as GeoDataFrame gdf = ev.locations.to_geopandas() # Create point layer points = gv.Points(gdf).opts( size=8, color='blue', tools=['hover'], ) # Add basemap tiles tiles = gts.OSM # Combine layers map_plot = tiles * points map_plot.opts(width=700, height=500, title='Evaluation Locations') Metrics on a Map ================ Visualize performance metrics spatially: .. code-block:: python import geoviews as gv from bokeh.palettes import RdYlGn11 ev = teehr.LocalReadWriteEvaluation(dir_path="/path/to/evaluation") # Calculate metrics with geometry from teehr.metrics import DeterministicMetrics metrics_gdf = ev.joined_timeseries_view().aggregate( metrics=[DeterministicMetrics.KlingGuptaEfficiency()], group_by=["primary_location_id"], ).to_geopandas() # Create colored points based on KGE points = gv.Points( metrics_gdf, kdims=['geometry'], vdims=['kling_gupta_efficiency', 'primary_location_id'] ).opts( size=10, color='kling_gupta_efficiency', cmap='RdYlGn', clim=(0, 1), colorbar=True, tools=['hover'], ) # Add basemap tiles = gv.tile_sources.OSM map_plot = tiles * points map_plot.opts( width=700, height=500, title='Kling-Gupta Efficiency by Location' ) Hydrograph Comparison ===================== Compare observed and simulated hydrographs with metrics overlay: .. code-block:: python import holoviews as hv import hvplot.pandas ev = teehr.LocalReadWriteEvaluation(dir_path="/path/to/evaluation") # Get timeseries df = ev.joined_timeseries_view().filter( "primary_location_id = 'usgs-01184000'", "configuration_name = 'nwm30_retrospective'" ).to_pandas() # Calculate metrics from teehr.metrics import DeterministicMetrics metrics = ev.joined_timeseries_view().filter( "primary_location_id = 'usgs-01184000'", "configuration_name = 'nwm30_retrospective'" ).aggregate( metrics=[ DeterministicMetrics.KlingGuptaEfficiency(), DeterministicMetrics.NashSutcliffeEfficiency(), ], group_by=["primary_location_id"] ).to_pandas() kge = metrics['kling_gupta_efficiency'].values[0] nse = metrics['nash_sutcliffe_efficiency'].values[0] # Create hydrograph plot obs_line = df.hvplot.line( x='value_time', y='primary_value', label='Observed', color='blue', line_width=1.5 ) sim_line = df.hvplot.line( x='value_time', y='secondary_value', label='Simulated', color='red', line_width=1.5, alpha=0.7 ) # Add metrics as text annotation title = f'Hydrograph Comparison | KGE: {kge:.3f}, NSE: {nse:.3f}' plot = (obs_line * sim_line).opts( title=title, xlabel='Time', ylabel='Streamflow (cfs)', legend_position='top_right', width=900, height=400 ) plot Additional Resources ==================== For more visualization examples, see: - `HoloViews Documentation `_ - `hvPlot Documentation `_ - `GeoViews Documentation `_ Example notebooks demonstrating TEEHR visualizations are available in the :ref:`example_notebooks_index` section.