Skip to content

Commit

Permalink
Constant value datashader aggregation (#2860)
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr authored and jlstevens committed Jul 6, 2018
1 parent 4227c0f commit 0a154d7
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 2 deletions.
16 changes: 16 additions & 0 deletions holoviews/element/raster.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,22 @@ def __setstate__(self, state):
super(Dataset, self).__setstate__(state)


def clone(self, data=None, shared_data=True, new_type=None, *args, **overrides):
"""
Returns a clone of the object with matching parameter values
containing the specified args and kwargs.
If shared_data is set to True and no data explicitly supplied,
the clone will share data with the original. May also supply
a new_type, which will inherit all shared parameters.
"""
if data is None and (new_type is None or issubclass(new_type, Image)):
sheet_params = dict(bounds=self.bounds, xdensity=self.xdensity,
ydensity=self.ydensity)
overrides = dict(sheet_params, **overrides)
return super(Image, self).clone(data, shared_data, new_type, *args, **overrides)


def aggregate(self, dimensions=None, function=None, spreadfn=None, **kwargs):
agg = super(Image, self).aggregate(dimensions, function, spreadfn, **kwargs)
return Curve(agg) if isinstance(agg, Dataset) and len(self.vdims) == 1 else agg
Expand Down
13 changes: 11 additions & 2 deletions holoviews/operation/datashader.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,8 +439,10 @@ def _process(self, element, key=None):
(x0, x1), (y0, y1) = x_range, y_range
if xtype == 'datetime':
x0, x1 = (np.array([x0, x1])/10e5).astype('datetime64[us]')
xs = (xs/10e5).astype('datetime64[us]')
if ytype == 'datetime':
y0, y1 = (np.array([y0, y1])/10e5).astype('datetime64[us]')
ys = (ys/10e5).astype('datetime64[us]')
bounds = (x0, y0, x1, y1)
params = dict(get_param_values(element), kdims=[x, y],
datatype=['xarray'], bounds=bounds)
Expand All @@ -459,8 +461,10 @@ def _process(self, element, key=None):
params['vdims'] = vdims

if x is None or y is None or width == 0 or height == 0:
x = x.name if x else 'x'
y = y.name if x else 'y'
xarray = xr.DataArray(np.full((height, width), np.NaN),
dims=['y', 'x'], coords={'x': xs, 'y': ys})
dims=[y, x], coords={x: xs, y: ys})
if width == 0:
params['xdensity'] = 1
if height == 0:
Expand Down Expand Up @@ -888,10 +892,14 @@ def _process(self, element, key=None):
element = element.map(self.to_xarray, Image)
if isinstance(element, NdOverlay):
bounds = element.last.bounds
xdensity = element.last.xdensity
ydensity = element.last.ydensity
element = self.concatenate(element)
elif isinstance(element, Overlay):
return element.map(self._process, [Element])
else:
xdensity = element.xdensity
ydensity = element.ydensity
bounds = element.bounds

vdim = element.vdims[0].name
Expand Down Expand Up @@ -940,7 +948,8 @@ def _process(self, element, key=None):
else:
img = tf.shade(array, **shade_opts)
params = dict(get_param_values(element), kdims=kdims,
bounds=bounds, vdims=RGB.vdims[:])
bounds=bounds, vdims=RGB.vdims[:],
xdensity=xdensity, ydensity=ydensity)
return RGB(self.uint32_to_uint8(img.data), **params)


Expand Down
12 changes: 12 additions & 0 deletions tests/operation/testdatashader.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@ def test_aggregate_ndoverlay_count_cat_datetimes_microsecond_timebase(self):
self.assertEqual(imgs[0], expected)
self.assertEqual(imgs[1], expected2)

def test_aggregate_dt_xaxis_constant_yaxis(self):
df = pd.DataFrame({'y': np.ones(100)}, index=pd.date_range('1980-01-01', periods=100, freq='1T'))
img = rasterize(Curve(df), dynamic=False)
xs = np.array(['1980-01-01T00:16:30.000000', '1980-01-01T00:49:30.000000',
'1980-01-01T01:22:30.000000'], dtype='datetime64[us]')
ys = np.array([])
bounds = (np.datetime64('1980-01-01T00:00:00.000000'), 1.0,
np.datetime64('1980-01-01T01:39:00.000000'), 1.0)
expected = Image((xs, ys, np.empty((0, 3))), ['index', 'y'], 'Count',
xdensity=1, ydensity=1, bounds=bounds)
self.assertEqual(img, expected)

def test_aggregate_ndoverlay(self):
ds = Dataset([(0.2, 0.3, 0), (0.4, 0.7, 1), (0, 0.99, 2)], kdims=['x', 'y', 'z'])
ndoverlay = ds.to(Points, ['x', 'y'], [], 'z').overlay()
Expand Down

0 comments on commit 0a154d7

Please sign in to comment.