holoviz-topics / EarthSim

Tools for working with and visualizing environmental simulations.
https://earthsim.holoviz.org
BSD 3-Clause "New" or "Revised" License
65 stars 21 forks source link

PolyAnnotator should accept element not just data #133

Closed philippjfr closed 6 years ago

philippjfr commented 6 years ago

The PolyAnnotator and PointAnnotator classes accept polys and points but currently those are expected to be the raw data. These should also accept actual elements containing the desired data.

kcpevey commented 6 years ago

I think this is the same issue, but since I demoed it during a call I'm not sure.

Reproducible example:

data_df = pd.read_csv('hurricane_data.txt', sep=',', header=0, skipinitialspace=True)
p = gv.Path([data_df], kdims=['Longitude', 'Latitude'], vdims=['Pressure','Max_Wind_Speed'], crs=ccrs.PlateCarree())
print(type(p))
annot = PolyAndPointAnnotator(path_type=Path, polys=p, tile_url='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}')

hurricane_data.txt

Error traceback:


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\pandas\core\indexes\base.py in get_value(self, series, key)
   3123             try:
-> 3124                 return libindex.get_value_box(s, key)
   3125             except IndexError:

pandas/_libs/index.pyx in pandas._libs.index.get_value_box()

pandas/_libs/index.pyx in pandas._libs.index.get_value_box()

TypeError: 'str' object cannot be interpreted as an integer

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
<ipython-input-2-d7dd2b63e208> in <module>()
      2 p = gv.Path([data_df], kdims=['Longitude', 'Latitude'], vdims=['Pressure','Max_Wind_Speed'], crs=ccrs.PlateCarree())
      3 print(type(p))
----> 4 annot = PolyAndPointAnnotator(path_type=Path, polys=p, tile_url='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}')

c:\projects\ers\github\earthsim_pyviz\master\earthsim\earthsim\annotators.py in __init__(self, poly_data, **params)
    195         self.polys.interface = GeoPandasInterface
    196         if len(self.polys):
--> 197             poly_data = gv.project(self.polys).split()
    198             self.poly_stream.event(data={kd.name: [p.dimension_values(kd) for p in poly_data]
    199                                          for kd in self.polys.kdims})

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\param\parameterized.py in __new__(class_, *args, **params)
   2029         inst = class_.instance()
   2030         inst.param._set_name(class_.__name__)
-> 2031         return inst.__call__(*args,**params)
   2032 
   2033     def __call__(self,*args,**kw):

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\holoviews\core\operation.py in __call__(self, element, **params)
    161                                 operation=self, kwargs=params)
    162         elif isinstance(element, ViewableElement):
--> 163             processed = self._apply(element)
    164         elif isinstance(element, DynamicMap):
    165             if any((not d.values) for d in element.kdims):

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\holoviews\core\operation.py in _apply(self, element, key)
    119         for hook in self._preprocess_hooks:
    120             kwargs.update(hook(self, element))
--> 121         ret = self._process(element, key)
    122         for hook in self._postprocess_hooks:
    123             ret = hook(self, ret, **kwargs)

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\geoviews\operation\projection.py in _process(self, element, key)
    408         for op in self._operations:
    409             element = element.map(op.instance(projection=self.p.projection),
--> 410                                   op.supported_types)
    411         return element

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\holoviews\core\dimension.py in map(self, map_fn, specs, clone)
    727             return deep_mapped
    728         else:
--> 729             return map_fn(self) if applies else self
    730 
    731 

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\holoviews\core\operation.py in __call__(self, element, **params)
    161                                 operation=self, kwargs=params)
    162         elif isinstance(element, ViewableElement):
--> 163             processed = self._apply(element)
    164         elif isinstance(element, DynamicMap):
    165             if any((not d.values) for d in element.kdims):

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\holoviews\core\operation.py in _apply(self, element, key)
    119         for hook in self._preprocess_hooks:
    120             kwargs.update(hook(self, element))
--> 121         ret = self._process(element, key)
    122         for hook in self._postprocess_hooks:
    123             ret = hook(self, ret, **kwargs)

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\geoviews\operation\projection.py in _process(self, element, key)
     32 
     33     def _process(self, element, key=None):
---> 34         return element.map(self._process_element, self.supported_types)
     35 
     36 

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\holoviews\core\dimension.py in map(self, map_fn, specs, clone)
    727             return deep_mapped
    728         else:
--> 729             return map_fn(self) if applies else self
    730 
    731 

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\geoviews\operation\projection.py in _process_element(self, element)
    129             return element.clone(crs=self.p.projection)
    130         elif element.interface.datatype == 'geodataframe':
--> 131             return self._project_geodataframe(element)
    132 
    133         boundary = element.crs.project_geometry(Polygon(self.p.projection.boundary),

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\geoviews\operation\projection.py in _project_geodataframe(self, element)
    118 
    119     def _project_geodataframe(self, element):
--> 120         geoms = element.split(datatype='geom')
    121         projected = [self.p.projection.project_geometry(geom, element.crs)
    122                      for geom in geoms]

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\holoviews\element\path.py in split(self, start, end, datatype, **kwargs)
    119                 raise ValueError("%s datatype not support" % datatype)
    120             return [obj]
--> 121         return self.interface.split(self, start, end, datatype, **kwargs)
    122 
    123 

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\geoviews\data\geopandas.py in split(cls, dataset, start, end, datatype, **kwargs)
    156         arr = geom_to_array(row['geometry'])
    157         d = {(xdim.name, ydim.name): arr}
--> 158         d.update({vd.name: row[vd.name] for vd in dataset.vdims})
    159         ds = dataset.clone(d, datatype=['dictionary'])
    160         for i, row in dataset.data.iterrows():

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\geoviews\data\geopandas.py in <dictcomp>(.0)
    156         arr = geom_to_array(row['geometry'])
    157         d = {(xdim.name, ydim.name): arr}
--> 158         d.update({vd.name: row[vd.name] for vd in dataset.vdims})
    159         ds = dataset.clone(d, datatype=['dictionary'])
    160         for i, row in dataset.data.iterrows():

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\pandas\core\series.py in __getitem__(self, key)
    765         key = com._apply_if_callable(key, self)
    766         try:
--> 767             result = self.index.get_value(self, key)
    768 
    769             if not is_scalar(result):

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\pandas\core\indexes\base.py in get_value(self, series, key)
   3130                     raise InvalidIndexError(key)
   3131                 else:
-> 3132                     raise e1
   3133             except Exception:  # pragma: no cover
   3134                 raise e1

C:\ProgramData\Anaconda3\envs\earthsim\lib\site-packages\pandas\core\indexes\base.py in get_value(self, series, key)
   3116         try:
   3117             return self._engine.get_value(s, k,
-> 3118                                           tz=getattr(series.dtype, 'tz', None))
   3119         except KeyError as e1:
   3120             if len(self) > 0 and self.inferred_type in ['integer', 'boolean']:

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

KeyError: 'Pressure'
```​
kcpevey commented 6 years ago

I'm still getting the traceback above.

I also tried to change polys=p to polys=[p] since it seems like sometimes I have to do that, but that gave me the dreaded:
DataError: None of the available storage backends were able to support the supplied data format.
aka the bane of my existence.

@philippjfr Any idea what I'm doing wrong?

kcpevey commented 6 years ago

@philippjfr I'm still struggling with getting this to work and its on my critical path.

The above snippet now doesn't give an error, but if you try to visualize that annot, it throws another error that I can't seem to get around no matter how I specify things. New snippet and traceback:

data_df = pd.read_csv(input_param.hurricane_path_file, sep=',', header=0, skipinitialspace=True)
p = gv.Path([data_df], kdims=['Longitude', 'Latitude'], vdims=['Pressure','Max_Wind_Speed'], crs=proj)
annot = PolyAndPointAnnotator(path_type=Path, polys=p, tile_url='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}')
annot.tiles * annot.polys * annot.points
---------------------------------------------------------------------------
DataError                                 Traceback (most recent call last)
C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\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:

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\dimension.py in _repr_mimebundle_(self, include, exclude)
   1263         combined and returned.
   1264         """
-> 1265         return Store.render(self)
   1266 
   1267 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\options.py in render(cls, obj)
   1287         data, metadata = {}, {}
   1288         for hook in hooks:
-> 1289             ret = hook(obj)
   1290             if ret is None:
   1291                 continue

c:\projects\ers\github\holoviews\master\holoviews\holoviews\ipython\display_hooks.py in pprint_display(obj)
    270     if not ip.display_formatter.formatters['text/plain'].pprint:
    271         return None
--> 272     return display(obj, raw_output=True)
    273 
    274 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\ipython\display_hooks.py in display(obj, raw_output, **kwargs)
    240     elif isinstance(obj, (CompositeOverlay, ViewableElement)):
    241         with option_state(obj):
--> 242             output = element_display(obj)
    243     elif isinstance(obj, (Layout, NdLayout, AdjointLayout)):
    244         with option_state(obj):

c:\projects\ers\github\holoviews\master\holoviews\holoviews\ipython\display_hooks.py in wrapped(element)
    140         try:
    141             max_frames = OutputSettings.options['max_frames']
--> 142             mimebundle = fn(element, max_frames=max_frames)
    143             if mimebundle is None:
    144                 return {}, {}

c:\projects\ers\github\holoviews\master\holoviews\holoviews\ipython\display_hooks.py in element_display(element, max_frames)
    186         return None
    187 
--> 188     return render(element)
    189 
    190 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\ipython\display_hooks.py in render(obj, **kwargs)
     63         renderer = renderer.instance(fig='png')
     64 
---> 65     return renderer.components(obj, **kwargs)
     66 
     67 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\bokeh\renderer.py in components(self, obj, fmt, comm, **kwargs)
    268         # Bokeh has to handle comms directly in <0.12.15
    269         comm = False if bokeh_version < '0.12.15' else comm
--> 270         return super(BokehRenderer, self).components(obj,fmt, comm, **kwargs)
    271 
    272 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\renderer.py in components(self, obj, fmt, comm, **kwargs)
    327             plot = obj
    328         else:
--> 329             plot, fmt = self._validate(obj, fmt)
    330 
    331         widget_id = None

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\renderer.py in _validate(self, obj, fmt, **kwargs)
    226         if isinstance(obj, tuple(self.widgets.values())):
    227             return obj, 'html'
--> 228         plot = self.get_plot(obj, renderer=self, **kwargs)
    229 
    230         fig_formats = self.mode_formats['fig'][self.mode]

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\bokeh\renderer.py in get_plot(self_or_cls, obj, doc, renderer)
    153             curdoc().theme = self_or_cls.theme
    154         doc.theme = self_or_cls.theme
--> 155         plot = super(BokehRenderer, self_or_cls).get_plot(obj, renderer)
    156         plot.document = doc
    157         return plot

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\renderer.py in get_plot(self_or_cls, obj, renderer)
    213             init_key = tuple(v if d is None else d for v, d in
    214                              zip(plot.keys[0], defaults))
--> 215             plot.update(init_key)
    216         else:
    217             plot = obj

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\plot.py in update(self, key)
    511     def update(self, key):
    512         if len(self) == 1 and ((key == 0) or (key == self.keys[0])) and not self.drawn:
--> 513             return self.initialize_plot()
    514         item = self.__getitem__(key)
    515         self.traverse(lambda x: setattr(x, '_updated', True))

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews\plotting\bokeh\plot.py in initialize_plot(self, ranges, plot, plots, source)
     82     def initialize_plot(self, ranges=None, plot=None, plots=None, source=None):
     83         opts = {} if isinstance(self, HvOverlayPlot) else {'source': source}
---> 84         fig = super(GeoPlot, self).initialize_plot(ranges, plot, plots, **opts)
     85         if self.geographic and self.show_bounds and not self.overlaid:
     86             from . import GeoShapePlot

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\bokeh\element.py in initialize_plot(self, ranges, plot, plots)
   1423             if self.tabs:
   1424                 subplot.overlaid = False
-> 1425             child = subplot.initialize_plot(ranges, plot, plots)
   1426             if isinstance(element, CompositeOverlay):
   1427                 frame = element.get(key, None)

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews\plotting\bokeh\plot.py in initialize_plot(self, ranges, plot, plots, source)
     82     def initialize_plot(self, ranges=None, plot=None, plots=None, source=None):
     83         opts = {} if isinstance(self, HvOverlayPlot) else {'source': source}
---> 84         fig = super(GeoPlot, self).initialize_plot(ranges, plot, plots, **opts)
     85         if self.geographic and self.show_bounds and not self.overlaid:
     86             from . import GeoShapePlot

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\bokeh\element.py in initialize_plot(self, ranges, plot, plots, source)
    735 
    736         for cb in self.callbacks:
--> 737             cb.initialize()
    738 
    739         if not self.overlaid:

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\bokeh\callbacks.py in initialize(self, plot_id)
    895                                  **kwargs)
    896         plot.state.tools.append(poly_tool)
--> 897         super(PolyDrawCallback, self).initialize(plot_id)
    898 
    899 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\bokeh\callbacks.py in initialize(self, plot_id)
    809         super(CDSCallback, self).initialize(plot_id)
    810         plot = self.plot
--> 811         data = self._process_msg({'data': plot.handles['source'].data})['data']
    812         for stream in self.streams:
    813             stream.update(data=data)

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews\plotting\bokeh\callbacks.py in _process_msg(self, msg)
    209         if not msg['data']:
    210             return msg
--> 211         projected = project_drawn(self, msg)
    212         if projected is None:
    213             return msg

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews\plotting\bokeh\callbacks.py in project_drawn(cb, msg)
     82     old_data = stream.data
     83     stream.update(data=msg['data'])
---> 84     element = stream.element
     85     stream.update(data=old_data)
     86     proj = cb.plot.projection

c:\projects\ers\github\holoviews\master\holoviews\holoviews\streams.py in element(self)
    919         data = [{lookup.get(c, c): data[c][i] for c in self.data}
    920                 for i in range(len(data[cols[0]]))]
--> 921         return source.clone(data)
    922 
    923     @property

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews\element\geo.py in clone(self, data, shared_data, new_type, *args, **overrides)
    101             overrides['crs'] = self.crs
    102         return super(_Element, self).clone(data, shared_data, new_type,
--> 103                                            *args, **overrides)
    104 
    105 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\data\__init__.py in clone(self, data, shared_data, new_type, *args, **overrides)
    672             datatypes = [self.interface.datatype] + self.datatype
    673             overrides['datatype'] = list(unique_iterator(datatypes))
--> 674         return super(Dataset, self).clone(data, shared_data, new_type, *args, **overrides)
    675 
    676 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\dimension.py in clone(self, data, shared_data, new_type, *args, **overrides)
    629         # Apply name mangling for __ attribute
    630         pos_args = getattr(self, '_' + type(self).__name__ + '__pos_params', [])
--> 631         return clone_type(data, *args, **{k:v for k,v in settings.items()
    632                                           if k not in pos_args})
    633 

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews\element\geo.py in __init__(self, data, kdims, vdims, **kwargs)
     93         elif crs:
     94             kwargs['crs'] = crs
---> 95         super(_Element, self).__init__(data, kdims=kdims, vdims=vdims, **kwargs)
     96 
     97 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\element\path.py in __init__(self, data, kdims, vdims, **params)
     57         elif isinstance(data, list) and all(isinstance(path, Path) for path in data):
     58             data = [p for path in data for p in path.data]
---> 59         super(Path, self).__init__(data, kdims=kdims, vdims=vdims, **params)
     60 
     61     def __setstate__(self, state):

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\data\__init__.py in __init__(self, data, kdims, vdims, **kwargs)
    232         (data, self.interface, dims, extra_kws) = initialized
    233         super(Dataset, self).__init__(data, **dict(kwargs, **dict(dims, **extra_kws)))
--> 234         self.interface.validate(self, validate_vdims)
    235 
    236         self.redim = redim(self, mode='dataset')

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\data\multipath.py in validate(cls, dataset, vdims)
     55         if not dataset.data:
     56             return
---> 57         ds = cls._inner_dataset_template(dataset)
     58         for d in dataset.data:
     59             ds.data = d

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\data\multipath.py in _inner_dataset_template(cls, dataset)
     70         vdims = dataset.vdims if getattr(dataset, 'level', None) is None else []
     71         return Dataset(dataset.data[0], datatype=cls.subtypes,
---> 72                        kdims=dataset.kdims, vdims=vdims)
     73 
     74     @classmethod

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\data\__init__.py in __init__(self, data, kdims, vdims, **kwargs)
    232         (data, self.interface, dims, extra_kws) = initialized
    233         super(Dataset, self).__init__(data, **dict(kwargs, **dict(dims, **extra_kws)))
--> 234         self.interface.validate(self, validate_vdims)
    235 
    236         self.redim = redim(self, mode='dataset')

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\data\dictionary.py in validate(cls, dataset, vdims)
    121         if not_found:
    122             raise DataError('Following columns specified as dimensions '
--> 123                             'but not found in data: %s' % not_found, cls)
    124         lengths = [(dim, 1 if isscalar(dataset.data[dim]) else len(dataset.data[dim]))
    125                    for dim in dimensions]

DataError: Following columns specified as dimensions but not found in data: ['Pressure', 'Max_Wind_Speed']

DictInterface expects tabular data, for more information on supported datatypes see http://holoviews.org/user_guide/Tabular_Datasets.html

:Overlay
   .WMTS.I   :WMTS   [Longitude,Latitude]
   .Path.I   :Path   [Longitude,Latitude]   (Pressure,Max_Wind_Speed)
   .Points.I :Points   [Longitude,Latitude]   (Size)

I don't understand DataError: Following columns specified as dimensions but not found in data: ['Pressure', 'Max_Wind_Speed'] because those are clearly specified and interpreted by gv.

philippjfr commented 6 years ago

I don't understand DataError: Following columns specified as dimensions but not found in data: ['Pressure', 'Max_Wind_Speed'] because those are clearly specified and interpreted by gv.

Are those already columns in data_df? I'll have a look at this now.

kcpevey commented 6 years ago

Yes, they are columns in the hurricane_data.txt so they get loaded in as column labels in data_df

philippjfr commented 6 years ago

Okay thanks, definitely a bizarre error then.

kcpevey commented 6 years ago

I'll also point out that the text file has commas followed by a space in the header line but even with the extra spaces removed, it gives the same error.

kcpevey commented 6 years ago

This snippet (adapted from above) now works.

proj = ccrs.PlateCarree()
data_df = pd.read_csv(input_param.hurricane_path_file, sep=',', header=0, skipinitialspace=True)
gvpath = gv.Path([data_df], kdims=['Longitude', 'Latitude'], vdims=['Pressure','Max_Wind_Speed'], crs=proj)
gvpoint = gv.Points(data_df, kdims=['Longitude', 'Latitude'], vdims=['Pressure','Max_Wind_Speed'], crs=proj)

annot = PolyAndPointAnnotator(path_type=Path, polys=[gvpath], poly_columns=['Pressure', 'Max_Wind_Speed'], points=gvpoint,
                              tile_url='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}',
                              crs=proj)
annot.tiles * annot.polys * annot.points  

However, its throwing an error when I try to add a colorbar to the path. Adding a colorbar to the points works just fine. I'm adding the colorbar like this:

%%opts Points (size=10, cmap=colors) [color_index='Max_Wind_Speed', color_levels=levels, colorbar=True]
%%opts Path (line_width=2, cmap=colors) [color_index='Max_Wind_Speed', color_levels=levels, colorbar=True]

With these levels and colors:

levels = [0, 38, 73, 95, 110, 130, 156, 999]
colors = ['#5ebaff', '#00faf4', '#ffffcc', '#ffe775', '#ffc140', '#ff8f20', '#ff6060']

The error:

BokehUserWarning: ColumnDataSource's columns must be of the same length. Current lengths: ('Max_Wind_Speed', 5), ('Pressure', 1), ('xs', 5), ('ys', 5)
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\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:

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\dimension.py in _repr_mimebundle_(self, include, exclude)
   1263         combined and returned.
   1264         """
-> 1265         return Store.render(self)
   1266 
   1267 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\options.py in render(cls, obj)
   1287         data, metadata = {}, {}
   1288         for hook in hooks:
-> 1289             ret = hook(obj)
   1290             if ret is None:
   1291                 continue

c:\projects\ers\github\holoviews\master\holoviews\holoviews\ipython\display_hooks.py in pprint_display(obj)
    270     if not ip.display_formatter.formatters['text/plain'].pprint:
    271         return None
--> 272     return display(obj, raw_output=True)
    273 
    274 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\ipython\display_hooks.py in display(obj, raw_output, **kwargs)
    240     elif isinstance(obj, (CompositeOverlay, ViewableElement)):
    241         with option_state(obj):
--> 242             output = element_display(obj)
    243     elif isinstance(obj, (Layout, NdLayout, AdjointLayout)):
    244         with option_state(obj):

c:\projects\ers\github\holoviews\master\holoviews\holoviews\ipython\display_hooks.py in wrapped(element)
    140         try:
    141             max_frames = OutputSettings.options['max_frames']
--> 142             mimebundle = fn(element, max_frames=max_frames)
    143             if mimebundle is None:
    144                 return {}, {}

c:\projects\ers\github\holoviews\master\holoviews\holoviews\ipython\display_hooks.py in element_display(element, max_frames)
    186         return None
    187 
--> 188     return render(element)
    189 
    190 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\ipython\display_hooks.py in render(obj, **kwargs)
     63         renderer = renderer.instance(fig='png')
     64 
---> 65     return renderer.components(obj, **kwargs)
     66 
     67 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\bokeh\renderer.py in components(self, obj, fmt, comm, **kwargs)
    268         # Bokeh has to handle comms directly in <0.12.15
    269         comm = False if bokeh_version < '0.12.15' else comm
--> 270         return super(BokehRenderer, self).components(obj,fmt, comm, **kwargs)
    271 
    272 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\renderer.py in components(self, obj, fmt, comm, **kwargs)
    314             plot = obj
    315         else:
--> 316             plot, fmt = self._validate(obj, fmt)
    317 
    318         widget_id = None

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\renderer.py in _validate(self, obj, fmt, **kwargs)
    213         if isinstance(obj, tuple(self.widgets.values())):
    214             return obj, 'html'
--> 215         plot = self.get_plot(obj, renderer=self, **kwargs)
    216 
    217         fig_formats = self.mode_formats['fig'][self.mode]

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\bokeh\renderer.py in get_plot(self_or_cls, obj, doc, renderer)
    153             curdoc().theme = self_or_cls.theme
    154         doc.theme = self_or_cls.theme
--> 155         plot = super(BokehRenderer, self_or_cls).get_plot(obj, renderer)
    156         plot.document = doc
    157         return plot

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\renderer.py in get_plot(self_or_cls, obj, renderer)
    200             init_key = tuple(v if d is None else d for v, d in
    201                              zip(plot.keys[0], defaults))
--> 202             plot.update(init_key)
    203         else:
    204             plot = obj

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\plot.py in update(self, key)
    513     def update(self, key):
    514         if len(self) == 1 and ((key == 0) or (key == self.keys[0])) and not self.drawn:
--> 515             return self.initialize_plot()
    516         item = self.__getitem__(key)
    517         self.traverse(lambda x: setattr(x, '_updated', True))

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews-1.5.4a6-py3.6.egg\geoviews\plotting\bokeh\plot.py in initialize_plot(self, ranges, plot, plots, source)
     82     def initialize_plot(self, ranges=None, plot=None, plots=None, source=None):
     83         opts = {} if isinstance(self, HvOverlayPlot) else {'source': source}
---> 84         fig = super(GeoPlot, self).initialize_plot(ranges, plot, plots, **opts)
     85         if self.geographic and self.show_bounds and not self.overlaid:
     86             from . import GeoShapePlot

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\bokeh\element.py in initialize_plot(self, ranges, plot, plots)
   1423             if self.tabs:
   1424                 subplot.overlaid = False
-> 1425             child = subplot.initialize_plot(ranges, plot, plots)
   1426             if isinstance(element, CompositeOverlay):
   1427                 frame = element.get(key, None)

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews-1.5.4a6-py3.6.egg\geoviews\plotting\bokeh\plot.py in initialize_plot(self, ranges, plot, plots, source)
     82     def initialize_plot(self, ranges=None, plot=None, plots=None, source=None):
     83         opts = {} if isinstance(self, HvOverlayPlot) else {'source': source}
---> 84         fig = super(GeoPlot, self).initialize_plot(ranges, plot, plots, **opts)
     85         if self.geographic and self.show_bounds and not self.overlaid:
     86             from . import GeoShapePlot

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\bokeh\element.py in initialize_plot(self, ranges, plot, plots, source)
    735 
    736         for cb in self.callbacks:
--> 737             cb.initialize()
    738 
    739         if not self.overlaid:

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\bokeh\callbacks.py in initialize(self, plot_id)
    903         plot.state.tools.append(poly_tool)
    904         self._update_cds_vdims()
--> 905         super(PolyDrawCallback, self).initialize(plot_id)
    906 
    907     def _update_cds_vdims(self):

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\bokeh\callbacks.py in initialize(self, plot_id)
    816         super(CDSCallback, self).initialize(plot_id)
    817         plot = self.plot
--> 818         data = self._process_msg({'data': plot.handles['source'].data})['data']
    819         for stream in self.streams:
    820             stream.update(data=data)

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews-1.5.4a6-py3.6.egg\geoviews\plotting\bokeh\callbacks.py in _process_msg(self, msg)
    224     def _process_msg(self, msg):
    225         msg = super(GeoPolyDrawCallback, self)._process_msg(msg)
--> 226         return project_poly(self, msg)
    227 
    228     def _update_cds_vdims(self):

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews-1.5.4a6-py3.6.egg\geoviews\plotting\bokeh\callbacks.py in project_poly(cb, msg)
     96     if not msg['data']:
     97         return msg
---> 98     projected = project_drawn(cb, msg)
     99     if projected is None:
    100         return msg

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews-1.5.4a6-py3.6.egg\geoviews\plotting\bokeh\callbacks.py in project_drawn(cb, msg)
     83     old_data = stream.data
     84     stream.update(data=msg['data'])
---> 85     element = stream.element
     86     stream.update(data=old_data)
     87     proj = cb.plot.projection

c:\projects\ers\github\holoviews\master\holoviews\holoviews\streams.py in element(self)
    973         lookup = {'xs': x.name, 'ys': y.name}
    974         data = [{lookup.get(c, c): data[c][i] for c in self.data}
--> 975                 for i in range(len(data[cols[0]]))]
    976         return source.clone(data)
    977 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\streams.py in <listcomp>(.0)
    973         lookup = {'xs': x.name, 'ys': y.name}
    974         data = [{lookup.get(c, c): data[c][i] for c in self.data}
--> 975                 for i in range(len(data[cols[0]]))]
    976         return source.clone(data)
    977 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\streams.py in <dictcomp>(.0)
    972         x, y = source.kdims
    973         lookup = {'xs': x.name, 'ys': y.name}
--> 974         data = [{lookup.get(c, c): data[c][i] for c in self.data}
    975                 for i in range(len(data[cols[0]]))]
    976         return source.clone(data)

IndexError: list index out of range
:Overlay
   .WMTS.I   :WMTS   [Longitude,Latitude]
   .Path.I   :Path   [Longitude,Latitude]   (Pressure,Max_Wind_Speed)
   .Points.I :Points   [Longitude,Latitude]   (Size,Pressure,Max_Wind_Speed)

Note that the Pressure variables all contain 5 values so I don't understand why its not seeing them.

philippjfr commented 6 years ago

@kcpevey I've identified the issue now and have a fix, unfortunately when I try to generate synthetic data I run into another issue first. Is there any chance you could send me the hurricane data you were working with?

philippjfr commented 6 years ago

Another issue I've identified, when you're constructing an annotator with an existing element there is no need to wrap the data in a list, so it should be something like this:

tile_url = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}'
annot = PolyAndPointAnnotator(polys=gvpath, poly_columns=['Pressure', 'Max_Wind_Speed'], points=gvpoint, tile_url=tile_url)
philippjfr commented 6 years ago

Here's the PR with the immediate fix for the bug, if you could try it out before we release a new holoviews dev version that would be very helpful: https://github.com/ioam/holoviews/pull/2990

kcpevey commented 6 years ago

input_param.hurricane_path_file = 'hurricane_path.txt'

hurricane_path.txt

kcpevey commented 6 years ago

I'll try out your PR now.

philippjfr commented 6 years ago

Do you have a file with more than two datapoints? The colorbar seemingly doesn't like having a zero range.

philippjfr commented 6 years ago

I'll try fixing that as well before releasing a new dev version.

kcpevey commented 6 years ago

With the PR, it doesn't throw an error, but the cell is completely empty -no plot, not even lots of whitespace. I'm using the code from above:

%%opts Points (size=10, cmap=colors) [color_index='Max_Wind_Speed', color_levels=levels, colorbar=True]
%%opts Path (line_width=2, cmap=colors) [color_index='Max_Wind_Speed', color_levels=levels, colorbar=True]

proj = proj_widget.get_crs()
data_df = pd.read_csv('../../data/hurricane_path.txt', sep=',', header=0, skipinitialspace=True)
gvpath = gv.Path([data_df], kdims=['Longitude', 'Latitude'], vdims=['Pressure','Max_Wind_Speed'], crs=proj)
gvpoint = gv.Points(data_df, kdims=['Longitude', 'Latitude'], vdims=['Pressure','Max_Wind_Speed'], crs=proj)

annot = PolyAndPointAnnotator(path_type=Path, polys=gvpath, poly_columns=['Pressure', 'Max_Wind_Speed'], points=gvpoint,
                              tile_url='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}',
                              crs=proj)
annot.tiles * annot.polys * annot.points 

Same thing happens with more data points - new file: hurricane_path.txt

philippjfr commented 6 years ago

That's what I was referring to when I said the colorbar doesn't like having a zero range, try disabling it while I fix that issue as well.

kcpevey commented 6 years ago

Oops: proj = ccrs.PlateCarree()

kcpevey commented 6 years ago

colorbar=False creates this: color_path

No path exists at all and the points are all colored white.

philippjfr commented 6 years ago

About to push another fix.

philippjfr commented 6 years ago

Okay, just pushed to the same holoviews PR, mind trying again?

kcpevey commented 6 years ago

yep.

philippjfr commented 6 years ago

Okay, last commit had a small bug causing the wrong range to be used, should be fixed now.

kcpevey commented 6 years ago

saw that, trying it again.

philippjfr commented 6 years ago

Here's what I see now:

screen shot 2018-09-07 at 3 14 20 pm
kcpevey commented 6 years ago

yes, I'm seeing the same thing with the snippet and file I gave you. First - that colorbar is wrong. it doesn't match the colors and levels that I specified.

kcpevey commented 6 years ago

If you use this file instead (which has better variance on the max wind speed variable) hurricane_path_color.txt

Then I get this error:

---------------------------------------------------------------------------
DataError                                 Traceback (most recent call last)
<ipython-input-5-ce4e5ab1a70f> in <module>()
      7 annot = PolyAndPointAnnotator(path_type=Path, polys=gvpath, poly_columns=['Pressure', 'Max_Wind_Speed'], points=gvpoint,
      8                               tile_url='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}',
----> 9                               crs=proj)
     10 annot.tiles * annot.polys * annot.points

c:\projects\ers\github\earthsim\master\earthsim\earthsim\annotators.py in __init__(self, poly_data, **params)
    205 
    206         poly_data = {c: self.polys.dimension_values(c, expanded=False) for c in self.poly_columns}
--> 207         self.poly_table = Table(poly_data, self.poly_columns, []).opts(plot=plot, style=style)
    208         self.poly_link = DataLink(source=self.polys, target=self.poly_table)
    209         self.vertex_table = Table([], self.polys.kdims, self.vertex_columns).opts(plot=plot, style=style)

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\core\data\__init__.py in __init__(self, data, kdims, vdims, **kwargs)
    229         validate_vdims = kwargs.pop('_validate_vdims', True)
    230         initialized = Interface.initialize(type(self), data, kdims, vdims,
--> 231                                            datatype=kwargs.get('datatype'))
    232         (data, self.interface, dims, extra_kws) = initialized
    233         super(Dataset, self).__init__(data, **dict(kwargs, **dict(dims, **extra_kws)))

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\core\data\interface.py in initialize(cls, eltype, data, kdims, vdims, datatype)
    186         for interface in prioritized:
    187             try:
--> 188                 (data, dims, extra_kws) = interface.init(eltype, data, kdims, vdims)
    189                 break
    190             except DataError:

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\core\data\xarray.py in init(cls, eltype, data, kdims, vdims)
    152             raise DataError("xarray Dataset must define coordinates "
    153                             "for all defined kdims, %s coordinates not found."
--> 154                             % not_found, cls)
    155 
    156         return data, {'kdims': kdims, 'vdims': vdims}, {}

DataError: xarray Dataset must define coordinates for all defined kdims, [Dimension('Pressure'), Dimension('Max_Wind_Speed')] coordinates not found.

XArrayInterface expects gridded data, for more information on supported datatypes see http://holoviews.org/user_guide/Gridded_Datasets.html
kcpevey commented 6 years ago

Ohh, your image DOES match the colors and levels I specified - its just showing the one level. But... I want all levels to be shown regardless of the plotted data. Is that possible?

philippjfr commented 6 years ago

Ohh, your image DOES match the colors and levels I specified - its just showing the one level. But... I want all levels to be shown regardless of the plotted data.

Right, I was about to reply with that. You can override the range using redim.range:

gvpath = gv.Path([data_df], kdims=['Longitude', 'Latitude'], vdims=['Pressure','Max_Wind_Speed'], crs=proj).redim.range(Max_Wind_Speed=(0, 999))

Looking at the new error you posted next.

philippjfr commented 6 years ago

@kcpevey Quick question about the intent behind declaring ['Pressure', 'Max_Wind_Speed'] as poly_columns. The poly_columns are meant for annotating each individual path/polygon, not for annotating each vertex. Hence the error, it's assuming that the path has one value when it actually has a bunch of values.

kcpevey commented 6 years ago

Ah. Good catch. I suppose I do mean to annotate the point_columns with that information instead. I guess I was hoping that eventually I could figure out a way to color the path accordingly as well, but that's not a priority for right now.

kcpevey commented 6 years ago

That actually fixes it AND colors the path like I want. Woot!

Now I'm applying this to the 'real' code. Working through things (e.g. the dreaded DataError: None of the available storage backends were able to support the supplied data format.). Let me see if I can debug this.

philippjfr commented 6 years ago

Now I'm applying this to the 'real' code. Working through things (e.g. the dreaded DataError: None of the available storage backends were able to support the supplied data format.). Let me see if I can debug this.

Could you supply the full traceback? I'm worried this is related to the issue I initially encountered with my synthetic data, which is to do with projecting the data.

kcpevey commented 6 years ago
wind_df = pd.read_csv('../../data/hurricane_path_color.txt', delimiter=',', header=0, parse_dates=['Datetime'])
data_df = wind_df.drop('Datetime',axis=1)
gvpath = gv.Path([data_df], kdims=['Longitude', 'Latitude'], vdims=['Pressure','Max_Wind_Speed','Radius','Direction_Degrees','Direction_Speed'], crs=proj)
gvpoint = gv.Points(data_df, kdims=['Longitude', 'Latitude'], vdims=['Pressure','Max_Wind_Speed','Radius','Direction_Degrees','Direction_Speed'], crs=proj)
annot = PolyAndPointAnnotator(path_type=Path, polys=gvpath, points=gvpoint,
                              point_columns=['Pressure','Max_Wind_Speed'], 
                              tile_url='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}',
                              crs=proj) 
annot.tiles * annot.polys * annot.points 
---------------------------------------------------------------------------
DataError                                 Traceback (most recent call last)
C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\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:

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\core\dimension.py in _repr_mimebundle_(self, include, exclude)
   1263         combined and returned.
   1264         """
-> 1265         return Store.render(self)
   1266 
   1267 

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\core\options.py in render(cls, obj)
   1287         data, metadata = {}, {}
   1288         for hook in hooks:
-> 1289             ret = hook(obj)
   1290             if ret is None:
   1291                 continue

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\ipython\display_hooks.py in pprint_display(obj)
    270     if not ip.display_formatter.formatters['text/plain'].pprint:
    271         return None
--> 272     return display(obj, raw_output=True)
    273 
    274 

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\ipython\display_hooks.py in display(obj, raw_output, **kwargs)
    240     elif isinstance(obj, (CompositeOverlay, ViewableElement)):
    241         with option_state(obj):
--> 242             output = element_display(obj)
    243     elif isinstance(obj, (Layout, NdLayout, AdjointLayout)):
    244         with option_state(obj):

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\ipython\display_hooks.py in wrapped(element)
    140         try:
    141             max_frames = OutputSettings.options['max_frames']
--> 142             mimebundle = fn(element, max_frames=max_frames)
    143             if mimebundle is None:
    144                 return {}, {}

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\ipython\display_hooks.py in element_display(element, max_frames)
    186         return None
    187 
--> 188     return render(element)
    189 
    190 

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\ipython\display_hooks.py in render(obj, **kwargs)
     63         renderer = renderer.instance(fig='png')
     64 
---> 65     return renderer.components(obj, **kwargs)
     66 
     67 

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\plotting\bokeh\renderer.py in components(self, obj, fmt, comm, **kwargs)
    268         # Bokeh has to handle comms directly in <0.12.15
    269         comm = False if bokeh_version < '0.12.15' else comm
--> 270         return super(BokehRenderer, self).components(obj,fmt, comm, **kwargs)
    271 
    272 

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\plotting\renderer.py in components(self, obj, fmt, comm, **kwargs)
    314             plot = obj
    315         else:
--> 316             plot, fmt = self._validate(obj, fmt)
    317 
    318         widget_id = None

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\plotting\renderer.py in _validate(self, obj, fmt, **kwargs)
    213         if isinstance(obj, tuple(self.widgets.values())):
    214             return obj, 'html'
--> 215         plot = self.get_plot(obj, renderer=self, **kwargs)
    216 
    217         fig_formats = self.mode_formats['fig'][self.mode]

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\plotting\bokeh\renderer.py in get_plot(self_or_cls, obj, doc, renderer)
    153             curdoc().theme = self_or_cls.theme
    154         doc.theme = self_or_cls.theme
--> 155         plot = super(BokehRenderer, self_or_cls).get_plot(obj, renderer)
    156         plot.document = doc
    157         return plot

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\plotting\renderer.py in get_plot(self_or_cls, obj, renderer)
    200             init_key = tuple(v if d is None else d for v, d in
    201                              zip(plot.keys[0], defaults))
--> 202             plot.update(init_key)
    203         else:
    204             plot = obj

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\plotting\plot.py in update(self, key)
    513     def update(self, key):
    514         if len(self) == 1 and ((key == 0) or (key == self.keys[0])) and not self.drawn:
--> 515             return self.initialize_plot()
    516         item = self.__getitem__(key)
    517         self.traverse(lambda x: setattr(x, '_updated', True))

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews-1.5.4a6-py3.6.egg\geoviews\plotting\bokeh\plot.py in initialize_plot(self, ranges, plot, plots, source)
     82     def initialize_plot(self, ranges=None, plot=None, plots=None, source=None):
     83         opts = {} if isinstance(self, HvOverlayPlot) else {'source': source}
---> 84         fig = super(GeoPlot, self).initialize_plot(ranges, plot, plots, **opts)
     85         if self.geographic and self.show_bounds and not self.overlaid:
     86             from . import GeoShapePlot

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\plotting\bokeh\element.py in initialize_plot(self, ranges, plot, plots)
   1423             if self.tabs:
   1424                 subplot.overlaid = False
-> 1425             child = subplot.initialize_plot(ranges, plot, plots)
   1426             if isinstance(element, CompositeOverlay):
   1427                 frame = element.get(key, None)

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews-1.5.4a6-py3.6.egg\geoviews\plotting\bokeh\plot.py in initialize_plot(self, ranges, plot, plots, source)
     82     def initialize_plot(self, ranges=None, plot=None, plots=None, source=None):
     83         opts = {} if isinstance(self, HvOverlayPlot) else {'source': source}
---> 84         fig = super(GeoPlot, self).initialize_plot(ranges, plot, plots, **opts)
     85         if self.geographic and self.show_bounds and not self.overlaid:
     86             from . import GeoShapePlot

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\plotting\bokeh\element.py in initialize_plot(self, ranges, plot, plots, source)
    735 
    736         for cb in self.callbacks:
--> 737             cb.initialize()
    738 
    739         if not self.overlaid:

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\plotting\bokeh\callbacks.py in initialize(self, plot_id)
    903         plot.state.tools.append(poly_tool)
    904         self._update_cds_vdims()
--> 905         super(PolyDrawCallback, self).initialize(plot_id)
    906 
    907     def _update_cds_vdims(self):

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\plotting\bokeh\callbacks.py in initialize(self, plot_id)
    816         super(CDSCallback, self).initialize(plot_id)
    817         plot = self.plot
--> 818         data = self._process_msg({'data': plot.handles['source'].data})['data']
    819         for stream in self.streams:
    820             stream.update(data=data)

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews-1.5.4a6-py3.6.egg\geoviews\plotting\bokeh\callbacks.py in _process_msg(self, msg)
    224     def _process_msg(self, msg):
    225         msg = super(GeoPolyDrawCallback, self)._process_msg(msg)
--> 226         return project_poly(self, msg)
    227 
    228     def _update_cds_vdims(self):

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews-1.5.4a6-py3.6.egg\geoviews\plotting\bokeh\callbacks.py in project_poly(cb, msg)
     96     if not msg['data']:
     97         return msg
---> 98     projected = project_drawn(cb, msg)
     99     if projected is None:
    100         return msg

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews-1.5.4a6-py3.6.egg\geoviews\plotting\bokeh\callbacks.py in project_drawn(cb, msg)
     83     old_data = stream.data
     84     stream.update(data=msg['data'])
---> 85     element = stream.element
     86     stream.update(data=old_data)
     87     proj = cb.plot.projection

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\streams.py in element(self)
    974         data = [{lookup.get(c, c): data[c][i] for c in self.data}
    975                 for i in range(len(data[cols[0]]))]
--> 976         return source.clone(data)
    977 
    978     @property

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews-1.5.4a6-py3.6.egg\geoviews\element\geo.py in clone(self, data, shared_data, new_type, *args, **overrides)
    103             overrides['crs'] = self.crs
    104         return super(_Element, self).clone(data, shared_data, new_type,
--> 105                                            *args, **overrides)
    106 
    107 

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\core\data\__init__.py in clone(self, data, shared_data, new_type, *args, **overrides)
    672             datatypes = [self.interface.datatype] + self.datatype
    673             overrides['datatype'] = list(unique_iterator(datatypes))
--> 674         return super(Dataset, self).clone(data, shared_data, new_type, *args, **overrides)
    675 
    676 

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\core\dimension.py in clone(self, data, shared_data, new_type, *args, **overrides)
    629         # Apply name mangling for __ attribute
    630         pos_args = getattr(self, '_' + type(self).__name__ + '__pos_params', [])
--> 631         return clone_type(data, *args, **{k:v for k,v in settings.items()
    632                                           if k not in pos_args})
    633 

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\geoviews-1.5.4a6-py3.6.egg\geoviews\element\geo.py in __init__(self, data, kdims, vdims, **kwargs)
     95         elif crs:
     96             kwargs['crs'] = crs
---> 97         super(_Element, self).__init__(data, kdims=kdims, vdims=vdims, **kwargs)
     98 
     99 

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\element\path.py in __init__(self, data, kdims, vdims, **params)
     57         elif isinstance(data, list) and all(isinstance(path, Path) for path in data):
     58             data = [p for path in data for p in path.data]
---> 59         super(Path, self).__init__(data, kdims=kdims, vdims=vdims, **params)
     60 
     61     def __setstate__(self, state):

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\core\data\__init__.py in __init__(self, data, kdims, vdims, **kwargs)
    229         validate_vdims = kwargs.pop('_validate_vdims', True)
    230         initialized = Interface.initialize(type(self), data, kdims, vdims,
--> 231                                            datatype=kwargs.get('datatype'))
    232         (data, self.interface, dims, extra_kws) = initialized
    233         super(Dataset, self).__init__(data, **dict(kwargs, **dict(dims, **extra_kws)))

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\core\data\interface.py in initialize(cls, eltype, data, kdims, vdims, datatype)
    186         for interface in prioritized:
    187             try:
--> 188                 (data, dims, extra_kws) = interface.init(eltype, data, kdims, vdims)
    189                 break
    190             except DataError:

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\core\data\multipath.py in init(cls, eltype, data, kdims, vdims)
     39         for d in data:
     40             d, interface, dims, _ = Interface.initialize(eltype, d, kdims, vdims,
---> 41                                                          datatype=cls.subtypes)
     42             if prev_interface:
     43                 if prev_interface != interface:

C:\ProgramData\Anaconda3\envs\earthsimAUG\lib\site-packages\holoviews-1.11.0a4.post9+gaf9f5947-py3.6.egg\holoviews\core\data\interface.py in initialize(cls, eltype, data, kdims, vdims, datatype)
    201                                   % (intfc.__name__, e))
    202                 error = ' '.join([error, priority_error])
--> 203             raise DataError(error)
    204 
    205         return data, interface, dims, extra_kws

DataError: None of the available storage backends were able to support the supplied data format. DictInterface raised following error:

 DictInterface expects data for each column to be flat.
:Overlay
   .WMTS.I   :WMTS   [Longitude,Latitude]
   .Path.I   :Path   [Longitude,Latitude]   (Group,Pressure,Max_Wind_Speed,Radius,Direction_Degrees,Direction_Speed)
   .Points.I :Points   [Longitude,Latitude]   (Pressure,Max_Wind_Speed,Radius,Direction_Degrees,Direction_Speed)

The only difference is the inclusion of the additional columns as vdims

kcpevey commented 6 years ago

Dropping the Datetime column because I don't think it can be rendered/promoted properly. RE: #214

philippjfr commented 6 years ago

It seems to work as long as you declare the color_index for the paths.

kcpevey commented 6 years ago

Yep, that works.

philippjfr commented 6 years ago

I'll add a proper fix shortly.

kcpevey commented 6 years ago

Great. Thanks!

philippjfr commented 6 years ago

Okay, pushed a fix for that to the PR as well.

kcpevey commented 6 years ago
%%opts Points (size=10, cmap=colors) [color_index='Max_Wind_Speed', color_levels=levels, colorbar=True, tools=['hover']]
%%opts Path (line_width=2, cmap=colors) [color_index='Max_Wind_Speed', color_levels=levels, colorbar=True]

wind_df = pd.read_csv('../../data/hurricane_path_color.txt', delimiter=',', header=0, parse_dates=['Datetime'])
data_df = wind_df.drop('Datetime',axis=1)
gvpath = gv.Path([data_df], kdims=['Longitude', 'Latitude'], vdims=['Pressure','Max_Wind_Speed','Radius','Direction_Degrees','Direction_Speed'], crs=proj)
gvpoint = gv.Points(data_df, kdims=['Longitude', 'Latitude'], vdims=['Pressure','Max_Wind_Speed','Radius','Direction_Degrees','Direction_Speed'], crs=proj)
annot = PolyAndPointAnnotator(path_type=Path, polys=gvpath, points=gvpoint,
                              point_columns=['Pressure','Max_Wind_Speed'], 
                              tile_url='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}',
                              crs=proj) 
(annot.tiles * annot.polys * annot.points + annot.point_table).cols(1) 

Modifying the Max_Wind_Speed column of point_table doesn't change the coloring in the drawing. Am I not doing something right?

philippjfr commented 6 years ago

Modifying the Max_Wind_Speed column of point_table doesn't change the coloring in the drawing. Am I not doing something right?

Are you sure? That works for me.

kcpevey commented 6 years ago

Weird. Its working now.

New question: modifying the point_table changes the color of the points, but the path is still colored by the original data. I'm guessing in order to link these two, it would require some work inside of the annotator class to link the two streams somehow? (i.e. not something that can be accomplished today)

philippjfr commented 6 years ago

I'm guessing in order to link these two, it would require some work inside of the annotator class to link the two streams somehow? (i.e. not something that can be accomplished today)

That's a fairly difficult problem because in order to color the path in the first place it has to be split up into lots of individual paths. Mapping between the vertices and the split up paths is going to be very difficult, but not impossible.

kcpevey commented 6 years ago

I can confirm that everything looks to be working properly now. NOT specifying color_index for the path does not throw an error.

One last thing and then we can close this issue for good. Given this

That's a fairly difficult problem because in order to color the path in the first place it has to be split up into lots of individual paths. Mapping between the vertices and the split up paths is going to be very difficult, but not impossible.

I just want to specify the path as a single color. However, %%opts Path (cmap='red') seems to have no effect (the path is still plotted as blue)

philippjfr commented 6 years ago

I just want to specify the path as a single color. However, %%opts Path (cmap='red') seems to have no effect (the path is still plotted as blue)

Does it work when you explicitly set color_index=None?

kcpevey commented 6 years ago

Nope. Still blue
%%opts Path (cmap='red') [color_index=None]

kcpevey commented 6 years ago

@philippjfr Should I move this to its own issue?

philippjfr commented 6 years ago

Yes good idea, this one is getting a bit unwieldy.

kcpevey commented 6 years ago

Moved to new issue #230