I am new to Bokeh. Trying to implement few widget callbacks recently and hard to find any resources online.
Scenario: I have a multi_select bokeh widget with the list of the companies. Based on the companies selcted, data in the Vbar has to be changed. For this, i am trying to change the datasource that is used in the Vbar based on the values from Multi select. I am unable to get desired results. Can someone please help me out with this.
I am poor at CustomJs and hence doing this on Bokeh Server for callabcks. If there is a solution on CustomJs too, that would help me a lot.
Thank you very much for your time in Advance !
Below is the code I am using
source =source1[source1['year']== dt.now().year]
sourcex = source[source['month'] ==1 &
source['CompanyNo'].isin(['01','02','03','04','05','08']) ]
Overall= ColumnDataSource(source)
Curr= ColumnDataSource(sourcex)
boolinit = source['month']==1
view = CDSView(source=Overall, filters=[BooleanFilter(boolinit)])
hover3 = HoverTool(
tooltips = [
('day', '@day'),
('ExtendedPrice','@{ExtendedPrice}{0,0}'),
],
formatters = {
'day': 'datetime',
'ExtendedPrice': 'numeral'}
)
p = figure(
title='YEARLY SALES',
plot_width=600,
plot_height=400,
min_border=3,
tools = [hover3,'box_zoom','wheel_zoom', 'pan','reset'],
toolbar_location="above")
p.vbar(x='day', top='ExtendedPrice', width=0.2, color='#e8bc76',
source=Curr)
p.xaxis.axis_label = 'Day'
p.xaxis.axis_label_text_font_style = 'normal'
p.xaxis.axis_label_text_font_size = '12pt'
p.yaxis[0].formatter = NumeralTickFormatter(format="0,0")
def Multi_Selectupdate(attrname, old, new):
curr=sourcex[sourcex['CompanyNo'].isin(new)]
source.data=curr.data
companies=['All']+sourcex['CompanyNo'].unique().tolist()
multi_select = MultiSelect(title="Select:", value=['01'], options=companies,
height=200, width=100)
multi_select.on_change('value',Multi_Selectupdate )
layout = column(multi_select, p )
show(layout)
Since I don't have the data, I generated it using following script. I have assumed your data has 3 columns -
Date
,ExtendedPrice
,CompanyNo
. I have generated first a random data of 10K rows and then summarized it atCompanyNo
,day
,month
,year
level.Now, what you want to accomplish is that given a day and set of company names, you need to publish a bar chart of some type of aggregation of
ExtendedPrice
, i.e. say there are 2 rows for company '01' and '02' (which are selected), and for month 2 (that is also selected by a slider) for current year, the ExtendedPrice value for these two is say 100, and 200. In case we want to show a sum, you need to show 300 in barchart. This summary, you need to calculate dynamically.There are two ways to accomplish it.
1. Bokeh Callbacks
This will use native python functions, but you need to run it with
bokeh serve
, e.gbokeh serve --show <filename.py>
. See the code below, a native python functioncompsel
is filtering pandas dataframe and summarizing it and replacing the chart backend data with newly created data -There are other options to host this application. See other option by typing
bokeh serve --help
in terminal2. JavaScript Callbacks
This will generate a javascript function to interact with the chart, which will not require bokeh server and work directly on the browser. This will require very simple code in javascript. In the example solved here, I am summarizing
ExtendedPrice
as sum, but code will require small tweaks to calculate other stats e.g. mean. The js callback function here does the similar thing as bokeh callback function, it reads the larger datasets and filters it based on the select and slider values -