0

I have an application using Bokeh. During a callback I update the source in order to display another feature of my data on the figure. This works fine so far, but the actual update is done AFTER the callback is finished. (Which somehow makes sense).
My question is, can I manually update the figure during my callback, to have new the attributes like the new y-range that result from the updated data?
Below is a minimal working example that should explain what my need is.

import pandas as pd

from bokeh.plotting import figure, curdoc
from bokeh.models import ColumnDataSource, Button
from bokeh.layouts import layout

plot = figure(plot_width=1000, plot_height=250)

df = pd.DataFrame({"ID":[0, 1, 2, 3, 4, 5, 6, 7], 
                   "Value1":[0, 100, 200, 300, 400, 500, 600, 700], 
                   "Value2":[0, 1, 2, 4,8 , 16, 32, 64]})
source = ColumnDataSource(df)

plot_data = 'Value1'
source.data['plot_data'] = source.data[plot_data]

line1 = plot.line(x='ID', y='plot_data', source=source)

def function_to_do_stuff_based_on_y_axis_range():
    print(f"After changing source: Y-Axis start: {plot.y_range.start}")
    print(f"After changing source: Y-Axis end: {plot.y_range.end}")

def callback(event):
    global plot_data
    print("Entering Callback...")

    # Change plot_data
    if plot_data == "Value1":
        plot_data = "Value2"
    else:
        plot_data = "Value1"

    print(f"Before changing source: Y-Axis start: {plot.y_range.start}")
    print(f"Before changing source: Y-Axis end: {plot.y_range.end}")

    # actual change of data
    source.data['plot_data'] = source.data[plot_data]
   
    # Here something is needed like 
    # plot.draw_new_and_update_all_attributes() 
    # so that the following fuction has the 'new' attributes of plot.y_range...

    function_to_do_stuff_based_on_y_axis_range()

button_val = Button(label="Toggle Data")
button_val.on_click(callback)

layout_ = layout([[plot],[button_val],])
curdoc().add_root(layout_)

The problem is, that the plot.y_range only is updated after my callback as shown by the following output:

Output:

Entering Callback...
Before changing source: Y-Axis start: -35.00000000000006
Before changing source: Y-Axis end: 735
After changing source: Y-Axis start: -35.00000000000006
After changing source: Y-Axis end: 735
Entering Callback...
Before changing source: Y-Axis start: -3.200000000000003
Before changing source: Y-Axis end: 67.2
After changing source: Y-Axis start: -3.200000000000003
After changing source: Y-Axis end: 67.2

Any suggestions on this?

1 Answer 1

1

I am afraid the graph only got refreshed when the callback finished executing. If you want the graph to reflect the change in steps then you will need more than one callback functions.

Also, I think you have to do source.change.emit() to save the change of your data in the callback.

See https://docs.bokeh.org/en/latest/docs/user_guide/interaction/callbacks.html?highlight=callback

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.