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

Misleading error when including invalid string characters in point_columns #202

Closed kcpevey closed 5 years ago

kcpevey commented 6 years ago

Up until last week sometime, I had been specifying point_columns=['depth/elevation'] . Aside from the general wrist slapping I should get for trying to do something foolish... it used to interpret this, do some regex somewhere and give me back "depth_over_elevation". I had a note to fix it later. Now, the same thing throws a misleading error.

sample_points = pd.DataFrame({
    'Longitude': [-10131185, -10131943, -10131766, -10131032],
    'Latitude':  [  3805587,   3803182,   3801073,   3799778],
    'Size':      [        5,        50,       500,      5000]})

annot = PointAnnotator(point_columns=['Size/foo'], points=sample_points)

Leads to:

---------------------------------------------------------------------------
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)
    243     elif isinstance(obj, (Layout, NdLayout, AdjointLayout)):
    244         with option_state(obj):
--> 245             output = layout_display(obj)
    246     elif isinstance(obj, (HoloMap, DynamicMap)):
    247         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 layout_display(layout, max_frames)
    213         return None
    214 
--> 215     return render(layout)
    216 
    217 

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:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\bokeh\plot.py in initialize_plot(self, plots, ranges)
    836 
    837                 shared_plots = list(passed_plots) if self.shared_axes else None
--> 838                 subplots = subplot.initialize_plot(ranges=ranges, plots=shared_plots)
    839                 nsubplots = len(subplots)
    840 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\bokeh\plot.py in initialize_plot(self, ranges, plots)
    956             else:
    957                 passed_plots = plots + adjoined_plots
--> 958                 adjoined_plots.append(subplot.initialize_plot(ranges=ranges, plots=passed_plots))
    959         self.drawn = True
    960         if not adjoined_plots: adjoined_plots = [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)
   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)
    862             if dim not in source.data:
    863                 source.data[dim] = element.dimension_values(d)
--> 864         super(PointDrawCallback, self).initialize(plot_id)
    865 
    866 

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)
    227         if not msg['data']:
    228             return msg
--> 229         projected = project_drawn(self, msg)
    230         if projected is None:
    231             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)
    864         if not self.data:
    865             return source.clone([])
--> 866         return source.clone(self.data)
    867 
    868     @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\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: ['Size/foo']

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

:Layout
   .Overlay.I :Overlay
      .WMTS.I     :WMTS   [Longitude,Latitude]
      .Polygons.I :Polygons   [Longitude,Latitude]
      .Points.I   :Points   [Longitude,Latitude]   (Size/foo,Size)
   .Table.I   :Table   [Longitude,Latitude]   (Size/foo,Size)

While point_columns=['foo'] throws no error and populates a column of NaNs.

kcpevey commented 5 years ago

This no longer throws an error