Repository: holoviz/hvplot

Issue:
hvplot.hist with ibis+duckdb: ValueError: The truth value of an Ibis expression is not defined
hvplot==0.8.1

I'm trying to contribute a guide for ibis + DuckDB. When I try to plot a `hist` plot I get `ValueError: The truth value of an Ibis expression is not defined`.

```python
import duckdb
import ibis
import pandas as pd

from pathlib import Path
import hvplot.ibis
import holoviews as hv

hvplot.extension("plotly")

DUCKDB_PATH = "DuckDB.db"

if not Path(DUCKDB_PATH).exists():
    pandas_df = pd.DataFrame(
        {
            "actual": [100, 150, 125, 140, 145, 135, 123],
            "forecast": [90, 160, 125, 150, 141, 141, 120],
            "numerical": [1.1, 1.9, 3.2, 3.8, 4.3, 5.0, 5.5],
            "date": pd.date_range("2022-01-03", "2022-01-09"),
            "string": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
        },
    )
    duckdb_con = duckdb.connect(DUCKDB_PATH)
    duckdb_con.execute("CREATE TABLE df AS SELECT * FROM pandas_df")

ibis.options.sql.default_limit = None

db = ibis.duckdb.connect(DUCKDB_PATH)

df = db.table("df")
df.hvplot.hist("forecast", bins=3)
```

```bash
C:\repos\private\hvplot\.venv\lib\site-packages\ibis\backends\postgres\registry.py:164: UserWarning: locale specific date formats (%c, %x, %X) are not yet implemented for Windows
  warnings.warn(
C:\repos\private\hvplot\.venv\lib\site-packages\duckdb_engine\__init__.py:229: DuckDBEngineWarning: duckdb-engine doesn't yet support 
reflection on indices
  warnings.warn(
Traceback (most recent call last):
  File "C:\repos\private\hvplot\script2.py", line 31, in <module>
    df.hvplot.hist("forecast", bins=3)
  File "C:\repos\private\hvplot\hvplot\plotting\core.py", line 1309, in hist
    return self(kind="hist", x=None, y=y, by=by, **kwds)
  File "C:\repos\private\hvplot\hvplot\plotting\core.py", line 92, in __call__
    return self._get_converter(x, y, kind, **kwds)(kind, x, y)
  File "C:\repos\private\hvplot\hvplot\converter.py", line 1240, in __call__
    obj = method(x, y)
  File "C:\repos\private\hvplot\hvplot\converter.py", line 1820, in hist
    hists = histogram(ds, dimension=y, **hist_opts)
  File "C:\repos\private\hvplot\.venv\lib\site-packages\param\parameterized.py", line 3654, in __new__
    return inst.__call__(*args,**params)
  File "c:\repos\private\tmp\holoviews\holoviews\core\operation.py", line 220, in __call__
    return element.apply(self, **kwargs)
  File "c:\repos\private\tmp\holoviews\holoviews\core\accessors.py", line 45, in pipelined_call
    result = __call__(*args, **kwargs)
  File "c:\repos\private\tmp\holoviews\holoviews\core\accessors.py", line 202, in __call__
    new_obj = apply_function(self._obj, **inner_kwargs)
  File "c:\repos\private\tmp\holoviews\holoviews\core\operation.py", line 214, in __call__
    return self._apply(element)
  File "c:\repos\private\tmp\holoviews\holoviews\core\operation.py", line 141, in _apply
    ret = self._process(element, key)
  File "c:\repos\private\tmp\holoviews\holoviews\operation\element.py", line 785, in _process
    null_hist_range = hist_range == (0, 0)
  File "C:\repos\private\hvplot\.venv\lib\site-packages\ibis\expr\types\core.py", line 68, in __bool__
    raise ValueError(
ValueError: The truth value of an Ibis expression is not defined
```


Discussion:

Resolving patch:
diff --git a/hvplot/converter.py b/hvplot/converter.py
--- a/hvplot/converter.py
+++ b/hvplot/converter.py
@@ -1860,6 +1860,8 @@ def hist(self, x=None, y=None, data=None):
                 ymin, ymax = (ys.min(), ys.max())
                 if is_dask(ys):
                     ymin, ymax = ymin.compute(), ymax.compute()
+                elif is_ibis(ys):
+                    ymin, ymax = ymin.execute(), ymax.execute()
                 hist_opts['bin_range'] = ymin, ymax
 
             ds = Dataset(data, self.by)
@@ -1883,6 +1885,8 @@ def hist(self, x=None, y=None, data=None):
                 ymin, ymax = (ys.min(), ys.max())
                 if is_dask(ys):
                     ymin, ymax = ymin.compute(), ymax.compute()
+                elif is_ibis(ys):
+                    ymin, ymax = ymin.execute(), ymax.execute()
                 ranges.append((ymin, ymax))
         if ranges:
             hist_opts['bin_range'] = max_range(ranges)
diff --git a/hvplot/ibis.py b/hvplot/ibis.py
--- a/hvplot/ibis.py
+++ b/hvplot/ibis.py
@@ -1,3 +1,7 @@
+"""
+Experimental support for ibis.
+"""
+
 def patch(name='hvplot', extension='bokeh', logo=False):
     from . import hvPlotTabular, post_patch
 
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -63,6 +63,7 @@ def get_setup_version(reponame):
     'dask',
     'polars',
     'fugue',
+    'ibis-framework',  # ibis-sqlite on conda
 ]
 
 # Dependencies required to run the notebooks


Test patch:
diff --git a/hvplot/tests/testibis.py b/hvplot/tests/testibis.py
--- a/hvplot/tests/testibis.py
+++ b/hvplot/tests/testibis.py
@@ -1,22 +1,19 @@
-"""Ibis works with hvplot"""
+"""Basic ibis tests"""
+
+import numpy as np
+import pandas as pd
 import pytest
 
 try:
+    import hvplot.ibis  # noqa
     import ibis
-    import hvplot.ibis # noqa
-    import pandas as pd
-except:
+except ImportError:
     pytest.skip(allow_module_level=True)
+else:
+    ibis.set_backend('sqlite')
 
 
-@pytest.fixture
-def table():
-    df = pd.DataFrame({
-        "x": [pd.Timestamp("2022-01-01"), pd.Timestamp("2022-01-02")], "y": [1,2]
-    })
-    con = ibis.pandas.connect({"df": df})
-    return con.table("df")
-
-def test_can_hvplot(table):
-    """hvplot works with Ibis"""
-    table.hvplot(x="x", y="y")
+def test_ibis_hist():
+    df = pd.DataFrame(dict(x=np.arange(10)))
+    table = ibis.memtable(df)
+    table.hvplot.hist('x')