I need help with setting up bokeh server to update my plots with sliders interaction. I understand from python - Bokeh Sliders associated with a plot (without bokeh server) - Stack Overflow this post that when we use Attribute.on_change(‘value’,function) which is a realPython code, it does work with html to have interactive data visualization.
I need to make the plot interactive and want it to update by moving of sliders. “Hoping that I have defined the updating function callback correctly, it should work if the bokeh server is setup the right way.
Please find Function call back under sliders where I have attempted to use slider values to update my data frame using rangeslider values” All i want to do here is use the slider values and filter the data frames and use these data frames to update the colum data source and thus update the plots
There is an option of custom JavaScript but I don’t know how to write a custom JavaScript, nor do I know how to set up a bokeh server. As I have really large scale data, I feel it is better to use bokeh server (webgl) and I gave it my attempt and it is too advanced for me to understand how to implement it. I need help with slider update, drop down menu and color update. Here is my code using Bokeh server.
I have written the code on latest Python 3.7 and latest Bokeh 1.2.0 and latest Pandas on Spyder IDE. I tried doing custom JS since I don’t really know programming on JavaScript, I would rather avoid it completely.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
######
import tkinter as tk
from tkinter import filedialog
import pandas as pd
from pandas import DataFrame
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from bokeh.models import HoverTool
from bokeh.themes import built_in_themes
##
# Bokeh libraries
from bokeh.io import curdoc
from bokeh.layouts import row, column
from bokeh.models import CustomJS, Slider
from bokeh.plotting import figure, output_file, show, ColumnDataSource
from bokeh.plotting import figure, show
from bokeh.layouts import row, column, gridplot
from bokeh.models.widgets import Tabs, Panel
from bokeh.core.properties import Float, Instance, Tuple, Bool, Enum
from bokeh.models import InputWidget
from bokeh.models.callbacks import Callback
from bokeh.core.enums import SliderCallbackPolicy
from bokeh.layouts import column
from bokeh.models import Slider, CustomJS, ColumnDataSource , Select
from bokeh.io import show
from bokeh.plotting import Figure
from bokeh.io import output_file, show
from bokeh.models.widgets import RangeSlider
from tornado.ioloop import IOLoop
from bokeh.application.handlers import FunctionHandler
from bokeh.application import Application
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
from bokeh.server.server import Server
doc = curdoc()
curdoc().theme = 'caliber'
#Import excel file
Data = pd.read_excel (r'C:\Users\vsrigiri\Desktop\app\try.xlsx')
## Define data frames
# use the below code for extracting imp parameters from large excel file
df = pd.DataFrame (Data, columns= ['No.','a','z_1', 'z_2','u'])
#df = pd.DataFrame(Data) to import all data
########later you may give legends to the required lables for now iterate over the df Dataframe
legends= {'parameter_names': ['XX','YY (in mm)', 'ZZ','MM', 'NN']}
symbols = {'symbols' : ['No.','a','z_1', 'z_2','u']}
df_leg = pd.DataFrame(legends, columns= ['parameter_names'])
df_sym = pd.DataFrame(symbols,columns=['symbols'])
#convert Dataframe to columnDatasource
source = ColumnDataSource(df)
#Slider Definition
a_Slider= RangeSlider(start=min(df['a']), end=max(df['a']), value=(min(df['a']),max(df['a'])), step=1, title='YY in mm')
z_1_Slider = RangeSlider(start=min(df['z_1']), end=max(df['z_1']), value=(min(df['z_1']),max(df['z_1'])), step=1, title='ZZ')
z_2_Slider = RangeSlider(start=min(df['z_2']), end=max(df['z_2']), value=(min(df['z_2']),max(df['z_2'])), step=1, title='MM')
u_Slider = RangeSlider(start=min(df['u']), end=max(df['u']), value=(min(df['u']),max(df['u'])), step=.01, title='NN')
#function to call back
#to update graphs as slider updates
def callback(attr, old, new):
# Value for the range slider is a tuple (start, end)
# Read the current value of the slider: scale """
a_s = a_Slider.value[0]
a_e = a_Slider.value[1]
z_1_s= z_1_Slider.value[0]
z_1_e= z_1_Slider.value[1]
z_2_s= z_2_Slider.value[0]
z_2_e= z_2_Slider.value[1]
u_s= u_Slider.value[0]
u_e= u_Slider.value[1]
#problematic part has been updating the data frame first sort this and next move on to linking this to the plot and updating the plot
##Create New Datasource from which dolumn datasource can be developed
#update the slider range
#finding the indicies which do not fall under selected range in slider
dff= pd.DataFrame(df[(df.a >= a_s) & (df.a <= a_e) & (df.z_1 >= z_1_s) & (df.z_1 <= z_1_e) & (df.z_2 >= z_2_s) & (df.z_2 <= z_2_e)& (df.u >= u_s)& (df.u <= u_e)])
source.data = ColumnDataSource.from_df(dff)
#function ends here
# Updating graphs from slider values
#updating all the slider values
#a_slider is an object and i have created it before and i have to update this object
a_Slider.on_change("value",callback)
z_1_Slider.on_change("value",callback)
z_2_Slider.on_change("value",callback)
u_Slider.on_change("value",callback)
#lEARN TO ITERATE OVER THE DATA FRAMES AND ASSIGN VALUES FOR TOOLTIPS ATTRIBUTES
tooltips = [("Index", "$index"),
("XX", "@No."),
('YY in mm' ,'@a'),
('ZZ','@z_1'),
('MM','@z_2'),
('NN','@u')]
hover = HoverTool(tooltips=tooltips)
#Plotting
#Learn to make drop down with a loop for graphs
#Define the tools Needed
toollist = ['lasso_select', 'tap', 'reset', 'save','crosshair','wheel_zoom','pan','tap','hover','box_select']
plot = figure(title="FOS ag Pvs FOS ag RBG", plot_height=400, plot_width=400,
tools=toollist,x_range=[min(df['a']),max(df['a'])], y_range=[min(df['z_1']),max(df['z_1'])])
sctr = figure(title="FOS ag P vs FOS ag RBP", plot_height=400, plot_width=400,
tools=toollist,x_range=[min(df['a']),max(df['a'])], y_range=[min(df['z_2']),max(df['z_2'])])
comp = figure(title="Load Distribution comparision", plot_height=400, plot_width=400,
tools=toollist,x_range=[min(df['a']),max(df['a'])], y_range=[min(df['u']),max(df['u'])])
plot.scatter(x='a', y='z_1',source=source.data)
sctr.scatter(x='a', y='z_2',source=source.data)
comp.scatter(x='a', y='u',source=source.data)
##LEARN TO GIVE THE LABLES iterating over DATAFRAMES dfleg and dfsym
plot.xaxis.axis_label = 'FOS ag PG'
plot.yaxis.axis_label = 'FOS ag RBG'
sctr.xaxis.axis_label = 'FOS ag PP'
sctr.yaxis.axis_label = 'FOS ag RBP'
comp.xaxis.axis_label = 'FOS ag RpP'
comp.yaxis.axis_label = 'FOS ag RBg'
# Add the HoverTool to the figure
plot.add_tools(HoverTool(tooltips=tooltips))
sctr.add_tools(HoverTool(tooltips=tooltips))
comp.add_tools(HoverTool(tooltips=tooltips))
#
Graphs = row([plot,sctr,comp])
Controls1= column([a_Slider,z_1_Slider])
Controls2= column([z_2_Slider,u_Slider])
#layout= row(Controls1, Controls2,Graphs)
grid = gridplot([[Graphs],
[Controls1,Controls2]])
#This is important! Save curdoc() to make sure all threads
curdoc().add_root(grid)
show(grid)
curdoc().title = "codeinprocess"
Basically I have about 60 such parameters and about 150 thousand combinations of them. I am trying to fix up some 15 to 20 sliders and trying to play with them to see which of these combinations fall into my criteria based on some engineering filters.
Initially, I am trying to filter data based on some engineering conventions and later I am trying to visualize the filtered data and select the best possible combinations which will give me an idea of what range each of 15 parameters should fall in for optimum design
I am expecting the sliders to work with bokeh server first So a step by step guide would help.
on a second priority if you could guide me with template to create and update plots with drop down select options and color coding based on the same filtering criteria to understand which side of the graph has favorable points.