Skip to content

Commit

Permalink
Various fixes for unsupported elements
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Mar 2, 2020
1 parent 9df4a55 commit 3b7cc18
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 14 deletions.
2 changes: 1 addition & 1 deletion holoviews/core/accessors.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ def _transform_dimension(self, kdims, vdims, dimension):
return dimension

def _create_expression_transform(self, kdims, vdims, exclude=[]):
from .dimension import dimension_name, Dimension
from .dimension import dimension_name
from ..util.transform import dim

def _transform_expression(expression):
Expand Down
2 changes: 1 addition & 1 deletion holoviews/core/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ def select(self, selection_expr=None, selection_specs=None, **selection):
selection = {dim_name: sel for dim_name, sel in selection.items()
if dim_name in self.dimensions()+['selection_mask']}
if (selection_specs and not any(self.matches(sp) for sp in selection_specs)
or (not selection and not selection_expr)):
or (not selection and not selection_expr)):
return self

# Handle selection dim expression
Expand Down
3 changes: 3 additions & 0 deletions holoviews/element/chart3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ def __init__(self, data, kdims=None, vdims=None, extents=None, **params):
extents = extents if extents else (None, None, None, None, None, None)
Image.__init__(self, data, kdims=kdims, vdims=vdims, extents=extents, **params)

def _get_selection_expr_for_stream_value(self, **kwargs):
expr, bbox, _ = super(Surface, self)._get_selection_expr_for_stream_value(**kwargs)
return expr, bbox, None


class TriSurface(Element3D, Points):
Expand Down
22 changes: 19 additions & 3 deletions holoviews/element/graphs.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ def __init__(self, data, kdims=None, vdims=None, **params):
node_info = None
if edgepaths is not None and not isinstance(edgepaths, self.edge_type):
edgepaths = self.edge_type(edgepaths)

self._nodes = nodes
self._edgepaths = edgepaths
super(Graph, self).__init__(edges, kdims=kdims, vdims=vdims, **params)
Expand Down Expand Up @@ -251,7 +252,7 @@ def clone(self, data=None, shared_data=True, new_type=None, link=True,
*args, **overrides)


def select(self, selection_specs=None, selection_mode='edges', **selection):
def select(self, selection_expr=None, selection_specs=None, selection_mode='edges', **selection):
"""
Allows selecting data by the slices, sets and scalar values
along a particular dimension. The indices should be supplied as
Expand All @@ -265,17 +266,28 @@ def select(self, selection_specs=None, selection_mode='edges', **selection):
connected to the selected nodes. To select only edges between the
selected nodes set the selection_mode to 'nodes'.
"""
from ...util.transform import dim
if selection_expr is not None and not isinstance(selection_expr, dim):
raise ValueError("""\
The first positional argument to the Dataset.select method is expected to be a
holoviews.util.transform.dim expression. Use the selection_specs keyword
argument to specify a selection specification""")

selection = {dim: sel for dim, sel in selection.items()
if dim in self.dimensions('ranges')+['selection_mask']}
if (selection_specs and not any(self.matches(sp) for sp in selection_specs)
or not selection):
or (not selection and not selection_expr)):
return self

index_dim = self.nodes.kdims[2].name
dimensions = self.kdims+self.vdims
node_selection = {index_dim: v for k, v in selection.items()
if k in self.kdims}
nodes = self.nodes.select(**dict(selection, **node_selection))
if selection_expr:
mask = selection_expr.apply(self.nodes, compute=False, keep_index=True)
dataset = self.nodes[mask]
else:
nodes = self.nodes.select(**dict(selection, **node_selection))
selection = {k: v for k, v in selection.items() if k in dimensions}

# Compute mask for edges if nodes were selected on
Expand Down Expand Up @@ -364,8 +376,12 @@ def nodes(self):
Computes the node positions the first time they are requested
if no explicit node information was supplied.
"""

if self._nodes is None:
from ..operation.element import chain
self._nodes = layout_nodes(self, only_nodes=True)
self._nodes._dataset = None
self._nodes._pipeline = chain.instance()
return self._nodes


Expand Down
3 changes: 3 additions & 0 deletions holoviews/plotting/bokeh/annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from ...element import HLine, VLine, VSpan
from ..plot import GenericElementPlot
from .element import AnnotationPlot, ElementPlot, CompositeElementPlot, ColorbarPlot
from .selection import BokehOverlaySelectionDisplay
from .styles import text_properties, line_properties, fill_properties
from .plot import BokehPlot
from .util import date_to_integer
Expand Down Expand Up @@ -88,6 +89,8 @@ class LabelsPlot(ColorbarPlot, AnnotationPlot):
allow_None=True, doc="""
Deprecated in favor of color style mapping, e.g. `color=dim('color')`""")

selection_display = BokehOverlaySelectionDisplay()

style_opts = text_properties + ['cmap', 'angle', 'visible']

_nonvectorized_styles = ['cmap']
Expand Down
4 changes: 2 additions & 2 deletions holoviews/plotting/bokeh/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,7 @@ def _process_msg(self, msg):
x0, x1 = int(round(x0)), int(round(x1))
xfactors = x_range.factors[x0: x1]
if x_range.tags and x_range.tags[0]:
xdim = el.get_dimension(x_range.tags[0][0])
xdim = el.get_dimension(x_range.tags[0][0][0])
if xdim and hasattr(el, 'interface'):
dtype = el.interface.dtype(el, xdim)
try:
Expand All @@ -905,7 +905,7 @@ def _process_msg(self, msg):
y0, y1 = int(round(y0)), int(round(y1))
yfactors = y_range.factors[y0: y1]
if y_range.tags and y_range.tags[0]:
ydim = el.get_dimension(y_range.tags[0][0])
ydim = el.get_dimension(y_range.tags[0][0][0])
if ydim and hasattr(el, 'interface'):
dtype = el.interface.dtype(el, ydim)
try:
Expand Down
9 changes: 5 additions & 4 deletions holoviews/plotting/bokeh/chart.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,17 +508,18 @@ def _init_glyph(self, plot, mapping, properties):

class ErrorPlot(ColorbarPlot):

style_opts = line_properties + ['lower_head', 'upper_head', 'visible']
style_opts = ([
p for p in line_properties if p.split('_')[0] not in
('hover', 'selection', 'nonselection', 'muted')
] + ['lower_head', 'upper_head', 'visible'])

_nonvectorized_styles = ['line_dash', 'visible']

_mapping = dict(base="base", upper="upper", lower="lower")

_plot_methods = dict(single=Whisker)

# selection_display should be changed to BokehOverlaySelectionDisplay
# when #3950 is fixed
selection_display = NoOpSelectionDisplay()
selection_display = BokehOverlaySelectionDisplay()

def get_data(self, element, ranges, style):
mapping = dict(self._mapping)
Expand Down
2 changes: 2 additions & 0 deletions holoviews/plotting/bokeh/heatmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ def get_data(self, element, ranges, style):
cmapper = self._get_colormapper(element.vdims[0], element, ranges, style)
if 'line_alpha' not in style and 'line_width' not in style:
style['line_alpha'] = 0
style['selection_line_alpha'] = 0
style['nonselection_line_alpha'] = 0
elif 'line_color' not in style:
style['line_color'] = 'white'

Expand Down
2 changes: 1 addition & 1 deletion holoviews/plotting/bokeh/selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def _build_element_layer(self, element, layer_color, layer_alpha, **opts):
merged_opts = {opt_name: layer_alpha for opt_name in allowed
if 'alpha' in opt_name}
if el_name in ('HeatMap', 'QuadMesh'):
merged_opts.pop('line_alpha')
merged_opts = {k: v for k, v in merged_opts.items() if 'line_' not in k}
elif layer_color is None:
# Keep current color (including color from cycle)
for color_prop in self.color_props:
Expand Down
4 changes: 4 additions & 0 deletions holoviews/plotting/plotly/chart3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class SurfacePlot(Chart3DPlot, ColorbarPlot):

style_opts = ['visible', 'alpha', 'lighting', 'lightposition', 'cmap']

selection_display = PlotlyOverlaySelectionDisplay(supports_region=False)

def graph_options(self, element, ranges, style):
opts = super(SurfacePlot, self).graph_options(element, ranges, style)
copts = self.get_color_opts(element.vdims[0], element, ranges, style)
Expand Down Expand Up @@ -89,6 +91,8 @@ class TriSurfacePlot(Chart3DPlot, ColorbarPlot):

style_opts = ['cmap', 'edges_color', 'facecolor']

selection_display = PlotlyOverlaySelectionDisplay(supports_region=False)

def get_data(self, element, ranges, style):
try:
from scipy.spatial import Delaunay
Expand Down
5 changes: 3 additions & 2 deletions holoviews/selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,12 +374,13 @@ class OverlaySelectionDisplay(SelectionDisplay):
colored subsets on top of the original element in an Overlay container.
"""

def __init__(self, color_prop='color', is_cmap=False):
def __init__(self, color_prop='color', is_cmap=False, supports_region=True):
if not isinstance(color_prop, (list, tuple)):
self.color_props = [color_prop]
else:
self.color_props = color_prop
self.is_cmap = is_cmap
self.supports_region = supports_region

def _get_color_kwarg(self, color):
return {color_prop: [color] if self.is_cmap else color
Expand Down Expand Up @@ -433,7 +434,7 @@ def update_cmap(cmap, default=op.cmap, kw=kwargs.get('cmap')):
layers[layer_number] = layer

# Build region layer
if region_stream is not None:
if region_stream is not None and self.supports_region:
def update_region(element, region_element, colors, **kwargs):
unselected_color = colors[0]
if region_element is None:
Expand Down

0 comments on commit 3b7cc18

Please sign in to comment.