bokeh application sharing which has tkinter fileopen command is not being shared over network

Hello,

I am using bokeh to dynamically plot by having some control widgets. I am using tkinter package to browse for file on my system and then bokeh code uses that file to do plotting. The code works fine on my system but when I am sharing the app over the network, the tkinter package file open window is open on my local system instead of the sytem on which another person’s system accessing this app.

I am very new to bokeh and python.

App code:

import pandas as pd
import numpy as np
from bokeh.io import output_file, show, curdoc,set_curdoc
from bokeh.layouts import widgetbox,layout,row,gridplot
from bokeh.models import MultiSelect,Select,ColumnDataSource,Slider,TextInput
from bokeh.models import Button as bb
from bokeh.plotting import figure
import sklearn.metrics as fs
from tkinter import *
from tkinter.filedialog import askopenfilename

In[35]:

#code to insert logo in the plot
logo = figure(x_range=(0,3), y_range=(0,1),tools="",toolbar_location=None,
x_axis_location=None, y_axis_location=None,height=100)
logo.xgrid.grid_line_color = None
logo.ygrid.grid_line_color = None
logo.outline_line_color = None
logo.image_url(url=[“C:\Users\dgurram\Desktop\ASF\Work on\referrence\Amsted Rail Logo.png”]
,x=0,y=1,w=3,h=0.8)

#Initialization
data = pd.DataFrame()
featurevalues = list()
fs_methods = dict({‘Mutual Information’:‘mutual_info_score’,
‘Adjusted Mutual Information’:‘adjusted_mutual_info_score’,
‘Normalized Mutual Information’:‘normalized_mutual_info_score’})
fsl = list(fs_methods.keys())[0]
numerics = [‘int16’, ‘int32’, ‘int64’, ‘float16’, ‘float32’, ‘float64’]
discrete_options = [‘Default’,‘Equal width binning’,‘Equal percentile binning’]

In[40]:

#Get dataset from user system
def updatedata():
global featurevalues
global data
#clear the existing values if any while changing datasets
target.options = list()
features.options = list()
source.data.update(emptysrc.data)
#File selection window
root = Tk()
root.update()
root.filename = askopenfilename(initialdir = “/”,title = “Select file”,filetypes = ((“excel files”,[".xlsx",".xls"]),(“all files”,".")))
root.destroy()
selectdata.label = str(‘Loading…’) #To indicate while loading large files
name = root.filename
#Set the selected file as a pandas dataframe
#Update the feature and target options based on the chosen data
data = pd.read_excel(name)
selectdata.label = str(name) #To indicate which file has beeen selected
featurevalues = list(data)
target.options = featurevalues
features.options = featurevalues

def get_data(t,f,fsl,dm,e,p):
#Discritize continuous data based on selection
all_data = data[f]
if list(all_data.select_dtypes(include=numerics)):
num_vars = list(all_data.select_dtypes(include=numerics))
if dm != discrete_options[0]: #Discretization is done only upon selection
if dm == discrete_options[1]:
num_bins = e
for i in range(0,len(num_vars)):
bins = np.arange(min(data[num_vars[i]]),
max(data[num_vars[i]]),
(max(data[num_vars[i]])-min(data[num_vars[i]]))/num_bins)
#Replacing the selected continuous columns in dataset with discretized data.
data[num_vars[i]] = np.digitize(data[num_vars[i]],bins)
elif dm == discrete_options[2]:
pct = p
for i in range(0,len(num_vars)):
bins = np.arange(min(data[num_vars[i]]),
max(data[num_vars[i]]),
np.percentile(data[num_vars[i]],pct))
#Replacing the selected continuous columns in dataset with discretized data.
data[num_vars[i]] = np.digitize(data[num_vars[i]],bins)
#Feature selection score calculation
res = lambda x:getattr(fs,fs_methods[fsl])(data,data[t])
score = list()
for i in range(0,len(f)):score.append(res(f[i]))
plot_data = pd.DataFrame({‘feature’ : list(f), ‘mutual_info’ : score}).sort_values(by=‘mutual_info’,ascending=False)
return ColumnDataSource(data = plot_data)

#Initilizing the plot
def make_plot(source):
plot = figure(x_range = source.data[‘feature’],title = “Feature Selection”,width = 800)
plot.vbar(x=‘feature’, width=0.5, bottom=0,top=‘mutual_info’,source=source,
color=“firebrick”)
return plot

#function to update plot on callback
def update_plot(attr, old, new):
tn = target.value
fn = features.value
fsn = feature_sel.value
dmn = discrete_method.value
en = Ebinning.value
pn = Pbinning.value
if (tn and fn) :
src = get_data(tn,fn,fsn,dmn,en,pn)
source.data.update(src.data)
plot.x_range.factors = source.data[‘feature’]
layout.children = [widgets,plot]
if discrete_method.value == discrete_options[1] :
layout.children.append(Ebinning)
elif discrete_method.value == discrete_options[2]:
layout.children.append(Pbinning)

In[37]:

#data = pd.read_excel(‘C:\Users\dgurram\Desktop\ASF\Work on\New Sand Trial.xlsx’)
#text = TextInput(value=“Default”)

#Initial widgets and plots declaration
selectdata = bb(label = “Select Data”, button_type=“success”)
target = Select(title=“Select Target”)
t = target.value
features = MultiSelect(title=“Select Features”)
f = features.value
discrete_method = Select(title=“Select Discretization Method”,
value = discrete_options[0],
options = discrete_options)
dm = discrete_method.value
Ebinning = Slider(title=“Select num of bins”, value=5, start=1, end=20, step=1)
Pbinning = Slider(title=“Select Percentile”, value=5, start=1, end=100, step=5)
feature_sel = Select(title=“Select Feature Selection Method”,value = fsl, options = list(fs_methods.keys()))
emptysrc = ColumnDataSource(pd.DataFrame({‘feature’ : [’’], ‘mutual_info’ : [’’]}))
source = ColumnDataSource(pd.DataFrame({‘feature’ : [’’], ‘mutual_info’ : [’’]}))
plot = make_plot(source)

In[38]:

#callback
selectdata.on_click(updatedata)
controls = [target, features,feature_sel,discrete_method,Ebinning,Pbinning]
for control in controls:
control.on_change(‘value’,update_plot)

In[39]:

#printing on web page
widgets = widgetbox(selectdata,features,target,feature_sel,discrete_method)
layout = row(widgets,plot)
curdoc().add_root(layout)
curdoc().title = “FSapp”

···

run code on network code:

from socket import gethostbyname, gethostname
from os import system

ip = gethostbyname(gethostname())
port = 5000

print("\nTo access the tool, go to: “+ip+”:"+str(port)+"\n")

command = “”.join(("bokeh serve --show Code1.py --port “, str(port), " --allow-websocket-origin=”, ip, ‘:’, str(port), " --host ", ip, ‘:’, str(port)))
system(command)

Hi,

This is approach is not going to work, unfortunately. Tkinter is a separate library for creating rich client GUI applications that run locally on a machine. It does not have any capability to display GUIs over the network in a browser, for example. Python apps that use TKinter for GUI presentation will only ever show the GUI on the machine that the app is run on (modulo any display forwarding or VNC, etc). This is just the way Tkinter works, and what it does.

So, the next option would be to create a GUI in the browser with Bokeh widgets. Bokeh specifically is for showing plots and widgets across a network in a browser. Unfortunately, the built in set of widgets does not yet include a file chooser widget. It would be possible to extend Bokeh by wrapping an existing JavaScript file dialog:

  http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html

This is not a completely trivial task, but we are happy to answer any questions if you did want to try and go this route.

Thanks,

Bryan

···

On Apr 21, 2017, at 12:08, Divya Mounika Gurram <[email protected]> wrote:

Hello,

I am using bokeh to dynamically plot by having some control widgets. I am using tkinter package to browse for file on my system and then bokeh code uses that file to do plotting. The code works fine on my system but when I am sharing the app over the network, the tkinter package file open window is open on my local system instead of the sytem on which another person's system accessing this app.

I am very new to bokeh and python.

App code:

import pandas as pd
import numpy as np
from bokeh.io import output_file, show, curdoc,set_curdoc
from bokeh.layouts import widgetbox,layout,row,gridplot
from bokeh.models import MultiSelect,Select,ColumnDataSource,Slider,TextInput
from bokeh.models import Button as bb
from bokeh.plotting import figure
import sklearn.metrics as fs
from tkinter import *
from tkinter.filedialog import askopenfilename

# In[35]:
#code to insert logo in the plot
logo = figure(x_range=(0,3), y_range=(0,1),tools="",toolbar_location=None,
              x_axis_location=None, y_axis_location=None,height=100)
logo.xgrid.grid_line_color = None
logo.ygrid.grid_line_color = None
logo.outline_line_color = None
logo.image_url(url=["C:\\Users\\dgurram\\Desktop\\ASF\\Work on\\referrence\\Amsted Rail Logo.png"]
               ,x=0,y=1,w=3,h=0.8)
#Initialization
data = pd.DataFrame()
featurevalues = list()
fs_methods = dict({'Mutual Information':'mutual_info_score',
                   'Adjusted Mutual Information':'adjusted_mutual_info_score',
                  'Normalized Mutual Information':'normalized_mutual_info_score'})
fsl = list(fs_methods.keys())[0]
numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
discrete_options = ['Default','Equal width binning','Equal percentile binning']

# In[40]:
#Get dataset from user system
def updatedata():
    global featurevalues
    global data
    #clear the existing values if any while changing datasets
    target.options = list()
    features.options = list()
    source.data.update(emptysrc.data)
    #File selection window
    root = Tk()
    root.update()
    root.filename = askopenfilename(initialdir = "/",title = "Select file",filetypes = (("excel files",["*.xlsx","*.xls"]),("all files","*.*")))
    root.destroy()
    selectdata.label = str('Loading...') #To indicate while loading large files
    name = root.filename
    #Set the selected file as a pandas dataframe
    #Update the feature and target options based on the chosen data
    data = pd.read_excel(name)
    selectdata.label = str(name) #To indicate which file has beeen selected
    featurevalues = list(data)
    target.options = featurevalues
    features.options = featurevalues
def get_data(t,f,fsl,dm,e,p):
    #Discritize continuous data based on selection
    all_data = data[f]
    if list(all_data.select_dtypes(include=numerics)):
        num_vars = list(all_data.select_dtypes(include=numerics))
        if dm != discrete_options[0]: #Discretization is done only upon selection
            if dm == discrete_options[1]:
                num_bins = e
                for i in range(0,len(num_vars)):
                    bins = np.arange(min(data[num_vars[i]]),
                                     max(data[num_vars[i]]),
                                     (max(data[num_vars[i]])-min(data[num_vars[i]]))/num_bins)
                    #Replacing the selected continuous columns in dataset with discretized data.
                    data[num_vars[i]] = np.digitize(data[num_vars[i]],bins)
            elif dm == discrete_options[2]:
                pct = p
                for i in range(0,len(num_vars)):
                    bins = np.arange(min(data[num_vars[i]]),
                                     max(data[num_vars[i]]),
                                     np.percentile(data[num_vars[i]],pct))
                    #Replacing the selected continuous columns in dataset with discretized data.
                    data[num_vars[i]] = np.digitize(data[num_vars[i]],bins)
    #Feature selection score calculation
    res = lambda x:getattr(fs,fs_methods[fsl])(data,data[t])
    score = list()
    for i in range(0,len(f)):score.append(res(f[i]))
    plot_data = pd.DataFrame({'feature' : list(f), 'mutual_info' : score}).sort_values(by='mutual_info',ascending=False)
    return ColumnDataSource(data = plot_data)
#Initilizing the plot
def make_plot(source):
    plot = figure(x_range = source.data['feature'],title = "Feature Selection",width = 800)
    plot.vbar(x='feature', width=0.5, bottom=0,top='mutual_info',source=source,
              color="firebrick")
    return plot
#function to update plot on callback
def update_plot(attr, old, new):
    tn = target.value
    fn = features.value
    fsn = feature_sel.value
    dmn = discrete_method.value
    en = Ebinning.value
    pn = Pbinning.value
    if (tn and fn) :
        src = get_data(tn,fn,fsn,dmn,en,pn)
        source.data.update(src.data)
        plot.x_range.factors = source.data['feature']
    layout.children = [widgets,plot]
    if discrete_method.value == discrete_options[1] :
        layout.children.append(Ebinning)
    elif discrete_method.value == discrete_options[2]:
        layout.children.append(Pbinning)

# In[37]:
#data = pd.read_excel('C:\\Users\\dgurram\\Desktop\\ASF\\Work on\\New Sand Trial.xlsx')
#text = TextInput(value="Default")

#Initial widgets and plots declaration
selectdata = bb(label = "Select Data", button_type="success")
target = Select(title="Select Target")
t = target.value
features = MultiSelect(title="Select Features")
f = features.value
discrete_method = Select(title="Select Discretization Method",
                        value = discrete_options[0],
                        options = discrete_options)
dm = discrete_method.value
Ebinning = Slider(title="Select num of bins", value=5, start=1, end=20, step=1)
Pbinning = Slider(title="Select Percentile", value=5, start=1, end=100, step=5)
feature_sel = Select(title="Select Feature Selection Method",value = fsl, options = list(fs_methods.keys()))
emptysrc = ColumnDataSource(pd.DataFrame({'feature' : [''], 'mutual_info' : ['']}))
source = ColumnDataSource(pd.DataFrame({'feature' : [''], 'mutual_info' : ['']}))
plot = make_plot(source)

# In[38]:
#callback
selectdata.on_click(updatedata)
controls = [target, features,feature_sel,discrete_method,Ebinning,Pbinning]
for control in controls:
    control.on_change('value',update_plot)

# In[39]:
#printing on web page
widgets = widgetbox(selectdata,features,target,feature_sel,discrete_method)
layout = row(widgets,plot)
curdoc().add_root(layout)
curdoc().title = "FSapp"

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
run code on network code:

from socket import gethostbyname, gethostname
from os import system
ip = gethostbyname(gethostname())
port = 5000
print("\nTo access the tool, go to: "+ip+":"+str(port)+"\n")
command = "".join(("bokeh serve --show Code1.py --port ", str(port), " --allow-websocket-origin=", ip, ':', str(port), " --host ", ip, ':', str(port)))
system(command)

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/b748f6dc-5027-4a49-afba-6b0827c72452%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Hello Bryan,

Thank you for the help. I was trying to understand the content in the link you provided. I tried replicating the example on the page. I am getting runtime error stating that ----> no such module: core/dom

-Divya

···

On Friday, April 21, 2017 at 12:25:16 PM UTC-5, Bryan Van de ven wrote:

Hi,

This is approach is not going to work, unfortunately. Tkinter is a separate library for creating rich client GUI applications that run locally on a machine. It does not have any capability to display GUIs over the network in a browser, for example. Python apps that use TKinter for GUI presentation will only ever show the GUI on the machine that the app is run on (modulo any display forwarding or VNC, etc). This is just the way Tkinter works, and what it does.

So, the next option would be to create a GUI in the browser with Bokeh widgets. Bokeh specifically is for showing plots and widgets across a network in a browser. Unfortunately, the built in set of widgets does not yet include a file chooser widget. It would be possible to extend Bokeh by wrapping an existing JavaScript file dialog:

    [http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html](http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html)

This is not a completely trivial task, but we are happy to answer any questions if you did want to try and go this route.

Thanks,

Bryan

On Apr 21, 2017, at 12:08, Divya Mounika Gurram [email protected] wrote:

Hello,

I am using bokeh to dynamically plot by having some control widgets. I am using tkinter package to browse for file on my system and then bokeh code uses that file to do plotting. The code works fine on my system but when I am sharing the app over the network, the tkinter package file open window is open on my local system instead of the sytem on which another person’s system accessing this app.

I am very new to bokeh and python.

App code:

import pandas as pd

import numpy as np

from bokeh.io import output_file, show, curdoc,set_curdoc

from bokeh.layouts import widgetbox,layout,row,gridplot

from bokeh.models import MultiSelect,Select,ColumnDataSource,Slider,TextInput

from bokeh.models import Button as bb

from bokeh.plotting import figure

import sklearn.metrics as fs

from tkinter import *

from tkinter.filedialog import askopenfilename

In[35]:

#code to insert logo in the plot

logo = figure(x_range=(0,3), y_range=(0,1),tools=“”,toolbar_location=None,

          x_axis_location=None, y_axis_location=None,height=100)

logo.xgrid.grid_line_color = None

logo.ygrid.grid_line_color = None

logo.outline_line_color = None

logo.image_url(url=[“C:\Users\dgurram\Desktop\ASF\Work on\referrence\Amsted Rail Logo.png”]

           ,x=0,y=1,w=3,h=0.8)

#Initialization

data = pd.DataFrame()

featurevalues = list()

fs_methods = dict({‘Mutual Information’:‘mutual_info_score’,

               'Adjusted Mutual Information':'adjusted_mutual_info_score',
              'Normalized Mutual Information':'normalized_mutual_info_score'})

fsl = list(fs_methods.keys())[0]

numerics = [‘int16’, ‘int32’, ‘int64’, ‘float16’, ‘float32’, ‘float64’]

discrete_options = [‘Default’,‘Equal width binning’,‘Equal percentile binning’]

In[40]:

#Get dataset from user system

def updatedata():

global featurevalues
global data
#clear the existing values if any while changing datasets
target.options = list()
features.options = list()
source.data.update(emptysrc.data)
#File selection window
root = Tk()
root.update()
root.filename =  askopenfilename(initialdir = "/",title = "Select file",filetypes = (("excel files",["*.xlsx","*.xls"]),("all files","*.*")))
root.destroy()
selectdata.label = str('Loading...') #To indicate while loading large files
name = root.filename
#Set the selected file as a pandas dataframe
#Update the feature and target options based on the chosen data
data = pd.read_excel(name)
selectdata.label = str(name) #To indicate which file has beeen selected
featurevalues = list(data)
target.options = featurevalues
features.options = featurevalues

def get_data(t,f,fsl,dm,e,p):

#Discritize continuous data based on selection
all_data = data[f]
if list(all_data.select_dtypes(include=numerics)):
    num_vars = list(all_data.select_dtypes(include=numerics))
    if dm != discrete_options[0]: #Discretization is done only upon selection
        if dm == discrete_options[1]:
            num_bins = e
            for i in range(0,len(num_vars)):
                bins = np.arange(min(data[num_vars[i]]),
                                 max(data[num_vars[i]]),
                                 (max(data[num_vars[i]])-min(data[num_vars[i]]))/num_bins)
                #Replacing the selected continuous columns in dataset with discretized data.
                data[num_vars[i]] = np.digitize(data[num_vars[i]],bins)                    
        elif dm == discrete_options[2]:
            pct = p
            for i in range(0,len(num_vars)):
                bins = np.arange(min(data[num_vars[i]]),
                                 max(data[num_vars[i]]),
                                 np.percentile(data[num_vars[i]],pct))
                #Replacing the selected continuous columns in dataset with discretized data.
                data[num_vars[i]] = np.digitize(data[num_vars[i]],bins)
#Feature selection score calculation
res = lambda x:getattr(fs,fs_methods[fsl])(data[x],data[t])    
score = list()
for i in range(0,len(f)):score.append(res(f[i]))
plot_data = pd.DataFrame({'feature' : list(f), 'mutual_info' : score}).sort_values(by='mutual_info',ascending=False)
return ColumnDataSource(data = plot_data)

#Initilizing the plot

def make_plot(source):

plot = figure(x_range = source.data['feature'],title = "Feature Selection",width = 800)
plot.vbar(x='feature', width=0.5, bottom=0,top='mutual_info',source=source,
          color="firebrick")
return plot

#function to update plot on callback

def update_plot(attr, old, new):
tn = target.value

fn = features.value
fsn = feature_sel.value    
dmn = discrete_method.value
en = Ebinning.value
pn = Pbinning.value
if (tn and fn) :
    src = get_data(tn,fn,fsn,dmn,en,pn)
    source.data.update(src.data)
    plot.x_range.factors = source.data['feature']
layout.children = [widgets,plot]
if discrete_method.value == discrete_options[1] :
    layout.children.append(Ebinning)
elif discrete_method.value == discrete_options[2]:
    layout.children.append(Pbinning)  

In[37]:

#data = pd.read_excel(‘C:\Users\dgurram\Desktop\ASF\Work on\New Sand Trial.xlsx’)

#text = TextInput(value=“Default”)

#Initial widgets and plots declaration

selectdata = bb(label = “Select Data”, button_type=“success”)

target = Select(title=“Select Target”)

t = target.value

features = MultiSelect(title=“Select Features”)

f = features.value

discrete_method = Select(title=“Select Discretization Method”,

                    value = discrete_options[0],
                    options = discrete_options)

dm = discrete_method.value

Ebinning = Slider(title=“Select num of bins”, value=5, start=1, end=20, step=1)

Pbinning = Slider(title=“Select Percentile”, value=5, start=1, end=100, step=5)

feature_sel = Select(title=“Select Feature Selection Method”,value = fsl, options = list(fs_methods.keys()))

emptysrc = ColumnDataSource(pd.DataFrame({‘feature’ : [‘’], ‘mutual_info’ : [‘’]}))

source = ColumnDataSource(pd.DataFrame({‘feature’ : [‘’], ‘mutual_info’ : [‘’]}))

plot = make_plot(source)

In[38]:

#callback

selectdata.on_click(updatedata)

controls = [target, features,feature_sel,discrete_method,Ebinning,Pbinning]
for control in controls:

control.on_change('value',update_plot)

In[39]:

#printing on web page

widgets = widgetbox(selectdata,features,target,feature_sel,discrete_method)

layout = row(widgets,plot)

curdoc().add_root(layout)

curdoc().title = “FSapp”


run code on network code:

from socket import gethostbyname, gethostname

from os import system

ip = gethostbyname(gethostname())

port = 5000

print(“\nTo access the tool, go to: “+ip+”:”+str(port)+“\n”)

command = “”.join(("bokeh serve --show Code1.py --port “, str(port), " --allow-websocket-origin=”, ip, ‘:’, str(port), " --host ", ip, ‘:’, str(port)))

system(command)


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/b748f6dc-5027-4a49-afba-6b0827c72452%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Hello Bryan,

The code I was running is the same code in the link you provided. Can you guide on what might be wrong.

from bokeh.core.properties import Instance,String
from bokeh.io import output_file, show
from bokeh.models import LayoutDOM, Slider
from bokeh.plotting import figure
from bokeh.layouts import column

class Custom(LayoutDOM):
implementation = JS_CODE
text = String(default=“Custom text”)
slider = Instance(Slider)

JS_CODE = “”"

The “core/properties” module has all the property types

import * as p from “core/properties”
import {div, empty} from “core/dom”

We will subclass in JavaScript from the same class that was subclassed

from in Python

import {LayoutDOM, LayoutDOMView} from “models/layouts/layout_dom”

This model will actually need to render things, so we must provide

view. The LayoutDOM model has a view already, so we will start with that

export class CustomView extends LayoutDOMView

initialize: (options) →
super(options)

@render()

Set Backbone listener so that when the Bokeh slider has a change

# event, we can process the new data
@listenTo(@model.slider, 'change', () => @render())

render: () →
# Backbone Views create

elements by default, accessible as @el.
# Many Bokeh views ignore this default
, and instead do things
# like draw to the HTML canvas. In this case though, we change the
# contents of the
, based on the current slider value.
empty(@el)
@el.appendChild(div({
style: {
color: ‘#686d8e
‘background-color’: ‘#2a3153
}
}, “#{@model.text}: #{@model.slider.value}”))

export class Custom extends LayoutDOM

If there is an associated view, this is boilerplate.

default_view: CustomView

The type class attribute should generally match exactly the name

of the corresponding Python class.

type: “Custom”

The @define block adds corresponding “properties” to the JS model. These

should basically line up 1-1 with the Python model class. Most property

types have counterparts, e.g. bokeh.core.properties.String will be

p.String in the JS implementation. Where the JS type system is not yet

as rich, you can use p.Any as a “wildcard” property type.

@define {
text: [ p.String ]
slider: [ p.Any ]
}
“”"

slider = Slider(start=0, end=10, step=0.1, value=0, title=“value”)

custom = Custom(text=“Special Slider Display”, slider=slider)

layout = column(slider, custom)

show(layout)

···

On Friday, April 21, 2017 at 2:24:36 PM UTC-5, Divya Mounika Gurram wrote:

Hello Bryan,

Thank you for the help. I was trying to understand the content in the link you provided. I tried replicating the example on the page. I am getting runtime error stating that ----> no such module: core/dom

-Divya

On Friday, April 21, 2017 at 12:25:16 PM UTC-5, Bryan Van de ven wrote:

Hi,

This is approach is not going to work, unfortunately. Tkinter is a separate library for creating rich client GUI applications that run locally on a machine. It does not have any capability to display GUIs over the network in a browser, for example. Python apps that use TKinter for GUI presentation will only ever show the GUI on the machine that the app is run on (modulo any display forwarding or VNC, etc). This is just the way Tkinter works, and what it does.

So, the next option would be to create a GUI in the browser with Bokeh widgets. Bokeh specifically is for showing plots and widgets across a network in a browser. Unfortunately, the built in set of widgets does not yet include a file chooser widget. It would be possible to extend Bokeh by wrapping an existing JavaScript file dialog:

    [http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html](http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html)

This is not a completely trivial task, but we are happy to answer any questions if you did want to try and go this route.

Thanks,

Bryan

On Apr 21, 2017, at 12:08, Divya Mounika Gurram [email protected] wrote:

Hello,

I am using bokeh to dynamically plot by having some control widgets. I am using tkinter package to browse for file on my system and then bokeh code uses that file to do plotting. The code works fine on my system but when I am sharing the app over the network, the tkinter package file open window is open on my local system instead of the sytem on which another person’s system accessing this app.

I am very new to bokeh and python.

App code:

import pandas as pd

import numpy as np

from bokeh.io import output_file, show, curdoc,set_curdoc

from bokeh.layouts import widgetbox,layout,row,gridplot

from bokeh.models import MultiSelect,Select,ColumnDataSource,Slider,TextInput

from bokeh.models import Button as bb

from bokeh.plotting import figure

import sklearn.metrics as fs

from tkinter import *

from tkinter.filedialog import askopenfilename

In[35]:

#code to insert logo in the plot

logo = figure(x_range=(0,3), y_range=(0,1),tools=“”,toolbar_location=None,

          x_axis_location=None, y_axis_location=None,height=100)

logo.xgrid.grid_line_color = None

logo.ygrid.grid_line_color = None

logo.outline_line_color = None

logo.image_url(url=[“C:\Users\dgurram\Desktop\ASF\Work on\referrence\Amsted Rail Logo.png”]

           ,x=0,y=1,w=3,h=0.8)

#Initialization

data = pd.DataFrame()

featurevalues = list()

fs_methods = dict({‘Mutual Information’:‘mutual_info_score’,

               'Adjusted Mutual Information':'adjusted_mutual_info_score',
              'Normalized Mutual Information':'normalized_mutual_info_score'})

fsl = list(fs_methods.keys())[0]

numerics = [‘int16’, ‘int32’, ‘int64’, ‘float16’, ‘float32’, ‘float64’]

discrete_options = [‘Default’,‘Equal width binning’,‘Equal percentile binning’]

In[40]:

#Get dataset from user system

def updatedata():

global featurevalues
global data
#clear the existing values if any while changing datasets
target.options = list()
features.options = list()
source.data.update(emptysrc.data)
#File selection window
root = Tk()
root.update()
root.filename =  askopenfilename(initialdir = "/",title = "Select file",filetypes = (("excel files",["*.xlsx","*.xls"]),("all files","*.*")))
root.destroy()
selectdata.label = str('Loading...') #To indicate while loading large files
name = root.filename
#Set the selected file as a pandas dataframe
#Update the feature and target options based on the chosen data
data = pd.read_excel(name)
selectdata.label = str(name) #To indicate which file has beeen selected
featurevalues = list(data)
target.options = featurevalues
features.options = featurevalues

def get_data(t,f,fsl,dm,e,p):

#Discritize continuous data based on selection
all_data = data[f]
if list(all_data.select_dtypes(include=numerics)):
    num_vars = list(all_data.select_dtypes(include=numerics))
    if dm != discrete_options[0]: #Discretization is done only upon selection
        if dm == discrete_options[1]:
            num_bins = e
            for i in range(0,len(num_vars)):
                bins = np.arange(min(data[num_vars[i]]),
                                 max(data[num_vars[i]]),
                                 (max(data[num_vars[i]])-min(data[num_vars[i]]))/num_bins)
                #Replacing the selected continuous columns in dataset with discretized data.
                data[num_vars[i]] = np.digitize(data[num_vars[i]],bins)                    
        elif dm == discrete_options[2]:
            pct = p
            for i in range(0,len(num_vars)):
                bins = np.arange(min(data[num_vars[i]]),
                                 max(data[num_vars[i]]),
                                 np.percentile(data[num_vars[i]],pct))
                #Replacing the selected continuous columns in dataset with discretized data.
                data[num_vars[i]] = np.digitize(data[num_vars[i]],bins)
#Feature selection score calculation
res = lambda x:getattr(fs,fs_methods[fsl])(data[x],data[t])    
score = list()
for i in range(0,len(f)):score.append(res(f[i]))
plot_data = pd.DataFrame({'feature' : list(f), 'mutual_info' : score}).sort_values(by='mutual_info',ascending=False)
return ColumnDataSource(data = plot_data)

#Initilizing the plot

def make_plot(source):

plot = figure(x_range = source.data['feature'],title = "Feature Selection",width = 800)
plot.vbar(x='feature', width=0.5, bottom=0,top='mutual_info',source=source,
          color="firebrick")
return plot

#function to update plot on callback

def update_plot(attr, old, new):
tn = target.value

fn = features.value
fsn = feature_sel.value    
dmn = discrete_method.value
en = Ebinning.value
pn = Pbinning.value
if (tn and fn) :
    src = get_data(tn,fn,fsn,dmn,en,pn)
    source.data.update(src.data)
    plot.x_range.factors = source.data['feature']
layout.children = [widgets,plot]
if discrete_method.value == discrete_options[1] :
    layout.children.append(Ebinning)
elif discrete_method.value == discrete_options[2]:
    layout.children.append(Pbinning)  

In[37]:

#data = pd.read_excel(‘C:\Users\dgurram\Desktop\ASF\Work on\New Sand Trial.xlsx’)

#text = TextInput(value=“Default”)

#Initial widgets and plots declaration

selectdata = bb(label = “Select Data”, button_type=“success”)

target = Select(title=“Select Target”)

t = target.value

features = MultiSelect(title=“Select Features”)

f = features.value

discrete_method = Select(title=“Select Discretization Method”,

                    value = discrete_options[0],
                    options = discrete_options)

dm = discrete_method.value

Ebinning = Slider(title=“Select num of bins”, value=5, start=1, end=20, step=1)

Pbinning = Slider(title=“Select Percentile”, value=5, start=1, end=100, step=5)

feature_sel = Select(title=“Select Feature Selection Method”,value = fsl, options = list(fs_methods.keys()))

emptysrc = ColumnDataSource(pd.DataFrame({‘feature’ : [‘’], ‘mutual_info’ : [‘’]}))

source = ColumnDataSource(pd.DataFrame({‘feature’ : [‘’], ‘mutual_info’ : [‘’]}))

plot = make_plot(source)

In[38]:

#callback

selectdata.on_click(updatedata)

controls = [target, features,feature_sel,discrete_method,Ebinning,Pbinning]
for control in controls:

control.on_change('value',update_plot)

In[39]:

#printing on web page

widgets = widgetbox(selectdata,features,target,feature_sel,discrete_method)

layout = row(widgets,plot)

curdoc().add_root(layout)

curdoc().title = “FSapp”


run code on network code:

from socket import gethostbyname, gethostname

from os import system

ip = gethostbyname(gethostname())

port = 5000

print(“\nTo access the tool, go to: “+ip+”:”+str(port)+“\n”)

command = “”.join(("bokeh serve --show Code1.py --port “, str(port), " --allow-websocket-origin=”, ip, ‘:’, str(port), " --host ", ip, ‘:’, str(port)))

system(command)


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/b748f6dc-5027-4a49-afba-6b0827c72452%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

You probably need to make sure the version of Bokeh installed matches the version of the docs you are looking at.

Some parts of Bokeh are very stable but a few parts are not yet. The JS API was, until recently, an internal implementation detail, so it is still stabilizing and some details have changed between releases.

Thanks,

Bryan

···

On Apr 21, 2017, at 16:17, Divya Mounika Gurram <[email protected]> wrote:

Hello Bryan,

The code I was running is the same code in the link you provided. Can you guide on what might be wrong.

from bokeh.core.properties import Instance,String
from bokeh.io import output_file, show
from bokeh.models import LayoutDOM, Slider
from bokeh.plotting import figure
from bokeh.layouts import column
class Custom(LayoutDOM):
    __implementation__ = JS_CODE
    text = String(default="Custom text")
    slider = Instance(Slider)
JS_CODE = """
# The "core/properties" module has all the property types
import * as p from "core/properties"
import {div, empty} from "core/dom"
# We will subclass in JavaScript from the same class that was subclassed
# from in Python
import {LayoutDOM, LayoutDOMView} from "models/layouts/layout_dom"
# This model will actually need to render things, so we must provide
# view. The LayoutDOM model has a view already, so we will start with that
export class CustomView extends LayoutDOMView
  initialize: (options) ->
    super(options)
    @render()
    # Set Backbone listener so that when the Bokeh slider has a change
    # event, we can process the new data
    @listenTo(@model.slider, 'change', () => @render())
  render: () ->
    # Backbone Views create <div> elements by default, accessible as @el.
    # Many Bokeh views ignore this default <div>, and instead do things
    # like draw to the HTML canvas. In this case though, we change the
    # contents of the <div>, based on the current slider value.
    empty(@el)
    @el.appendChild(div({
      style: {
        color: '#686d8e'
        'background-color': '#2a3153'
      }
    }, "#{@model.text}: #{@model.slider.value}"))
export class Custom extends LayoutDOM
  # If there is an associated view, this is boilerplate.
  default_view: CustomView
  # The ``type`` class attribute should generally match exactly the name
  # of the corresponding Python class.
  type: "Custom"
  # The @define block adds corresponding "properties" to the JS model. These
  # should basically line up 1-1 with the Python model class. Most property
  # types have counterparts, e.g. bokeh.core.properties.String will be
  # p.String in the JS implementation. Where the JS type system is not yet
  # as rich, you can use p.Any as a "wildcard" property type.
  @define {
    text: [ p.String ]
    slider: [ p.Any ]
  }
"""

slider = Slider(start=0, end=10, step=0.1, value=0, title="value")
custom = Custom(text="Special Slider Display", slider=slider)
layout = column(slider, custom)
show(layout)

On Friday, April 21, 2017 at 2:24:36 PM UTC-5, Divya Mounika Gurram wrote:
Hello Bryan,

Thank you for the help. I was trying to understand the content in the link you provided. I tried replicating the example on the page. I am getting runtime error stating that ----> no such module: core/dom

-Divya

On Friday, April 21, 2017 at 12:25:16 PM UTC-5, Bryan Van de ven wrote:
Hi,

This is approach is not going to work, unfortunately. Tkinter is a separate library for creating rich client GUI applications that run locally on a machine. It does not have any capability to display GUIs over the network in a browser, for example. Python apps that use TKinter for GUI presentation will only ever show the GUI on the machine that the app is run on (modulo any display forwarding or VNC, etc). This is just the way Tkinter works, and what it does.

So, the next option would be to create a GUI in the browser with Bokeh widgets. Bokeh specifically is for showing plots and widgets across a network in a browser. Unfortunately, the built in set of widgets does not yet include a file chooser widget. It would be possible to extend Bokeh by wrapping an existing JavaScript file dialog:

        http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html

This is not a completely trivial task, but we are happy to answer any questions if you did want to try and go this route.

Thanks,

Bryan

> On Apr 21, 2017, at 12:08, Divya Mounika Gurram <[email protected]> wrote:
>
> Hello,
>
> I am using bokeh to dynamically plot by having some control widgets. I am using tkinter package to browse for file on my system and then bokeh code uses that file to do plotting. The code works fine on my system but when I am sharing the app over the network, the tkinter package file open window is open on my local system instead of the sytem on which another person's system accessing this app.
>
> I am very new to bokeh and python.
>
> App code:
>
> import pandas as pd
> import numpy as np
> from bokeh.io import output_file, show, curdoc,set_curdoc
> from bokeh.layouts import widgetbox,layout,row,gridplot
> from bokeh.models import MultiSelect,Select,ColumnDataSource,Slider,TextInput
> from bokeh.models import Button as bb
> from bokeh.plotting import figure
> import sklearn.metrics as fs
> from tkinter import *
> from tkinter.filedialog import askopenfilename
>
> # In[35]:
> #code to insert logo in the plot
> logo = figure(x_range=(0,3), y_range=(0,1),tools="",toolbar_location=None,
> x_axis_location=None, y_axis_location=None,height=100)
> logo.xgrid.grid_line_color = None
> logo.ygrid.grid_line_color = None
> logo.outline_line_color = None
> logo.image_url(url=["C:\\Users\\dgurram\\Desktop\\ASF\\Work on\\referrence\\Amsted Rail Logo.png"]
> ,x=0,y=1,w=3,h=0.8)
> #Initialization
> data = pd.DataFrame()
> featurevalues = list()
> fs_methods = dict({'Mutual Information':'mutual_info_score',
> 'Adjusted Mutual Information':'adjusted_mutual_info_score',
> 'Normalized Mutual Information':'normalized_mutual_info_score'})
> fsl = list(fs_methods.keys())[0]
> numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
> discrete_options = ['Default','Equal width binning','Equal percentile binning']
>
> # In[40]:
> #Get dataset from user system
> def updatedata():
> global featurevalues
> global data
> #clear the existing values if any while changing datasets
> target.options = list()
> features.options = list()
> source.data.update(emptysrc.data)
> #File selection window
> root = Tk()
> root.update()
> root.filename = askopenfilename(initialdir = "/",title = "Select file",filetypes = (("excel files",["*.xlsx","*.xls"]),("all files","*.*")))
> root.destroy()
> selectdata.label = str('Loading...') #To indicate while loading large files
> name = root.filename
> #Set the selected file as a pandas dataframe
> #Update the feature and target options based on the chosen data
> data = pd.read_excel(name)
> selectdata.label = str(name) #To indicate which file has beeen selected
> featurevalues = list(data)
> target.options = featurevalues
> features.options = featurevalues
> def get_data(t,f,fsl,dm,e,p):
> #Discritize continuous data based on selection
> all_data = data[f]
> if list(all_data.select_dtypes(include=numerics)):
> num_vars = list(all_data.select_dtypes(include=numerics))
> if dm != discrete_options[0]: #Discretization is done only upon selection
> if dm == discrete_options[1]:
> num_bins = e
> for i in range(0,len(num_vars)):
> bins = np.arange(min(data[num_vars[i]]),
> max(data[num_vars[i]]),
> (max(data[num_vars[i]])-min(data[num_vars[i]]))/num_bins)
> #Replacing the selected continuous columns in dataset with discretized data.
> data[num_vars[i]] = np.digitize(data[num_vars[i]],bins)
> elif dm == discrete_options[2]:
> pct = p
> for i in range(0,len(num_vars)):
> bins = np.arange(min(data[num_vars[i]]),
> max(data[num_vars[i]]),
> np.percentile(data[num_vars[i]],pct))
> #Replacing the selected continuous columns in dataset with discretized data.
> data[num_vars[i]] = np.digitize(data[num_vars[i]],bins)
> #Feature selection score calculation
> res = lambda x:getattr(fs,fs_methods[fsl])(data,data[t])
> score = list()
> for i in range(0,len(f)):score.append(res(f[i]))
> plot_data = pd.DataFrame({'feature' : list(f), 'mutual_info' : score}).sort_values(by='mutual_info',ascending=False)
> return ColumnDataSource(data = plot_data)
> #Initilizing the plot
> def make_plot(source):
> plot = figure(x_range = source.data['feature'],title = "Feature Selection",width = 800)
> plot.vbar(x='feature', width=0.5, bottom=0,top='mutual_info',source=source,
> color="firebrick")
> return plot
> #function to update plot on callback
> def update_plot(attr, old, new):
> tn = target.value
> fn = features.value
> fsn = feature_sel.value
> dmn = discrete_method.value
> en = Ebinning.value
> pn = Pbinning.value
> if (tn and fn) :
> src = get_data(tn,fn,fsn,dmn,en,pn)
> source.data.update(src.data)
> plot.x_range.factors = source.data['feature']
> layout.children = [widgets,plot]
> if discrete_method.value == discrete_options[1] :
> layout.children.append(Ebinning)
> elif discrete_method.value == discrete_options[2]:
> layout.children.append(Pbinning)
>
> # In[37]:
> #data = pd.read_excel('C:\\Users\\dgurram\\Desktop\\ASF\\Work on\\New Sand Trial.xlsx')
> #text = TextInput(value="Default")
>
> #Initial widgets and plots declaration
> selectdata = bb(label = "Select Data", button_type="success")
> target = Select(title="Select Target")
> t = target.value
> features = MultiSelect(title="Select Features")
> f = features.value
> discrete_method = Select(title="Select Discretization Method",
> value = discrete_options[0],
> options = discrete_options)
> dm = discrete_method.value
> Ebinning = Slider(title="Select num of bins", value=5, start=1, end=20, step=1)
> Pbinning = Slider(title="Select Percentile", value=5, start=1, end=100, step=5)
> feature_sel = Select(title="Select Feature Selection Method",value = fsl, options = list(fs_methods.keys()))
> emptysrc = ColumnDataSource(pd.DataFrame({'feature' : [''], 'mutual_info' : ['']}))
> source = ColumnDataSource(pd.DataFrame({'feature' : [''], 'mutual_info' : ['']}))
> plot = make_plot(source)
>
> # In[38]:
> #callback
> selectdata.on_click(updatedata)
> controls = [target, features,feature_sel,discrete_method,Ebinning,Pbinning]
> for control in controls:
> control.on_change('value',update_plot)
>
> # In[39]:
> #printing on web page
> widgets = widgetbox(selectdata,features,target,feature_sel,discrete_method)
> layout = row(widgets,plot)
> curdoc().add_root(layout)
> curdoc().title = "FSapp"
>
>
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> run code on network code:
>
> from socket import gethostbyname, gethostname
> from os import system
> ip = gethostbyname(gethostname())
> port = 5000
> print("\nTo access the tool, go to: "+ip+":"+str(port)+"\n")
> command = "".join(("bokeh serve --show Code1.py --port ", str(port), " --allow-websocket-origin=", ip, ':', str(port), " --host ", ip, ':', str(port)))
> system(command)
>
> --
> You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to bokeh+un...@continuum.io.
> To post to this group, send email to bo...@continuum.io.
> To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/b748f6dc-5027-4a49-afba-6b0827c72452%40continuum.io\.
> For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/784fa8f0-0d69-4f81-91cf-dfc2b299e460%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Hello Bryan,

Can you give me a head start on how I can start with this? Thank you so much for your help.

-Divya

Hi,

You should know what version of Bokeh you have installed, I have no way of telling you what that might be. Once you know what version you are using, you can look at the corresponding specific versions of the docs online. E.g.

  Welcome to Bokeh — Bokeh 0.12.3 documentation

will specifically display the docs for 0.12.3 instead of the "latest" docs.

Thanks,

Bryan

···

On Apr 25, 2017, at 09:52, Divya Mounika Gurram <[email protected]> wrote:

Hello Bryan,

Can you give me a head start on how I can start with this? Thank you so much for your help.

-Divya

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/16888287-d841-4b2c-9ba2-1db90dc2d643%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Hello Bryan,

Thank you for the guidance.

I tried to customize a button to upload a file. I am able to get the file select window and get properties of the selected file. The alert statements in the following code gives me the properties of the file I selected. But I am not sure how to pass the contents of the file to columndatasource object. Could you please guide me on this.

import pandas as pd
from bokeh.layouts import row
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import Button
from bokeh.io import curdoc

source = ColumnDataSource(dict())

button = Button(label=“Upload”, button_type=“success”)
button.callback = CustomJS(args=dict(source=source),
code="""
fileSelector = document.createElement(‘input’);
fileSelector.setAttribute(‘type’, ‘file’);

selectDialogueLink = document.createElement(‘a’);
selectDialogueLink.setAttribute(‘href’, ‘’);

selectDialogueLink.onclick = fileSelector.click();

document.body.appendChild(selectDialogueLink);

if (‘files’ in fileSelector) {
if (fileSelector.files.length == 0) {
alert(“Select file.”);
} else {
for (var i = 0; i < fileSelector.files.length; i++) {
var file = fileSelector.files[i];
var reader = new FileReader();
reader.readAsDataURL(file);
if (‘name’ in file) {
alert("name: " + file.name);
}
if (‘size’ in file) {
alert(“size: " + file.size);
}
}
}
}
“””)

curdoc().add_root(row(button))

Actually, the sample code Divya was trying to run in the ‘latest’ documentation needs to be updated:

http://bokeh.pydata.org/en/latest/docs/user_guide/extensions_gallery/widget.html

After some searching through the bokehjs source, I got the above example to work by making the following changes:

  • extentions_ion_range_slider.coffee: import {throttle} from core/util/callback → import {throttle} from “core/util/throttle”
  • extentions_ion_range_slider_template.tsx: import * as DOM from “core/dom”; → import * as DOM from “core/util/dom”;
    Chris
···

On Friday, April 21, 2017 at 2:21:24 PM UTC-7, Bryan Van de ven wrote:

You probably need to make sure the version of Bokeh installed matches the version of the docs you are looking at.

Some parts of Bokeh are very stable but a few parts are not yet. The JS API was, until recently, an internal implementation detail, so it is still stabilizing and some details have changed between releases.

Thanks,

Bryan

On Apr 21, 2017, at 16:17, Divya Mounika Gurram [email protected] wrote:

Hello Bryan,

The code I was running is the same code in the link you provided. Can you guide on what might be wrong.

from bokeh.core.properties import Instance,String

from bokeh.io import output_file, show

from bokeh.models import LayoutDOM, Slider

from bokeh.plotting import figure

from bokeh.layouts import column

class Custom(LayoutDOM):

__implementation__ = JS_CODE
text = String(default="Custom text")
slider = Instance(Slider)

JS_CODE = “”"

The “core/properties” module has all the property types

import * as p from “core/properties”

import {div, empty} from “core/dom”

We will subclass in JavaScript from the same class that was subclassed

from in Python

import {LayoutDOM, LayoutDOMView} from “models/layouts/layout_dom”

This model will actually need to render things, so we must provide

view. The LayoutDOM model has a view already, so we will start with that

export class CustomView extends LayoutDOMView

initialize: (options) →

super(options)
@render()
# Set Backbone listener so that when the Bokeh slider has a change
# event, we can process the new data
@listenTo(@model.slider, 'change', () => @render())

render: () →

# Backbone Views create <div> elements by default, accessible as @el.
# Many Bokeh views ignore this default <div>, and instead do things
# like draw to the HTML canvas. In this case though, we change the
# contents of the <div>, based on the current slider value.
empty(@el)
@el.appendChild(div({
  style: {
    color: '#686d8e'
    'background-color': '#2a3153'
  }
}, "#{@model.text}: #{@model.slider.value}"))

export class Custom extends LayoutDOM

If there is an associated view, this is boilerplate.

default_view: CustomView

The type class attribute should generally match exactly the name

of the corresponding Python class.

type: “Custom”

The @define block adds corresponding “properties” to the JS model. These

should basically line up 1-1 with the Python model class. Most property

types have counterparts, e.g. bokeh.core.properties.String will be

p.String in the JS implementation. Where the JS type system is not yet

as rich, you can use p.Any as a “wildcard” property type.

@define {

text:   [ p.String ]
slider: [ p.Any    ]

}

“”"

slider = Slider(start=0, end=10, step=0.1, value=0, title=“value”)

custom = Custom(text=“Special Slider Display”, slider=slider)

layout = column(slider, custom)

show(layout)

On Friday, April 21, 2017 at 2:24:36 PM UTC-5, Divya Mounika Gurram wrote:

Hello Bryan,

Thank you for the help. I was trying to understand the content in the link you provided. I tried replicating the example on the page. I am getting runtime error stating that ----> no such module: core/dom

-Divya

On Friday, April 21, 2017 at 12:25:16 PM UTC-5, Bryan Van de ven wrote:

Hi,

This is approach is not going to work, unfortunately. Tkinter is a separate library for creating rich client GUI applications that run locally on a machine. It does not have any capability to display GUIs over the network in a browser, for example. Python apps that use TKinter for GUI presentation will only ever show the GUI on the machine that the app is run on (modulo any display forwarding or VNC, etc). This is just the way Tkinter works, and what it does.

So, the next option would be to create a GUI in the browser with Bokeh widgets. Bokeh specifically is for showing plots and widgets across a network in a browser. Unfortunately, the built in set of widgets does not yet include a file chooser widget. It would be possible to extend Bokeh by wrapping an existing JavaScript file dialog:

    [http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html](http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html)

This is not a completely trivial task, but we are happy to answer any questions if you did want to try and go this route.

Thanks,

Bryan

On Apr 21, 2017, at 12:08, Divya Mounika Gurram [email protected] wrote:

Hello,

I am using bokeh to dynamically plot by having some control widgets. I am using tkinter package to browse for file on my system and then bokeh code uses that file to do plotting. The code works fine on my system but when I am sharing the app over the network, the tkinter package file open window is open on my local system instead of the sytem on which another person’s system accessing this app.

I am very new to bokeh and python.

App code:

import pandas as pd
import numpy as np
from bokeh.io import output_file, show, curdoc,set_curdoc
from bokeh.layouts import widgetbox,layout,row,gridplot
from bokeh.models import MultiSelect,Select,ColumnDataSource,Slider,TextInput
from bokeh.models import Button as bb
from bokeh.plotting import figure
import sklearn.metrics as fs
from tkinter import *
from tkinter.filedialog import askopenfilename

In[35]:

#code to insert logo in the plot
logo = figure(x_range=(0,3), y_range=(0,1),tools=“”,toolbar_location=None,
x_axis_location=None, y_axis_location=None,height=100)
logo.xgrid.grid_line_color = None
logo.ygrid.grid_line_color = None
logo.outline_line_color = None
logo.image_url(url=[“C:\Users\dgurram\Desktop\ASF\Work on\referrence\Amsted Rail Logo.png”]
,x=0,y=1,w=3,h=0.8)
#Initialization
data = pd.DataFrame()
featurevalues = list()
fs_methods = dict({‘Mutual Information’:‘mutual_info_score’,
‘Adjusted Mutual Information’:‘adjusted_mutual_info_score’,
‘Normalized Mutual Information’:‘normalized_mutual_info_score’})
fsl = list(fs_methods.keys())[0]
numerics = [‘int16’, ‘int32’, ‘int64’, ‘float16’, ‘float32’, ‘float64’]
discrete_options = [‘Default’,‘Equal width binning’,‘Equal percentile binning’]

In[40]:

#Get dataset from user system
def updatedata():
global featurevalues
global data
#clear the existing values if any while changing datasets
target.options = list()
features.options = list()
source.data.update(emptysrc.data)
#File selection window
root = Tk()
root.update()
root.filename = askopenfilename(initialdir = “/”,title = “Select file”,filetypes = ((“excel files”,[“.xlsx",".xls”]),(“all files”,“.”)))
root.destroy()
selectdata.label = str(‘Loading…’) #To indicate while loading large files
name = root.filename
#Set the selected file as a pandas dataframe
#Update the feature and target options based on the chosen data
data = pd.read_excel(name)
selectdata.label = str(name) #To indicate which file has beeen selected
featurevalues = list(data)
target.options = featurevalues
features.options = featurevalues
def get_data(t,f,fsl,dm,e,p):
#Discritize continuous data based on selection
all_data = data[f]
if list(all_data.select_dtypes(include=numerics)):
num_vars = list(all_data.select_dtypes(include=numerics))
if dm != discrete_options[0]: #Discretization is done only upon selection
if dm == discrete_options[1]:
num_bins = e
for i in range(0,len(num_vars)):
bins = np.arange(min(data[num_vars[i]]),
max(data[num_vars[i]]),
(max(data[num_vars[i]])-min(data[num_vars[i]]))/num_bins)
#Replacing the selected continuous columns in dataset with discretized data.
data[num_vars[i]] = np.digitize(data[num_vars[i]],bins)
elif dm == discrete_options[2]:
pct = p
for i in range(0,len(num_vars)):
bins = np.arange(min(data[num_vars[i]]),
max(data[num_vars[i]]),
np.percentile(data[num_vars[i]],pct))
#Replacing the selected continuous columns in dataset with discretized data.
data[num_vars[i]] = np.digitize(data[num_vars[i]],bins)
#Feature selection score calculation
res = lambda x:getattr(fs,fs_methods[fsl])(data,data[t])
score = list()
for i in range(0,len(f)):score.append(res(f[i]))
plot_data = pd.DataFrame({‘feature’ : list(f), ‘mutual_info’ : score}).sort_values(by=‘mutual_info’,ascending=False)
return ColumnDataSource(data = plot_data)
#Initilizing the plot
def make_plot(source):
plot = figure(x_range = source.data[‘feature’],title = “Feature Selection”,width = 800)
plot.vbar(x=‘feature’, width=0.5, bottom=0,top=‘mutual_info’,source=source,
color=“firebrick”)
return plot
#function to update plot on callback
def update_plot(attr, old, new):
tn = target.value
fn = features.value
fsn = feature_sel.value
dmn = discrete_method.value
en = Ebinning.value
pn = Pbinning.value
if (tn and fn) :
src = get_data(tn,fn,fsn,dmn,en,pn)
source.data.update(src.data)
plot.x_range.factors = source.data[‘feature’]
layout.children = [widgets,plot]
if discrete_method.value == discrete_options[1] :
layout.children.append(Ebinning)
elif discrete_method.value == discrete_options[2]:
layout.children.append(Pbinning)

In[37]:

#data = pd.read_excel(‘C:\Users\dgurram\Desktop\ASF\Work on\New Sand Trial.xlsx’)
#text = TextInput(value=“Default”)

#Initial widgets and plots declaration
selectdata = bb(label = “Select Data”, button_type=“success”)
target = Select(title=“Select Target”)
t = target.value
features = MultiSelect(title=“Select Features”)
f = features.value
discrete_method = Select(title=“Select Discretization Method”,
value = discrete_options[0],
options = discrete_options)
dm = discrete_method.value
Ebinning = Slider(title=“Select num of bins”, value=5, start=1, end=20, step=1)
Pbinning = Slider(title=“Select Percentile”, value=5, start=1, end=100, step=5)
feature_sel = Select(title=“Select Feature Selection Method”,value = fsl, options = list(fs_methods.keys()))
emptysrc = ColumnDataSource(pd.DataFrame({‘feature’ : [‘’], ‘mutual_info’ : [‘’]}))
source = ColumnDataSource(pd.DataFrame({‘feature’ : [‘’], ‘mutual_info’ : [‘’]}))
plot = make_plot(source)

In[38]:

#callback
selectdata.on_click(updatedata)
controls = [target, features,feature_sel,discrete_method,Ebinning,Pbinning]
for control in controls:
control.on_change(‘value’,update_plot)

In[39]:

#printing on web page
widgets = widgetbox(selectdata,features,target,feature_sel,discrete_method)
layout = row(widgets,plot)
curdoc().add_root(layout)
curdoc().title = “FSapp”


run code on network code:

from socket import gethostbyname, gethostname
from os import system
ip = gethostbyname(gethostname())
port = 5000
print(“\nTo access the tool, go to: “+ip+”:”+str(port)+“\n”)
command = “”.join(("bokeh serve --show Code1.py --port “, str(port), " --allow-websocket-origin=”, ip, ‘:’, str(port), " --host ", ip, ‘:’, str(port)))
system(command)


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/b748f6dc-5027-4a49-afba-6b0827c72452%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/784fa8f0-0d69-4f81-91cf-dfc2b299e460%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.