Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xarray Image plot fails with datashade=True #563

Closed
michaelaye opened this issue Mar 2, 2021 · 6 comments
Closed

xarray Image plot fails with datashade=True #563

michaelaye opened this issue Mar 2, 2021 · 6 comments

Comments

@michaelaye
Copy link
Contributor

ALL software version info

xarray 0.17.0
hvplot 0.7.0
holoviews 1.14.1
bokeh 2.2.3
python 3.8.x
notebook 6.2
OS: PopOS(Ubuntu) 20.10
Browser Brave (Chrome)

Description of expected behavior and the observed behavior

Like for xarray.hvplot.scatter in the docs, using the datashade option should work for Image rasters.
Instead it throws a huge traceback.

Complete, minimal, self-contained example code that reproduces the issue

arr = xr.DataArray(
    np.arange(10000).reshape(100, 100),
    dims=("x", "y"),
    coords={"x": np.arange(100), "y": np.arange(100)},
)
arr.hvplot()
arr.hvplot(datashade=True)

Stack traceback and/or browser JavaScript console output

WARNING:param.dynamic_operation: Callable raised "AttributeError("'DataArray' object has no attribute '_file_obj'")".
Invoked as dynamic_operation(height=300, scale=1.0, width=700, x_range=None, y_range=None)
WARNING:param.dynamic_operation: Callable raised "AttributeError("'DataArray' object has no attribute '_file_obj'")".
Invoked as dynamic_operation(height=300, scale=1.0, width=700, x_range=None, y_range=None)

AttributeError Traceback (most recent call last)
~/miniconda3/envs/py38/lib/python3.8/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:

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/dimension.py in repr_mimebundle(self, include, exclude)
1314 combined and returned.
1315 """
-> 1316 return Store.render(self)
1317
1318

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/options.py in render(cls, obj)
1403 data, metadata = {}, {}
1404 for hook in hooks:
-> 1405 ret = hook(obj)
1406 if ret is None:
1407 continue

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

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/ipython/display_hooks.py in display(obj, raw_output, **kwargs)
256 elif isinstance(obj, (HoloMap, DynamicMap)):
257 with option_state(obj):
--> 258 output = map_display(obj)
259 elif isinstance(obj, Plot):
260 output = render(obj)

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

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/ipython/display_hooks.py in map_display(vmap, max_frames)
204 return None
205
--> 206 return render(vmap)
207
208

~/miniconda3/envs/py38/lib/python3.8/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

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/plotting/renderer.py in components(self, obj, fmt, comm, **kwargs)
408 doc = Document()
409 with config.set(embed=embed):
--> 410 model = plot.layout._render_model(doc, comm)
411 if embed:
412 return render_model(model, comm)

~/miniconda3/envs/py38/lib/python3.8/site-packages/panel/viewable.py in _render_model(self, doc, comm)
422 if comm is None:
423 comm = state._comm_manager.get_server_comm()
--> 424 model = self.get_root(doc, comm)
425
426 if config.embed:

~/miniconda3/envs/py38/lib/python3.8/site-packages/panel/viewable.py in get_root(self, doc, comm, preprocess)
480 """
481 doc = init_doc(doc)
--> 482 root = self._get_model(doc, comm=comm)
483 if preprocess:
484 self._preprocess(root)

~/miniconda3/envs/py38/lib/python3.8/site-packages/panel/layout/base.py in _get_model(self, doc, root, parent, comm)
110 if root is None:
111 root = model
--> 112 objects = self._get_objects(model, [], doc, root, comm)
113 props = dict(self._init_properties(), objects=objects)
114 model.update(**self._process_param_change(props))

~/miniconda3/envs/py38/lib/python3.8/site-packages/panel/layout/base.py in _get_objects(self, model, old_objects, doc, root, comm)
100 else:
101 try:
--> 102 child = pane._get_model(doc, root, model, comm)
103 except RerenderError:
104 return self._get_objects(model, current_objects[:i], doc, root, comm)

~/miniconda3/envs/py38/lib/python3.8/site-packages/panel/pane/holoviews.py in _get_model(self, doc, root, parent, comm)
239 plot = self.object
240 else:
--> 241 plot = self._render(doc, comm, root)
242
243 plot.pane = self

~/miniconda3/envs/py38/lib/python3.8/site-packages/panel/pane/holoviews.py in _render(self, doc, comm, root)
304 kwargs['comm'] = comm
305
--> 306 return renderer.get_plot(self.object, **kwargs)
307
308 def _cleanup(self, root):

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/plotting/bokeh/renderer.py in get_plot(self_or_cls, obj, doc, renderer, **kwargs)
71 combining the bokeh model with another plot.
72 """
---> 73 plot = super(BokehRenderer, self_or_cls).get_plot(obj, doc, renderer, **kwargs)
74 if plot.document is None:
75 plot.document = Document() if self_or_cls.notebook_context else curdoc()

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/plotting/renderer.py in get_plot(self_or_cls, obj, doc, renderer, comm, **kwargs)
218
219 # Initialize DynamicMaps with first data item
--> 220 initialize_dynamic(obj)
221
222 if not renderer:

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/plotting/util.py in initialize_dynamic(obj)
250 continue
251 if not len(dmap):
--> 252 dmap[dmap._initial_key()]
253
254

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/spaces.py in getitem(self, key)
1329 # Not a cross product and nothing cached so compute element.
1330 if cache is not None: return cache
-> 1331 val = self._execute_callback(*tuple_key)
1332 if data_slice:
1333 val = self._dataslice(val, data_slice)

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/spaces.py in _execute_callback(self, *args)
1098
1099 with dynamicmap_memoization(self.callback, self.streams):
-> 1100 retval = self.callback(*args, **kwargs)
1101 return self._style(retval)
1102

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/spaces.py in call(self, *args, **kwargs)
712
713 try:
--> 714 ret = self.callable(*args, **kwargs)
715 except KeyError:
716 # KeyError is caught separately because it is used to signal

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/util/init.py in dynamic_operation(*key, **kwargs)
1016
1017 def dynamic_operation(*key, **kwargs):
-> 1018 key, obj = resolve(key, kwargs)
1019 return apply(obj, *key, **kwargs)
1020

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/util/init.py in resolve(key, kwargs)
1005 elif isinstance(map_obj, DynamicMap) and map_obj._posarg_keys and not key:
1006 key = tuple(kwargs[k] for k in map_obj._posarg_keys)
-> 1007 return key, map_obj[key]
1008
1009 def apply(element, *key, **kwargs):

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/spaces.py in getitem(self, key)
1329 # Not a cross product and nothing cached so compute element.
1330 if cache is not None: return cache
-> 1331 val = self._execute_callback(*tuple_key)
1332 if data_slice:
1333 val = self._dataslice(val, data_slice)

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/spaces.py in _execute_callback(self, *args)
1098
1099 with dynamicmap_memoization(self.callback, self.streams):
-> 1100 retval = self.callback(*args, **kwargs)
1101 return self._style(retval)
1102

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/spaces.py in call(self, *args, **kwargs)
712
713 try:
--> 714 ret = self.callable(*args, **kwargs)
715 except KeyError:
716 # KeyError is caught separately because it is used to signal

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/util/init.py in dynamic_operation(*key, **kwargs)
1017 def dynamic_operation(*key, **kwargs):
1018 key, obj = resolve(key, kwargs)
-> 1019 return apply(obj, *key, **kwargs)
1020
1021 operation = self.p.operation

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/util/init.py in apply(element, *key, **kwargs)
1009 def apply(element, *key, **kwargs):
1010 kwargs = dict(util.resolve_dependent_kwargs(self.p.kwargs), **kwargs)
-> 1011 processed = self._process(element, key, kwargs)
1012 if (self.p.link_dataset and isinstance(element, Dataset) and
1013 isinstance(processed, Dataset) and processed._dataset is None):

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/util/init.py in _process(self, element, key, kwargs)
991 elif isinstance(self.p.operation, Operation):
992 kwargs = {k: v for k, v in kwargs.items() if k in self.p.operation.param}
--> 993 return self.p.operation.process_element(element, key, **kwargs)
994 else:
995 return self.p.operation(element, **kwargs)

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/operation.py in process_element(self, element, key, **params)
192 self.p = param.ParamOverrides(self, params,
193 allow_extra_keywords=self._allow_extra_keywords)
--> 194 return self._apply(element, key)
195
196

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/operation.py in _apply(self, element, key)
139 if not in_method:
140 element._in_method = True
--> 141 ret = self._process(element, key)
142 if hasattr(element, '_in_method') and not in_method:
143 element._in_method = in_method

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/operation/datashader.py in _process(self, element, key)
1496
1497 def _process(self, element, key=None):
-> 1498 agg = rasterize._process(self, element, key)
1499 shaded = shade._process(self, agg, key)
1500 return shaded

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/operation/datashader.py in _process(self, element, key)
1475 if k in transform.param})
1476 op._precomputed = self._precomputed
-> 1477 element = element.map(op, predicate)
1478 self._precomputed = op._precomputed
1479

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/data/init.py in pipelined_fn(*args, **kwargs)
199
200 try:
--> 201 result = method_fn(*args, **kwargs)
202 if PipelineMeta.disable:
203 return result

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/data/init.py in map(self, *args, **kwargs)
1214
1215 def map(self, *args, **kwargs):
-> 1216 return super(Dataset, self).map(*args, **kwargs)
1217 map.doc = LabelledData.map.doc
1218

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/dimension.py in map(self, map_fn, specs, clone)
707 return deep_mapped
708 else:
--> 709 return map_fn(self) if applies else self
710
711

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/operation.py in call(self, element, **kwargs)
212 elif ((self._per_element and isinstance(element, Element)) or
213 (not self._per_element and isinstance(element, ViewableElement))):
--> 214 return self._apply(element)
215 elif 'streams' not in kwargs:
216 kwargs['streams'] = self.p.streams

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/core/operation.py in _apply(self, element, key)
139 if not in_method:
140 element._in_method = True
--> 141 ret = self._process(element, key)
142 if hasattr(element, '_in_method') and not in_method:
143 element._in_method = in_method

~/miniconda3/envs/py38/lib/python3.8/site-packages/holoviews/operation/datashader.py in _process(self, element, key)
937 agg_fn = self._get_aggregator(element, add_field=False)
938 for vd, xarr in arrays.items():
--> 939 rarray = cvs.raster(xarr, upsample_method=interp,
940 downsample_method=agg_fn)
941

~/miniconda3/envs/py38/lib/python3.8/site-packages/datashader/core.py in raster(self, source, layer, upsample_method, downsample_method, nan_value, agg, interpolate, chunksize, max_mem)
1131 dims = [ydim, xdim]
1132 attrs = dict(res=res[0])
-> 1133 if source._file_obj is not None and hasattr(source._file_obj, 'nodata'):
1134 attrs['nodata'] = source._file_obj.nodata
1135

~/miniconda3/envs/py38/lib/python3.8/site-packages/xarray/core/common.py in getattr(self, name)
237 with suppress(KeyError):
238 return source[name]
--> 239 raise AttributeError(
240 "{!r} object has no attribute {!r}".format(type(self).name, name)
241 )

AttributeError: 'DataArray' object has no attribute '_file_obj'

Screenshots or screencasts of the bug in action

image

@michaelaye
Copy link
Contributor Author

This looks really involved but is maybe simpler than it looks?

In datashader/core.py I'd change lines from 1133:

if source._file_obj is not None and hasattr(source._file_obj, 'nodata'):
            attrs['nodata'] = source._file_obj.nodata

to

if hasattr(source, "_file_obj") and source._file_obj is not None and hasattr(source._file_obj, 'nodata'):
            attrs['nodata'] = source._file_obj.nodata

unless the underlying issue is that source really should have an _file_obj and it should be set to None, instead of being missing?

@jbednar
Copy link
Member

jbednar commented Mar 3, 2021

From https://github.com/pydata/xarray/pull/4809/files#r557628298 it looks to me like _file_obj is no longer expected to exist at all, with that object stuffed inside a closure and really, clearly not being meant to be used. I would assume that we need to fix our code to find the nodata attribute some other more reliable way. I don't know where we were supposed to find it if not on _file_obj, though!

@ghost
Copy link

ghost commented Mar 3, 2021

Hello,

I do experience the same issue using:
xarray 0.17.0
hvplot 0.7.0
holoviews 1.14.1
bokeh 2.2.3
geoviews 1.8.1
python 3.8.5
notebook 6.2.0
OS: Ubuntu 18.04
Google Chrome (Chromium)

Where I use the hvplot.rgb(), adding rasterize=True generates the error below.


WARNING:param.dynamic_operation: Callable raised "AttributeError("'DataArray' object has no attribute '_file_obj'")".
Invoked as dynamic_operation(height=400, scale=1.0, width=400, x_range=None, y_range=None)

AttributeError Traceback (most recent call last)
/usr/local/lib/python3.8/dist-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:

/usr/local/lib/python3.8/dist-packages/holoviews/core/dimension.py in repr_mimebundle(self, include, exclude)
1314 combined and returned.
1315 """
-> 1316 return Store.render(self)
1317
1318

/usr/local/lib/python3.8/dist-packages/holoviews/core/options.py in render(cls, obj)
1403 data, metadata = {}, {}
1404 for hook in hooks:
-> 1405 ret = hook(obj)
1406 if ret is None:
1407 continue

/usr/local/lib/python3.8/dist-packages/holoviews/ipython/display_hooks.py in pprint_display(obj)
280 if not ip.display_formatter.formatters['text/plain'].pprint:
281 return None
--> 282 return display(obj, raw_output=True)
283
284

/usr/local/lib/python3.8/dist-packages/holoviews/ipython/display_hooks.py in display(obj, raw_output, **kwargs)
256 elif isinstance(obj, (HoloMap, DynamicMap)):
257 with option_state(obj):
--> 258 output = map_display(obj)
259 elif isinstance(obj, Plot):
260 output = render(obj)

/usr/local/lib/python3.8/dist-packages/holoviews/ipython/display_hooks.py in wrapped(element)
144 try:
145 max_frames = OutputSettings.options['max_frames']
--> 146 mimebundle = fn(element, max_frames=max_frames)
147 if mimebundle is None:
148 return {}, {}

/usr/local/lib/python3.8/dist-packages/holoviews/ipython/display_hooks.py in map_display(vmap, max_frames)
204 return None
205
--> 206 return render(vmap)
207
208

/usr/local/lib/python3.8/dist-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

/usr/local/lib/python3.8/dist-packages/holoviews/plotting/renderer.py in components(self, obj, fmt, comm, **kwargs)
408 doc = Document()
409 with config.set(embed=embed):
--> 410 model = plot.layout._render_model(doc, comm)
411 if embed:
412 return render_model(model, comm)

/usr/local/lib/python3.8/dist-packages/panel/viewable.py in _render_model(self, doc, comm)
422 if comm is None:
423 comm = state._comm_manager.get_server_comm()
--> 424 model = self.get_root(doc, comm)
425
426 if config.embed:

/usr/local/lib/python3.8/dist-packages/panel/viewable.py in get_root(self, doc, comm, preprocess)
480 """
481 doc = init_doc(doc)
--> 482 root = self._get_model(doc, comm=comm)
483 if preprocess:
484 self._preprocess(root)

/usr/local/lib/python3.8/dist-packages/panel/layout/base.py in _get_model(self, doc, root, parent, comm)
110 if root is None:
111 root = model
--> 112 objects = self._get_objects(model, [], doc, root, comm)
113 props = dict(self._init_properties(), objects=objects)
114 model.update(**self._process_param_change(props))

/usr/local/lib/python3.8/dist-packages/panel/layout/base.py in _get_objects(self, model, old_objects, doc, root, comm)
100 else:
101 try:
--> 102 child = pane._get_model(doc, root, model, comm)
103 except RerenderError:
104 return self._get_objects(model, current_objects[:i], doc, root, comm)

/usr/local/lib/python3.8/dist-packages/panel/pane/holoviews.py in _get_model(self, doc, root, parent, comm)
239 plot = self.object
240 else:
--> 241 plot = self._render(doc, comm, root)
242
243 plot.pane = self

/usr/local/lib/python3.8/dist-packages/panel/pane/holoviews.py in _render(self, doc, comm, root)
304 kwargs['comm'] = comm
305
--> 306 return renderer.get_plot(self.object, **kwargs)
307
308 def _cleanup(self, root):

/usr/local/lib/python3.8/dist-packages/holoviews/plotting/bokeh/renderer.py in get_plot(self_or_cls, obj, doc, renderer, **kwargs)
71 combining the bokeh model with another plot.
72 """
---> 73 plot = super(BokehRenderer, self_or_cls).get_plot(obj, doc, renderer, **kwargs)
74 if plot.document is None:
75 plot.document = Document() if self_or_cls.notebook_context else curdoc()

/usr/local/lib/python3.8/dist-packages/holoviews/plotting/renderer.py in get_plot(self_or_cls, obj, doc, renderer, comm, **kwargs)
218
219 # Initialize DynamicMaps with first data item
--> 220 initialize_dynamic(obj)
221
222 if not renderer:

/usr/local/lib/python3.8/dist-packages/holoviews/plotting/util.py in initialize_dynamic(obj)
250 continue
251 if not len(dmap):
--> 252 dmap[dmap._initial_key()]
253
254

/usr/local/lib/python3.8/dist-packages/holoviews/core/spaces.py in getitem(self, key)
1329 # Not a cross product and nothing cached so compute element.
1330 if cache is not None: return cache
-> 1331 val = self._execute_callback(*tuple_key)
1332 if data_slice:
1333 val = self._dataslice(val, data_slice)

/usr/local/lib/python3.8/dist-packages/holoviews/core/spaces.py in _execute_callback(self, *args)
1098
1099 with dynamicmap_memoization(self.callback, self.streams):
-> 1100 retval = self.callback(*args, **kwargs)
1101 return self._style(retval)
1102

/usr/local/lib/python3.8/dist-packages/holoviews/core/spaces.py in call(self, *args, **kwargs)
712
713 try:
--> 714 ret = self.callable(*args, **kwargs)
715 except KeyError:
716 # KeyError is caught separately because it is used to signal

/usr/local/lib/python3.8/dist-packages/holoviews/util/init.py in dynamic_operation(*key, **kwargs)
1016
1017 def dynamic_operation(*key, **kwargs):
-> 1018 key, obj = resolve(key, kwargs)
1019 return apply(obj, *key, **kwargs)
1020

/usr/local/lib/python3.8/dist-packages/holoviews/util/init.py in resolve(key, kwargs)
1005 elif isinstance(map_obj, DynamicMap) and map_obj._posarg_keys and not key:
1006 key = tuple(kwargs[k] for k in map_obj._posarg_keys)
-> 1007 return key, map_obj[key]
1008
1009 def apply(element, *key, **kwargs):

/usr/local/lib/python3.8/dist-packages/holoviews/core/spaces.py in getitem(self, key)
1329 # Not a cross product and nothing cached so compute element.
1330 if cache is not None: return cache
-> 1331 val = self._execute_callback(*tuple_key)
1332 if data_slice:
1333 val = self._dataslice(val, data_slice)

/usr/local/lib/python3.8/dist-packages/holoviews/core/spaces.py in _execute_callback(self, *args)
1098
1099 with dynamicmap_memoization(self.callback, self.streams):
-> 1100 retval = self.callback(*args, **kwargs)
1101 return self._style(retval)
1102

/usr/local/lib/python3.8/dist-packages/holoviews/core/spaces.py in call(self, *args, **kwargs)
712
713 try:
--> 714 ret = self.callable(*args, **kwargs)
715 except KeyError:
716 # KeyError is caught separately because it is used to signal

/usr/local/lib/python3.8/dist-packages/holoviews/util/init.py in dynamic_operation(*key, **kwargs)
1017 def dynamic_operation(*key, **kwargs):
1018 key, obj = resolve(key, kwargs)
-> 1019 return apply(obj, *key, **kwargs)
1020
1021 operation = self.p.operation

/usr/local/lib/python3.8/dist-packages/holoviews/util/init.py in apply(element, *key, **kwargs)
1009 def apply(element, *key, **kwargs):
1010 kwargs = dict(util.resolve_dependent_kwargs(self.p.kwargs), **kwargs)
-> 1011 processed = self._process(element, key, kwargs)
1012 if (self.p.link_dataset and isinstance(element, Dataset) and
1013 isinstance(processed, Dataset) and processed._dataset is None):

/usr/local/lib/python3.8/dist-packages/holoviews/util/init.py in _process(self, element, key, kwargs)
991 elif isinstance(self.p.operation, Operation):
992 kwargs = {k: v for k, v in kwargs.items() if k in self.p.operation.param}
--> 993 return self.p.operation.process_element(element, key, **kwargs)
994 else:
995 return self.p.operation(element, **kwargs)

/usr/local/lib/python3.8/dist-packages/holoviews/core/operation.py in process_element(self, element, key, **params)
192 self.p = param.ParamOverrides(self, params,
193 allow_extra_keywords=self._allow_extra_keywords)
--> 194 return self._apply(element, key)
195
196

/usr/local/lib/python3.8/dist-packages/holoviews/core/operation.py in _apply(self, element, key)
139 if not in_method:
140 element._in_method = True
--> 141 ret = self._process(element, key)
142 if hasattr(element, '_in_method') and not in_method:
143 element._in_method = in_method

/usr/local/lib/python3.8/dist-packages/holoviews/operation/datashader.py in _process(self, element, key)
1475 if k in transform.param})
1476 op._precomputed = self._precomputed
-> 1477 element = element.map(op, predicate)
1478 self._precomputed = op._precomputed
1479

/usr/local/lib/python3.8/dist-packages/holoviews/core/data/init.py in pipelined_fn(*args, **kwargs)
199
200 try:
--> 201 result = method_fn(*args, **kwargs)
202 if PipelineMeta.disable:
203 return result

/usr/local/lib/python3.8/dist-packages/holoviews/core/data/init.py in map(self, *args, **kwargs)
1214
1215 def map(self, *args, **kwargs):
-> 1216 return super(Dataset, self).map(*args, **kwargs)
1217 map.doc = LabelledData.map.doc
1218

/usr/local/lib/python3.8/dist-packages/holoviews/core/dimension.py in map(self, map_fn, specs, clone)
707 return deep_mapped
708 else:
--> 709 return map_fn(self) if applies else self
710
711

/usr/local/lib/python3.8/dist-packages/holoviews/core/operation.py in call(self, element, **kwargs)
212 elif ((self._per_element and isinstance(element, Element)) or
213 (not self._per_element and isinstance(element, ViewableElement))):
--> 214 return self._apply(element)
215 elif 'streams' not in kwargs:
216 kwargs['streams'] = self.p.streams

/usr/local/lib/python3.8/dist-packages/holoviews/core/operation.py in _apply(self, element, key)
139 if not in_method:
140 element._in_method = True
--> 141 ret = self._process(element, key)
142 if hasattr(element, '_in_method') and not in_method:
143 element._in_method = in_method

/usr/local/lib/python3.8/dist-packages/holoviews/operation/datashader.py in _process(self, element, key)
937 agg_fn = self._get_aggregator(element, add_field=False)
938 for vd, xarr in arrays.items():
--> 939 rarray = cvs.raster(xarr, upsample_method=interp,
940 downsample_method=agg_fn)
941

/usr/local/lib/python3.8/dist-packages/datashader/core.py in raster(self, source, layer, upsample_method, downsample_method, nan_value, agg, interpolate, chunksize, max_mem)
1131 dims = [ydim, xdim]
1132 attrs = dict(res=res[0])
-> 1133 if source._file_obj is not None and hasattr(source._file_obj, 'nodata'):
1134 attrs['nodata'] = source._file_obj.nodata
1135

/usr/local/lib/python3.8/dist-packages/xarray/core/common.py in getattr(self, name)
237 with suppress(KeyError):
238 return source[name]
--> 239 raise AttributeError(
240 "{!r} object has no attribute {!r}".format(type(self).name, name)
241 )

AttributeError: 'DataArray' object has no attribute '_file_obj'
:DynamicMap []

@jbednar
Copy link
Member

jbednar commented Mar 3, 2021

@dev-eo , you should be able to avoid the problem by pinning xarray<0.17.0. We don't have a proper fix yet, other than that.

@scottyhq
Copy link

scottyhq commented Mar 3, 2021

just hit the same thing. @philippjfr @jbednar in case it helps, this issue has been cropping up in other libraries with xarray as a dependency (see corteva/rioxarray#254, intake/intake-xarray#99 (comment)). There are some pretty big changes with backend I/O and indexing, so it might be good to add a test environment against xarray master.

@philippjfr
Copy link
Member

Closing since this is an upstream issue in datashader (see holoviz/datashader#990). Upstream testing of the master branch of all supported data backends seems like a good idea though. Could one of you file an issue about that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants