【问题标题】:How to update a source in a JavaScript Callback of Bokeh in Python?如何在 Python 中更新散景的 JavaScript 回调中的源?
【发布时间】:2018-07-08 18:21:26
【问题描述】:

我正在为我的案例调整this answer,我想要一个交互式的独立图表,其中滑块选择要在条形图中绘制的数据列。 (独立很重要,我不能运行 Bokeh 服务器,因此需要JavaScript callbacks。)

数据是一个浮点矩形,38 列中的每一列有 100 行,它们都有字符串标签,如 '40' 等。(这是 pandas .read_csv() 默认处理标题中的数字的方式。)这里是左上角的样本(3x3,加上行和列标签):

        # ,        40,        41,        42,
   1.00000,   1.00000,   0.99287,   0.98489,
   2.00000,   1.00000,   0.99348,   0.98626,
   3.00000,   1.00000,   0.99433,   0.98922,

下面的代码为第一列生成图表,但在移动滑块时不会更新图表。

通过查看它,我怀疑问题出在 JavaScript 代码上,尽管 ColumnDataSource 对我来说仍然有点神秘。 (更直接的数字列标签字典到列中的数字列表不能用作datasource_available,但对应于链接答案的用例。)

datadf = pd.read_csv('male_survival_by_pctile.csv')
datadf.set_index('# ',inplace=True)
years = range(40,77)
data = {}
data_available = {}

for year in years:
    data[year] = {'top':datadf[str(year)],'x':range(1,101)}
data_available = ColumnDataSource.from_df(datadf)

from bokeh.core.properties import field
from bokeh.io import curdoc, output_notebook, show
from bokeh.layouts import layout, column
from bokeh.models import (ColumnDataSource, HoverTool, SingleIntervalTicker,
                          Slider, Button, Label, CustomJS)
from bokeh.plotting import figure

output_notebook()

source_visible = ColumnDataSource(data=dict(x=range(1,101),top=data_available[str(years[0])]))
source_available = ColumnDataSource(data=data_available)

plot = figure(output_backend="webgl")
plot.xaxis.ticker = SingleIntervalTicker(interval=.01)
plot.xaxis.axis_label = "Income percentile"
plot.yaxis.ticker = SingleIntervalTicker(interval=.05)
plot.yaxis.axis_label = "Survival rate"

label = Label(x=1.1, y=18, text=str(years[0]), text_font_size='70pt', text_color='#eeeeee')
plot.add_layout(label)

plot.vbar(top='top',x='x',width=1,source=source_visible)

slider = Slider(start=years[0], end=years[-1], value=years[0], step=1, title="Age")

slider.callback = CustomJS(
    args=dict(source_visible=source_visible,
              source_available=source_available), code="""
        var selected_function = cb_obj.get('value').toString();
        // Get the data from the data sources
        var data_visible = source_visible.get('data');
        var data_available = source_available.get('data');
        // Change bar height to the selected value
        data_visible.top = data_available[selected_function];
        // Update the plot
        source_visible.trigger('change');
    """)

layout = column(slider, plot)

show(layout)

【问题讨论】:

    标签: javascript python callback bokeh bokehjs


    【解决方案1】:

    正如您所怀疑的,问题出在CustomJS 代码中。有两件事需要解决。

    1. Bokeh 已弃用 get()set() 方法,并将它们替换为 getv()setv()。但是,访问或修改模型属性的首选方式是通过常用的 JavaScript 属性,例如,source_visible.data

    2. Bokeh 有 deprecated trigger('change') 并将其替换为 change.emit()

    固定的CustomJS代码:

    slider.callback = CustomJS(
        args=dict(source_visible=source_visible,
                  source_available=source_available), code="""
            var selected_function = cb_obj.value.toString();
            // Get the data from the data sources
            var data_visible = source_visible.data;
            var data_available = source_available.data;
            // Change bar height to the selected value
            data_visible.top = data_available[selected_function];
            // Update the plot
            source_visible.change.emit();
        """)
    

    在浏览器的控制台中可以看到 JavaScript 错误和警告。 Here are instructions for opening the console in different browsers.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-29
      • 2022-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多