diff --git a/doc/Tutorials/Columnar_Data.ipynb b/doc/Tutorials/Columnar_Data.ipynb index e94ffce45b..9c5425207f 100644 --- a/doc/Tutorials/Columnar_Data.ipynb +++ b/doc/Tutorials/Columnar_Data.ipynb @@ -46,7 +46,7 @@ "metadata": {}, "outputs": [], "source": [ - "xs = range(10)\n", + "xs = np.arange(10)\n", "ys = np.exp(xs)\n", "\n", "table = hv.Table((xs, ys), kdims=['x'], vdims=['y'])\n", @@ -185,7 +185,7 @@ "metadata": {}, "outputs": [], "source": [ - "print(type(hv.Scatter((xs, ys), datatype=['array']).data))\n", + "print(type(hv.Scatter((xs.astype('float64'), ys), datatype=['array']).data))\n", "print(type(hv.Scatter((xs, ys), datatype=['dictionary']).data))\n", "print(type(hv.Scatter((xs, ys), datatype=['dataframe']).data))" ] diff --git a/doc/nbpublisher b/doc/nbpublisher index 4d41d4b7bb..d710f20f05 160000 --- a/doc/nbpublisher +++ b/doc/nbpublisher @@ -1 +1 @@ -Subproject commit 4d41d4b7bb72e760bb1da97faffc197130a4828a +Subproject commit d710f20f05505757ef97ae4f36919439b11fd9c4 diff --git a/examples/user_guide/07-Tabular_Datasets.ipynb b/examples/user_guide/07-Tabular_Datasets.ipynb index c1875136da..63549879d1 100644 --- a/examples/user_guide/07-Tabular_Datasets.ipynb +++ b/examples/user_guide/07-Tabular_Datasets.ipynb @@ -73,7 +73,7 @@ "metadata": {}, "outputs": [], "source": [ - "xs = range(10)\n", + "xs = np.arange(10)\n", "ys = np.exp(xs)\n", "\n", "table = hv.Table((xs, ys), 'x', 'y')\n", @@ -201,7 +201,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Note these include grid based datatypes, which are covered in [Gridded Datasets](http://holoviews.org/user_guide/Gridded_Datasets.html). To select a particular storage format explicitly, supply one or more allowed datatypes:" + "Note these include grid based datatypes, which are covered in [Gridded Datasets](http://holoviews.org/user_guide/Gridded_Datasets.html). To select a particular storage format explicitly, supply one or more allowed datatypes (note that the 'array' interface only supports data with matching types):" ] }, { @@ -210,7 +210,7 @@ "metadata": {}, "outputs": [], "source": [ - "print(type(hv.Scatter((xs, ys), datatype=['array']).data))\n", + "print(type(hv.Scatter((xs.astype('float64'), ys), datatype=['array']).data))\n", "print(type(hv.Scatter((xs, ys), datatype=['dictionary']).data))\n", "print(type(hv.Scatter((xs, ys), datatype=['dataframe']).data))" ] diff --git a/holoviews/core/data/__init__.py b/holoviews/core/data/__init__.py index 02e86d533a..d709b95932 100644 --- a/holoviews/core/data/__init__.py +++ b/holoviews/core/data/__init__.py @@ -17,12 +17,12 @@ from .multipath import MultiInterface # noqa (API import) from .image import ImageInterface # noqa (API import) -datatypes = ['array', 'dictionary', 'grid'] +datatypes = ['dictionary', 'grid'] try: import pandas as pd # noqa (Availability import) from .pandas import PandasInterface - datatypes = ['array', 'dataframe', 'dictionary', 'grid', 'ndelement'] + datatypes = ['dataframe', 'dictionary', 'grid', 'ndelement', 'array'] DFColumns = PandasInterface except ImportError: pass @@ -53,6 +53,9 @@ except ImportError: pass +if 'array' not in datatypes: + datatypes.append('array') + from ..dimension import Dimension, process_dimensions from ..element import Element from ..ndmapping import OrderedDict diff --git a/holoviews/core/data/array.py b/holoviews/core/data/array.py index 973a7ba060..607fcbbe47 100644 --- a/holoviews/core/data/array.py +++ b/holoviews/core/data/array.py @@ -33,7 +33,9 @@ def init(cls, eltype, data, kdims, vdims): d for d in kdims + vdims] if ((isinstance(data, dict) or util.is_dataframe(data)) and all(d in data for d in dimensions)): - dataset = [data[d] for d in dimensions] + dataset = [d if isinstance(d, np.ndarray) else np.asarray(data[d]) for d in dimensions] + if len(set(d.dtype.kind for d in dataset)) > 1: + raise ValueError('ArrayInterface expects all columns to be of the same dtype') data = np.column_stack(dataset) elif isinstance(data, dict) and not all(d in data for d in dimensions): dict_data = sorted(data.items()) @@ -41,10 +43,10 @@ def init(cls, eltype, data, kdims, vdims): for k, v in dict_data)) data = np.column_stack(dataset) elif isinstance(data, tuple): - data = [np.asarray(d) for d in data] - if any(arr.ndim > 1 for arr in data): - raise ValueError('ArrayInterface expects data to be of flat shape.') - if cls.expanded(data): + data = [d if isinstance(d, np.ndarray) else np.asarray(d) for d in data] + if len(set(d.dtype.kind for d in data)) > 1: + raise ValueError('ArrayInterface expects all columns to be of the same dtype') + elif cls.expanded(data): data = np.column_stack(data) else: raise ValueError('ArrayInterface expects data to be of uniform shape.') diff --git a/holoviews/element/util.py b/holoviews/element/util.py index 7e67dc831b..3dc5c3218b 100644 --- a/holoviews/element/util.py +++ b/holoviews/element/util.py @@ -178,6 +178,7 @@ def _aggregate_dataset(self, obj, xcoords, ycoords): xdim, ydim = dim_labels[:2] shape = (len(ycoords), len(xcoords)) nsamples = np.product(shape) + grid_data = {xdim: xcoords, ydim: ycoords} ys, xs = cartesian_product([ycoords, xcoords], copy=True) data = {xdim: xs, ydim: ys} @@ -189,7 +190,9 @@ def _aggregate_dataset(self, obj, xcoords, ycoords): dense_data = Dataset(data, kdims=obj.kdims, vdims=obj.vdims, datatype=[dtype]) concat_data = obj.interface.concatenate([dense_data, obj], datatype=[dtype]) reindexed = concat_data.reindex([xdim, ydim], vdims) - if pd: + if not reindexed: + agg = reindexed + elif pd: df = PandasInterface.as_dframe(reindexed) df = df.groupby([xdim, ydim], sort=False).first().reset_index() agg = reindexed.clone(df) @@ -197,7 +200,6 @@ def _aggregate_dataset(self, obj, xcoords, ycoords): agg = reindexed.aggregate([xdim, ydim], reduce_fn) # Convert data to a gridded dataset - grid_data = {xdim: xcoords, ydim: ycoords} for vdim in vdims: grid_data[vdim.name] = agg.dimension_values(vdim).reshape(shape) return agg.clone(grid_data, kdims=[xdim, ydim], vdims=vdims, diff --git a/holoviews/operation/element.py b/holoviews/operation/element.py index 2334072025..4e80d68b7a 100644 --- a/holoviews/operation/element.py +++ b/holoviews/operation/element.py @@ -692,6 +692,8 @@ def _process_layer(self, element, key=None): if self.p.interpolation not in INTERPOLATE_FUNCS: return element x, y = element.dimension_values(0), element.dimension_values(1) + if 'f' in (x.dtype.kind, y.dtype.kind): + x, y = x.astype('float'), y.astype('float') array = INTERPOLATE_FUNCS[self.p.interpolation](x, y) dvals = tuple(element.dimension_values(d) for d in element.dimensions()[2:]) return element.clone((array[0, :].astype(x.dtype), array[1, :].astype(y.dtype))+dvals) diff --git a/tests/core/data/testdataset.py b/tests/core/data/testdataset.py index cf7d4d3bf2..1d35fa4626 100644 --- a/tests/core/data/testdataset.py +++ b/tests/core/data/testdataset.py @@ -849,6 +849,20 @@ def test_dataset_simple_dict_sorted(self): self.assertEqual(dataset, Dataset([(i, i) for i in range(1, 4)], kdims=['x'], vdims=['y'])) + def test_dataset_sort_hm(self): + ds = Dataset(([2, 2, 1], [2,1,2], [1, 2, 3]), + kdims=['x', 'y'], vdims=['z']).sort() + ds_sorted = Dataset(([1, 2, 2], [2, 1, 2], [3, 2, 1]), + kdims=['x', 'y'], vdims=['z']) + self.assertEqual(ds.sort(), ds_sorted) + + def test_dataset_sort_reverse_hm(self): + ds = Dataset(([2, 1, 2, 1], [2, 2, 1, 1], [0, 1, 2, 3]), + kdims=['x', 'y'], vdims=['z']) + ds_sorted = Dataset(([2, 2, 1, 1], [2, 1, 2, 1], [0, 2, 1, 3]), + kdims=['x', 'y'], vdims=['z']) + self.assertEqual(ds.sort(reverse=True), ds_sorted) + class DFDatasetTest(HeterogeneousColumnTypes, ComparisonTestCase):