Dynamically change y data on button click

Hi,

I am trying to do a simple plot where the plot source changes on a button click. I have the code below but it seems to overlap the figure.

Anyone have a elegant code to show me how to do it?

from bokeh.io import curdoc

from bokeh.layouts import layout

from bokeh.models import ColumnDataSource

from bokeh.plotting import figure

from bokeh.models.widgets import RadioButtonGroup

source = ColumnDataSource(dict(x = [1, 2, 3], Test1 = [4, 5, 6], Test2 = [7, 8, 9]))

plot = figure()

plot.line(x = ‘x’, y = ‘Test1’, source = source)

dropdown = RadioButtonGroup(labels=[‘Test1’, ‘Test2’], active=0)

def update_plot(attr, old, new):

plot.line(x = ‘x’, y = dropdown.active, source = source)

dropdown.on_change(‘active’, update_plot)

lay_out = layout([plot, dropdown])

curdoc().add_root(lay_out)

``

I assume you are running your application via “bokeh serve app.py” . Anyway, your code would only add an additional line to the plot each time the button is clicked.
You need rather to manipulate the data source object.
I think handling python callbacks is only possible in server applications so the server can respond to user events (on_change in this case)

If you are not using a bokeh server you would need to use javascript callbacks or Python callback converted to javascript like “callback = CustomJS.from_py_func(python_callback)”

Here is a javascript callback example tested on 0.12.6:

from bokeh.io import curdoc

from bokeh.layouts import Row

from bokeh.models import ColumnDataSource, CustomJS

from bokeh.plotting import figure

from bokeh.models.widgets import RadioButtonGroup

from bokeh.io import show

source = ColumnDataSource(dict(x = [1, 2, 3], y = [4, 5, 6], Test1 = [4, 5, 6], Test2 = [6, 5, 4]))

plot = figure()

plot.line(x = ‘x’, y = ‘y’, source = source)

code = “”" var new_data = {‘x’: [], ‘y’: [], ‘Test1’: [], ‘Test2’: []};

  •        var old_data = source.data;*
    
  •        new_data['x'] = source.data['x'];*
    
  •        new_data['Test1'] = source.data['Test1'];*
    
  •        new_data['Test2'] = source.data['Test2'];*
    
  •        new_data['y'] = old_data[cb_obj.labels[cb_obj.active]];*
    
  •        source.data = new_data; """*
    

callback = CustomJS(args = {‘source’: source}, code = code)

dropdown = RadioButtonGroup(labels = [‘Test1’, ‘Test2’], active = 0, callback = callback)

layout = Row(plot, dropdown)

curdoc().add_root(layout)

show(layout)

···

On Thursday, November 1, 2018 at 4:48:24 PM UTC+1, Zana wrote:

Hi,

I am trying to do a simple plot where the plot source changes on a button click. I have the code below but it seems to overlap the figure.

Anyone have a elegant code to show me how to do it?

from bokeh.io import curdoc

from bokeh.layouts import layout

from bokeh.models import ColumnDataSource

from bokeh.plotting import figure

from bokeh.models.widgets import RadioButtonGroup

source = ColumnDataSource(dict(x = [1, 2, 3], Test1 = [4, 5, 6], Test2 = [7, 8, 9]))

plot = figure()

plot.line(x = ‘x’, y = ‘Test1’, source = source)

dropdown = RadioButtonGroup(labels=[‘Test1’, ‘Test2’], active=0)

def update_plot(attr, old, new):

plot.line(x = ‘x’, y = dropdown.active, source = source)

dropdown.on_change(‘active’, update_plot)

lay_out = layout([plot, dropdown])

curdoc().add_root(lay_out)

``