Leevi L
Leevi L

Reputation: 1789

How to use custom JS to change source of line plot?

My dataframe has several columns. I want to use a dropdown to trigger a change in the y-values.

So far I have

import pandas as pd

from bokeh.io import output_file, save
from bokeh.models import ColumnDataSource, Dropdown, CustomJS
from bokeh.layouts import column
from bokeh.plotting import figure


if __name__ == '__main__':
    df = pd.DataFrame(data={"a": [1, 2, 3], "b": [2, 2, 2], "c": [3, 2, 1]})
    source = ColumnDataSource(df)

    fig = figure()
    line = fig.line(x="a", y="b", source=source)

    dropdown = Dropdown(label="Choose y", menu=[("b", "b"), ("c", "c")])
    code = """
    // how to set the line source equal to "this.item"?
    """
    update_line_callback = CustomJS(args={"dropdown": dropdown, "line": line, "source": source}, code=code)
    dropdown.js_on_event("menu_item_click", update_line_callback)

    output_file("out.html")
    save(column(children=[fig, dropdown]))

How do I link the dropdown item with the line source?

Upvotes: 0

Views: 181

Answers (1)

mosc9575
mosc9575

Reputation: 6337

One working option is to create a column in your data source you want to show and change this values if the Dropdown is called by the selected name. The new name is this.item if you call dropdown.js_on_event("menu_item_click", *callback)

Here is the working code:

import pandas as pd

from bokeh.io import output_file, save
from bokeh.models import ColumnDataSource, Dropdown, CustomJS
from bokeh.layouts import column
from bokeh.plotting import figure, show, output_notebook
output_notebook()

# create some source
df = pd.DataFrame(data={"a": [1, 2, 3], "b": [2, 2, 2], "c": [3, 2, 1]})
df["show"] = df["b"]
source = ColumnDataSource(df)

# figure
fig = figure()
line = fig.line(x="a", y="show", source=source)
dropdown = Dropdown(label="Choose y", menu=[("b", "b"), ("c", "c")])

# overwrite show values with new selection
code = """
    let s = source.data
    s["show"] = s[this.item]
    source.change.emit();
"""
dropdown.js_on_event("menu_item_click", CustomJS(args={"source": source}, code=code))

# output figure
show(column(children=[fig, dropdown]))

Upvotes: 2

Related Questions