Python Bokeh JSCallback,根据Select过滤折线图

Python Bokeh JSCallback, filtering line graph based on Select

我在 Python Bokeh 中的 JSCallback 函数中编写代码时遇到了一些问题。

具体来说,我正在尝试创建一个折线图,它只显示下拉框中列出的数据。我必须使用 JSCallback 函数,因为服务器应用程序选项在工作中被禁用。

例如,如果我有不同系列(A、B、C、D)的数据集。我想这样做 selecting "A" 在 select 框中将只显示折线图中的那个系列,"B" 显示 B 等。它是相当于我在绘制数据之前过滤数据集(例如,在 Pandas 中使用 loc 函数)。我已尽力从文档中推断但无济于事。这是一个示例脚本。我知道 "var z == f" 不正确,但我不知道如何在 JS 回调代码中过滤数据表。提前谢谢你。

import pandas as pd
from bokeh.io import show
from bokeh.layouts import column, widgetbox
from bokeh.models import ColumnDataSource, CustomJS, Select
from bokeh.models.widgets import Dropdown
from bokeh.plotting import figure


df = pd.DataFrame(data = {"A": [1,2,3,4,5],
                          "B": [6,7,8,9,10],
                          "C": [11,12,13,14,15],
                          "D": [16,17,18,19,20],
                          "day":[100,101,102,103,104]})

df = df.melt(id_vars = ["day"], var_name = "var",  value_name = "val")
source = ColumnDataSource(dict (val = df["val"],
                                day = df["day"]))


dropdown = Select(title ="Variable", value = "A", options = ["A","B","C","D"])



p = figure(plot_height = 300, plot_width = 800)                 
p.line("day", "val", source= source)


callback = CustomJS(args = dict(source=  source), code = """

data = source.data;
var f = cb.obj_value
var z = data["variable"]
var z == f

source.change.emit()


""")


dropdown.js_on_change("value", callback)

combined= column(p, widgetbox(dropdown))

show(combined)

如果要转换或过滤某些内容,请不要更改数据源。为此,Bokeh 中有视图、过滤器和转换。

但是由于您使用的是线条字形,因此使用过滤器会发出警告,因为线条是连接的字形。您可以做的是避免融化数据框,只需切换列即可:

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

df = pd.DataFrame(data={"A": [1, 2, 3, 4, 5],
                        "B": [6, 7, 8, 9, 10],
                        "C": [11, 12, 13, 14, 15],
                        "D": [16, 17, 18, 19, 20],
                        "day": [100, 101, 102, 103, 104]})

source = ColumnDataSource({c: v.values for c, v in df.items()})

initial_value = "A"
dropdown = Select(title="Variable", value=initial_value, options=["A", "B", "C", "D"])

p = figure(plot_height=300, plot_width=800)
l = p.line("day", initial_value, source=source)

dropdown.js_on_change("value", CustomJS(args=dict(line=l),
                                        code="line.glyph.y = {field: cb_obj.value};"))

show(column(p, dropdown))