How to perform an onclick action on button click in python bokeh?
I'm new to bokeh and I have aquery regarding button onclick event, the code is provided below:
x = widgetbox(button) show(x) fruits = ['Answered', 'Unanswered','Total'] top1=[1,2,3] def callback(): p = figure(x_range=fruits, plot_height=250, title="sophia bot") p.vbar(x=fruits, top=top1, width=0.9) p.xgrid.grid_line_color = None p.y_range.start = 0 output_file("abc.html") show(p) button_one = Button(label="Start", disabled=True, callback=callback) show(button_one)
but this isnt performing the action, the following code when used alone, does plot the graph, i want the graph to be shown alongisde when i clicke the button.
fruits = ['Answered', 'Unanswered','Total'] top1=[1,2,3] p = figure(x_range=fruits, plot_height=250, title="sophia bot") p.vbar(x=fruits, top=top1, width=0.9) p.xgrid.grid_line_color = None p.y_range.start = 0 output_file("abc.html") show(p)
You must assign the callback to the button like this:
from bokeh.models import Button from bokeh.io import curdoc bt = Button(label='Click me') def change_click(): print('I was clicked') bt.on_click(change_click) curdoc().add_root(bt)
Launch this with
bokeh serve --show example.py.
Note: Also take a look at my question where I talk about dynamic layout
See also questions close to this topic
Calculating matrix product with numpy
Is this: layer_1 = self.layer_0.dot(self.weights_0_1)
The same as this? layer_1 = np.dot(self.layer_0, self.weights_0_1)
Sense Hat's API show_message function cannot be stopped in a middle of message
I'm super new to Python language. I want to stop displaying the message on Sense Hat on Raspberry Pi "MSG before middle stick" when I release the stick, start to print the message "Hey" from the demo_display_string method.
import threading import time from sense_hat import SenseHat busy = True DISPLAY_STRING = "Hey" run = False def demo_display_string(arg_list): global DISPLAY_STRING global run run = True while run: sense.show_message(DISPLAY_STRING, text_colour=(255,0,0)) for event in sense.stick.get_events(): if event.action == 'released': print(event.action) if event.direction == 'middle': run = False def menu(): global CURRENT_POSITION_IN_MENU busy = False exists = False while True: if not busy: # msg = positions[CURRENT_POSITION_IN_MENU] msg = "MSG before middle stick" sense.show_message(msg, scroll_speed=0.05) for event in sense.stick.get_events(): sense.clear() if event.action == 'released': if event.direction == 'middle': busy = True demo_display_string(None) busy = False sense = SenseHat() menu()
It seems to work, but the problem is that sense.show_message is blocking and won't stop until the end of the message. So when I press the stick in a middle of "MSG before middle stick" it still displays the whole message and after that start displaying "Hey". I want it to happen in real time when I press stick, message changes.
Pandas difference between xlsx and XLSX
I am simply reading an excel file with name as abc.XLSX and then writing it is
writer = pandas.ExcelWriter('myFile.XLSX'). It is giving below error: ValueError: No engine for filetype: 'XLSX'
But if I do :
writer = pandas.ExcelWriter('myFile.xlsx')it is working fine.
Don't know what is the difference between
XLSX. Any Suggestions?
Mapbox: how to add Dot density and Hexbins to a map?
I'm working on an Angular 4 project for visualisation of a huge amount of data with mapbox, I need to provide different visualisations. I already made a heatmaps layer and I choose to continue with Dot density and Hexbins but I can't find any tutorials about it. Your help is highly appreciated.
How to get labels of clicked position in Bokeh heatmap
I have Bokeh heatmap. I register callback and able to get x and y coordinates of clicked position. Is there way to get x and y labels for the same positions? It seems that cb_data doesn't contain any useful information.
source = ColumnDataSource(data=dict(xname=xname, yname=yname, colors=color, alphas=alpha, means=means.flatten(), stds=stds.flatten(),)) callback = CustomJS(args=dict(source=source), code="""alert(JSON.stringify(cb_obj));""") p = figure(title="Plot", x_axis_location="above", tools="pan,hover,save,wheel_zoom,box_zoom,reset", x_range=labels, y_range=list(reversed(labels))) p.js_on_event('tap', callback)
How to use TDAmapper from Tableau (via R)?
I'm currently trying to use TDAmapper (which is a package from R) from Tableau because all my data is currently loaded onto Tableau server, and I would like to use the algorithm to identify useful groups within my dataset.
This, in principle, should be possible since: (i) one can pass calculations from Tableau to R via Rserve, which I understand the basics of; (ii) it is possible to do k-means clustering using the SCRIPT_INT command in Tableau.
Unfortunately, while I'm able to follow the basic applications of TDAmapper in R (see below for reference), I don't quite know how to employ TDAmapper from Tableau. Can somebody tell me how to do this? I tried the following code but it didn't work:
SCRIPT_INT( "library(TDAmapper) X<-scale(.arg1,.arg2,.arg3,center=FALSE) X.dist=dist(X) library(ks) filter.kde<-kde(X,H=diag(1,nrow=3),eval.points=X)$estimate X.mapper<-mapper(dist_object=X.dist,filter_values=filter.kde,num_intervals=4,percent_overlap=50,num_bins_when_clustering=18)$cluster", MAX([Arising Credit Item Cost]),[Sales Discount %],[Sales Margin %] )
For convenience, let me briefly discuss the general pieces of this puzzle:
1) How does one pass from Tableau to R?
One has to do this by one of four commands, the most relevant to us being SCRIPT_INT, which is a command we use if we expect a computation to yield us an integer result. The general form of the command is:
SCRIPT_INT ( “R code”, Tableau fields being passed in)
For example, if we want to find the correlation between the variables "Profit" and "Discount", then we use the SCRIPT_REAL function (which is when we expect the computation to yield us a real-value/non-integer value), which is written as:
SCRIPT_REAL( "cor(.arg1,.arg2)", sum([Discount]), sum([Profit])
where sum([Discount]) is .arg1, and sum([Profit]) is .arg2 respectively in the R script.
2) How does one do k-means clustering in Tableau by passing through R?
The code is as follows:
SCRIPT_INT(" ## Sets the seed set.seed( .arg8 ) ## Studentizes the variables age <- ( .arg1 - mean(.arg1) ) / sd(.arg1) edu <- ( .arg2 - mean(.arg2) ) / sd(.arg2) gen <- ( .arg3 - mean(.arg3) ) / sd(.arg3) car <- ( .arg4 - mean(.arg4) ) / sd(.arg4) chi <- ( .arg5 - mean(.arg5) ) / sd(.arg5) inc <- ( .arg6 - mean(.arg6) ) / sd(.arg6) dat <- cbind(age, edu, gen, car, chi, inc) num <- .arg7 ## Creates the clusters kmeans(dat, num)$cluster ", MAX( [Age] ), MAX( [Education ID] ), MAX( [Gender ID] ), MAX( [Number of Cars] ), MAX( [Number of Children] ), MAX( [Yearly Income] ), [Number of Clusters], [Seed] )
3) How does one use TDAmapper in R?
TDAmapper is an algorithm in R that gives us a specific way of identifying similar members of the dataset. The prototypical example of this would be applying TDAmapper to identifying similar types of diabetic patients based on the dataset (made available as "chemdiab")
The general idea is that we have a dataset of points, and we define a particular function (known as the "filter function") to assign a value to these points. Once we have done this, we cover these datapoints with a finite number of intervals - furthermore, for the algorithm we also need to specify: (i) the number of intervals we use; (ii) the percentage overlap between these intervals.
library(TDAmapper) library(locfit) data(chemdiab) normdiab<- chemdiab normdiab[,1:5]<-scale(normdiab[,1:5],center=FALSE) normdiab.dist=dist(normdiab[,1:5]) library(ks) filter.kde<-kde(normdiab[,1:5],H=diag(1,nrow = 5),eval.points =normdiab[,1:5])$estimate ## filter.kde is defined to be our filter function ## In this case, we assign values to the data points based on the kernel density. diab.mapper<-mapper( dist_object = normdiab.dist, filter_values = filter.kde, num_intervals =4, percent_overlap=50, num_bins_when_clustering=18) ## Here, the mapper() algorithm accepts as input the distance matrix of the data points we want, the filter function, the number of intervals, the percentage overlap. ## We also have another parameter (which affects the clustering algorithm that is implicitly used in the TDAmapper algorithm), which can be any integer value we like.
References: - http://bertrand.michel.perso.math.cnrs.fr/Enseignements/TDA/Mapper.html - http://breaking-bi.blogspot.co.uk/2013/12/performing-k-means-clustering-in-tableau.html -https://www.associationanalytics.com/2017/01/31/tableaus-r-integration/
Star plots for visualizing multivariate data
In the illustration below, star plots are used to display multivariate observations with an arbitrary number of variables (each observation is represented as a star-shaped figure with one ray for each variable).
Are there any libraries/packages (with implementation examples) in Python and/or R that enable the user to create such visualizations?
rbokeh, add legend to histogram plot
I'd like to make a chart with
rbokehthat includes three overlapping histograms. I can do this, but no legend appears:
library(rbokeh) figure(tools=c(), legend_location="top_right", padding_factor = 0.01) %>% ly_hist(rnorm(10000, mean=0), color=color_palette, alpha = 0.3, breaks=20, lname="L", legend="L", freq=F) %>% ly_hist(rnorm(10000, mean=1, sd=0.25), color=color_palette, alpha = 0.3, breaks=20, lname="M", legend="M", freq=F) %>% ly_hist(rnorm(10000, mean=2, sd=0.5), color=color_palette, alpha = 0.3, breaks=20, lname="H", legend="H", freq=F)
If I was using base R, I would need to call
legend()explicitly, as in Adding key legend to multi-histogram plot in R
I don't see an
Can anyone advise how to add a legend to the plot?
Thanks in advance.
python bokeh: Interaction lost when adding/changing children in a password secured dashboard.
I want to add a password functionality to a bokeh dashboard (a modified and extended code based on the example shown here. The logic behind is that I create a dashboard with a "passblock" item where a password can be entered and a second block which is empty. If the password is correct the "passblock" item is removed and the empty placeholder bloxk is filled with the interactive dashboard block. In this example the interactive dashboard is the slider and if you change it the value is printed via the callback function. While the callback works fine if I directly include a range slider in the dashboard section (see commented section) it is not working any more if the password and user have been entered correctly. Even if I add the range_slider before and only replace it with the new one within the verify_pwd section it is not working. Any ideas appreciated.
from bokeh.models.widgets import PasswordInput,Button, TextInput,PreText,RangeSlider from bokeh.layouts import column, row PASSWD = "1" #password USER = "1" #username max_count_tries = 5 #max allowed tries before dashboard is killed count_tries = 0 # counter for max tries def verify_pwd(): """ verifies if user and pwd are entered correctly. If so the password block is set to zero and the dashboard block which was zero before is replaced by the slider""" global count_tries global range_slider if (pwd.value==PASSWD) & (user.value == USER): #pwe and user entered correctly print('logged in') range_slider = RangeSlider(start=0., end=10., value=(2.,3.), step=.1, title="secret slider") layout.children = row() layout.children = row([range_slider]) else: #pwd or user are wrong if (pwd.value!=PASSWD) & (user.value == USER): mytext.text = ''.join(['wrong password!\n',str(max_count_tries-count_tries), ' tries left']) elif (pwd.value==PASSWD) & (user.value != USER): mytext.text = ''.join(['wrong user!\n',str(max_count_tries-count_tries), ' tries left']) else: mytext.text = ''.join(['wrong user and wrong password!\n',str(max_count_tries-count_tries), ' tries left']) count_tries += 1 if count_tries>max_count_tries: layout.children = row() def callback(attrname, old, new): # Get the current slider values and print the value in the console global range_slider lower = range_slider.value upper = range_slider.value print(lower,upper) mytext = PreText() #placeholder for error message user = TextInput(title="UserName:") # unser name entry field pwd = PasswordInput(title="Password:") #password entry field btn = Button(label="login") # button to log in btn.on_click(verify_pwd) # if button was clicked compare pwd and user with entries #pwd.callback(verify_pwd) passblock = row([user, pwd, btn, mytext]) # create a block to the dashboard where the pwd and user can be entered range_slider = RangeSlider(start=0., end=10., value=(0.,0.), step=.1, title="dummy") # create a dummy slider which is not used range_slider.on_change('value', callback) # callback for slider if values change layout = column(passblock,row()) # create a layout with the password block and an empty block which is filled as soon as the pwd and user are ok #layout = column(passblock,range_slider) # create bokeh document and deploy it from bokeh.io import curdoc curdoc().add_root(layout)