Skip to content

DynamicMap explicit set slicing fails with value dimensions #4900

@nitrocalcite

Description

@nitrocalcite

If a DynamicMap is sliced with a set of explicit tuples, and has kdims with defined values, the slicing fails.

Here's a walkthrough of an MRE adapted from the docs:

import numpy as np
import holoviews as hv
hv.extension('bokeh')

def shapes(N, radius=0.3): # Positional keyword arguments are fine
    N = int(N)
    radius = float(radius)
    paths = [hv.Path([[(radius*np.sin(a), radius*np.cos(a)) 
                        for a in np.linspace(-np.pi, np.pi, n+2)]], 
                     extents=(-1,-1,1,1)) 
             for n in range(N,N+3)]
    return hv.Overlay(paths)

dmap_novalue = hv.DynamicMap(shapes, kdims=[hv.Dimension('N', range=(1,5)), hv.Dimension('radius')])

dmap_strvalue = hv.DynamicMap(shapes, kdims=[hv.Dimension('N', values=['1','4']), hv.Dimension('radius')])
dmap_intvalue = hv.DynamicMap(shapes, kdims=[hv.Dimension('N', values=[1,4]), hv.Dimension('radius')])

dmap_novalue behaves properly; the other two do not.
Compare these statements, which should be equivalent:

hv.HoloMap(dmap_novalue[{(1, 0.3)}])

hv.HoloMap(dmap_strvalue[{('1', 0.3)}])
hv.HoloMap(dmap_intvalue[{(1, 0.3)}])

The first succeeds, producing the expected HoloMap; the other two throw exceptions (tracebacks below), where I expect them to return the same result.

On the other hand, Cartesian product indexing works fine with all three:

hv.HoloMap(dmap_novalue[{1}, {0.3}])

hv.HoloMap(dmap_strvalue[{'1'}, {0.3}])
hv.HoloMap(dmap_intvalue[{1}, {0.3}])

ALL software version info

holoviews 1.14.3
Windows 10 & Chrome

Stack traceback and/or browser JavaScript console output

For the str DynamicMap:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-f8c045550924> in <module>
----> 1 hv.HoloMap(dmap_strvalue[{('1', 0.3)}])

~/miniconda3/envs/tsunami/lib/python3.7/site-packages/holoviews/core/spaces.py in __getitem__(self, key)
   1328             if dimensionless or empty:
   1329                 raise KeyError('Using dimensionless streams disables DynamicMap cache')
-> 1330             cache = super(DynamicMap,self).__getitem__(key)
   1331         except KeyError:
   1332             cache = None

~/miniconda3/envs/tsunami/lib/python3.7/site-packages/holoviews/core/ndmapping.py in __getitem__(self, indexslice)
    662             return self._dataslice(self.data[map_slice], data_slice)
    663         else:
--> 664             conditions = self._generate_conditions(map_slice)
    665             items = self.data.items()
    666             for cidx, (condition, dim) in enumerate(zip(conditions, self.kdims)):

~/miniconda3/envs/tsunami/lib/python3.7/site-packages/holoviews/core/ndmapping.py in _generate_conditions(self, map_slice)
    735                 if dim.values:
    736                     dim_slice = [dim.values.index(dim_val)
--> 737                                  for dim_val in dim_slice]
    738                 conditions.append(self._values_condition(dim_slice))
    739             elif dim_slice is Ellipsis:

~/miniconda3/envs/tsunami/lib/python3.7/site-packages/holoviews/core/ndmapping.py in <listcomp>(.0)
    735                 if dim.values:
    736                     dim_slice = [dim.values.index(dim_val)
--> 737                                  for dim_val in dim_slice]
    738                 conditions.append(self._values_condition(dim_slice))
    739             elif dim_slice is Ellipsis:

ValueError: ('1', 0.3) is not in list

Similarly for the int DynamicMap:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-79db19dbd007> in <module>
----> 1 hv.HoloMap(dmap_intvalue[{(1, 0.3)}])

~/miniconda3/envs/tsunami/lib/python3.7/site-packages/holoviews/core/spaces.py in __getitem__(self, key)
   1328             if dimensionless or empty:
   1329                 raise KeyError('Using dimensionless streams disables DynamicMap cache')
-> 1330             cache = super(DynamicMap,self).__getitem__(key)
   1331         except KeyError:
   1332             cache = None

~/miniconda3/envs/tsunami/lib/python3.7/site-packages/holoviews/core/ndmapping.py in __getitem__(self, indexslice)
    662             return self._dataslice(self.data[map_slice], data_slice)
    663         else:
--> 664             conditions = self._generate_conditions(map_slice)
    665             items = self.data.items()
    666             for cidx, (condition, dim) in enumerate(zip(conditions, self.kdims)):

~/miniconda3/envs/tsunami/lib/python3.7/site-packages/holoviews/core/ndmapping.py in _generate_conditions(self, map_slice)
    735                 if dim.values:
    736                     dim_slice = [dim.values.index(dim_val)
--> 737                                  for dim_val in dim_slice]
    738                 conditions.append(self._values_condition(dim_slice))
    739             elif dim_slice is Ellipsis:

~/miniconda3/envs/tsunami/lib/python3.7/site-packages/holoviews/core/ndmapping.py in <listcomp>(.0)
    735                 if dim.values:
    736                     dim_slice = [dim.values.index(dim_val)
--> 737                                  for dim_val in dim_slice]
    738                 conditions.append(self._values_condition(dim_slice))
    739             elif dim_slice is Ellipsis:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

I think this is unique from #3743, #3085, and #4876, but collectively, I feel that these problems make DynamicMap slicing quite a bit more difficult to use as compared to the rest of the API.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions