Repository: holoviz/holoviews

Issue:
Path failing with vdims with categorical dtypes 

Noticed while updating the [opensky](https://examples.holoviz.org/opensky/opensky.html#opensky-gallery-opensky) example.

```python
import numpy as np
import pandas as pd
import holoviews as hv

hv.extension('bokeh')

df = pd.DataFrame({
    'x': np.random.randn(100),
    'y': np.random.randn(100),
    'cat': np.random.choice(['a', 'b', 'c'], 100)
})
df['cat'] = df['cat'].astype('category')
hv.Path(df, ['x', 'y'], vdims=['cat'])
```

End of the traceback:
```
File ~/dev/examples/opensky/envs/default/lib/python3.9/site-packages/holoviews/plotting/plot.py:819, in DimensionedPlot._compute_group_range(cls, group, elements, ranges, framewise, axiswise, robust, top_level, prev_frame)
    816     if (isinstance(values, np.ndarray) and values.dtype.kind == 'O' and
    817         all(isinstance(v, (np.ndarray)) for v in values)):
    818         values = np.concatenate(values) if len(values) else []
--> 819     factors = util.unique_array(values)
    820     group_ranges[dim_name]['factors'].append(factors)
    821 group_ranges[dim_name]['id'].append(id(el))

File ~/dev/examples/opensky/envs/default/lib/python3.9/site-packages/holoviews/core/util.py:1222, in unique_array(arr)
   1220         v = pd.Timestamp(v).to_datetime64()
   1221     values.append(v)
-> 1222 return pd.unique(np.asarray(values))

File ~/dev/examples/opensky/envs/default/lib/python3.9/site-packages/pandas/core/algorithms.py:401, in unique(values)
    307 def unique(values):
    308     """
    309     Return unique values based on a hash table.
    310 
   (...)
    399     array([('a', 'b'), ('b', 'a'), ('a', 'c')], dtype=object)
    400     """
--> 401     return unique_with_mask(values)

File ~/dev/examples/opensky/envs/default/lib/python3.9/site-packages/pandas/core/algorithms.py:440, in unique_with_mask(values, mask)
    438 table = hashtable(len(values))
    439 if mask is None:
--> 440     uniques = table.unique(values)
    441     uniques = _reconstruct_data(uniques, original.dtype, original)
    442     return uniques

File pandas/_libs/hashtable_class_helper.pxi:6968, in pandas._libs.hashtable.StringHashTable.unique()

ValueError: Buffer has wrong number of dimensions (expected 1, got 2)
```


Discussion:

Resolving patch:
diff --git a/holoviews/core/util.py b/holoviews/core/util.py
--- a/holoviews/core/util.py
+++ b/holoviews/core/util.py
@@ -1218,8 +1218,10 @@ def unique_array(arr):
         if (isinstance(v, datetime_types) and
             not isinstance(v, cftime_types)):
             v = pd.Timestamp(v).to_datetime64()
+        elif isinstance(getattr(v, "dtype", None), pd.CategoricalDtype):
+            v = v.dtype.categories
         values.append(v)
-    return pd.unique(np.asarray(values))
+    return pd.unique(np.asarray(values).ravel())
 
 
 def match_spec(element, specification):


Test patch:
diff --git a/holoviews/tests/core/test_utils.py b/holoviews/tests/core/test_utils.py
--- a/holoviews/tests/core/test_utils.py
+++ b/holoviews/tests/core/test_utils.py
@@ -28,6 +28,7 @@
     sanitize_identifier_fn,
     search_indices,
     tree_attribute,
+    unique_array,
     wrap_tuple_streams,
 )
 from holoviews.element.comparison import ComparisonTestCase
@@ -799,3 +800,9 @@ def test_seach_indices_dtype_object():
     values = np.array(["c0", "c0", np.nan], dtype=object)
     source = np.array(["c0", np.nan], dtype=object)
     search_indices(values, source)
+
+
+def test_unique_array_categorial():
+    ser = pd.Series(np.random.choice(["a", "b", "c"], 100)).astype("category")
+    res = unique_array([ser])
+    assert sorted(res) == ["a", "b", "c"]