ReferenceMaker/ReferenceFileSystem GRIB2/HRRR Example

Requires development version of fsspec_reference_maker

  • pip install --user git+https://github.com/intake/fsspec-reference-maker
In [5]:
import xarray as xr
import hvplot.xarray
import datetime as dt
import dask
import json
import fsspec
from fsspec_reference_maker.grib2 import scan_grib
from fsspec_reference_maker.combine import MultiZarrToZarr
In [2]:
fs = fsspec.filesystem('s3', anon=True, skip_instance_cache=True)
In [3]:
today = dt.datetime.utcnow().strftime('%Y%m%d')
In [4]:
files = fs.glob(f's3://noaa-hrrr-bdp-pds/hrrr.{today}/conus/*wrfsfcf01.grib2')
files
Out[4]:
['noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t00z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t01z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t02z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t03z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t04z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t05z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t06z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t07z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t08z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t09z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t10z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t11z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t12z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t13z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t14z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t15z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t16z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t17z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t18z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t19z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t20z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t21z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf01.grib2']
In [5]:
latest = files[-1].split('/')[3].split('.')[1]
print(latest)
t22z
In [6]:
latest_files = fs.glob(f's3://noaa-hrrr-bdp-pds/hrrr.{today}/conus/hrrr.{latest}.wrfsfc*.grib2')
files.extend(latest_files[2:])
In [7]:
files
Out[7]:
['noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t00z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t01z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t02z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t03z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t04z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t05z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t06z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t07z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t08z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t09z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t10z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t11z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t12z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t13z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t14z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t15z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t16z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t17z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t18z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t19z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t20z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t21z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf01.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf02.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf03.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf04.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf05.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf06.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf07.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf08.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf09.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf10.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf11.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf12.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf13.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf14.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf15.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf16.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf17.grib2',
 'noaa-hrrr-bdp-pds/hrrr.20210901/conus/hrrr.t22z.wrfsfcf18.grib2']

Create Dask gateway cluster with credentials to write to specified S3 bucket

This is for the ESIP qhub: you will need to modify to work elsewhere.

In [8]:
import os
import sys
sys.path.append(os.path.join(os.environ['HOME'],'shared','users','lib'))
import ebdpy as ebd

ebd.set_credentials(profile='esip-qhub')

profile = 'esip-qhub'
region = 'us-west-2'
endpoint = f's3.{region}.amazonaws.com'
ebd.set_credentials(profile=profile, region=region, endpoint=endpoint)
worker_max = 30
client,cluster = ebd.start_dask_cluster(profile=profile,worker_max=worker_max, 
                                      region=region, use_existing_cluster=True,
                                      adaptive_scaling=False, wait_for_cluster=False, 
                                      environment='pangeo', worker_profile='Pangeo Worker', 
                                      propagate_env=True)
/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/dask_gateway/client.py:21: FutureWarning: format_bytes is deprecated and will be removed in a future release. Please use dask.utils.format_bytes instead.
  from distributed.utils import LoopRunner, format_bytes
Existing Dask clusters:
Cluster Index c_idx: 0 / Name: dev.121ab652553e4aa0a3ad2c05a8f601c3 ClusterStatus.RUNNING
Using existing cluster [0].
Setting Fixed Scaling workers=30
Reconnect client to clear cache
client.dashboard_link (for new browser tab/window or dashboard searchbar in Jupyterhub):
https://jupyter.qhub.esipfed.org/gateway/clusters/dev.121ab652553e4aa0a3ad2c05a8f601c3/status
Propagating environment variables to workers

Create reference jsons

In [9]:
afilter={'typeOfLevel': 'heightAboveGround', 'level': 2}    
so = {"anon": True, "default_cache_type": "readahead"}
common = ['time', 'step', 'latitude', 'longitude', 'valid_time']
In [10]:
def gen_json(u):
    date = u.split('/')[3].split('.')[1]
    name = u.split('/')[5].split('.')[1:3]
    outfname = f'{json_dir}{date}.{name[0]}.{name[1]}.json'
    out = scan_grib(u, common, so, inline_threashold=100, filter=afilter)        
    with fs2.open(outfname, "w") as f:
        f.write(json.dumps(out))
In [11]:
json_dir = 's3://esip-qhub/noaa/hrrr/jsons/'
fs2 = fsspec.filesystem('s3', anon=False) 
In [12]:
try:
    fs2.rm(json_dir, recursive=True)
except:
    pass
In [13]:
urls = [f's3://{file}' for file in files]
#so = dict(mode='rb', anon=True, default_fill_cache=False, default_cache_type='first')
In [14]:
%%time
_ = dask.compute(*[dask.delayed(gen_json)(u) for u in urls], retries=10);
CPU times: user 295 ms, sys: 106 ms, total: 401 ms
Wall time: 3min 44s

Use MultiZarrToZarr() to combine into single reference

In [15]:
flist2 = fs2.ls(json_dir)
furls = sorted(['s3://'+f for f in flist2])
print(furls[0])
print(furls[-1])
s3://esip-qhub/noaa/hrrr/jsons/20210901.t00z.wrfsfcf01.json
s3://esip-qhub/noaa/hrrr/jsons/20210901.t22z.wrfsfcf18.json
In [16]:
# mzz = MultiZarrToZarr(furls, 
#     storage_options={'anon':False}, 
#     remote_protocol='s3',
#     remote_options={'anon' : 'True'},   #JSON files  
#     xarray_open_kwargs={
#         'decode_cf' : False,
#         'mask_and_scale' : False,
#         'decode_times' : False,
#         'use_cftime' : False,
#         'drop_variables': ['reference_time', 'crs'],
#         'decode_coords' : False
#     },
#     xarray_concat_args={
# #          "data_vars": "minimal",
# #          "coords": "minimal",
# #          "compat": "override",
#         "join": "override",
#         "combine_attrs": "override",
#         "dim": "time"
#     }
# )
mzz = MultiZarrToZarr(furls, 
            storage_options={'anon':False},
            remote_protocol='s3', 
            remote_options={'anon': True},
            xarray_concat_args={'dim': 'time'})
In [17]:
%%time
#%%prun -D multizarr_profile 
mzz.translate('hrrr_best.json')
CPU times: user 1.45 s, sys: 329 ms, total: 1.78 s
Wall time: 10.3 s
In [18]:
rpath = 's3://esip-qhub-public/noaa/hrrr/hrrr_best.json'
fs2.put_file(lpath='hrrr_best.json', rpath=rpath)

Access data and plot

In [11]:
rpath = 's3://esip-qhub-public/noaa/hrrr/hrrr_best.json'
s_opts = {'requester_pays':True, 'skip_instance_cache':True}
r_opts = {'anon':True}
fs = fsspec.filesystem("reference", fo=rpath, ref_storage_args=s_opts,
                       remote_protocol='s3', remote_options=r_opts)
m = fs.get_mapper("")
ds = xr.open_dataset(m, engine="zarr", backend_kwargs=dict(consolidated=False))
In [14]:
ds
Out[14]:
<xarray.Dataset>
Dimensions:            (y: 1059, x: 1799, time: 40)
Coordinates:
    heightAboveGround  float64 1e+03
    latitude           (y, x) float64 ...
    longitude          (y, x) float64 ...
    step               timedelta64[ns] 01:00:00
  * time               (time) datetime64[us] 2021-09-01 ... 2021-09-01T22:00:00
    valid_time         (time) datetime64[ns] 2021-09-01T01:00:00 ... NaT
Dimensions without coordinates: y, x
Data variables:
    refd               (time, y, x) float32 ...
    si10               (time, y, x) float32 ...
    u                  (time, y, x) float32 ...
    u10                (time, y, x) float32 ...
    unknown            (time, y, x) float32 ...
    v                  (time, y, x) float32 ...
    v10                (time, y, x) float32 ...
Attributes:
    Conventions:             CF-1.7
    GRIB_centre:             kwbc
    GRIB_centreDescription:  US National Weather Service - NCEP 
    GRIB_edition:            2
    GRIB_subCentre:          0
    history:                 2021-09-01T23:54 GRIB to CDM+CF via cfgrib-0.9.9...
    institution:             US National Weather Service - NCEP 
In [17]:
ds.time.values
Out[17]:
array(['2021-09-01T00:00:00.000000', '2021-09-01T01:00:00.000000',
       '2021-09-01T02:00:00.000000', '2021-09-01T03:00:00.000000',
       '2021-09-01T04:00:00.000000', '2021-09-01T05:00:00.000000',
       '2021-09-01T06:00:00.000000', '2021-09-01T07:00:00.000000',
       '2021-09-01T08:00:00.000000', '2021-09-01T09:00:00.000000',
       '2021-09-01T10:00:00.000000', '2021-09-01T11:00:00.000000',
       '2021-09-01T12:00:00.000000', '2021-09-01T13:00:00.000000',
       '2021-09-01T14:00:00.000000', '2021-09-01T15:00:00.000000',
       '2021-09-01T16:00:00.000000', '2021-09-01T17:00:00.000000',
       '2021-09-01T18:00:00.000000', '2021-09-01T19:00:00.000000',
       '2021-09-01T20:00:00.000000', '2021-09-01T21:00:00.000000',
       '2021-09-01T22:00:00.000000', '2021-09-01T22:00:00.000000',
       '2021-09-01T22:00:00.000000', '2021-09-01T22:00:00.000000',
       '2021-09-01T22:00:00.000000', '2021-09-01T22:00:00.000000',
       '2021-09-01T22:00:00.000000', '2021-09-01T22:00:00.000000',
       '2021-09-01T22:00:00.000000', '2021-09-01T22:00:00.000000',
       '2021-09-01T22:00:00.000000', '2021-09-01T22:00:00.000000',
       '2021-09-01T22:00:00.000000', '2021-09-01T22:00:00.000000',
       '2021-09-01T22:00:00.000000', '2021-09-01T22:00:00.000000',
       '2021-09-01T22:00:00.000000', '2021-09-01T22:00:00.000000'],
      dtype='datetime64[us]')
In [18]:
ds.valid_time
Out[18]:
<xarray.DataArray 'valid_time' (time: 40)>
array(['2021-09-01T01:00:00.000000000', '2021-09-01T02:00:00.000000000',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT',
                                 'NaT',                           'NaT'],
      dtype='datetime64[ns]')
Coordinates:
    heightAboveGround  float64 1e+03
    step               timedelta64[ns] 01:00:00
  * time               (time) datetime64[us] 2021-09-01 ... 2021-09-01T22:00:00
    valid_time         (time) datetime64[ns] 2021-09-01T01:00:00 ... NaT
Attributes:
    long_name:      time
    standard_name:  time
In [13]:
ds.u10.hvplot.quadmesh(x='longitude', y='latitude', rasterize=True, geo=True, 
                      tiles='OSM', cmap='turbo')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/IPython/core/formatters.py in __call__(self, obj, include, exclude)
    968 
    969             if method is not None:
--> 970                 return method(include=include, exclude=exclude)
    971             return None
    972         else:

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/holoviews/core/dimension.py in _repr_mimebundle_(self, include, exclude)
   1315         combined and returned.
   1316         """
-> 1317         return Store.render(self)
   1318 
   1319 

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/holoviews/core/options.py in render(cls, obj)
   1403         data, metadata = {}, {}
   1404         for hook in hooks:
-> 1405             ret = hook(obj)
   1406             if ret is None:
   1407                 continue

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/holoviews/ipython/display_hooks.py in pprint_display(obj)
    280     if not ip.display_formatter.formatters['text/plain'].pprint:
    281         return None
--> 282     return display(obj, raw_output=True)
    283 
    284 

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/holoviews/ipython/display_hooks.py in display(obj, raw_output, **kwargs)
    256     elif isinstance(obj, (HoloMap, DynamicMap)):
    257         with option_state(obj):
--> 258             output = map_display(obj)
    259     elif isinstance(obj, Plot):
    260         output = render(obj)

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/holoviews/ipython/display_hooks.py in wrapped(element)
    144         try:
    145             max_frames = OutputSettings.options['max_frames']
--> 146             mimebundle = fn(element, max_frames=max_frames)
    147             if mimebundle is None:
    148                 return {}, {}

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/holoviews/ipython/display_hooks.py in map_display(vmap, max_frames)
    204         return None
    205 
--> 206     return render(vmap)
    207 
    208 

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/holoviews/ipython/display_hooks.py in render(obj, **kwargs)
     66         renderer = renderer.instance(fig='png')
     67 
---> 68     return renderer.components(obj, **kwargs)
     69 
     70 

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/holoviews/plotting/renderer.py in components(self, obj, fmt, comm, **kwargs)
    386             plot = obj
    387         else:
--> 388             plot, fmt = self._validate(obj, fmt)
    389 
    390         data, metadata = {}, {}

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/holoviews/plotting/renderer.py in _validate(self, obj, fmt, **kwargs)
    306 
    307         if fmt in self.widgets:
--> 308             plot = self.get_widget(obj, fmt)
    309             fmt = 'html'
    310         elif dynamic or (self._render_with_panel and fmt == 'html'):

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/holoviews/plotting/renderer.py in get_widget(self_or_cls, plot, widget_type, **kwargs)
    473             widget_location = self_or_cls.widget_location or 'right'
    474 
--> 475         layout = HoloViewsPane(plot, widget_type=widget_type, center=self_or_cls.center,
    476                                widget_location=widget_location, renderer=self_or_cls)
    477         interval = int((1./self_or_cls.fps) * 1000)

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/panel/pane/holoviews.py in __init__(self, object, **params)
     89         self.widget_box = self.widget_layout()
     90         self._widget_container = []
---> 91         self._update_widgets()
     92         self._plots = {}
     93         self.param.watch(self._update_widgets, self._rerender_params)

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/param/parameterized.py in _depends(*args, **kw)
    349     @wraps(func)
    350     def _depends(*args,**kw):
--> 351         return func(*args,**kw)
    352 
    353     deps = list(dependencies)+list(kw.values())

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/panel/pane/holoviews.py in _update_widgets(self, *events)
    157             widgets, values = [], []
    158         else:
--> 159             widgets, values = self.widgets_from_dimensions(
    160                 self.object, self.widgets, self.widget_type)
    161         self._values = values

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/panel/pane/holoviews.py in widgets_from_dimensions(cls, object, widget_types, widgets_type)
    416                 if all(isnumeric(v) or isinstance(v, datetime_types) for v in vals) and len(vals) > 1:
    417                     vals = sorted(vals)
--> 418                     labels = [unicode(dim.pprint_value(v)) for v in vals]
    419                     options = OrderedDict(zip(labels, vals))
    420                     widget_type = widget_type or DiscreteSlider

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/panel/pane/holoviews.py in <listcomp>(.0)
    416                 if all(isnumeric(v) or isinstance(v, datetime_types) for v in vals) and len(vals) > 1:
    417                     vals = sorted(vals)
--> 418                     labels = [unicode(dim.pprint_value(v)) for v in vals]
    419                     options = OrderedDict(zip(labels, vals))
    420                     widget_type = widget_type or DiscreteSlider

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/holoviews/core/dimension.py in pprint_value(self, value, print_unit)
    420                     formatted_value = value.strftime(formatter)
    421                 elif isinstance(value, np.datetime64):
--> 422                     formatted_value = util.dt64_to_dt(value).strftime(formatter)
    423                 elif re.findall(r"\{(\w+)\}", formatter):
    424                     formatted_value = formatter.format(value)

/home/conda/store/3d745bdbbc77faf1b06381a24d6e593eeec3375ed3ddf4003aa2fc578a214eab-pangeo/lib/python3.9/site-packages/holoviews/core/util.py in dt64_to_dt(dt64)
   2012     """
   2013     ts = (dt64 - np.datetime64('1970-01-01T00:00:00')) / np.timedelta64(1, 's')
-> 2014     return dt.datetime(1970,1,1,0,0,0) + dt.timedelta(seconds=ts)
   2015 
   2016 

ValueError: cannot convert float NaN to integer
Out[13]:
:DynamicMap   [time]
In [24]:
client.close(); cluster.shutdown()
In [ ]: