Skip to content

Commit

Permalink
GridInterface bin support for Histogram and QuadMesh (#2160)
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr authored and jlstevens committed Dec 22, 2017
1 parent 8b03af9 commit 0f5ad5d
Show file tree
Hide file tree
Showing 33 changed files with 1,089 additions and 572 deletions.
84 changes: 84 additions & 0 deletions examples/gallery/demos/bokeh/irregular_quadmesh.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Most examples work across multiple plotting backends, this example is also available for:\n",
"\n",
"* [Matplotlib irregular_quadmesh](../matplotlib/irregular_quadmesh.ipynb)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import holoviews as hv\n",
"hv.extension('bokeh')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Declaring data"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"n = 20\n",
"coords = np.linspace(-1.5, 1.5, n)\n",
"X,Y = np.meshgrid(coords, coords);\n",
"Qx = np.cos(Y) - np.cos(X)\n",
"Qz = np.sin(Y) + np.sin(X)\n",
"Z = np.sqrt(X**2 + Y**2)\n",
"\n",
"qmesh = hv.QuadMesh((Qx, Qz, Z))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plot"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"qmesh"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
85 changes: 85 additions & 0 deletions examples/gallery/demos/matplotlib/irregular_quadmesh.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Most examples work across multiple plotting backends, this example is also available for:\n",
"\n",
"* [Bokeh irregular_quadmesh](../bokeh/irregular_quadmesh.ipynb)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import holoviews as hv\n",
"hv.extension('matplotlib')\n",
"%output fig='svg'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Declaring data\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"n = 20\n",
"coords = np.linspace(-1.5, 1.5, n)\n",
"X,Y = np.meshgrid(coords, coords);\n",
"Qx = np.cos(Y) - np.cos(X)\n",
"Qz = np.sin(Y) + np.sin(X)\n",
"Z = np.sqrt(X**2 + Y**2)\n",
"\n",
"qmesh = hv.QuadMesh((Qx, Qz, Z))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plot"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"qmesh"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
70 changes: 69 additions & 1 deletion examples/reference/elements/bokeh/QuadMesh.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
"xs = np.logspace(1, 3, n)\n",
"ys = np.linspace(1, 10, n)\n",
"zs = np.arange((n-1)**2).reshape(n-1, n-1)\n",
"print('Shape of x-coordinates:', xs.shape)\n",
"print('Shape of y-coordinates:', ys.shape)\n",
"print('Shape of value array:', zs.shape)\n",
"hv.QuadMesh((xs, ys, zs))"
]
},
Expand Down Expand Up @@ -106,12 +109,77 @@
"\n",
"For full documentation and the available style and plot options, use ``hv.help(hv.QuadMesh).``"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Irregular meshes\n",
"\n",
"In addition to axis aligned meshes like those we worked with above, a ``QuadMesh`` may also be used to represent irregular or unstructured meshes. In this example we will create an irregular mesh consisting of 2D X, Y and Z arrays defining the position and value of each simplex in the mesh:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"n=20\n",
"coords = np.linspace(-1.5,1.5,n)\n",
"X,Y = np.meshgrid(coords, coords);\n",
"Qx = np.cos(Y) - np.cos(X)\n",
"Qy = np.sin(Y) + np.sin(X)\n",
"Z = np.sqrt(X**2 + Y**2)\n",
"\n",
"print('Shape of x-coordinates:', Qx.shape)\n",
"print('Shape of y-coordinates:', Qy.shape)\n",
"print('Shape of value array:', Z.shape)\n",
"\n",
"qmesh = hv.QuadMesh((Qx, Qy, Z))\n",
"qmesh"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To illustrate irregular meshes a bit further we will randomly jitter the mesh coordinates along both dimensions, demonstrating that ``QuadMesh`` may be used to represent completely arbitrary meshes. It may also be used to represent overlapping meshes, however the behavior during slicing and other operations may not be well defined in such cases."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.random.seed(13)\n",
"xs, ys = np.meshgrid(np.linspace(-20, 20, 10), np.linspace(0, 30, 8))\n",
"xs += xs/10 + np.random.rand(*xs.shape)*4\n",
"ys += ys/10 + np.random.rand(*ys.shape)*4\n",
"\n",
"zs = np.arange(80).reshape(8, 10)\n",
"hv.QuadMesh((xs, ys, zs))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"pygments_lexer": "ipython3"
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
Expand Down
70 changes: 69 additions & 1 deletion examples/reference/elements/matplotlib/QuadMesh.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
"xs = np.logspace(1, 3, n)\n",
"ys = np.linspace(1, 10, n)\n",
"zs = np.arange((n-1)**2).reshape(n-1, n-1)\n",
"print('Shape of x-coordinates:', xs.shape)\n",
"print('Shape of y-coordinates:', ys.shape)\n",
"print('Shape of value array:', zs.shape)\n",
"hv.QuadMesh((xs, ys, zs))"
]
},
Expand Down Expand Up @@ -88,12 +91,77 @@
"\n",
"For full documentation and the available style and plot options, use ``hv.help(hv.QuadMesh).``"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Irregular meshes\n",
"\n",
"In addition to axis aligned meshes like those we worked with above, a ``QuadMesh`` may also be used to represent irregular or unstructured meshes. In this example we will create an irregular mesh consisting of 2D X, Y and Z arrays defining the position and value of each simplex in the mesh:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"n=20\n",
"coords = np.linspace(-1.5,1.5,n)\n",
"X,Y = np.meshgrid(coords, coords);\n",
"Qx = np.cos(Y) - np.cos(X)\n",
"Qy = np.sin(Y) + np.sin(X)\n",
"Z = np.sqrt(X**2 + Y**2)\n",
"\n",
"print('Shape of x-coordinates:', Qx.shape)\n",
"print('Shape of y-coordinates:', Qy.shape)\n",
"print('Shape of value array:', Z.shape)\n",
"\n",
"qmesh = hv.QuadMesh((Qx, Qy, Z))\n",
"qmesh"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To illustrate irregular meshes a bit further we will randomly jitter the mesh coordinates along both dimensions, demonstrating that ``QuadMesh`` may be used to represent completely arbitrary meshes. It may also be used to represent overlapping meshes, however the behavior during slicing and other operations may not be well defined in such cases."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.random.seed(13)\n",
"xs, ys = np.meshgrid(np.linspace(-20, 20, 10), np.linspace(0, 30, 8))\n",
"xs += xs/10 + np.random.rand(*xs.shape)*4\n",
"ys += ys/10 + np.random.rand(*ys.shape)*4\n",
"\n",
"zs = np.arange(80).reshape(8, 10)\n",
"hv.QuadMesh((xs, ys, zs))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"pygments_lexer": "ipython3"
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
Expand Down
5 changes: 4 additions & 1 deletion holoviews/core/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ class Dataset(Element):
# Define a class used to transform Datasets into other Element types
_conversion_interface = DataConversion

# Whether the key dimensions are specified as bins
_binned = False

_vdim_reductions = {}
_kdim_reductions = {}

Expand Down Expand Up @@ -361,7 +364,7 @@ def __getitem__(self, slices):
value_select = slices[self.ndims]
elif len(slices) == self.ndims+1 and isinstance(slices[self.ndims],
(Dimension,str)):
raise Exception("%r is not an available value dimension" % slices[self.ndims])
raise IndexError("%r is not an available value dimension" % slices[self.ndims])
else:
selection = dict(zip(self.dimensions(label=True), slices))
data = self.select(**selection)
Expand Down
4 changes: 3 additions & 1 deletion holoviews/core/data/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ def init(cls, eltype, data, kdims, vdims):
for k, v in dict_data))
data = np.column_stack(dataset)
elif isinstance(data, tuple):
data = [d if isinstance(d, np.ndarray) else np.array(d) for d in data]
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 = np.column_stack(data)
else:
Expand Down
5 changes: 4 additions & 1 deletion holoviews/core/data/dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ def init(cls, eltype, data, kdims, vdims):
for i, sd in enumerate(d):
unpacked.append((sd, vals[:, i]))
else:
unpacked.append((d, vals if np.isscalar(vals) else np.asarray(vals)))
vals = vals if np.isscalar(vals) else np.asarray(vals)
if not np.isscalar(vals) and not vals.ndim == 1:
raise ValueError('DictInterface expects data for each column to be flat.')
unpacked.append((d, vals))
if not cls.expanded([d[1] for d in unpacked if not np.isscalar(d[1])]):
raise ValueError('DictInterface expects data to be of uniform shape.')
if isinstance(data, odict_types):
Expand Down

0 comments on commit 0f5ad5d

Please sign in to comment.