Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Bokeh, how do I add tooltips to a Timeseries chart (hover tool)?

Is it possible to add Tooltips to a Timeseries chart?

In the simplified code example below, I want to see a single column name ('a','b' or 'c') when the mouse hovers over the relevant line.

Instead, a "???" is displayed and ALL three lines get a tool tip (rather than just the one im hovering over)

enter image description here

Per the documentation ( http://docs.bokeh.org/en/latest/docs/user_guide/tools.html#hovertool), field names starting with “@” are interpreted as columns on the data source.

  1. How can I display the 'columns' from a pandas DataFrame in the tooltip?

  2. Or, if the high level TimeSeries interface doesn't support this, any clues for using the lower level interfaces to do the same thing? (line? multi_line?) or convert the DataFrame into a different format (ColumnDataSource?)

  3. For bonus credit, how should the "$x" be formatted to display the date as a date?

thanks in advance

    import pandas as pd     import numpy as np     from bokeh.charts import TimeSeries     from bokeh.models import HoverTool     from bokeh.plotting import show      toy_df = pd.DataFrame(data=np.random.rand(5,3), columns = ('a', 'b' ,'c'), index = pd.DatetimeIndex(start='01-01-2015',periods=5, freq='d'))         p = TimeSeries(toy_df, tools='hover')        hover = p.select(dict(type=HoverTool))     hover.tooltips = [         ("Series", "@columns"),         ("Date", "$x"),         ("Value", "$y"),         ]      show(p) 
like image 240
bs123 Avatar asked Jul 18 '15 23:07

bs123


People also ask

What is hover tool?

The hover tool displays tooltips associated with individual glyphs. You can configure these tooltips to activate in different ways with a mode property: "mouse" only when the mouse is directly over a glyph.

How do you zoom in on bokeh?

Zoom In. Bokeh can be achieved at any focal length, but if you're struggling to get a strong bokeh effect, try zooming in more, or using a lens with a longer focal length. If zooming in means you can't fit your subject in the frame, move further away from your subject and re-shoot.


1 Answers

Below is what I came up with.

Its not pretty but it works.

Im still new to Bokeh (& Python for that matter) so if anyone wants to suggest a better way to do this, please feel free.

enter image description here

import pandas as pd import numpy as np from bokeh.charts import TimeSeries from bokeh.models import HoverTool from bokeh.plotting import show  toy_df = pd.DataFrame(data=np.random.rand(5,3), columns = ('a', 'b' ,'c'), index = pd.DatetimeIndex(start='01-01-2015',periods=5, freq='d'))          _tools_to_show = 'box_zoom,pan,save,hover,resize,reset,tap,wheel_zoom'          p = figure(width=1200, height=900, x_axis_type="datetime", tools=_tools_to_show)   # FIRST plot ALL lines (This is a hack to get it working, why can't i pass in a dataframe to multi_line?)    # It's not pretty but it works.  # what I want to do!: p.multi_line(df) ts_list_of_list = [] for i in range(0,len(toy_df.columns)):     ts_list_of_list.append(toy_df.index.T)  vals_list_of_list = toy_df.values.T.tolist()  # Define colors because otherwise multi_line will use blue for all lines... cols_to_use =  ['Black', 'Red', 'Lime'] p.multi_line(ts_list_of_list, vals_list_of_list, line_color=cols_to_use)   # THEN put  scatter one at a time on top of each one to get tool tips (HACK! lines with tooltips not yet supported by Bokeh?)  for (name, series) in toy_df.iteritems():     # need to repmat the name to be same dimension as index     name_for_display = np.tile(name, [len(toy_df.index),1])      source = ColumnDataSource({'x': toy_df.index, 'y': series.values, 'series_name': name_for_display, 'Date': toy_df.index.format()})     # trouble formating x as datestring, so pre-formating and using an extra column. It's not pretty but it works.      p.scatter('x', 'y', source = source, fill_alpha=0, line_alpha=0.3, line_color="grey")           hover = p.select(dict(type=HoverTool))     hover.tooltips = [("Series", "@series_name"), ("Date", "@Date"),  ("Value", "@y{0.00%}"),]     hover.mode = 'mouse'  show(p) 
like image 92
bs123 Avatar answered Sep 29 '22 23:09

bs123