如何在复选框小部件的for循环中使用Bokeh悬停工具

时间:2018-05-08 15:36:19

标签: python-3.x hover widget bokeh

Python 3.6

散景12.15

我试图实现散景示例line_on_off.py,但是在带有悬停工具和不同长度数据的for循环中。但是,当关闭一条线时,它会关闭后面创建的任何线条的工具尖端。例如,如果我关闭第1行,则禁用第2,3,4行工具提示,或者如果我关闭第3行第4行,则禁用工具提示。

我可以像这样在for循环中使用悬停工具和复选框小部件吗?我看过this multiline example,但我的数据长度各不相同,我不想重新采样,因为我想查看数据是否有错误。

代码

from bokeh.plotting import figure
from bokeh.models import CheckboxGroup, CustomJS
from bokeh.models import ColumnDataSource
import pandas as pd
from bokeh.models import HoverTool

def create_plot(df_list):
    p = figure(x_axis_type = 'datetime')
    glyph_dict = {}
    labels = []
    active = []
    items = []
    names = 'abcdefghijklmnopqrstuvwxyz'
    callback_string = '{}.visible = {} in checkbox.active;'
    code_string = ''
    i = 0
    sources = []
    for df in df_list:
        legend = df.columns[0]
        series = df.iloc[:,0]
        labels.append(legend)
        x = series.index
        y = series.values
        source =ColumnDataSource(data = {'x':x,'y':y, 'date': [str(x) for x in x]})
        sources.append(source)
        line = p.line('x', 'y', source = sources[i])
        items.append((legend, [line]))
        name = names[i]
        line.name = name
        code_string += callback_string.format(name, str(i))
        glyph_dict.update({name:line})
        active.append(i)
        i+=1
    hover = HoverTool(tooltips=[('date', '@date'),('y', '@y')])
    p.add_tools(hover)
    checkbox = CheckboxGroup(labels=labels, active=active, width=200)
    glyph_dict.update({'checkbox':checkbox})
    checkbox.callback = CustomJS.from_coffeescript(args=glyph_dict, code=code_string)
    return checkbox, p

最小例子

import numpy as np
from datetime import datetime, timedelta
from bokeh.layouts import row
from bokeh.plotting import show


df_list = []
start = datetime(2017, 4,1)
end = datetime(2017,5,1)
for i in range(1,5):
    date = pd.date_range(start, end, freq = '1w')
    shape = len(date)
    df = pd.DataFrame(index = date, data = np.random.randn(shape,1))
    name = 'df'+ str(i)
    df.columns = [name]
    end = end + timedelta(weeks = 1)
    df_list.append(df)


c,p = create_plot(df_list)
r=row([c,p])

show(r)

1 个答案:

答案 0 :(得分:2)

在这种情况下,您应该通过限制每个悬停工具的renderers属性,为每一行创建一个新的单独悬停工具。因此,就您的代码而言,将循环工具创建移动到循环中,并且每次都设置renderers

line = p.line('x', 'y', source = sources[i])
hover = HoverTool(tooltips=[('date', '@date'),('y', '@y')]
                  renderers=[line])
p.add_tools(hover)