source.data在散景服务中更新,但情节不会改变

时间:2017-08-30 14:18:20

标签: python bokeh

我正在尝试用CheckButtonGroup创建一个散景服务图。我设法更新我的source.data,但情节没有更新。我做错了什么?

实际上,我从我的计算机导入数据集,但是现在我将创建一个示例pandas数据帧。我想选择'x'列(作为x轴变量)和一个或多个其他列(作为y轴变量)。

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

dataset = pd.DataFrame(columns=['x','y1','y2','y3'])
dataset['x'] = [1, 2, 3, 4]
dataset['y1'] = [10, 20, 30, 40]
dataset['y2'] = [11, 21, 31, 41]
dataset['y3'] = [12, 22, 32, 43]

pos_cols = ['y1', 'y2', 'y3'] # possible column names
col_list = ['y1', 'y2'] # default columns in plotted data
use_data = dataset[col_list]
use_data['x'] = dataset.loc[:, 'x']

source = ColumnDataSource(use_data)

p = figure(
   tools="pan,box_zoom,wheel_zoom,reset,save",
   x_axis_label='xtitle', y_axis_label='ytitle',
   title="Simulations"
)

# make default plot with the two columns
for column in col_list:
    p.line('x', column, source=source)

check = CheckboxButtonGroup(labels=["y1", "y2", "y3"], active=[0, 1]) # A check box for every column

def update_lines(new):

    col_list = [pos_cols[i] for i in new]
    use_data = dataset[col_list]
    use_data['x'] = dataset.loc[:, 'x']
    source.data = source.from_df(use_data)

    print(source.data) # source.data is correctly updated, but does not seem to trigger a new plot

check.on_click(update_lines)

doc = curdoc()
doc.add_root(row(check, p, width=800))
doc.title = "Simulations"

我将代码保存为try.py并使用bokeh服务器try.py从Windows提示符运行它。情节在http://localhost:5006

处可见

1 个答案:

答案 0 :(得分:1)

问题在于,您正在为'y3'之前的列创建字形,但实际上并未发送任何列'y3'来启动。 Bokeh不喜欢这样(你可以看到有关尝试访问浏览器JS控制台中不存在的列的错误消息)

一种更好的方法,也就是不会不必要地重新发送所有数据,可能只是切换字形渲染器的.visible属性。这是一个最小的例子(从可见的所有行开始,但你可以改变它):

import pandas as pd
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.layouts import row
from bokeh.models import CheckboxButtonGroup, ColumnDataSource

dataset = pd.DataFrame(columns=['x','y1','y2','y3'])
dataset['x'] = [1, 2, 3, 4]
dataset['y1'] = [10, 20, 30, 40]
dataset['y2'] = [11, 21, 31, 41]
dataset['y3'] = [12, 22, 32, 43]

source = ColumnDataSource(data=dataset)

p = figure( )

lines = []
for column in ['y1', 'y2', 'y3']:
    lines.append(p.line('x', column, source=source))

check = CheckboxButtonGroup(labels=["y1", "y2", "y3"], active=[0, 1, 2])

def update_lines(new):
    for i in [0, 1, 2]:
        if i in new:
            lines[i].visible = True
        else:
            lines[i].visible = False

check.on_click(update_lines)

doc = curdoc()
doc.add_root(row(check, p, width=800))

或者,如果您只是希望能够隐藏或静音线条,那么更容易使用Bokeh内置的交互式传奇:

http://bokeh.pydata.org/en/latest/docs/user_guide/interaction/legends.html#userguide-interaction-legends