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

geopandas requires kdims? #114

Closed kcpevey closed 6 years ago

kcpevey commented 6 years ago

I just updated my gv and hv to geoviews 1.5.1a3.post3+gd472e49 holoviews 1.10.4.post26+gdefe5c58

That broke a piece of previously working code:

hurr_path = [[-6349336.834486977, 1914106.9610980127],
             [-7829193.668502837, 2640900.7616723403],
             [-8389612.654597202, 3271372.0375195844],
             [-9081379.141170258, 3113754.30206669],
             [-9230240.799703084, 3604120.66437251],
             [-9615528.894397419, 3700442.8550639264]]
annot = PolyAndPointAnnotator(path_type=Path, polys=[hurr_path], tile_url='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}')

It throw the following error:

---------------------------------------------------------------------------
DataError                                 Traceback (most recent call last)
<ipython-input-7-c8b7f85a06e6> in <module>()
      1 
----> 2 annot = PolyAndPointAnnotator(path_type=Path, polys=[hurr_path], tile_url='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}')
      3 (annot.tiles * datashade(trimesh.edgepaths, cmap=['yellow']) * annot.polys * annot.points + annot.poly_table).options(shared_datasource=True, clone=False).cols(1)

c:\projects\ers\github\earthsim_pyviz\adhmodel\earthsim\earthsim\annotators.py in __init__(self, poly_data, **params)
    168             self.poly_stream.event(data={kd.name: [p.dimension_values(kd) for p in poly_data]
    169                                          for kd in self.polys.kdims})
--> 170         self.poly_table = Table(self.polys.data, self.poly_columns, []).opts(plot=plot, style=style)
    171 
    172     def view(self):

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\data\__init__.py in __init__(self, data, kdims, vdims, **kwargs)
    204         validate_vdims = kwargs.pop('_validate_vdims', True)
    205         initialized = Interface.initialize(type(self), data, kdims, vdims,
--> 206                                            datatype=kwargs.get('datatype'))
    207         (data, self.interface, dims, extra_kws) = initialized
    208         super(Dataset, self).__init__(data, **dict(kwargs, **dict(dims, **extra_kws)))

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\data\interface.py in initialize(cls, eltype, data, kdims, vdims, datatype)
    196         for interface in prioritized:
    197             try:
--> 198                 (data, dims, extra_kws) = interface.init(eltype, data, kdims, vdims)
    199                 break
    200             except DataError:

c:\projects\ers\github\geoviews\master\geoviews\geoviews\data\geopandas.py in init(cls, eltype, data, kdims, vdims)
     30             if len(kdims) != 2:
     31                 raise DataError("Expected two kdims to use GeoDataFrame, found %d."
---> 32                                 % len(kdims))
     33         else:
     34             kdims = eltype.kdims

DataError: Expected two kdims to use GeoDataFrame, found 1.

Is it now a requirement to pass kdims if I'm going to pass polys?

kcpevey commented 6 years ago

I get the same error if I don't pass polys at all.

philippjfr commented 6 years ago

I've got an update to fix this locally, which I'll push but I'll also make a small adjustment in bokeh to ensure this doesn't error in the first place (it should just fall back to using the regular pandas interface).

kcpevey commented 6 years ago

I updated this morning to: geoviews 1.5.1.post3+g3dba413 holoviews 1.10.5.post7+gd808fa99

The code snippet above (specifying a polys) now works as expected. However, if I don't give it polys:

annot = PolyAndPointAnnotator(path_type=Path, tile_url='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}')

Then I get a similar error to above:

---------------------------------------------------------------------------
DataError                                 Traceback (most recent call last)
C:\ProgramData\Anaconda3\envs\ers\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)
   1229         combined and returned.
   1230         """
-> 1231         return Store.render(self)
   1232 
   1233 

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)
    193 
    194         # Initialize DynamicMaps with first data item
--> 195         initialize_dynamic(obj)
    196 
    197         if not isinstance(obj, Plot):

c:\projects\ers\github\holoviews\master\holoviews\holoviews\plotting\util.py in initialize_dynamic(obj)
    242             continue
    243         if not len(dmap):
--> 244             dmap[dmap._initial_key()]
    245 
    246 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\spaces.py in __getitem__(self, key)
   1130         # Not a cross product and nothing cached so compute element.
   1131         if cache is not None: return cache
-> 1132         val = self._execute_callback(*tuple_key)
   1133         if data_slice:
   1134             val = self._dataslice(val, data_slice)

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\spaces.py in _execute_callback(self, *args)
    910         with dynamicmap_memoization(self.callback, self.streams):
    911             retval = self.callback(*args, **kwargs)
--> 912         return self._style(retval)
    913 
    914 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\spaces.py in _style(self, retval)
    883             return retval
    884         spec = StoreOptions.tree_to_dict(Store.custom_options()[self.id])
--> 885         return retval.opts(spec)
    886 
    887 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\dimension.py in opts(self, options, backend, clone, **kwargs)
   1176                 self.map(lambda x: setattr(x, 'id', None))
   1177         elif clone:
-> 1178             obj = self.map(lambda x: x.clone(id=x.id))
   1179         StoreOptions.set_options(obj, options, backend=backend, **kwargs)
   1180         return obj

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\dimension.py in map(self, map_fn, specs, clone)
    686             deep_mapped = self.clone(shared_data=False) if clone else self
    687             for k, v in self.items():
--> 688                 new_val = v.map(map_fn, specs, clone)
    689                 if new_val is not None:
    690                     deep_mapped[k] = new_val

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\dimension.py in map(self, map_fn, specs, clone)
    692             return deep_mapped
    693         else:
--> 694             return map_fn(self) if applies else self
    695 
    696 

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\dimension.py in <lambda>(x)
   1176                 self.map(lambda x: setattr(x, 'id', None))
   1177         elif clone:
-> 1178             obj = self.map(lambda x: x.clone(id=x.id))
   1179         StoreOptions.set_options(obj, options, backend=backend, **kwargs)
   1180         return obj

c:\projects\ers\github\geoviews\master\geoviews\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)
    647             datatypes = [self.interface.datatype] + self.datatype
    648             overrides['datatype'] = list(unique_iterator(datatypes))
--> 649         return super(Dataset, self).clone(data, shared_data, new_type, *args, **overrides)
    650 
    651 

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

c:\projects\ers\github\geoviews\master\geoviews\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)
     56         elif isinstance(data, list) and all(isinstance(path, Path) for path in data):
     57             data = [p for path in data for p in path.data]
---> 58         super(Path, self).__init__(data, kdims=kdims, vdims=vdims, **params)
     59 
     60     def __setstate__(self, state):

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\data\__init__.py in __init__(self, data, kdims, vdims, **kwargs)
    204         validate_vdims = kwargs.pop('_validate_vdims', True)
    205         initialized = Interface.initialize(type(self), data, kdims, vdims,
--> 206                                            datatype=kwargs.get('datatype'))
    207         (data, self.interface, dims, extra_kws) = initialized
    208         super(Dataset, self).__init__(data, **dict(kwargs, **dict(dims, **extra_kws)))

c:\projects\ers\github\holoviews\master\holoviews\holoviews\core\data\interface.py in initialize(cls, eltype, data, kdims, vdims, datatype)
    211                                   % (intfc.__name__, e))
    212                 error = ' '.join([error, priority_error])
--> 213             raise DataError(error)
    214 
    215         return data, interface, dims, extra_kws

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

 The GeopandasInterface can only read dataframes which share a common geometry type
philippjfr commented 6 years ago

Thanks, fixed in https://github.com/ioam/geoviews/commit/206d1f49d973b1905003333b49869655e7cdf27f