Search code examples
pythonplotbokeh

Bokeh hover tooltip to show data from a different column


I have the code below. I want the hover tooltip for the bars to show which account they are from. It is unclear to me how the hover.tooltips parameter should be used to retrieve data from the account column in the dataframe.

import pandas as pd
from bokeh.plotting import figure, output_notebook, show
output_notebook()

sales = [{'account': 'Jones LLC', 'sales': 150, 'day' : 1},
         {'account': 'Alpha Co',  'sales': 200, 'day' : 2},
         {'account': 'Blue Inc',  'sales': 50, 'day' : 3}]
df = pd.DataFrame(sales)

TOOLS = "hover,save,pan,box_zoom,reset,wheel_zoom"
p = figure(plot_width=400, plot_height=400, y_axis_label="sales", tools=TOOLS)
p.vbar(x=df.day, bottom=0, top=df.sales, width=0.25)

hover = p.select(dict(type=HoverTool))
hover.tooltips = [("account", "@account")]

show℗

A second reproducible example where tooltips are not showing

import pandas as pd
from bokeh.plotting import figure, output_notebook, show
from bokeh.models import HoverTool
output_notebook()

data = {'rt_by': ['somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename', 'somename'], 'to_followers': [473, 301, 172, 149, 2422, 106, 16, 3173, 562, 354, 1154, 301, 1228, 261, 204, 471, 2422, 22, 222, 965, 965, 869, 473, 63452, 3095, 220, 2177, 22, 69, 128, 2422, 1277, 702, 959, 365, 398, 3928], 'date': ['2018-01-25 16:39:03','2018-01-25 16:51:06','2018-01-25 17:05:31','2018-01-25 17:11:30','2018-01-25 21:31:26','2018-01-25 21:56:12','2018-01-25 23:15:17','2018-01-28 07:14:48','2018-01-28 07:43:35','2018-01-28 12:22:26','2018-01-28 20:15:29','2018-01-28 20:42:11','2018-01-29 07:35:38','2018-01-29 08:28:07','2018-01-29 09:32:24','2018-01-29 13:45:28','2018-01-29 14:53:12','2018-01-30 07:18:18','2018-01-30 07:19:13','2018-01-30 08:55:06','2018-01-30 09:10:30','2018-01-30 09:48:13','2018-01-30 09:49:13','2018-01-30 10:02:40','2018-01-30 10:06:55','2018-01-30 10:15:16','2018-01-30 10:40:50','2018-01-30 10:42:27','2018-01-30 10:46:07','2018-01-30 11:13:12','2018-01-30 11:13:34','2018-01-30 11:54:37','2018-01-30 12:17:02','2018-01-30 12:18:00','2018-01-30 12:26:04','2018-01-30 14:25:18','2018-01-30 14:32:12']}
df = pd.DataFrame.from_dict(data)
df['date'] = pd.to_datetime(df['date'])


TOOLS = "hover,save,pan,box_zoom,reset,wheel_zoom"

p = figure(plot_width=800, plot_height=400, tools=TOOLS)

p.vbar(x='date', bottom=0, top='to_followers', width=1, source=df)

hover = p.select(type=HoverTool)
hover.tooltips = [("rt_by", "@rt_by")]

show(p)

Solution

  • If you pass data directly to glyph methods vbar, etc., then Bokeh only sends exactly what you provide and nothing more. If you want to send extra data columns (e.g. to have displayed in a hover tool) then you have to arrange for that by specifying a source argument for the glyph, and referring to the column names. Previously this meant creating a ColumnDataSource from the dataframe yourself, but with recent versions of Bokeh you can just pass the dataframe directly. See the User Guide chapter Providing Data for full details. A complete example is below:

    import pandas as pd
    from bokeh.models import HoverTool
    from bokeh.plotting import figure, output_file, show
    
    output_file("foo.html")
    
    sales = [{'account': 'Jones LLC', 'sales': 150, 'day' : 1},
             {'account': 'Alpha Co',  'sales': 200, 'day' : 2},
             {'account': 'Blue Inc',  'sales': 50, 'day' : 3}]
    df = pd.DataFrame(sales)
    
    TOOLS = "hover,save,pan,box_zoom,reset,wheel_zoom"
    p = figure(plot_width=400, plot_height=400, y_axis_label="sales", tools=TOOLS)
    
    # THIS LINE CHANGED
    p.vbar(x='day', bottom=0, top='sales', width=0.25, source=df)
    
    hover = p.select(dict(type=HoverTool))
    hover.tooltips = [("account", "@account")]
    
    show(p)
    

    enter image description here