Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GridInterface bin support for Histogram and QuadMesh #2160

Merged
merged 25 commits into from
Dec 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
17f3fcb
Added GridInterface bin support for Histogram and QuadMesh
philippjfr Nov 28, 2017
7b8fa03
Fixed various issues for binned data
philippjfr Nov 29, 2017
dfd0261
Ensure QuadMesh uses GridInterface
philippjfr Nov 29, 2017
74fe640
Added Histogram values and edges properties for backward compatibility
philippjfr Nov 29, 2017
5e032fd
Added support for irregular meshes
philippjfr Nov 29, 2017
a646342
Improved support for irregular Datasets
philippjfr Nov 30, 2017
51dfbed
Improvements and docs for QuadMesh
philippjfr Nov 30, 2017
e9e1edd
Fixed bugs introduced by irregular data handling
philippjfr Nov 30, 2017
93052bc
Added old Histogram and QuadMesh pickle compatibility
philippjfr Nov 30, 2017
84ca707
Added gallery examples for irregular QuadMesh
philippjfr Nov 30, 2017
84743a5
Fixed interval breaks doctest
philippjfr Nov 30, 2017
2d62b34
Cleaned up colormesh utility
philippjfr Nov 30, 2017
d7d6b3e
Cleanup and fixes
philippjfr Dec 1, 2017
08fafd0
Handled scalar coords in xarray and grid interfaces
philippjfr Dec 5, 2017
c5db6b8
Allow slicing irregular meshes
philippjfr Dec 5, 2017
e5668ac
Guard array and dictionary interface against wrong dimensionality
philippjfr Dec 19, 2017
6af46f4
Added binned dataset tests
philippjfr Dec 19, 2017
af9724b
Implemented QuadMesh to TriMesh conversion
philippjfr Dec 19, 2017
981a218
Implemented QuadMesh datashader rasterization
philippjfr Dec 19, 2017
36a2ec4
Fixed array and dict interface validation
philippjfr Dec 19, 2017
7aabc20
Added unit tests for datashading QuadMesh
philippjfr Dec 20, 2017
2d346b2
Added strict validation for Image sampling
philippjfr Dec 20, 2017
298bbc4
Expanded on irregular meshes
philippjfr Dec 21, 2017
58676fb
Added comments for QuadMesh -> TriMesh conversion
philippjfr Dec 21, 2017
ee012a1
Losened Image sampling validation
philippjfr Dec 21, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading