【问题标题】:Bokeh plot line not updating after checking CheckboxGroup in server mode (python callback)在服务器模式下检查 CheckboxGroup 后散景图线未更新(python 回调)
【发布时间】:2020-01-23 03:43:12
【问题描述】:

我刚刚开始使用 Bokeh 库,我想在我的仪表板中添加交互性。为此,我想使用 CheckboxGroup 小部件来选择要绘制的 pandas DataFrame 列中的哪一个。
我已按照教程进行操作,但我一定误解了 ColumnDataSource 的使用,因为我无法制作一个简单的示例...
我知道以前关于此事的问题,在 StackOverflow 论坛上似乎相关的问题是后者: Bokeh not updating plot line update from CheckboxGroup

很遗憾,我没有成功重现正确的行为。

我试图按照#bigreddot 在Bokeh Server plot not updating as wanted, also it keeps shifting and axis information vanishes 中提出的相同更新结构重现一个示例,但没有成功。

import numpy as np
import pandas as pd

from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
from bokeh.palettes import Spectral
from bokeh.layouts import row
from bokeh.models.widgets import CheckboxGroup
from bokeh.io import curdoc


#  UPDATE FUNCTION ------------------------------------------------
# make update function
def update(attr, old, new):
    feature_selected_test = [feature_checkbox.labels[i] for i in feature_checkbox.active]
    # add index to plot
    feature_selected_test.insert(0, 'index')
    # create new DataFrame
    new_df = dummy_df.filter(feature_selected_test)
    plot_src.data = ColumnDataSource.from_df(data=new_df)


# CREATE DATA SOURCE ------------------------------------------------
# create dummy data for debugging purpose
index = list(range(0, 890))
index.extend(list(range(2376, 3618)))
feature_1 = np.random.rand(len(index))
feature_2 = np.random.rand(len(index))
feature_3 = np.random.rand(len(index))
feature_4 = np.random.rand(len(index))

dummy_df = pd.DataFrame(dict(index=index, feature_1=feature_1, feature_2=feature_2, feature_3=feature_3,feature_4=feature_4))


# CREATE CONTROL ------------------------------------------------------
# list available data to plot
available_feature = list(dummy_df.columns[1:])
# initialize control
feature_checkbox = CheckboxGroup(labels=available_feature, active=[0, 1], name='checkbox')
feature_checkbox.on_change('active', update)


# INITIALIZE DASHBOARD ---------------------------------------------------
# initialize ColumnDataSource object
plot_src = ColumnDataSource(dummy_df)
# create figure
line_fig = figure()
feature_selected = [feature_checkbox.labels[i] for i in feature_checkbox.active]
# feature_selected = ['feature_1', 'feature_2', 'feature_3', 'feature_4']

for index_int, col_name_str in enumerate(feature_selected):
    line_fig.line(x='index', y=col_name_str, line_width=2, color=Spectral[11][index_int % 11], source=plot_src)


curdoc().add_root(row(feature_checkbox, line_fig))

该程序应该可以使用复制/粘贴...没有交互性... 有人可以帮助我吗?提前非常感谢。

【问题讨论】:

  • 您应该进行一些打印调试以查看更新函数是否被调用以及它正在生成您想要/期望的数据。例如,您创建的 `new_df` 真的正确吗?浏览器js控制台也有报错信息吗?
  • @bigreddot 感谢您的回复!我使用了打印调试(和 PyCharm 中的断点)来监控每个变量的值。它显然运行顺利:一旦您检查了一个 box,就会调用函数 update 并且 DataFrame new_df 会正常更新。至于 plot_src.data。 ColumnDataSource 对象中的数据会根据选中的框进行相应更新...然后什么都没有...直到您选中另一个框...

标签: python-3.x bokeh


【解决方案1】:

您只是为所选功能的初始子集添加字形:

for index_int, col_name_str in enumerate(feature_selected):
    line_fig.line(x='index', y=col_name_str, line_width=2, color=Spectral[11][index_int % 11], source=plot_src)

这就是将要展示的全部内容。

向 CDS 添加新列不会自动产生任何特别的情况,它只是可供字形或悬停工具可能使用的额外数据。要实际显示它,必须配置字形来显示这些列。您可以这样做,动态地添加和删除字形,但只需预先添加所有内容,然后使用复选框仅切换可见性,会简单得多。回购中有一个例子:

https://github.com/bokeh/bokeh/blob/master/examples/app/line_on_off.py

该示例将数据作为字面量传递给 glyph 函数,但您也可以将所有数据放在 CDS 中。

【讨论】:

  • 非常感谢您的明确回答。我误以为 ColumnDataSource 将是一种神奇的对象!散景很棒。感谢您的工作。
  • 修改后的初始化为:instantiate_plot = list() for index_int, col_name_str in enumerate(available_feature): instantiate_plot.append(line_fig.line(x='index', y=col_name_str, line_width=2, color=Spectral[11][index_int % 11], source=plot_src)) instantiate_plot[index_int].visible = False
  • 更新函数为:for index_gr, glyph_renderer in enumerate(instantiate_plot): glyph_renderer.visible = index_gr in feature_checkbox.active
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-29
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 1970-01-01
  • 2022-10-14
相关资源
最近更新 更多