Skip to content

Commit

Permalink
Merge dc96dad into 98853fe
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Apr 29, 2020
2 parents 98853fe + dc96dad commit 1dc4ede
Show file tree
Hide file tree
Showing 23 changed files with 806 additions and 247 deletions.
111 changes: 73 additions & 38 deletions examples/user_guide/Linked_Brushing.ipynb
Expand Up @@ -135,7 +135,15 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"The same `box_select` tool should now work as for the `gridmatrix` plot, but this time by calling back to Python. There are now many more options and capabilities available, as described below, but by default you can now also select additional regions in different elements, and the selected points will be those that match _all_ of the selections, so that you can precisely specify the data points of interest with constraints on _all_ dimensions at once. A bounding box will be shown for each selection, but only the overall selected points (across all selection dimensions) will be highlighted in each plot. You can use the reset tool to clear all the selections and start over."
"The same `box_select` and `lasso_select` tools should now work as for the `gridmatrix` plot, but this time by calling back to Python. There are now many more options and capabilities available, as described below, but by default you can now also select additional regions in different elements, and the selected points will be those that match _all_ of the selections, so that you can precisely specify the data points of interest with constraints on _all_ dimensions at once. A bounding box will be shown for each selection, but only the overall selected points (across all selection dimensions) will be highlighted in each plot. You can use the reset tool to clear all the selections and start over.\n",
"\n",
"## Box-select vs Lasso-select\n",
"\n",
"Since HoloViews version 1.13.3 linked brushing supports both the `box_select` and `lasso_select` tools. The lasso selection provides more fine-grained control about the exact region to include in the selection, however it is a much more expensive operation and will not scale as well to very large columnar datasets. Additionally lasso select has a number of dependencies:\n",
"\n",
"* Lasso-select on tabular data requires either `spatialpandas` or `shapely`\n",
"* Lasso-select on gridded data requires `datashader`\n",
"* Lasso-select on geometry data requires `shapely`"
]
},
{
Expand Down Expand Up @@ -501,58 +509,85 @@
"<th class=\"sL\">Display selections</th>\n",
"<th class=\"sL\">Index-based selections</th>\n",
"<th class=\"sL\">Range-based selections</th>\n",
"<th class=\"sL\">Lasso-based selections</th>\n",
"<th class=\"sL\">Notes</th>\n",
"</tr></thead>\n",
"<tbody>\n",
"\n",
"<tr><td class=\"sG\">Area</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">Area</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sN\">No </td></tr>\n",
"<tr><td class=\"sG\">Bars</td><td class=\"sN\">No </td><td class=\"sN\">No </td><td class=\"sN\">No </td>\n",
" <td>Complicated to support stacked and multi-level bars</td></tr>\n",
"<tr><td class=\"sG\">Bivariate</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">BoxWhisker</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
" <td class=\"sN\">No </td><td>Complicated to support stacked and multi-level bars</td></tr>\n",
"<tr><td class=\"sG\">Bivariate</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">BoxWhisker</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sN\">No </td></tr>\n",
"<tr><td class=\"sG\">Chord</td><td class=\"sN\">No </td><td class=\"sN\">No </td><td class=\"sN\">No </td>\n",
" <td>Complicated to support composite elements</td>\n",
"<tr><td class=\"sG\">Contours</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td></tr>\n",
"<tr><td class=\"sG\">Curve</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">Distribution</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">ErrorBars</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td><td class=\"sN\">No </td></tr>\n",
" <td class=\"sN\">No </td><td>Complicated to support composite elements</td>\n",
"<tr><td class=\"sG\">Contours</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">Curve</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sN\">No </td></tr>\n",
"<tr><td class=\"sG\">Distribution</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sN\">No </td></tr>\n",
"<tr><td class=\"sG\">ErrorBars</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td><td class=\"sN\">No </td>\n",
" <td class=\"sN\">No </td></tr>\n",
"<tr><td class=\"sG\">Graph</td><td class=\"sN\">No </td><td class=\"sN\">No </td><td class=\"sN\">No </td>\n",
" <td>Complicated to support composite elements</td></tr>\n",
"<tr><td class=\"sG\">HeatMap</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">HexTiles</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">Histogram</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">HSV</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">Image</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">Labels</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td><td class=\"sN\">No </td></tr>\n",
" <td class=\"sY\">Yes </td><td>Complicated to support composite elements</td></tr>\n",
"<tr><td class=\"sG\">HeatMap</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">HexTiles</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">Histogram</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sN\">No </td></tr>\n",
"<tr><td class=\"sG\">HSV</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">Image</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">Labels</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td><td class=\"sN\">No </td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">Path3D</td><td class=\"sN\">No </td><td class=\"sN\">No </td><td class=\"sN\">No </td>\n",
" <td>Complicated to support masking partial paths; no 3D selections</td></tr>\n",
" <td class=\"sN\">No </td><td>Complicated to support masking partial paths; no 3D selections</td></tr>\n",
"<tr><td class=\"sG\">Path</td><td class=\"sN\">No </td><td class=\"sN\">No </td><td class=\"sN\">No </td>\n",
" <td>Complicated to support masking partial paths</td></tr>\n",
"<tr><td class=\"sG\">Points</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">Polygons</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td></tr>\n",
"<tr><td class=\"sG\">QuadMesh</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">RadialHeatMap</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td><td class=\"sN\">No </td></tr>\n",
" <td class=\"sN\">No </td><td>Complicated to support masking partial paths</td></tr>\n",
"<tr><td class=\"sG\">Points</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">Polygons</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">QuadMesh</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">RadialHeatMap</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td><td class=\"sN\">No </td>\n",
" <td class=\"sN\">No </td></tr>\n",
"<tr><td class=\"sG\">Raster</td><td class=\"sN\">No </td><td class=\"sN\">No </td><td class=\"sN\">No </td>\n",
" <td>Special-case code that is difficult to replace</td></tr>\n",
"<tr><td class=\"sG\">Rectangles</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">RGB</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
" <td class=\"sN\">No </td><td>Special-case code that is difficult to replace</td></tr>\n",
"<tr><td class=\"sG\">Rectangles</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">RGB</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">Sankey</td><td class=\"sN\">No </td><td class=\"sN\">No </td><td class=\"sN\">No </td>\n",
" <td>Complicated to support composite elements</td></tr>\n",
"<tr><td class=\"sG\">Scatter</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
" <td class=\"sN\">No </td><td>Complicated to support composite elements</td></tr>\n",
"<tr><td class=\"sG\">Scatter</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">Scatter3D</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td><td class=\"sN\">No </td>\n",
" <td>3D selections not yet available</td></tr>\n",
"<tr><td class=\"sG\">Segments</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">Spikes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">Spread</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
" <td class=\"sN\">No </td><td>3D selections not yet available</td></tr>\n",
"<tr><td class=\"sG\">Segments</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">Spikes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sN\">No </td></tr>\n",
"<tr><td class=\"sG\">Spread</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sN\">No </td></tr>\n",
"<tr><td class=\"sG\">Surface</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td><td class=\"sN\">No </td>\n",
" <td>3D selections not yet available</td></tr>\n",
"<tr><td class=\"sG\">Table</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td></tr>\n",
" <td class=\"sN\">No </td><td>3D selections not yet available</td></tr>\n",
"<tr><td class=\"sG\">Table</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td>\n",
" <td class=\"sN\">No </td></tr>\n",
"<tr><td class=\"sG\">TriMesh</td><td class=\"sN\">No </td><td class=\"sN\">No </td><td class=\"sN\">No </td>\n",
" <td>Complicated to support composite elements</td></tr>\n",
" <td class=\"sN\">No </td><td>Complicated to support composite elements</td></tr>\n",
"<tr><td class=\"sG\">TriSurface</td><td class=\"sY\">Yes</td><td class=\"sN\">No </td><td class=\"sN\">No </td>\n",
" <td>3D selections not yet available</td></tr>\n",
"<tr><td class=\"sG\">VectorField</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
"<tr><td class=\"sG\">Violin</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td></tr>\n",
" <td class=\"sN\">No </td><td>3D selections not yet available</td></tr>\n",
"<tr><td class=\"sG\">VectorField</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sY\">Yes </td></tr>\n",
"<tr><td class=\"sG\">Violin</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td><td class=\"sY\">Yes</td>\n",
" <td class=\"sN\">No </td></tr>\n",
"\n",
"</tbody></table></div>"
]
Expand Down
23 changes: 17 additions & 6 deletions holoviews/core/accessors.py
Expand Up @@ -97,8 +97,8 @@ class Apply(object):
def __init__(self, obj, mode=None):
self._obj = obj

def __call__(self, apply_function, streams=[], link_inputs=True, dynamic=None,
per_element=False, **kwargs):
def __call__(self, apply_function, streams=[], link_inputs=True,
link_dataset=True, dynamic=None, per_element=False, **kwargs):
"""Applies a function to all (Nd)Overlay or Element objects.
Any keyword arguments are passed through to the function. If
Expand All @@ -118,6 +118,8 @@ def __call__(self, apply_function, streams=[], link_inputs=True, dynamic=None,
link_inputs (bool, optional): Whether to link the inputs
Determines whether Streams and Links attached to
original object will be inherited.
link_dataset (bool, optional): Whether to link the dataset
Determines whether the dataset will be inherited.
dynamic (bool, optional): Whether to make object dynamic
By default object is made dynamic if streams are
supplied, an instance parameter is supplied as a
Expand All @@ -135,6 +137,7 @@ def __call__(self, apply_function, streams=[], link_inputs=True, dynamic=None,
A new object where the function was applied to all
contained (Nd)Overlay or Element objects.
"""
from .data import Dataset
from .dimension import ViewableElement
from .element import Element
from .spaces import HoloMap, DynamicMap
Expand All @@ -150,7 +153,9 @@ def __call__(self, apply_function, streams=[], link_inputs=True, dynamic=None,
if not len(samples):
return self._obj[samples]
return HoloMap(self._obj[samples]).apply(
apply_function, streams, link_inputs, dynamic, **kwargs)
apply_function, streams, link_inputs, link_dataset,
dynamic, per_element, **kwargs
)

if isinstance(apply_function, util.basestring):
args = kwargs.pop('_method_args', ())
Expand Down Expand Up @@ -190,17 +195,23 @@ def apply_function(object, **kwargs):

if (applies or isinstance(self._obj, HoloMap)) and is_dynamic:
return Dynamic(self._obj, operation=apply_function, streams=streams,
kwargs=kwargs, link_inputs=link_inputs)
kwargs=kwargs, link_inputs=link_inputs,
link_dataset=link_dataset)
elif applies:
inner_kwargs = util.resolve_dependent_kwargs(kwargs)
if hasattr(apply_function, 'dynamic'):
inner_kwargs['dynamic'] = False
return apply_function(self._obj, **inner_kwargs)
new_obj = apply_function(self._obj, **inner_kwargs)
if (link_dataset and isinstance(self._obj, Dataset) and
isinstance(new_obj, Dataset) and new_obj._dataset is None):
new_obj._dataset = self._obj.dataset
return new_obj
elif self._obj._deep_indexable:
mapped = []
for k, v in self._obj.data.items():
new_val = v.apply(apply_function, dynamic=dynamic, streams=streams,
link_inputs=link_inputs, **kwargs)
link_inputs=link_inputs, link_dataset=link_dataset,
**kwargs)
if new_val is not None:
mapped.append((k, new_val))
return self._obj.clone(mapped, link=link_inputs)
Expand Down
11 changes: 5 additions & 6 deletions holoviews/core/data/__init__.py
Expand Up @@ -357,6 +357,8 @@ def __init__(self, data, kdims=None, vdims=None, **kwargs):
if input_pipeline is None:
input_pipeline = chain_op.instance()

kwargs['kdims'] = self.kdims
kwargs['vdims'] = self.vdims
init_op = factory.instance(
output_type=type(self),
args=[],
Expand Down Expand Up @@ -1164,16 +1166,13 @@ def clone(self, data=None, shared_data=True, new_type=None, link=True,
data = self
if link:
overrides['plot_id'] = self._plot_id
elif self._in_method:
if 'dataset' not in overrides:
overrides['dataset'] = self.dataset
elif self._in_method and 'dataset' not in overrides:
overrides['dataset'] = self.dataset

new_dataset = super(Dataset, self).clone(
return super(Dataset, self).clone(
data, shared_data, new_type, *args, **overrides
)

return new_dataset

# Overrides of superclass methods that are needed so that PipelineMeta
# will find them to wrap with pipeline support
def options(self, *args, **kwargs):
Expand Down
8 changes: 4 additions & 4 deletions holoviews/core/data/interface.py
Expand Up @@ -83,6 +83,7 @@ class iloc(Accessor):
integer indices, slices, lists and arrays of values. For more
information see the ``Dataset.iloc`` property docstring.
"""

@classmethod
def _perform_getitem(cls, dataset, index):
index = util.wrap_tuple(index)
Expand Down Expand Up @@ -113,12 +114,11 @@ def _perform_getitem(cls, dataset, index):
kdims = [d for d in dims if d in kdims]
vdims = [d for d in dims if d in vdims]

datatype = [dt for dt in dataset.datatype
if dt in Interface.interfaces and
datatypes = util.unique_iterator([dataset.interface.datatype]+dataset.datatype)
datatype = [dt for dt in datatypes if dt in Interface.interfaces and
not Interface.interfaces[dt].gridded]
if not datatype: datatype = ['dataframe', 'dictionary']
return dataset.clone(data, kdims=kdims, vdims=vdims,
datatype=datatype)
return dataset.clone(data, kdims=kdims, vdims=vdims, datatype=datatype)


class ndloc(Accessor):
Expand Down
9 changes: 8 additions & 1 deletion holoviews/core/data/xarray.py
Expand Up @@ -506,8 +506,15 @@ def mask(cls, dataset, mask, mask_val=np.nan):
else:
orig_mask = mask
for vd in dataset.vdims:
data_coords = list(dataset.data[vd.name].dims)
dims = list(dataset.data[vd.name].dims)
if any(cls.irregular(dataset, kd) for kd in dataset.kdims):
data_coords = dims
else:
data_coords = [kd.name for kd in dataset.kdims][::-1]
mask = cls.canonicalize(dataset, orig_mask, data_coords)
if data_coords != dims:
inds = [dims.index(d) for d in data_coords]
mask = mask.transpose(inds)
masked[vd.name] = marr = masked[vd.name].astype('float')
marr.values[mask] = mask_val
return masked
Expand Down

0 comments on commit 1dc4ede

Please sign in to comment.