Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Applied formatting to bokeh datetime hover tool labels #1263

Merged
merged 1 commit into from
Apr 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions holoviews/plotting/bokeh/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ def _get_hover_data(self, data, element, empty=False):
dim = util.dimension_sanitizer(d.name)
if dim not in data:
data[dim] = element.dimension_values(d)
elif isinstance(data[dim], np.ndarray) and data[dim].dtype.kind == 'M':
data[dim+'_dt_strings'] = [d.pprint_value(v) for v in data[dim]]

for k, v in self.overlay_dims.items():
dim = util.dimension_sanitizer(k.name)
Expand Down Expand Up @@ -573,7 +575,6 @@ def _categorize_data(self, data, cols, dims):
(isinstance(column, list) or column.dtype.kind not in 'SU')):
data[col] = [dims[i].pprint_value(v) for v in column]


def _get_factors(self, element):
"""
Get factors for categorical axes.
Expand Down Expand Up @@ -664,6 +665,27 @@ def _execute_hooks(self, element):
self.warning("Plotting hook %r could not be applied:\n\n %s" % (hook, e))


def _postprocess_hover(self, renderer, source):
"""
Attaches renderer to hover tool and processes tooltips to
ensure datetime data is displayed correctly.
"""
hover = self.handles.get('hover')
if hover is None:
return
hover.renderers = [renderer]

# If datetime column is in the data replace hover formatter
for k, v in source.data.items():
if k+'_dt_strings' in source.data:
tooltips = []
for name, formatter in hover.tooltips:
if formatter == '@{%s}' % k:
formatter = '@{%s_dt_strings}' % k
tooltips.append((name, formatter))
hover.tooltips = tooltips


def initialize_plot(self, ranges=None, plot=None, plots=None, source=None):
"""
Initializes a new plot object with the last available frame.
Expand Down Expand Up @@ -709,8 +731,7 @@ def initialize_plot(self, ranges=None, plot=None, plots=None, source=None):
if isinstance(renderer, Renderer):
self.handles['glyph_renderer'] = renderer

if 'hover' in self.handles:
self.handles['hover'].renderers = [renderer]
self._postprocess_hover(renderer, source)

# Update plot, source and glyph
with abbreviated_exception():
Expand Down
14 changes: 14 additions & 0 deletions tests/testplotinstantiation.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,20 @@ def _test_hover_info(self, element, tooltips, line_policy='nearest'):
self.assertEqual(hover[0].tooltips, tooltips)
self.assertEqual(hover[0].line_policy, line_policy)

def test_points_overlay_datetime_hover(self):
obj = NdOverlay({i: Points((list(pd.date_range('2016-01-01', '2016-01-31')), range(31))) for i in range(5)},
kdims=['Test'])
opts = {'Points': {'tools': ['hover']}}
obj = obj(plot=opts)
self._test_hover_info(obj, [('Test', '@{Test}'), ('x', '@{x_dt_strings}'), ('y', '@{y}')])

def test_curve_overlay_datetime_hover(self):
obj = NdOverlay({i: Curve((list(pd.date_range('2016-01-01', '2016-01-31')), range(31))) for i in range(5)},
kdims=['Test'])
opts = {'Curve': {'tools': ['hover']}}
obj = obj(plot=opts)
self._test_hover_info(obj, [('Test', '@{Test}'), ('x', '@{x_dt_strings}'), ('y', '@{y}')])

def test_points_overlay_hover_batched(self):
obj = NdOverlay({i: Points(np.random.rand(10,2)) for i in range(5)},
kdims=['Test'])
Expand Down