5

I have 2 pandas dataframes, with identical column names. I try to update my plot based on the bokeh Select widget.

app.py

from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, output_file, show, output_notebook
from bokeh.models.widgets import Select
from bokeh.io import curdoc
from bokeh.layouts import column, row

import pandas as pd

d1 = {'time': [1,2,3,4], 'y': [2,4,6,8]}
d2 = {'time': [1,2,3,4,5], 'y': [2,1,1,8,22]}
df1 = pd.DataFrame(data=d1, )
df2 = pd.DataFrame(data=d2, )

source = ColumnDataSource(df1 )

p = figure()
r = p.vbar(x='time', top='y', width=1,
         source = source)

select = Select(title="monthly csv-s",  options=['d1', 'd2'])

def update_plot(attrname, old, new):
    if select.value == 'd1':
        newSource = df1
    if select.value == 'd2':
        newSource = df2
    source.data =  newSource 


select.on_change('value', update_plot)
layout = column(row(select, width=400), p)
curdoc().add_root(layout)

I try to run this using bokeh serve --show app.py I got the following error when I use the Select widget:

error handling message Message 'PATCH-DOC' (revision 1): ValueError('expected an element of ColumnData(String, Seq(Any)), got time y\n0 1 2\n1 2 1\n2 3 1\n3 4 8',)

Can you help me with that?

2 Answers 2

4

Following this example, you need to set source.data to be a dict, not a DataFrame. So your new code for update_plot() would be:

def update_plot(attrname, old, new):
    if select.value == 'd1':
        newSource = d1  # changed this to the dict
    if select.value == 'd2':
        newSource = d2  # changed this to the dict
    source.data =  newSource 
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, my data is from a csv d1, d2 are present only in my dummy example, but df.to_dict('list') was able to solve my problem.
i get the error Error running application handler <bokeh.application.handlers.script.ScriptHandler object at 0x7fc47ea98b70>: Cannot run the event loop while another loop is running File "base_events.py", line 417, in run_forever .. 200 GET /test_bokeh_app (127.0.0.1) 130.17ms , but the app appears to work.
0

if you are working with joined data frames and manipulate on the outcome, it would be easier to not refer to an raw source element (like the dict):

def update_plot(attrname, old, new):
   if select.value == 'd1':
       newSource =  ColumnDataSource(df1) 
   if select.value == 'd2':
       newSource =  ColumnDataSource(df2) 
   source.data = newSource.data

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.