holoviz / holoviews

With Holoviews, your data visualizes itself.
https://holoviews.org
BSD 3-Clause "New" or "Revised" License
2.7k stars 403 forks source link

decimate not working with ibis #5524

Open MarcSkovMadsen opened 1 year ago

MarcSkovMadsen commented 1 year ago

I'm on the current master branch of HoloViews. I get an error when I try to use decimate with an ibis table.

import pandas as pd
import panel as pn

import holoviews as hv
from holoviews.operation import decimate
import ibis

pn.extension(sizing_mode="stretch_width")

decimate.max_samples=1000

df = pd.DataFrame({
    "x": list(range(0,10000)),
    "y": list(range(0,10000)),
})

con = ibis.pandas.connect({"df": df})
table = con.table("df")

plot = hv.Curve(table, kdims=["x"], vdims=["y"]).opts(height=500)
plot = decimate(plot)
pn.panel(plot).servable()
panel serve script.py

image

AttributeError: 'tuple' object has no attribute 'columns'
Traceback (most recent call last):
  File "C:\repos\private\holoviews\.venv\lib\site-packages\bokeh\application\handlers\code_runner.py", line 231, in run
    exec(self._code, module.__dict__)
  File "C:\repos\private\holoviews\script.py", line 39, in <module>
    pn.panel(plot).servable()
  File "C:\repos\private\holoviews\.venv\lib\site-packages\panel\viewable.py", line 379, in servable
    self.server_doc(title=title, location=location) # type: ignore
  File "C:\repos\private\holoviews\.venv\lib\site-packages\panel\viewable.py", line 871, in server_doc
    model = self.get_root(doc)
  File "C:\repos\private\holoviews\.venv\lib\site-packages\panel\pane\base.py", line 316, in get_root
    root = self.layout._get_model(doc, comm=comm)
  File "C:\repos\private\holoviews\.venv\lib\site-packages\panel\layout\base.py", line 146, in _get_model
    objects = self._get_objects(model, [], doc, root, comm)
  File "C:\repos\private\holoviews\.venv\lib\site-packages\panel\layout\base.py", line 131, in _get_objects
    child = pane._get_model(doc, root, model, comm)
  File "C:\repos\private\holoviews\.venv\lib\site-packages\panel\pane\holoviews.py", line 265, in _get_model
    plot = self._render(doc, comm, root)
  File "C:\repos\private\holoviews\.venv\lib\site-packages\panel\pane\holoviews.py", line 342, in _render
    return renderer.get_plot(self.object, **kwargs)
  File "C:\repos\private\holoviews\holoviews\plotting\renderer.py", line 217, in get_plot
    initialize_dynamic(obj)
  File "C:\repos\private\holoviews\holoviews\plotting\util.py", line 257, in initialize_dynamic
    dmap[dmap._initial_key()]
  File "C:\repos\private\holoviews\holoviews\core\spaces.py", line 1217, in __getitem__
    val = self._execute_callback(*tuple_key)
  File "C:\repos\private\holoviews\holoviews\core\spaces.py", line 984, in _execute_callback
    retval = self.callback(*args, **kwargs)
  File "C:\repos\private\holoviews\holoviews\core\spaces.py", line 582, in __call__
    ret = self.callable(*args, **kwargs)
  File "C:\repos\private\holoviews\holoviews\util\__init__.py", line 1013, in dynamic_operation
    return apply(obj, *key, **kwargs)
  File "C:\repos\private\holoviews\holoviews\util\__init__.py", line 1005, in apply
    processed = self._process(element, key, kwargs)
  File "C:\repos\private\holoviews\holoviews\util\__init__.py", line 987, in _process
    return self.p.operation.process_element(element, key, **kwargs)
  File "C:\repos\private\holoviews\holoviews\core\operation.py", line 194, in process_element
    return self._apply(element, key)
  File "C:\repos\private\holoviews\holoviews\core\operation.py", line 141, in _apply
    ret = self._process(element, key)
  File "C:\repos\private\holoviews\holoviews\operation\element.py", line 917, in _process
    return element.map(self._process_layer, Element)
  File "C:\repos\private\holoviews\holoviews\core\data\__init__.py", line 204, in pipelined_fn
    result = method_fn(*args, **kwargs)
  File "C:\repos\private\holoviews\holoviews\core\data\__init__.py", line 1216, in map
    return super(Dataset, self).map(*args, **kwargs)
  File "C:\repos\private\holoviews\holoviews\core\dimension.py", line 700, in map
    return map_fn(self) if applies else self
  File "C:\repos\private\holoviews\holoviews\operation\element.py", line 900, in _process_layer
    element = element.clone(tuple(element.columns().values()))
  File "C:\repos\private\holoviews\holoviews\core\data\__init__.py", line 1206, in clone
    return super(Dataset, self).clone(data, shared_data, new_type, *args, **overrides)
  File "C:\repos\private\holoviews\holoviews\core\dimension.py", line 566, in clone
    return clone_type(data, *args, **{k:v for k,v in settings.items()
  File "C:\repos\private\holoviews\holoviews\element\selection.py", line 23, in __init__
    super().__init__(*args, **kwargs)
  File "C:\repos\private\holoviews\holoviews\element\chart.py", line 51, in __init__
    super().__init__(data, **params)
  File "C:\repos\private\holoviews\holoviews\core\data\__init__.py", line 342, in __init__
    self.interface.validate(self, validate_vdims)
  File "C:\repos\private\holoviews\holoviews\core\data\pandas.py", line 157, in validate
    cols = list(dataset.data.columns)
AttributeError: 'tuple' object has no attribute 'columns'
MarcSkovMadsen commented 1 year ago

The issue seems to be here

image

element.interface is of type holoviews.core.data.ibis.IbisInterface which is not in column_interfaces.

image

MarcSkovMadsen commented 1 year ago

I can see that if I add a workaround for this issue then another issue just pops up. To me it seems the ibis interface has never been thoroughly tested (with decimate). So please make the example work, not just the first issue encountered. Thanks.