Skip to content

Commit

Permalink
Handle single pixel Image types (#2794)
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr authored and jlstevens committed Jun 14, 2018
1 parent 3021981 commit c40cdd0
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 12 deletions.
2 changes: 1 addition & 1 deletion doc/nbpublisher
Submodule nbpublisher updated 1 files
+5 −0 nbtest.py
11 changes: 9 additions & 2 deletions holoviews/element/comparison.py
Expand Up @@ -28,7 +28,7 @@
HoloMap, Dimensioned, Layout, NdLayout, NdOverlay,
GridSpace, DynamicMap, GridMatrix, OrderedDict)
from ..core.options import Options, Cycle
from ..core.util import pd
from ..core.util import pd, datetime_types, dt_to_int


class ComparisonInterface(object):
Expand Down Expand Up @@ -265,8 +265,15 @@ def compare_dataframe(cls, df1, df2, msg='DataFrames'):

@classmethod
def bounds_check(cls, el1, el2, msg=None):
lbrt1 = el1.bounds.lbrt()
lbrt2 = el2.bounds.lbrt()
try:
cls.assert_array_almost_equal_fn(np.array(el1.bounds.lbrt()), np.array(el2.bounds.lbrt()))
for v1, v2 in zip(lbrt1, lbrt2):
if isinstance(v1, datetime_types):
v1 = dt_to_int(v1)
if isinstance(v2, datetime_types):
v2 = dt_to_int(v2)
cls.assert_array_almost_equal_fn(v1, v2)
except AssertionError:
raise cls.failureException("BoundingBoxes are mismatched: %s != %s."
% (el1.bounds.lbrt(), el2.bounds.lbrt()))
Expand Down
16 changes: 14 additions & 2 deletions holoviews/element/raster.py
Expand Up @@ -279,6 +279,11 @@ def __init__(self, data, kdims=None, vdims=None, bounds=None, extents=None,
l, b, r, t = bounds.lbrt()
xdensity = xdensity if xdensity else compute_density(l, r, dim1, self._time_unit)
ydensity = ydensity if ydensity else compute_density(b, t, dim2, self._time_unit)
if not np.isfinite(xdensity) or not np.isfinite(ydensity):
raise ValueError('Density along Image axes could not be determined. '
'If the data contains only one coordinate along the '
'x- or y-axis ensure you declare the bounds and/or '
'density.')
SheetCoordinateSystem.__init__(self, bounds, xdensity, ydensity)
self._validate(data_bounds, supplied_bounds)

Expand Down Expand Up @@ -322,8 +327,15 @@ def _validate(self, data_bounds, supplied_bounds):
else:
bounds = data_bounds

if not all(np.isclose(r, c, rtol=self.rtol) for r, c in zip(bounds, self.bounds.lbrt())
if util.isfinite(r) and not isinstance(r, util.datetime_types)):
not_close = False
for r, c in zip(bounds, self.bounds.lbrt()):
if isinstance(r, datetime_types):
r = util.dt_to_int(r)
if isinstance(c, datetime_types):
c = util.dt_to_int(c)
if util.isfinite(r) and not np.isclose(r, c, rtol=self.rtol):
not_close = True
if not_close:
raise ValueError('Supplied Image bounds do not match the coordinates defined '
'in the data. Bounds only have to be declared if no coordinates '
'are supplied, otherwise they must match the data. To change '
Expand Down
14 changes: 11 additions & 3 deletions holoviews/operation/datashader.py
Expand Up @@ -422,14 +422,23 @@ def _process(self, element, key=None):
self._precomputed[element._plot_id] = x, y, data, glyph
(x_range, y_range), (xs, ys), (width, height), (xtype, ytype) = self._get_sampling(element, x, y)

(x0, x1), (y0, y1) = x_range, y_range
if xtype == 'datetime':
x0, x1 = (np.array([x0, x1])/10e5).astype('datetime64[us]')
if ytype == 'datetime':
y0, y1 = (np.array([y0, y1])/10e5).astype('datetime64[us]')
bounds = (x0, y0, x1, y1)
params = dict(get_param_values(element), kdims=[x, y],
datatype=['xarray'], bounds=bounds)

if x is None or y is None:
xarray = xr.DataArray(np.full((height, width), np.NaN, dtype=np.float32),
dims=['y', 'x'], coords={'x': xs, 'y': ys})
return self.p.element_type(xarray)
elif not len(data):
xarray = xr.DataArray(np.full((height, width), np.NaN, dtype=np.float32),
dims=[y.name, x.name], coords={x.name: xs, y.name: ys})
return self.p.element_type(xarray)
return self.p.element_type(xarray, **params)

cvs = ds.Canvas(plot_width=width, plot_height=height,
x_range=x_range, y_range=y_range)
Expand All @@ -445,8 +454,7 @@ def _process(self, element, key=None):
vdims = [dims[0](name)]
else:
vdims = Dimension('Count')
params = dict(get_param_values(element), kdims=[x, y],
datatype=['xarray'], vdims=vdims)
params['vdims'] = vdims

dfdata = PandasInterface.as_dframe(data)
agg = getattr(cvs, glyph)(dfdata, x.name, y.name, agg_fn)
Expand Down
8 changes: 4 additions & 4 deletions tests/operation/testdatashader.py
Expand Up @@ -69,8 +69,8 @@ def test_aggregate_curve_datetimes(self):
dates = pd.date_range(start="2016-01-01", end="2016-01-03", freq='1D')
curve = Curve((dates, [1, 2, 3]))
img = aggregate(curve, width=2, height=2, dynamic=False)
bounds = (np.datetime64('2015-12-31T23:59:59.723518000'), 1.0,
np.datetime64('2016-01-03T00:00:00.276482000'), 3.0)
bounds = (np.datetime64('2016-01-01T00:00:00.000000'), 1.0,
np.datetime64('2016-01-03T00:00:00.000000'), 3.0)
dates = [np.datetime64('2016-01-01T12:00:00.000000000'),
np.datetime64('2016-01-02T12:00:00.000000000')]
expected = Image((dates, [1.5, 2.5], [[1, 0], [0, 2]]),
Expand All @@ -83,8 +83,8 @@ def test_aggregate_curve_datetimes_microsecond_timebase(self):
xend = np.datetime64('2016-01-03T00:00:00.276482000', 'us')
curve = Curve((dates, [1, 2, 3]))
img = aggregate(curve, width=2, height=2, x_range=(xstart, xend), dynamic=False)
bounds = (np.datetime64('2015-12-31T23:59:59.585277000'), 1.0,
np.datetime64('2016-01-03T00:00:00.414723000'), 3.0)
bounds = (np.datetime64('2015-12-31T23:59:59.723518'), 1.0,
np.datetime64('2016-01-03T00:00:00.276482'), 3.0)
dates = [np.datetime64('2016-01-01T11:59:59.861759000',),
np.datetime64('2016-01-02T12:00:00.138241000')]
expected = Image((dates, [1.5, 2.5], [[1, 0], [0, 2]]),
Expand Down

0 comments on commit c40cdd0

Please sign in to comment.