Skip to content

Commit

Permalink
Standardized constructor signature with dimensions as positional args
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Oct 5, 2017
1 parent 50182b7 commit 17d8b6e
Show file tree
Hide file tree
Showing 15 changed files with 77 additions and 80 deletions.
22 changes: 13 additions & 9 deletions holoviews/core/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import param

from ..dimension import redim
from ..util import dimension_range
from ..util import dimension_range, basestring
from .interface import Interface, iloc, ndloc
from .array import ArrayInterface
from .dictionary import DictInterface
Expand Down Expand Up @@ -170,19 +170,23 @@ class Dataset(Element):
_vdim_reductions = {}
_kdim_reductions = {}

def __init__(self, data, **kwargs):
def __init__(self, data, kdims=None, vdims=None, **kwargs):
if isinstance(data, Element):
pvals = util.get_param_values(data)
kwargs.update([(l, pvals[l]) for l in ['group', 'label']
if l in pvals and l not in kwargs])

kdims, vdims = None, None
if 'kdims' in kwargs:
kdims = [kd if isinstance(kd, Dimension) else Dimension(kd)
for kd in kwargs['kdims']]
if 'vdims' in kwargs:
vdims = [kd if isinstance(kd, Dimension) else Dimension(kd)
for kd in kwargs['vdims']]
for group, dims in [('kdims', kdims), ('vdims', vdims)]:
if dims is None:
continue
elif isinstance(dims, (tuple, basestring, Dimension)):
dims = [dims]
elif not isinstance(dims, list):
raise ValueError("%s must be a Dimension or list of dimensions, "
"specified as tuples, string or Dimension instances.")
kwargs[group] = [d if isinstance(d, Dimension) else Dimension(d)
for d in dims]
kdims, vdims = kwargs.get('kdims'), kwargs.get('vdims')

initialized = Interface.initialize(type(self), data, kdims, vdims,
datatype=kwargs.get('datatype'))
Expand Down
43 changes: 14 additions & 29 deletions holoviews/core/dimension.py
Original file line number Diff line number Diff line change
Expand Up @@ -783,35 +783,20 @@ class to be associated with dimensions. The contents associated
_dim_aliases = dict(key_dimensions='kdims', value_dimensions='vdims',
constant_dimensions='cdims', deep_dimensions='ddims')


# Long-name aliases

@property
def key_dimensions(self): return self.kdims

@property
def value_dimensions(self): return self.vdims

@property
def constant_dimensions(self): return self.cdims

@property
def deep_dimensions(self): return self.ddims

def __init__(self, data, **params):
for group in self._dim_groups+list(self._dim_aliases.keys()):
if group in ['deep_dimensions', 'ddims']: continue
if group in params:
if group in self._dim_aliases:
params[self._dim_aliases[group]] = params.pop(group)
group = self._dim_aliases[group]
if group == 'cdims':
dimensions = {d if isinstance(d, Dimension) else Dimension(d): val
for d, val in params.pop(group).items()}
else:
dimensions = [d if isinstance(d, Dimension) else Dimension(d)
for d in params.pop(group)]
params[group] = dimensions
def __init__(self, data, kdims=None, vdims=None, **params):
for group, dims in [('kdims', kdims), ('vdims', vdims)]:
if dims is None:
continue
elif isinstance(dims, (tuple, basestring, Dimension)):
dims = [dims]
elif not isinstance(dims, list):
raise ValueError("%s must be a Dimension or list of dimensions, "
"specified as tuples, string or Dimension instances.")
params[group] = [d if isinstance(d, Dimension) else Dimension(d)
for d in dims]
if 'cdims' in params:
params['cdims'] = {d if isinstance(d, Dimension) else Dimension(d): val
for d, val in params['cdims'].items()}
super(Dimensioned, self).__init__(data, **params)
self.ndims = len(self.kdims)
cdims = [(d.name, val) for d, val in self.cdims.items()]
Expand Down
2 changes: 1 addition & 1 deletion holoviews/core/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ def _add_dimensions(self, item, dims, constant_keys):
elif isinstance(item, self._nest_order[self.merge_type]):
if len(dim_vals):
dimensions, key = zip(*dim_vals)
new_item = self.merge_type({key: item}, kdims=dimensions,
new_item = self.merge_type({key: item}, kdims=list(dimensions),
cdims=constant_keys)
else:
new_item = item
Expand Down
5 changes: 3 additions & 2 deletions holoviews/core/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,11 @@ class NdLayout(UniformNdMapping):

data_type = (ViewableElement, AdjointLayout, UniformNdMapping)

def __init__(self, initial_items=None, **params):
def __init__(self, initial_items=None, kdims=None, **params):
self._max_cols = 4
self._style = None
super(NdLayout, self).__init__(initial_items=initial_items, **params)
super(NdLayout, self).__init__(initial_items=initial_items, kdims=kdims,
**params)


@property
Expand Down
10 changes: 6 additions & 4 deletions holoviews/core/ndmapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,13 @@ class MultiDimensionalMapping(Dimensioned):
_deep_indexable = False
_check_items = True

def __init__(self, initial_items=None, **params):
def __init__(self, initial_items=None, kdims=None, **params):
if isinstance(initial_items, MultiDimensionalMapping):
params = dict(util.get_param_values(initial_items),
**dict({'sort': self.sort}, **params))
super(MultiDimensionalMapping, self).__init__(OrderedDict(), **params)
if kdims is not None:
params['kdims'] = kdims
super(MultiDimensionalMapping, self).__init__(OrderedDict(), **dict(params))
if type(initial_items) is dict and not self.sort:
raise ValueError('If sort=False the data must define a fixed '
'ordering, please supply a list of items or '
Expand Down Expand Up @@ -733,11 +735,11 @@ class UniformNdMapping(NdMapping):
_deep_indexable = True
_auxiliary_component = False

def __init__(self, initial_items=None, group=None, label=None, **params):
def __init__(self, initial_items=None, kdims=None, group=None, label=None, **params):
self._type = None
self._group_check, self.group = None, group
self._label_check, self.label = None, label
super(UniformNdMapping, self).__init__(initial_items, **params)
super(UniformNdMapping, self).__init__(initial_items, kdims=kdims, **params)


def clone(self, data=None, shared_data=True, new_type=None, *args, **overrides):
Expand Down
4 changes: 2 additions & 2 deletions holoviews/core/overlay.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ class NdOverlay(UniformNdMapping, CompositeOverlay, Overlayable):

_deep_indexable = True

def __init__(self, overlays=None, **params):
super(NdOverlay, self).__init__(overlays, **params)
def __init__(self, overlays=None, kdims=None, **params):
super(NdOverlay, self).__init__(overlays, kdims=kdims, **params)


__all__ = list(set([_k for _k, _v in locals().items()
Expand Down
4 changes: 2 additions & 2 deletions holoviews/core/spaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -1341,8 +1341,8 @@ class GridSpace(UniformNdMapping):

kdims = param.List(default=[Dimension("X"), Dimension("Y")], bounds=(1,2))

def __init__(self, initial_items=None, **params):
super(GridSpace, self).__init__(initial_items, **params)
def __init__(self, initial_items=None, kdims=None, **params):
super(GridSpace, self).__init__(initial_items, kdims=kdims, **params)
if self.ndims > 2:
raise Exception('Grids can have no more than two dimensions.')

Expand Down
8 changes: 6 additions & 2 deletions holoviews/element/chart.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ class Histogram(Element2D):
vdims = param.List(default=[Dimension('Frequency')], bounds=(1,1))

def __init__(self, values, edges=None, **params):
if edges is not None:
self.warning("Histogram edges should be supplied as a tuple "
"along with the values, passing the edges will "
"be deprecated in holoviews 2.0.")
self.values, self.edges, settings = self._process_data(values, edges)
settings.update(params)
super(Histogram, self).__init__((self.values, self.edges), **settings)
Expand Down Expand Up @@ -340,10 +344,10 @@ class VectorField(Points):
_null_value = np.array([[], [], [], []]).T # For when data is None
_min_dims = 3 # Minimum number of columns

def __init__(self, data, **params):
def __init__(self, data, kdims=None, vdims=None, **params):
if isinstance(data, list) and all(isinstance(d, np.ndarray) for d in data):
data = np.column_stack([d.flat if d.ndim > 1 else d for d in data])
super(VectorField, self).__init__(data, **params)
super(VectorField, self).__init__(data, kdims=kdims, vdims=vdims, **params)



Expand Down
4 changes: 2 additions & 2 deletions holoviews/element/chart3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ class Surface(Image, Element3D):

group = param.String(default='Surface', constant=True)

def __init__(self, data, extents=None, **params):
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, extents=extents, **params)
Image.__init__(self, data, kdims=kdims, vdims=vdims, extents=extents, **params)



Expand Down
4 changes: 2 additions & 2 deletions holoviews/element/graphs.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class Graph(Dataset, Element2D):
kdims = param.List(default=[Dimension('start'), Dimension('end')],
bounds=(2, 2))

def __init__(self, data, **params):
def __init__(self, data, kdims=None, vdims=None, **params):
if isinstance(data, tuple):
data = data + (None,)* (3-len(data))
edges, nodes, edgepaths = data
Expand All @@ -122,7 +122,7 @@ def __init__(self, data, **params):
edgepaths = EdgePaths(edgepaths)
self._nodes = nodes
self._edgepaths = edgepaths
super(Graph, self).__init__(edges, **params)
super(Graph, self).__init__(edges, kdims=kdims, vdims=vdims, **params)
if self._nodes is None and node_info:
nodes = self.nodes.clone(datatype=['pandas', 'dictionary'])
for d in node_info.dimensions():
Expand Down
12 changes: 6 additions & 6 deletions holoviews/element/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Path(Dataset, Element2D):

datatype = param.ObjectSelector(default=['multitabular'])

def __init__(self, data, **params):
def __init__(self, data, kdims=None, vdims=None, **params):
if isinstance(data, tuple):
x, y = map(np.asarray, data)
if y.ndim == 1:
Expand All @@ -54,7 +54,7 @@ def __init__(self, data, **params):
data = [np.column_stack((x, y[:, i])) for i in range(y.shape[1])]
elif isinstance(data, list) and all(isinstance(path, tuple) for path in data):
data = [np.column_stack(path) for path in data]
super(Path, self).__init__(data, **params)
super(Path, self).__init__(data, kdims=kdims, vdims=vdims, **params)


def __setstate__(self, state):
Expand Down Expand Up @@ -127,13 +127,13 @@ class Contours(Path):

_level_vdim = Dimension('Level') # For backward compatibility

def __init__(self, data, **params):
def __init__(self, data, kdims=None, vdims=None, **params):
data = [] if data is None else data
if 'level' in params:
vdims = params.get('vdims', [self._level_vdim])
if params.get('level') is not None:
vdims = vdims or [self._level_vdim]
params['vdims'] = []
super(Contours, self).__init__(data, **params)
if 'level' in params:
if params.get('level') is not None:
self.vdims = [d if isinstance(d, Dimension) else Dimension(d)
for d in vdims]

Expand Down
17 changes: 9 additions & 8 deletions holoviews/element/raster.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,11 @@ class Image(Dataset, Raster, SheetCoordinateSystem):
bounds=(1, 1), doc="""
The dimension description of the data held in the matrix.""")

def __init__(self, data, bounds=None, extents=None, xdensity=None, ydensity=None, **params):
def __init__(self, data, kdims=None, vdims=None, bounds=None, extents=None,
xdensity=None, ydensity=None, **params):
extents = extents if extents else (None, None, None, None)
if data is None: data = np.array([[0]])
Dataset.__init__(self, data, extents=extents, **params)
Dataset.__init__(self, data, kdims=kdims, vdims=vdims, extents=extents, **params)

dim2, dim1 = self.interface.shape(self, gridded=True)[:2]
if bounds is None:
Expand Down Expand Up @@ -525,7 +526,7 @@ def load_image(cls, filename, height=1, array=False, bounds=None, bare=False, **
return rgb


def __init__(self, data, **params):
def __init__(self, data, kdims=None, vdims=None, **params):
if isinstance(data, Overlay):
images = data.values()
if not all(isinstance(im, Image) for im in images):
Expand All @@ -538,12 +539,12 @@ def __init__(self, data, **params):
raise ValueError("Ranges must be defined on all the value dimensions of all the Images")
arrays = [(im.data - r[0]) / (r[1] - r[0]) for r,im in zip(ranges, images)]
data = np.dstack(arrays)
vdims = list(params.get('vdims', self.vdims))
vdims = list(vdims or self.vdims)
if isinstance(data, np.ndarray):
if data.shape[-1] == 4 and len(vdims) == 3:
vdims.append(self.alpha_dimension)
params['vdims'] = vdims
super(RGB, self).__init__(data, **params)
super(RGB, self).__init__(data, kdims=kdims, vdims=vdims, **params)



Expand Down Expand Up @@ -610,9 +611,9 @@ class QuadMesh(Raster):

vdims = param.List(default=[Dimension('z')], bounds=(1,1))

def __init__(self, data, **params):
def __init__(self, data, kdims=None, vdims=None, **params):
data = self._process_data(data)
Element2D.__init__(self, data, **params)
Element2D.__init__(self, data, kdims=kdims, vdims=vdims, **params)
self.data = self._validate_data(self.data)
self._grid = self.data[0].ndim == 1

Expand Down Expand Up @@ -772,7 +773,7 @@ class HeatMap(Dataset, Element2D):

vdims = param.List(default=[Dimension('z')])

def __init__(self, data, **params):
def __init__(self, data, kdims=kdims, vdims=vdims, **params):
super(HeatMap, self).__init__(data, **params)
self.gridded = categorical_aggregate2d(self)

Expand Down
10 changes: 5 additions & 5 deletions holoviews/operation/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,10 @@ class transform(Operation):
Image to the data in the output Image. By default, acts as
the identity function such that the output matches the input.""")

def _process(self, matrix, key=None):
processed = (matrix.data if not self.p.operator
else self.p.operator(matrix.data))
return Image(processed, matrix.bounds, group=self.p.group)
def _process(self, img, key=None):
processed = (img.data if not self.p.operator
else self.p.operator(img.data))
return img.clone(processed, group=self.p.group)



Expand Down Expand Up @@ -347,7 +347,7 @@ def _process(self, matrix, key=None):
dx = np.where(np.abs(dx_negatives)<dx, dx_negatives, dx)
dy = np.where(np.abs(dy_negatives)<dy, dy_negatives, dy)

return Image(np.sqrt(dx * dx + dy * dy), matrix.bounds, group=self.p.group)
return Image(np.sqrt(dx * dx + dy * dy), bounds=matrix.bounds, group=self.p.group)



Expand Down
2 changes: 1 addition & 1 deletion holoviews/plotting/widgets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def __init__(self, plot, renderer=None, **params):
self.renderer = renderer
# Create mock NdMapping to hold the common dimensions and keys
self.mock_obj = NdMapping([(k, None) for k in self.keys],
kdims=self.dimensions, sort=False)
kdims=list(self.dimensions), sort=False)

NdWidget.widgets[self.id] = self

Expand Down
10 changes: 5 additions & 5 deletions tests/testcomparisonraster.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ def setUp(self):
self.arr2 = np.array([[10,2], [3,4]])
self.arr3 = np.array([[10,2], [3,40]])
# Varying arrays, default bounds
self.mat1 = Image(self.arr1, BoundingBox())
self.mat2 = Image(self.arr2, BoundingBox())
self.mat3 = Image(self.arr3, BoundingBox())
self.mat1 = Image(self.arr1, bounds=BoundingBox())
self.mat2 = Image(self.arr2, bounds=BoundingBox())
self.mat3 = Image(self.arr3, bounds=BoundingBox())
# Varying arrays, different bounds
self.mat4 = Image(self.arr1, BoundingBox(radius=0.3))
self.mat5 = Image(self.arr2, BoundingBox(radius=0.3))
self.mat4 = Image(self.arr1, bounds=BoundingBox(radius=0.3))
self.mat5 = Image(self.arr2, bounds=BoundingBox(radius=0.3))


class RasterOverlayTestCase(RasterTestCase):
Expand Down

0 comments on commit 17d8b6e

Please sign in to comment.