Bokeh单机版中带有下拉菜单的折线图不起作用

问题描述

我正在构建一个简单的HTML文件,以表示带有下拉菜单的图表中的某些数据,但此类交互的回调不起作用。 这是我的代码

from bokeh.models import CustomJS,ColumnDataSource,Select
from bokeh.plotting import figure,output_file,show
import pandas as pd
from bokeh.models import layouts

output_file("churn_graph.html",title="line_on_off.py example")

df_3_days = pd.read_excel("C:\\Users\\Admin\\Desktop\\data1.xlsx",sheet_name="3 days")
df_40_days = pd.read_excel("C:\\Users\\Admin\\Desktop\\data2.xlsx",sheet_name="40 days")
df_365_days = pd.read_excel("C:\\Users\\Admin\\Desktop\\data3.xlsx",sheet_name="365 days")

x = df_3_days['Month']
churn_3d_12m_all = df_3_days['churnRate_12m_all']
churn_3d_12m_b2b = df_3_days['churnRate_12m_B2B']
churn_3d_12m_b2c = df_3_days['churnRate_12m_B2C']
churn_3d_6m = df_3_days['churnRate_6m_all']

churn_40d_12m_all = df_40_days['churnRate_12m_all']
churn_40d_12m_b2b = df_40_days['churnRate_12m_B2B']
churn_40d_12m_b2c = df_40_days['churnRate_12m_B2C']
churn_40d_6m = df_40_days['churnRate_6m_all']

churn_365d_12m_all = df_365_days['churnRate_12m_all']
churn_365d_12m_b2b = df_365_days['churnRate_12m_B2B']
churn_365d_12m_b2c = df_365_days['churnRate_12m_B2C']
churn_365d_6m = df_365_days['churnRate_6m_all']

source = ColumnDataSource({
    'x' : x,'y3_12all' : churn_3d_12m_all,'x' : x,'y3_12B2B' : churn_3d_12m_b2b,'y3_12B2C' : churn_3d_12m_b2c,'y3_6m' : churn_3d_6m
})

p = figure(width=500,height=250)

y3_12all = p.line(x,churn_3d_12m_all,color='blue',legend_label="3 days,12m all")
y3_12B2B = p.line(x,churn_3d_12m_b2b,color='brown',legend_label="3 days B2B")
y3_12B2C = p.line(x,churn_3d_12m_b2c,color='red',legend_label="3 days B2C")
y3_6m = p.line(x,churn_3d_6m,color='green',6m")

callback = CustomJS(args=dict(source=source),code="""
    var data = source.get('data');
    var f = cb_obj.get('value')
    y3_12all = data['y3_12all']
    y3_12B2B = data['y3_12B2B']
    y3_12B2C = data['y3_12B2C']
    y3_6m = data['y3_6m']
    if (f == "y3_12all"){
        for (i = 0; i < y3_12all.length; i++) {y3_12all[i] = y3_12all[i]}
        for (i = 0; i < y3_12B2B.length; i++) {y3_12B2B[i] = 'nan'}
        for (i = 0; i < y3_12B2C.length; i++) {y3_12B2C[i] = 'nan'}
        for (i = 0; i < y3_6m.length; i++) {y3_6m[i] = 'nan'}
    else {
        for (i = 0; i < y3_12all.length; i++) {y3_12all[i] = y3_12all[i]}
        for (i = 0; i < y3_12B2B.length; i++) {y3_12B2B[i] = y3_12B2B[i]}
        for (i = 0; i < y3_12B2C.length; i++) {y3_12B2C[i] = y3_12B2C[i]}
        for (i = 0; i < y3_6m.length; i++) {y3_6m[i] = y3_6m[i]}
    }
    source.trigger('change');
""")
buffers = ['12m all','12m B2B','12m B2C','6m','all']
multi_select = Select(title="Select buffer: ",value=buffers[4],options=buffers,callback=callback)
output_file("churn_chart.html")

layout = layouts.VBox(multi_select,p)
show(layout)

运行后,我收到消息:“ Select的意外属性'callback',相似的属性是js_event_callbacks”。 关于如何解决它的任何建议? 谢谢:)

解决方法

https://docs.bokeh.org/en/latest/docs/releases.html#api-removals的2.0.0的更改日志中:

此外,从所有Bokeh模型中删除了callback属性,但CustomActionHoverToolTapToolOpenURL除外。相反,应使用更通用的js_on_changejs_on_event方法。

尝试删除callback的{​​{1}}参数并添加类似内容

Select

与您的问题无关,但您也可以考虑以下更改:

  • multi_select.js_on_change('value',callback) 替换为source.get('data')
  • 类似地,将source.data替换为cb_obj.get('value')

此外,我不确定cb_obj.value字符串是否是一种好方法。如果它们引起任何麻烦,您只需使用'nan'