[Q] Make Histogram selectable and link to Data Column Source

Hi,

I’m looking for a way to make the bars in a histogram selectable and link them to a data source.

What I want to do is the following:

I have a lot of different plots all on the same Data Source, so all are linked.

I also have a DataTable linked to the same source.

Inside that source there are a lot of columns with binary values which are not plotted.

Those collumns should be presented in a Histogram. If one bar of the Histogram is pressed all points that for example have value ‘1’ in that column should get selected in all plots as well as the Data Table.

And does anyone know a way to speed up opening the html?

I have about 90 plots, 300 points each and it takes about 2-4 minutes.

Here is some code which already does anythoing apart from linking the histograms and making them selectable.

Thanks, Tom

def init(self,xlsmPath):
#…
self.plotAll()

tabs =

p = layout.gridplot(self.__plots,ncols=4)

stat = layout.gridplot(self.__statPlots,ncols=4)

w = layout.WidgetBox(self.carSelect)

columns =

for i in range (1,self.__FirstColumn+self.__MaxNumParam):

columns.append(TableColumn(field=self.__desc[1,i], title=self.__desc[1,i]))

data_table = layout.WidgetBox(DataTable(source=self.view, columns=columns,width=5000, height=5000, sortable=True,scroll_to_selection=True))

tabs.append(Panel(child=p,title = ‘All’))

for i in range(0,self.__MaxNumParam):

collayout=layout.gridplot(self.__columnPlots[i],ncols=1)

tabs.append(Panel(child=collayout, title = (self.__desc[1,self.__FirstColumn+i])))

tabs.append(Panel(child=stat,title = ‘Statistics’))

tabs.append(Panel(child=data_table,title = ‘Result Table’))

tabs = Tabs(tabs=tabs,width=1000)

q=layout.layout([[w],[tabs]])

show(q)

def plotAll(self):

self.carRange = ColumnDataSource()

self.colNames = ColumnDataSource()

index=0

for elem in self.__carData:

self.rowArea(index) # now begin and end should be set

self.carRange.add([self.__begin,self.__end], name=str(elem[0]))

self.carmenu.append(elem[0])

index+=1

self.colNames.add([self.__MaxNumParam], name=‘length’)

index = 0

for i in range(0,self.__MaxNumParam):

self.colNames.add((self.__desc[1,self.__FirstColumn+i]), name=str(i))

index+=1

hover = HoverTool(

tooltips=[

(“index”, “$index”),

("(x,y)", “($x, $y)”),

])

TOOLS = “box_select,lasso_select,tap,wheel_zoom,reset,hover”

self.datadict = dict()

for i in range(1,self.__FirstColumn+self.__MaxNumParam):

self.datadict[(self.__desc[1,i])]=self.__data[:,i][0:self.__MaxNumRows]

self.source= ColumnDataSource(data=self.datadict)

self.view = ColumnDataSource(data=self.datadict)

index=0

for i in range(0,self.__MaxNumParam):

for j in range(i+1,self.__MaxNumParam):

self.__plots.append(figure(tools=TOOLS,plot_width=400, plot_height=400,

title=None, toolbar_location=“below”,webgl=True,name=‘circle’+str(i*j)))

self.__plots[index].scatter((self.__desc[1,self.__FirstColumn+i]),(self.__desc[1,self.__FirstColumn+j]),source=self.view)

self.__plots[index].xaxis.axis_label = (self.__desc[1,self.__FirstColumn+i])

self.__plots[index].yaxis.axis_label = (self.__desc[1,self.__FirstColumn+j])

hover = self.__plots[index].select(dict(type=HoverTool))

hover.tooltips = [

(“index”, “$index”),

("(x,y)", “($x, $y)”),

]

#select_tool = self.__plots[index].select(dict(type=BoxSelectTool))

p=self.__plots[index]

self.view.callback = CustomJS(args=dict(p=p,source=self.view), code="""

var inds = cb_obj.get(‘selected’)[‘1d’].indices;

var d1 = cb_obj.get(‘data’);

var text = ‘’;

var datatext = ‘’;

for (i = 0; i < inds.length; i++) {

text = text.concat(inds[i]+’||’);

datatext = datatext.concat(‘Point ‘+inds[i]+’ ||’);

}

“”"

)

index+=1

self.__columnPlots.append()

colindex = 0

for k in range(0,self.__MaxNumParam):

if i != k:

self.__columnPlots[i].append(figure(tools=TOOLS,plot_width=900, plot_height=400,

title=None, toolbar_location=“below”,webgl=True,name=‘test’+str(i*k)))

self.__columnPlots[i][colindex].scatter((self.__desc[1,self.__FirstColumn+i]),(self.__desc[1,self.__FirstColumn+k]),source=self.view)

self.__columnPlots[i][colindex].xaxis.axis_label = (self.__desc[1,self.__FirstColumn+i])

self.__columnPlots[i][colindex].yaxis.axis_label = (self.__desc[1,self.__FirstColumn+k])

hover = self.__columnPlots[i][colindex].select(dict(type=HoverTool))

hover.tooltips = [

(“index”, “$index”),

("(x,y)", “($x, $y)”),

]

colindex += 1

#TODO statistics (now its time for some Barcharts)

for i in range(2,self.__FirstColumn):

self.__statPlots.append(Histogram(self.datadict[self.__desc[1,i]], title=self.__desc[1,i]))

self.__statPlots[i-2].xaxis.axis_label = (self.__desc[1,i])

self.__statPlots[i-2].add_tools(bokeh.models.TapTool())

self.carSelect = Select(title=“Choose Car:”, options=self.carmenu)

self.carSelect.callback = CustomJS(args=dict(rangeData=self.carRange,source=self.source,view=self.view,colNames=self.colNames), code="""

var select = cb_obj.get(‘value’);

var viewData = view.get(‘data’);

var sourceData = source.get(‘data’);

var colNameData = colNames.get(‘data’);

var range = rangeData.get(‘data’)[select];

var numCols = parseInt(colNameData[‘length’]);

for (i = 0; i < numCols; i++) {

viewData[colNameData[i.toString()]]=sourceData[colNameData[i.toString()]].slice(range[0],range[1]);

}

view.trigger(‘change’);

“”"

)

print 'Number of plots: ',

print index

``

I’m guessing you’re going to
have the best luck by not using the high level Histogram feature, but b y using the plotting API
with HBar and VBar.

That means doing your own histo gram calculation which
is annoying, but the high level Charts interface is real ly designed for
quick exploration and not for more
custom ized
interactives.

Sincerely,

                                      Sarah

Bird

···

On 9/7/16 9:02 AM, wrote:

[email protected]

Hi,

      I'm looking for a way to make the bars in a histogram

selectable and link them to a data source.

What I want to do is the following:

        I have a lot of different plots all on the same Data

Source, so all are linked.

I also have a DataTable linked to the same source.

        Inside that source there are a lot of columns with binary

values which are not plotted.

        Those collumns should be presented in a Histogram. If one

bar of the Histogram is pressed all points that for example
have value ‘1’ in that column should get selected in all
plots as well as the Data Table.

And does anyone know a way to speed up opening the html?

      I have about 90 plots, 300 points each and it takes about

2-4 minutes.

      Here is some code which already does anythoing apart from

linking the histograms and making them selectable.

Thanks, Tom

                def

init(self,xlsmPath):

                        #....

                        self.plotAll()

tabs =

                p =

layout.gridplot(self.__plots,ncols=4)

                stat =

layout.gridplot(self.__statPlots,ncols=4)

                w =

layout.WidgetBox(self.carSelect)

columns =

                for i in range

(1,self.__FirstColumn+self.__MaxNumParam):

                columns.append(TableColumn(field=self.__desc[1,i],

title=self.__desc[1,i]))

                data_table =

layout.WidgetBox(DataTable(source=self.view,
columns=columns,width=5000, height=5000,
sortable=True,scroll_to_selection=True))

tabs.append(Panel(child=p,title = ‘All’))

                for i in

range(0,self.__MaxNumParam):

collayout=layout.gridplot(self.__columnPlots[i],ncols=1)

                tabs.append(Panel(child=collayout, title =

(self.__desc[1,self.__FirstColumn+i])))

tabs.append(Panel(child=stat,title = ‘Statistics’))

                tabs.append(Panel(child=data_table,title = 'Result

Table’))

                tabs =

Tabs(tabs=tabs,width=1000)

q=layout.layout([[w],[tabs]])

show(q)

def plotAll(self):

                self.carRange =

ColumnDataSource()

                self.colNames =

ColumnDataSource()

index=0

                for elem in

self.__carData:

                self.rowArea(index) # now begin and end should be

set

                self.carRange.add([self.__begin,self.__end],

name=str(elem[0]))

self.carmenu.append(elem[0])

index+=1

                self.colNames.add([self.__MaxNumParam],

name=‘length’)

index = 0

                for i in

range(0,self.__MaxNumParam):

                self.colNames.add((self.__desc[1,self.__FirstColumn+i]),

name=str(i))

index+=1

hover = HoverTool(

tooltips=[

                ("index",

“$index”),

                ("(x,y)",

“($x, $y)”),

])

                TOOLS =

“box_select,lasso_select,tap,wheel_zoom,reset,hover”

                self.datadict =

dict()

                for i in

range(1,self.__FirstColumn+self.__MaxNumParam):

self.datadict[(self.__desc[1,i])]=self.__data[:,i][0:self.__MaxNumRows]

                self.source=

ColumnDataSource(data=self.datadict)

                self.view =

ColumnDataSource(data=self.datadict)

index=0

                for i in

range(0,self.__MaxNumParam):

                for j in

range(i+1,self.__MaxNumParam):

                self.__plots.append(figure(tools=TOOLS,plot_width=400,

plot_height=400,

                title=None,

toolbar_location=“below”,webgl=True,name=‘circle’+str(i*j)))

self.__plots[index].scatter((self.__desc[1,self.__FirstColumn+i]),(self.__desc[1,self.__FirstColumn+j]),source=self.view)

                self.__plots[index].xaxis.axis_label =

(self.__desc[1,self.__FirstColumn+i])

                self.__plots[index].yaxis.axis_label =

(self.__desc[1,self.__FirstColumn+j])

                hover =

self.__plots[index].select(dict(type=HoverTool))

hover.tooltips = [

(“index”, “$index”),

("(x,y)", “($x, $y)”),

]

                #select_tool =

self.__plots[index].select(dict(type=BoxSelectTool))

p=self.__plots[index]

                self.view.callback =

CustomJS(args=dict(p=p,source=self.view), code="""

var inds = cb_obj.get(‘selected’)[‘1d’].indices;

var d1 = cb_obj.get(‘data’);

var text = ‘’;

var datatext = ‘’;

for (i = 0; i < inds.length; i++) {

text = text.concat(inds[i]+’||’);

                datatext = datatext.concat('Point '+inds[i]+'

||’);

}

“”"

)

index+=1

self.__columnPlots.append()

colindex = 0

                for k in

range(0,self.__MaxNumParam):

if i != k:

                self.__columnPlots[i].append(figure(tools=TOOLS,plot_width=900,

plot_height=400,

                title=None,

toolbar_location=“below”,webgl=True,name=‘test’+str(i*k)))

self.__columnPlots[i][colindex].scatter((self.__desc[1,self.__FirstColumn+i]),(self.__desc[1,self.__FirstColumn+k]),source=self.view)

                self.__columnPlots[i][colindex].xaxis.axis_label =

(self.__desc[1,self.__FirstColumn+i])

                self.__columnPlots[i][colindex].yaxis.axis_label =

(self.__desc[1,self.__FirstColumn+k])

                hover

=
self.__columnPlots[i][colindex].select(dict(type=HoverTool))

hover.tooltips = [

(“index”, “$index”),

("(x,y)", “($x, $y)”),

]

colindex += 1

                #TODO statistics

(now its time for some Barcharts)

                for i in

range(2,self.__FirstColumn):

                self.__statPlots.append(Histogram(self.datadict[self.__desc[1,i]],

title=self.__desc[1,i]))

                self.__statPlots[i-2].xaxis.axis_label =

(self.__desc[1,i])

self.__statPlots[i-2].add_tools(bokeh.models.TapTool())

                self.carSelect =

Select(title=“Choose Car:”, options=self.carmenu)

                self.carSelect.callback =

CustomJS(args=dict(rangeData=self.carRange,source=self.source,view=self.view,colNames=self.colNames),
code="""

var select = cb_obj.get(‘value’);

var viewData = view.get(‘data’);

var sourceData = source.get(‘data’);

var colNameData = colNames.get(‘data’);

var range = rangeData.get(‘data’)[select];

var numCols = parseInt(colNameData[‘length’]);

for (i = 0; i < numCols; i++) {

viewData[colNameData[i.toString()]]=sourceData[colNameData[i.toString()]].slice(range[0],range[1]);

}

view.trigger(‘change’);

“”"

)

                print 'Number of

plots: ',

print index

``

  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/38283eaf-9838-4b78-80e7-2ed1bcd8df43%40continuum.io](https://groups.google.com/a/continuum.io/d/msgid/bokeh/38283eaf-9838-4b78-80e7-2ed1bcd8df43%40continuum.io?utm_medium=email&utm_source=footer).

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


Sarah Bird
Developer, Bokeh

    [
      ![Continuum Analytics](http://docs.continuum.io/_static/img/ContinuumWordmark.png)
    ](http://continuum.io)

Thanks for the quick reply.
I’ll do it that way then.

Best,

Tom

···

Am Mittwoch, 7. September 2016 22:18:59 UTC+2 schrieb Sarah Bird:

I’m guessing you’re going to
have the best luck by not using the high level Histogram feature, but b y using the plotting API
with HBar and VBar.

That means doing your own histo gram calculation which
is annoying, but the high level Charts interface is real ly designed for
quick exploration and not for more
custom ized
interactives.

Sincerely,

                                      Sarah

Bird

On 9/7/16 9:02 AM, [email protected] > wrote:

Hi,

      I'm looking for a way to make the bars in a histogram

selectable and link them to a data source.

What I want to do is the following:

        I have a lot of different plots all on the same Data

Source, so all are linked.

I also have a DataTable linked to the same source.

        Inside that source there are a lot of columns with binary

values which are not plotted.

        Those collumns should be presented in a Histogram. If one

bar of the Histogram is pressed all points that for example
have value ‘1’ in that column should get selected in all
plots as well as the Data Table.

And does anyone know a way to speed up opening the html?

      I have about 90 plots, 300 points each and it takes about

2-4 minutes.

      Here is some code which already does anythoing apart from

linking the histograms and making them selectable.

Thanks, Tom

                def

init(self,xlsmPath):

                        #....

                        self.plotAll()

tabs =

                p =

layout.gridplot(self.__plots,ncols=4)

                stat =

layout.gridplot(self.__statPlots,ncols=4)

                w =

layout.WidgetBox(self.carSelect)

columns =

                for i in range

(1,self.__FirstColumn+self.__MaxNumParam):

columns.append(TableColumn( field=self.__desc[1,i],
title=self.__desc[1,i]))

                data_table =

layout.WidgetBox(DataTable( source=self.view,
columns=columns,width=5000, height=5000,
sortable=True,scroll_to_selection=True))

tabs.append(Panel(child=p,title = ‘All’))

                for i in

range(0,self.__MaxNumParam):

collayout=layout.gridplot(self.__columnPlots[i],ncols=1)

tabs.append(Panel(child= collayout, title =
(self.__desc[1,self.__FirstColumn+i])))

tabs.append(Panel(child=stat, title = ‘Statistics’))

tabs.append(Panel(child=data_ table,title = ‘Result
Table’))

                tabs =

Tabs(tabs=tabs,width=1000)

q=layout.layout([[w],[tabs]])

show(q)

def plotAll(self):

                self.carRange =

ColumnDataSource()

                self.colNames =

ColumnDataSource()

index=0

                for elem in

self.__carData:

                self.rowArea(index) # now begin and end should be

set

self.carRange.add([self.__ begin,self.__end],
name=str(elem[0]))

self.carmenu.append(elem[0])

index+=1

self.colNames.add([self.__ MaxNumParam],
name=‘length’)

index = 0

                for i in

range(0,self.__MaxNumParam):

self.colNames.add((self.__ desc[1,self.__FirstColumn+i]),
name=str(i))

index+=1

hover = HoverTool(

tooltips=[

                ("index",

“$index”),

                ("(x,y)",

“($x, $y)”),

])

                TOOLS =

“box_select,lasso_select,tap,wheel_zoom,reset,hover”

                self.datadict =

dict()

                for i in

range(1,self.__FirstColumn+self.__MaxNumParam):

self.datadict[(self.__desc[1,i])]=self.__data[:,i][0:self.__MaxNumRows]

                self.source=

ColumnDataSource(data=self.datadict)

                self.view =

ColumnDataSource(data=self.datadict)

index=0

                for i in

range(0,self.__MaxNumParam):

                for j in

range(i+1,self.__MaxNumParam):

self.__plots.append(figure( tools=TOOLS,plot_width=400,
plot_height=400,

                title=None,

toolbar_location=“below”,webgl=True,name=‘circle’+str(i*j)))

self.__plots[index].scatter((self.__desc[1,self.__FirstColumn+i]),(self.__desc[1,self.__FirstColumn+j]),source=self.view)

self.__plots[index].xaxis. axis_label =
(self.desc[1,self. FirstColumn+i])

self.__plots[index].yaxis. axis_label =
(self.desc[1,self. FirstColumn+j])

                hover =

self.__plots[index].select(dict(type=HoverTool))

hover.tooltips = [

(“index”, “$index”),

("(x,y)", “($x, $y)”),

]

                #select_tool =

self.__plots[index].select(dict(type=BoxSelectTool))

p=self.__plots[index]

                self.view.callback =

CustomJS(args=dict(p=p,source=self.view), code="""

var inds = cb_obj.get(‘selected’)[‘1d’].indices;

var d1 = cb_obj.get(‘data’);

var text = ‘’;

var datatext = ‘’;

for (i = 0; i < inds.length; i++) {

text = text.concat(inds[i]+’||’);

                datatext = datatext.concat('Point '+inds[i]+'

');

}

“”"

)

index+=1

self.__columnPlots.append()

colindex = 0

                for k in

range(0,self.__MaxNumParam):

if i != k:

self.__columnPlots[i].append(figure(tools=TOOLS,plot_width= 900,
plot_height=400,

                title=None,

toolbar_location=“below”,webgl=True,name=‘test’+str(i*k)))

self.__columnPlots[i][colindex].scatter((self.__desc[1,self.__FirstColumn+i]),(self.__desc[1,self.__FirstColumn+k]),source=self.view)

self.__columnPlots[i][ colindex].xaxis.axis_label =
(self.__desc[1,self.__FirstColumn+i])

self.__columnPlots[i][ colindex].yaxis.axis_label =
(self.__desc[1,self.__FirstColumn+k])

                hover

=
self.__columnPlots[i][colindex].select(dict(type=HoverTool))

hover.tooltips = [

(“index”, “$index”),

("(x,y)", “($x, $y)”),

]

colindex += 1

                #TODO statistics

(now its time for some Barcharts)

                for i in

range(2,self.__FirstColumn):

self._statPlots.append(Histogram(self.datadict[self. _desc[1,i]],
title=self.__desc[1,i]))

self.__statPlots[i-2].xaxis. axis_label =
(self.__desc[1,i])

self.__statPlots[i-2].add_tools(bokeh.models.TapTool())

                self.carSelect =

Select(title=“Choose Car:”, options=self.carmenu)

self.carSelect.callback =
CustomJS(args=dict(rangeData=self.carRange,source=self.source,view=self.view, colNames=self.colNames),
code="""

var select = cb_obj.get(‘value’);

var viewData = view.get(‘data’);

var sourceData = source.get(‘data’);

var colNameData = colNames.get(‘data’);

var range = rangeData.get(‘data’)[select];

var numCols = parseInt(colNameData[‘length’]);

for (i = 0; i < numCols; i++) {

viewData[colNameData[i.toString()]]=sourceData[colNameData[i.toString()]].slice(range[0],range[1]);

}

view.trigger(‘change’);

“”"

)

                print 'Number of

plots: ',

print index

``

  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/38283eaf-9838-4b78-80e7-2ed1bcd8df43%40continuum.io](https://groups.google.com/a/continuum.io/d/msgid/bokeh/38283eaf-9838-4b78-80e7-2ed1bcd8df43%40continuum.io?utm_medium=email&utm_source=footer).

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


Sarah Bird
Developer, Bokeh

    [
      <img alt="Continuum Analytics" src="https://lh6.googleusercontent.com/proxy/VYgVjggTk1hCXSN9wFkffE3I6kxTvJ51tT4KvDXOuKbs1WyFG66k7kt2-vkDimbyxfWtP-d1paJmstMYhPPnDYSUF4rLPoYM2GM2QFM=w5000-h5000" style="width:150px;min-height:30px" height="30px" width="150px">
    ](http://continuum.io)