HRRR Dashboard

The High Resolution Rapid Refresh (HRRR, pronouned “her”) is the highest resolution (2.5km) weather forecast for the entire Continental USA. Here we investigate the gridded HRRR forecast data products from Unidata’s THREDDS server and visualizing the data using the holoviz tools.

[1]:
import xarray as xr
[2]:
url = 'http://thredds.ucar.edu/thredds/dodsC/grib/NCEP/HRRR/CONUS_2p5km/Best'
ds = xr.open_dataset(url)

Find all the data variables that depend on time (and are not time bounds)

[3]:
time_vars = []
for var in ds.data_vars:
    if len(ds[var].dims) > 0:
        if 'time' in ds[var].dims[0] and not 'bounds' in var:
            time_vars.append(var)

Read the coordinate reference system (crs) using metpy

[4]:
import metpy
[5]:
init_var = 'Temperature_height_above_ground'
[6]:
ds  = ds.metpy.parse_cf()
[7]:
crs = ds[init_var].metpy.cartopy_crs

Import the holoviz tools we need

[8]:
from cartopy import crs as ccrs
import hvplot.xarray
import holoviews as hv
from geoviews import tile_sources as gvts
import panel as pn

Create widget for variable selection

[9]:
var_select = pn.widgets.Select(name='HRRR Variables:', options=time_vars,
                               value=init_var)

Create widget for basemap selection

[10]:
base_map_select = pn.widgets.Select(name='Basemap:', options=gvts.tile_sources, value=gvts.OSM)

Create a color mesh plot in Lambert Conformal coordinates with hvplot and cartopy

The plot function below creates the hvplot panel layout object. We specify a basemap, pick the quadmesh plot type for the selected variable, and indicate we want to rasterize the plot so that we can render massive meshes in the browser. We also specify the groupby parameter as the list of dimensions that remains after we remove Y and X: ds[var].dims[:-2], which automatically handles variables with either dimensions [T, Y, X] or [T, Z, Y, X]. We also specify which bokeh controls we want to be active by default: the wheel_zoom and pan controls.

We also change the default slider to a selection widget for the time dimension so that specific times are easy to select. See https://stackoverflow.com/a/54912917/2005869

[11]:
@pn.depends(var_select, base_map_select)
def plot(var, base_map):
    extra_dims = list(ds[var].dims[:-2])
    mesh = ds[var].hvplot.quadmesh(x='x', y='y', rasterize=True, crs=crs, title=var,
                                   attr_labels=False, project=True,
                                   groupby=extra_dims, cmap='rainbow',
                                   width=600, height=400).opts(alpha=0.7,
                                   data_aspect=None, active_tools=['wheel_zoom', 'pan'])
    return pn.panel(mesh * base_map, widgets={k: pn.widgets.Select for k in extra_dims})
[12]:
col = pn.Column(var_select, base_map_select, plot)

We use .servable() below not only to display the panel object, but to makes the panel servable outside the notebook via: panel serve HRRR_Dashboard.ipynb

[13]:
col.servable('HRRR Dashboard')
[13]:
[ ]: