geoviews icon indicating copy to clipboard operation
geoviews copied to clipboard

Plotting fails when using a non-global projection for rasterised projected mesh

Open pgierz opened this issue 6 years ago • 0 comments

import holoviews as hv
import geoviews as gv
import cmocean
import matplotlib.pyplot as plt
from holoviews import opts
from holoviews.operation.datashader import datashade, shade, dynspread, rasterize
from holoviews.operation import decimate
import numpy as np
import xarray as xr
import cartopy.crs as ccrs

hv.extension('bokeh')

hv.__version__, gv.__version__, xr.__version__
('1.12.3', '1.6.2', '0.11.3')

# WARNING: Broken if you use a non-global projection.
greenland_projection = ccrs.Miller()

projected_trimesh = gv.project(trimesh, projection=greenland_projection)
projected_fesom_mesh = gv.project(fesom_mesh, projection=greenland_projection)


# This next line results in an index error if a different projection is used:
rasterize(projected_trimesh).opts(
    colorbar=True, tools=['hover'],
    clim=(-2, 5), color_levels = [-2, -1.5, -1, -0.5, -0.25, 0.25, 0.5, 1, 1.5, 2],
    width=600, projection=greenland_projection, data_aspect=1,
    cmap=cmocean.cm.thermal)

Some discussion with @philippjfr seems to reveal that the gv.project command has problems when displaying plots where some of the simplifies are no longer on the map:

That confirms my guess I think, I think the project_trimesh operation isn't correctly dropping simplices which reference vertices outside of the projection so when it comes to plotting it tries to look for vertices which no longer exist.

Here is a full traceback of such an error (e.g. when using ccrs.EuroPP:

WARNING:param.dynamic_operation: Callable raised "IndexError('index 103130 is out of bounds for size 103130')".
Invoked as dynamic_operation(height=400, scale=1.0, width=400, x_range=None, y_range=None)
WARNING:param.dynamic_operation: Callable raised "IndexError('index 103130 is out of bounds for size 103130')".
Invoked as dynamic_operation(height=400, scale=1.0, width=400, x_range=None, y_range=None)
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
~/anaconda3/envs/palmod/lib/python3.7/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:

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/core/dimension.py in _repr_mimebundle_(self, include, exclude)
   1291         combined and returned.
   1292         """
-> 1293         return Store.render(self)
   1294 
   1295 

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/core/options.py in render(cls, obj)
   1360         data, metadata = {}, {}
   1361         for hook in hooks:
-> 1362             ret = hook(obj)
   1363             if ret is None:
   1364                 continue

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/ipython/display_hooks.py in pprint_display(obj)
    278     if not ip.display_formatter.formatters['text/plain'].pprint:
    279         return None
--> 280     return display(obj, raw_output=True)
    281 
    282 

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/ipython/display_hooks.py in display(obj, raw_output, **kwargs)
    254     elif isinstance(obj, (HoloMap, DynamicMap)):
    255         with option_state(obj):
--> 256             output = map_display(obj)
    257     elif isinstance(obj, Plot):
    258         output = render(obj)

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/ipython/display_hooks.py in wrapped(element)
    143         try:
    144             max_frames = OutputSettings.options['max_frames']
--> 145             mimebundle = fn(element, max_frames=max_frames)
    146             if mimebundle is None:
    147                 return {}, {}

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/ipython/display_hooks.py in map_display(vmap, max_frames)
    203         return None
    204 
--> 205     return render(vmap)
    206 
    207 

~/anaconda3/envs/palmod/lib/python3.7/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 

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/plotting/bokeh/renderer.py in components(self, obj, fmt, comm, **kwargs)
    248         # Bokeh has to handle comms directly in <0.12.15
    249         comm = False if bokeh_version < '0.12.15' else comm
--> 250         return super(BokehRenderer, self).components(obj,fmt, comm, **kwargs)
    251 
    252 

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/plotting/renderer.py in components(self, obj, fmt, comm, **kwargs)
    319             plot = obj
    320         else:
--> 321             plot, fmt = self._validate(obj, fmt)
    322 
    323         data, metadata = {}, {}

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/plotting/renderer.py in _validate(self, obj, fmt, **kwargs)
    218         if isinstance(obj, tuple(self.widgets.values())):
    219             return obj, 'html'
--> 220         plot = self.get_plot(obj, renderer=self, **kwargs)
    221 
    222         fig_formats = self.mode_formats['fig'][self.mode]

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/plotting/bokeh/renderer.py in get_plot(self_or_cls, obj, doc, renderer, **kwargs)
    133             curdoc().theme = self_or_cls.theme
    134         doc.theme = self_or_cls.theme
--> 135         plot = super(BokehRenderer, self_or_cls).get_plot(obj, renderer, **kwargs)
    136         plot.document = doc
    137         return plot

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/plotting/renderer.py in get_plot(self_or_cls, obj, renderer, **kwargs)
    184 
    185         # Initialize DynamicMaps with first data item
--> 186         initialize_dynamic(obj)
    187 
    188         if not isinstance(obj, Plot):

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/plotting/util.py in initialize_dynamic(obj)
    248             continue
    249         if not len(dmap):
--> 250             dmap[dmap._initial_key()]
    251 
    252 

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/core/spaces.py in __getitem__(self, key)
   1323         # Not a cross product and nothing cached so compute element.
   1324         if cache is not None: return cache
-> 1325         val = self._execute_callback(*tuple_key)
   1326         if data_slice:
   1327             val = self._dataslice(val, data_slice)

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/core/spaces.py in _execute_callback(self, *args)
   1096 
   1097         with dynamicmap_memoization(self.callback, self.streams):
-> 1098             retval = self.callback(*args, **kwargs)
   1099         return self._style(retval)
   1100 

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/core/spaces.py in __call__(self, *args, **kwargs)
    731 
    732         try:
--> 733             ret = self.callable(*args, **kwargs)
    734         except KeyError:
    735             # KeyError is caught separately because it is used to signal

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/util/__init__.py in dynamic_operation(*key, **kwargs)
    934                 if map_obj._posarg_keys and not key:
    935                     key = tuple(kwargs[k] for k in map_obj._posarg_keys)
--> 936                 return self._process(map_obj[key], key, kwargs)
    937         if isinstance(self.p.operation, Operation):
    938             return OperationCallable(dynamic_operation, inputs=[map_obj],

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/core/spaces.py in __getitem__(self, key)
   1323         # Not a cross product and nothing cached so compute element.
   1324         if cache is not None: return cache
-> 1325         val = self._execute_callback(*tuple_key)
   1326         if data_slice:
   1327             val = self._dataslice(val, data_slice)

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/core/spaces.py in _execute_callback(self, *args)
   1096 
   1097         with dynamicmap_memoization(self.callback, self.streams):
-> 1098             retval = self.callback(*args, **kwargs)
   1099         return self._style(retval)
   1100 

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/core/spaces.py in __call__(self, *args, **kwargs)
    731 
    732         try:
--> 733             ret = self.callable(*args, **kwargs)
    734         except KeyError:
    735             # KeyError is caught separately because it is used to signal

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/util/__init__.py in dynamic_operation(*key, **kwargs)
    928                 kwargs = dict(self._eval_kwargs(), **kwargs)
    929                 obj = map_obj[key] if isinstance(map_obj, HoloMap) else map_obj
--> 930                 return self._process(obj, key, kwargs)
    931         else:
    932             def dynamic_operation(*key, **kwargs):

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/util/__init__.py in _process(self, element, key, kwargs)
    906             kwargs = {k: v for k, v in kwargs.items()
    907                       if k in self.p.operation.params()}
--> 908             return self.p.operation.process_element(element, key, **kwargs)
    909         else:
    910             return self.p.operation(element, **kwargs)

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/core/operation.py in process_element(self, element, key, **params)
    141         """
    142         self.p = param.ParamOverrides(self, params)
--> 143         return self._apply(element, key)
    144 
    145 

~/anaconda3/envs/palmod/lib/python3.7/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)

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/operation/datashader.py in _process(self, element, key)
    855             op = transform.instance(**op_params)
    856             op._precomputed = self._precomputed
--> 857             element = element.map(op, predicate)
    858             self._precomputed = op._precomputed
    859         return element

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/core/dimension.py in map(self, map_fn, specs, clone)
    701             return deep_mapped
    702         else:
--> 703             return map_fn(self) if applies else self
    704 
    705 

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/core/operation.py in __call__(self, element, **kwargs)
    159                                       for k, el in element.items()])
    160             elif isinstance(element, ViewableElement):
--> 161                 return self._apply(element)
    162         elif 'streams' not in kwargs:
    163             kwargs['streams'] = self.p.streams

~/anaconda3/envs/palmod/lib/python3.7/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)

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/operation/datashader.py in _process(self, element, key)
    757             precomputed = self._precompute_wireframe(element, agg)
    758         else:
--> 759             precomputed = self._precompute(element, agg)
    760 
    761         params = dict(get_param_values(element), kdims=[x, y],

~/anaconda3/envs/palmod/lib/python3.7/site-packages/holoviews/operation/datashader.py in _precompute(self, element, agg)
    700             if dtype.kind != 'i':
    701                 simplices[c] = simplices[c].astype('int')
--> 702         return {'mesh': mesh(verts, simplices), 'simplices': simplices,
    703                 'vertices': verts}
    704 

~/anaconda3/envs/palmod/lib/python3.7/site-packages/datashader/utils.py in mesh(vertices, simplices)
    494         return _dd_mesh(vertices, simplices)
    495 
--> 496     return _pd_mesh(vertices, simplices)

~/anaconda3/envs/palmod/lib/python3.7/site-packages/datashader/utils.py in _pd_mesh(vertices, simplices)
    440     if not vertex_idxs.dtype == 'int64':
    441         vertex_idxs = vertex_idxs.astype(np.int64)
--> 442     vals = np.take(vertices.values, vertex_idxs, axis=0)
    443     vals = vals.reshape(np.prod(vals.shape[:2]), vals.shape[2])
    444     res = pd.DataFrame(vals, columns=vertices.columns)

~/anaconda3/envs/palmod/lib/python3.7/site-packages/numpy/core/fromnumeric.py in take(a, indices, axis, out, mode)
    187            [5, 7]])
    188     """
--> 189     return _wrapfunc(a, 'take', indices, axis=axis, out=out, mode=mode)
    190 
    191 

~/anaconda3/envs/palmod/lib/python3.7/site-packages/numpy/core/fromnumeric.py in _wrapfunc(obj, method, *args, **kwds)
     54 def _wrapfunc(obj, method, *args, **kwds):
     55     try:
---> 56         return getattr(obj, method)(*args, **kwds)
     57 
     58     # An AttributeError occurs if the object does not have

IndexError: index 103130 is out of bounds for size 103130

pgierz avatar Jul 15 '19 09:07 pgierz