@Bryan I have attached html files created by both versions of bokeh 2.2.3
and 2.3.0
named plot_bokeh_v2.2.3.html
and plot_bokeh_v2.3.0.html
respectively and a test.json
data file.
Google Drive link for files
Following is a simplified code of what I am using in my application:
import json
from bokeh.layouts import column, row, gridplot
from bokeh.models import DataRange1d, DatetimeAxis, LinearAxis, Legend, HoverTool, Slider, Span, CustomJS, TableColumn, \
DataTable, Title, ColumnDataSource, FreehandDrawTool, BoxEditTool,CheckboxGroup, Label, BasicTickFormatter, Div, DatetimeTickFormatter
from bokeh.models.glyphs import Line
from bokeh.palettes import Category20,viridis
from bokeh.plotting import figure, output_file, show, output_notebook
# output_notebook()
output_file('plot_bokeh_v2.2.3.html',mode='inline')
data = json.load(open('test.json'))
legend_text=['test1','test2']
color_mapper = dict(zip(legend_text,Category20[5]))
fig_dict={}
plot_lines={
'baseline':[],
'current':[]
}
fig_dict['baseline']=figure(plot_width=600,plot_height=450,title='Baseline',x_axis_type='datetime',y_range=DataRange1d(start=0,end=1000,bounds='auto'),y_axis_label='Response Time',output_backend='svg')
fig_dict['current']=figure(plot_width=600,plot_height=450,title='Current',x_axis_type='datetime',y_range=fig_dict.get('baseline').y_range,y_axis_label='Response Time',output_backend='svg')
# creating two line in each figure
# figure: baseline , Line : test1
timestamps = data.get('baseline').get('test1').get('timestamp')
response = data.get('baseline').get('test1').get('responsetime')
color=color_mapper.get('test1')
plot_lines.get('baseline').append( fig_dict.get('baseline').line(x=timestamps,y=response, name='test1', line_width=2, color=color) )
# figure: baseline , Line : test2
timestamps = data.get('baseline').get('test2').get('timestamp')
response = data.get('baseline').get('test2').get('responsetime')
color=color_mapper.get('test2')
plot_lines.get('baseline').append( fig_dict.get('baseline').line(x=timestamps,y=response, name='test2', line_width=2, color=color) )
# figure: current , Line : test1
timestamps = data.get('current').get('test1').get('timestamp')
response = data.get('current').get('test1').get('responsetime')
color=color_mapper.get('test1')
plot_lines.get('current').append( fig_dict.get('current').line(x=timestamps,y=response, name='test1', line_width=2, color=color) )
# figure: current , Line : test2
timestamps = data.get('current').get('test2').get('timestamp')
response = data.get('current').get('test2').get('responsetime')
color=color_mapper.get('test2')
plot_lines.get('current').append( fig_dict.get('current').line(x=timestamps,y=response, name='test2', line_width=2, color=color) )
# created checkbox group to act as legends for the two plots
checkbox_group = CheckboxGroup(labels=['All']+legend_text, active=[0], height=450,width =300)
callback_r = CustomJS(args=dict(plot_lines=plot_lines,checkbox_group=checkbox_group,fig_dict=fig_dict),code="""
for (const [key, value] of Object.entries(plot_lines)) {
value.forEach(line =>{line.visible = false;})
}
if (checkbox_group.active.includes(0)) {
for (const [key, value] of Object.entries(plot_lines)) {
value.forEach(line =>{line.visible = true;})
}
} else{
for (var i = 0; i < checkbox_group.active.length ; i++) {
var label_index = checkbox_group.active[i];
var label_name = checkbox_group.labels[label_index];
for (const [key, value] of Object.entries(plot_lines)) {
value.forEach(line =>{
if(line.name.localeCompare(label_name) === 0 ){ line.visible = true;} })
}
}
}
var y_value=[];
for (const [key, value] of Object.entries(plot_lines)) {
value.forEach(line =>{
//console.log(line.visible,line.data_source.data.y);
if (line.visible == true){
y_value.push.apply(y_value, line.data_source.data.y);
}
})
}
y_value.sort((a, b) => a - b);
for(const [key,value] of Object.entries(fig_dict)){
value.y_range.setv({"start":y_value[0]*0.95,"end":y_value[y_value.length-1]*1.05});
}
""")
checkbox_group.js_on_change("active", callback_r)
plot = gridplot([[*fig_dict.values(),checkbox_group]],merge_tools=True)
show(plot)
Please look at html file created from 2.2.3
version and select one checkbox at a time you will get the fell of what i am trying to achieve and that it was working it bokeh version 2.2.3
but somehow its breaking down in the latest version of bokeh 2.3.0
.
Let me know if there is a better way to accomplish this task