#!/usr/bin/env python # coding: utf-8 # # 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](http://thredds.ucar.edu) and visualizing the data using the [holoviz](holoviz.org) tools. # In[1]: import xarray as xr # In[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`) # In[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 # In[4]: import metpy # In[5]: init_var = 'Temperature_height_above_ground' # In[6]: ds = ds.metpy.parse_cf() # In[7]: crs = ds[init_var].metpy.cartopy_crs # Import the [holoviz](https://holoviz.org) tools we need # In[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 # In[9]: var_select = pn.widgets.Select(name='HRRR Variables:', options=time_vars, value=init_var) # Create widget for basemap selection # In[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 # In[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}) # In[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` # In[13]: col.servable('HRRR Dashboard')