Skip to content

Commit

Permalink
Ensure QuadMesh with xarray handles datetime range (#3081)
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr authored and jlstevens committed Oct 11, 2018
1 parent d91c86f commit a65ef97
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 4 deletions.
5 changes: 5 additions & 0 deletions holoviews/core/data/grid.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import absolute_import

import sys
import datetime as dt
from collections import OrderedDict, defaultdict, Iterable

try:
Expand Down Expand Up @@ -188,6 +190,9 @@ def _infer_interval_breaks(cls, coord, axis=0):
[ 2.5, 3.5, 4.5]])
"""
coord = np.asarray(coord)
if sys.version_info.major == 2 and len(coord) and isinstance(coord[0], (dt.datetime, dt.date)):
# np.diff does not work on datetimes in python 2
coord = coord.astype('datetime64')
deltas = 0.5 * np.diff(coord, axis=axis)
first = np.take(coord, [0], axis=axis) - np.take(deltas, [0], axis=axis)
last = np.take(coord, [-1], axis=axis) + np.take(deltas, [-1], axis=axis)
Expand Down
9 changes: 6 additions & 3 deletions holoviews/core/data/xarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,10 @@ def range(cls, dataset, dimension):
dim = dataset.get_dimension(dimension, strict=True).name
if dataset._binned and dimension in dataset.kdims:
data = cls.coords(dataset, dim, edges=True)
dmin, dmax = np.nanmin(data), np.nanmax(data)
if data.dtype.kind == 'M':
dmin, dmax = data.min(), data.max()
else:
dmin, dmax = np.nanmin(data), np.nanmax(data)
else:
data = dataset.data[dim]
if len(data):
Expand All @@ -211,8 +214,8 @@ def range(cls, dataset, dimension):
da = dask_array_module()
if da and isinstance(dmin, da.Array):
dmin, dmax = da.compute(dmin, dmax)
dmin = dmin if np.isscalar(dmin) else dmin.item()
dmax = dmax if np.isscalar(dmax) else dmax.item()
dmin = dmin if np.isscalar(dmin) or isinstance(dmin, util.datetime_types) else dmin.item()
dmax = dmax if np.isscalar(dmax) or isinstance(dmax, util.datetime_types) else dmax.item()
return dmin, dmax


Expand Down
22 changes: 21 additions & 1 deletion holoviews/tests/core/data/testxarrayinterface.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import datetime as dt
from collections import OrderedDict
from nose.plugins.attrib import attr
from unittest import SkipTest
Expand All @@ -12,7 +13,7 @@
from holoviews.core.data import Dataset, concat
from holoviews.core.dimension import Dimension
from holoviews.core.spaces import HoloMap
from holoviews.element import Image, RGB, HSV
from holoviews.element import Image, RGB, HSV, QuadMesh

from .testimageinterface import (
Image_ImageInterfaceTests, RGB_ImageInterfaceTests, HSV_ImageInterfaceTests
Expand Down Expand Up @@ -181,6 +182,25 @@ def test_zero_sized_coordinates_range(self):
self.assertTrue(np.isnan(z0))
self.assertTrue(np.isnan(z1))

def test_datetime_bins_range(self):
xs = [dt.datetime(2018, 1, i) for i in range(1, 11)]
ys = np.arange(10)
array = np.random.rand(10, 10)
ds = QuadMesh((xs, ys, array))
self.assertEqual(ds.interface.datatype, 'xarray')
expected = (dt.datetime(2017, 12, 31, 12, 0), dt.datetime(2018, 1, 10, 12, 0))
self.assertEqual(ds.range('x'), expected)

def test_datetime64_bins_range(self):
xs = [np.datetime64(dt.datetime(2018, 1, i)) for i in range(1, 11)]
ys = np.arange(10)
array = np.random.rand(10, 10)
ds = QuadMesh((xs, ys, array))
self.assertEqual(ds.interface.datatype, 'xarray')
expected = (np.datetime64(dt.datetime(2017, 12, 31, 12, 0)),
np.datetime64(dt.datetime(2018, 1, 10, 12, 0)))
self.assertEqual(ds.range('x'), expected)

def test_dataset_array_init_hm(self):
"Tests support for arrays (homogeneous)"
raise SkipTest("Not supported")
Expand Down

0 comments on commit a65ef97

Please sign in to comment.