Search code examples
python-3.xpandasbokeh

How to use Bokeh HoverTool with n number of columns


I'm trying to write a function that takes a pandas df as data source, with a selected number of columns and plot as (multiple) line chart using Bokeh:

import pandas as pd
import numpy as np

from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource


df = pd.DataFrame(np.random.randint(0,100,size=(10, 5)), columns=list('ABCDF'))
source = ColumnDataSource(df)
colors = ['blue', 'green', 'red', 'orange', 'brown', 'black']

###Plotting function
def plot(df, col_n):
    p = figure(height=300, width=300)
    for i, c in zip(col_n, colors):
        p.line(source=source, x= 'index', y=str(i), color=c)
    
    return p

ttt = plot(df, ['A', 'B', 'C', 'F'])
show(ttt) 

Now I want to add HoverTool to the chart, inclusing every column/line specified in tha function, how would I do that? I have tried numerous versions of the above for loop, but I just cannot make it work at all.

Any help much appreciated:)

My last attempt:

n = range(len(col_n))
    for i, x in zip(col_n, n):
        hover1 = HoverTool(tooltips=[("Date", "@index{%d/%m/%Y}"),
                                     ("Price_"+str(i), '"""@"+str(i)+"{€ %.2f}"""')],
                           formatters={'@date': 'datetime'}, 
                           mode='vline')

Solution

  • You can do this:

    import pandas as pd
    import numpy as np
    
    from bokeh.plotting import figure, show
    from bokeh.models import ColumnDataSource
    from bokeh.models import HoverTool
    
    
    df = pd.DataFrame(np.random.randint(0,100,size=(10, 5)), columns=list('ABCDF'))
    source = ColumnDataSource(df)
    colors = ['blue', 'green', 'red', 'orange', 'brown', 'black']
    
    def plot(df, col_n):
        p = figure(height=300, width=500, x_axis_type='datetime')
        for i, c in zip(col_n, colors):
            line = p.line(source=source, x='index', y=str(i), color=c, line_width=2)
            hover = HoverTool(tooltips=[('Date', '@index{%F}'), (str(i), f'€ @{{{str(i)}}}{{0.00}}')],
                              formatters={'@index': 'datetime'})
            p.add_tools(hover)
            hover.renderers = [line]
        return p
    
    
    tt = plot(df,['A', 'B', 'C', 'F'])
    show(tt)
    

    enter image description here