Skip to content

Commit

Permalink
Made datetime handling in plotting code more general
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Feb 2, 2017
1 parent 82a8d13 commit 14865de
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 37 deletions.
7 changes: 5 additions & 2 deletions holoviews/core/util.py
Expand Up @@ -16,8 +16,11 @@
except:
from collections import OrderedDict

datetime_types = (np.datetime64, dt.datetime)

try:
import pandas as pd # noqa (optional import)
datetime_types = datetime_types + (pd.tslib.Timestamp,)
except ImportError:
pd = None

Expand Down Expand Up @@ -493,13 +496,13 @@ def max_extents(extents, zrange=False):
for lidx, uidx in inds:
lower = [v for v in arr[lidx] if v is not None]
upper = [v for v in arr[uidx] if v is not None]
if lower and isinstance(lower[0], np.datetime64):
if lower and isinstance(lower[0], datetime_types):
extents[lidx] = np.min(lower)
elif any(isinstance(l, basestring) for l in lower):
extents[lidx] = np.sort(lower)[0]
elif lower:
extents[lidx] = np.nanmin(lower)
if upper and isinstance(upper[0], np.datetime64):
if upper and isinstance(upper[0], datetime_types):
extents[uidx] = np.max(upper)
elif any(isinstance(u, basestring) for u in upper):
extents[uidx] = np.sort(upper)[-1]
Expand Down
59 changes: 26 additions & 33 deletions holoviews/plotting/bokeh/element.py
Expand Up @@ -281,12 +281,12 @@ def _axes_props(self, plots, subplots, element, ranges):
if plot.yaxis[0].axis_label == xlabel:
plot_ranges['x_range'] = plot.y_range

if el.get_dimension_type(0) is np.datetime64:
if el.get_dimension_type(0) in util.datetime_types:
x_axis_type = 'datetime'
else:
x_axis_type = 'log' if self.logx else 'auto'

if len(dims) > 1 and el.get_dimension_type(1) is np.datetime64:
if len(dims) > 1 and el.get_dimension_type(1) in util.datetime_types:
y_axis_type = 'datetime'
else:
y_axis_type = 'log' if self.logy else 'auto'
Expand Down Expand Up @@ -517,44 +517,37 @@ def _update_ranges(self, element, ranges):
x_range = self.handles['x_range']
y_range = self.handles['y_range']

l, b, r, t = None, None, None, None
if any(isinstance(r, Range1d) for r in [x_range, y_range]):
l, b, r, t = self.get_extents(element, ranges)
if self.invert_axes:
l, b, r, t = b, l, t, r

xfactors, yfactors = None, None
if any(isinstance(r, FactorRange) for r in [x_range, y_range]):
xfactors, yfactors = self._get_factors(element)

if isinstance(x_range, Range1d):
if l == r and l is not None:
offset = abs(l*0.1 if l else 0.5)
l -= offset
r += offset

if self.invert_xaxis: l, r = r, l
if l is not None and (isinstance(l, np.datetime64) or np.isfinite(l)):
plot.x_range.start = l
if r is not None and (isinstance(r, np.datetime64) or np.isfinite(r)):
plot.x_range.end = r
elif isinstance(x_range, FactorRange):
xfactors = list(xfactors)
if self.invert_xaxis: xfactors = xfactors[::-1]
x_range.factors = xfactors

if isinstance(plot.y_range, Range1d):
if b == t and b is not None:
offset = abs(b*0.1 if b else 0.5)
b -= offset
t += offset
if self.invert_yaxis: b, t = t, b
if b is not None and (isinstance(l, np.datetime64) or np.isfinite(b)):
plot.y_range.start = b
if t is not None and (isinstance(l, np.datetime64) or np.isfinite(t)):
plot.y_range.end = t
elif isinstance(y_range, FactorRange):
yfactors = list(yfactors)
if self.invert_yaxis: yfactors = yfactors[::-1]
y_range.factors = yfactors
self._update_range(x_range, l, r, xfactors, self.invert_xaxis)
self._update_range(y_range, b, t, yfactors, self.invert_yaxis)


def _update_range(self, axis_range, low, high, factors, invert):
if isinstance(axis_range, Range1d):
if (low == high and low is not None and
not isinstance(high, util.datetime_types)):
offset = abs(low*0.1 if low else 0.5)
low -= offset
high += offset
if self.invert_yaxis: low, high = high, low
if low is not None and (isinstance(low, util.datetime_types)
or np.isfinite(low)):
axis_range.start = low
if high is not None and (isinstance(high, util.datetime_types)
or np.isfinite(high)):
axis_range.end = high
elif isinstance(axis_range, FactorRange):
factors = list(factors)
if self.invert_yaxis: factors = factors[::-1]
axis_range.factors = factors


def _categorize_data(self, data, cols, dims):
Expand Down
10 changes: 8 additions & 2 deletions holoviews/plotting/plot.py
Expand Up @@ -709,8 +709,14 @@ def get_extents(self, view, ranges):
if getattr(self, 'shared_axes', False) and self.subplot:
return util.max_extents([range_extents, extents], self.projection == '3d')
else:
return tuple(l1 if l2 is None or not np.isfinite(l2) else
l2 for l1, l2 in zip(range_extents, extents))
max_extent = []
for l1, l2 in zip(range_extents, extents):
if (isinstance(l2, util.datetime_types)
or (l2 is not None and np.isfinite(l2))):
max_extent.append(l2)
else:
max_extent.append(l1)
return tuple(max_extent)


def _get_axis_labels(self, dimensions, xlabel=None, ylabel=None, zlabel=None):
Expand Down

0 comments on commit 14865de

Please sign in to comment.