Bokeh 小部件 - 工作复选框组示例

Bokeh widget-Working Checkbox Group Example

我正在评估 Bokeh,看它是否已准备好用于更广泛的用途。我绘制了数据框的两列(最后的代码),"Close" 和 "Adj Close"。

我想放入复选框来切换图中两个折线图的显示。因此,如果取消选中相关复选框,则该行不会出现。 http://docs.bokeh.org/en/latest/docs/user_guide/interaction.html 的 Bokeh 文档确实讨论了复选框组,但没有提供明确的工作示例。如果您能为数据框的列设置复选框,我将不胜感激。

import pandas as pd
from bokeh.plotting import figure, output_file, show

IBM = pd.read_csv(
        "http://ichart.yahoo.com/table.csv?s=IBM&a=0&b=1&c=2011&d=0&e=1&f=2016",
        parse_dates=['Date'])

output_file("datetime.html")

p = figure(width=500, height=250, x_axis_type="datetime")

p.line(IBM['Date'], IBM['Close'], color='navy', alpha=0.5)
p.line(IBM['Date'], IBM['Adj Close'], color='red', alpha=0.5)

show(p)

我还不能使复选框起作用,但如果该功能即将推出,我不会感到惊讶。与此同时,这里有一个使用多选小部件的解决方法:

from bokeh.io import vform
from bokeh.models import CustomJS, ColumnDataSource, MultiSelect
from bokeh.plotting import figure, output_file, show
import pandas as pd

IBM = pd.read_csv(
        "http://ichart.yahoo.com/table.csv?s=IBM&a=0&b=1&c=2011&d=0&e=1&f=2016",
        parse_dates=['Date'])

output_file("datetime.html")
source = ColumnDataSource({'x': IBM['Date'], 'y1': IBM['Close'], \
'y2': IBM['Adj Close'], 'y1p': IBM['Close'], 'y2p': IBM['Adj Close']})

p = figure(width=500, height=250, x_axis_type="datetime")

p.line('x', 'y1', source=source, color='navy', alpha=0.5)
p.line('x', 'y2', source=source, color='red', alpha=0.5)

callback = CustomJS(args=dict(source=source), code="""
        var data = source.get('data');
        var f = cb_obj.get('value')
        y1 = data['y1']
        y2 = data['y2']
        y1p = data['y1p']
        y2p = data['y2p']
        if (f == "line2") {
            for (i = 0; i < y1.length; i++) {
                y1[i] = 'nan'
                y2[i] = y2p[i]
            }
        } else if (f == "line1") {
            for (i = 0; i < y2.length; i++) {
                y1[i] = y1p[i]
                y2[i] = 'nan'
            }
        } else if (f == "none") {
            for (i = 0; i < y2.length; i++) {
                y1[i] = 'nan'
                y2[i] = 'nan'
            }
        } else {
            for (i = 0; i < y2.length; i++) {
                y1[i] = y1p[i]
                y2[i] = y2p[i]
            }
        }
        source.trigger('change');
    """)

multi_select = MultiSelect(title="Lines to plot:", \
value=["line1", "line2", "none"], \
options=["line1", "line2", "none"], callback=callback)
layout = vform(multi_select, p)
show(layout)

输出如下所示:

这显然是一个迟到的回复,但我目前正在尝试学习 python 和 bokeh 来破解某种数据仪表板。我试图弄清楚复选框是如何工作的,但我无意中发现了你的问题。此解决方案仅适用于 bokeh serve 。我不知道如何让它在 HTML 输出中工作。

我只是在修改线条可见性,而不是源代码。我还没试过,但我相信传说中仍然会显示看不见的线条

对管道胶带代码表示歉意。

#-| bokeh serve
#-|

import pandas as pd
from bokeh.io import curdoc,output_file, show
from bokeh.layouts import row, widgetbox
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import *

#Widgets

ticker = TextInput(title='Ticker Symbol',value='IBM')
button=Button(label='Lookup',button_type='success')
log = Paragraph(text="""log""",
width=200, height=100)
cb_group = CheckboxButtonGroup(labels=['Close', 'Adj Close'],active=[0,1])
cb_group.labels.append('Placebo')

#Plot

p = figure(title='',width=500, height=250, x_axis_type='datetime')

source = ColumnDataSource({'x': [], 'y1': [],'y2': []})

lineClose=p.line('x','y1',source=source, color='navy', alpha=0.5)
lineAdj=p.line('x','y2',source=source, color='red', alpha=0.5)

lines=[lineClose,lineAdj]

#Event handling

def error(msg):
    log.text=msg

def update_data():
    try:
        src='http://ichart.yahoo.com/table.csv?s={symb}&a=0&b=1&c=2011&d=0&e=1&f=2016'.format(symb=ticker.value)
        df=pd.read_csv(src,parse_dates=['Date'])
        source.data=({'x': df['Date'], 'y1': df['Close'],'y2': df['Adj Close']})
    except:
        error('Error ticker')

def update_plot(new):

    switch=cb_group.active
    for x in range(0,len(lines)):
        if x in switch:
            lines[x].visible=True
        else:
            lines[x].visible=False

    error('<CheckboxButtonGroup>.active = '+str(switch))

button.on_click(update_data)
cb_group.on_click(update_plot)


inputs=widgetbox(ticker,button,cb_group,log)

curdoc().add_root(row(inputs,p,width=800))
curdoc().title = 'Bokeh Checkbox Example'
button.clicks=1

我添加了 'Placebo' 复选框以查看是否可以附加到复选框组 而不是典型的方法,所以我确信有一种方法可以更优雅、更动态地添加复选框。