Python Bokeh server ColumnDataSource for multiple sliders - attribute "value" unknown

Hi, I was working through the gapminder data set (I used this *.csv file as is, with no changes). I wish to have sliders for the year, life, population and income columns, to select minimum value for each. Also, I require a selection menu to choose x and y from any of year, life, population and income columns of the dataset.

I took the IMDB Bokeh Gallery and I have modified the main.py source code as below:

from bokeh.plotting import figure
from bokeh.layouts import layout, widgetbox
from bokeh.models import ColumnDataSource
from bokeh.io import curdoc
from bokeh.models.widgets import Slider, Select
import pandas as pd

dfr = pd.read_csv('gapminder.csv',thousands=',')

axis_map = {"Pop":"population", "Life":"life", "Inc":"income", "Year":"Year"}

life = Slider(title='Li',value=0,start=0,end=40)
inc = Slider(title='In',value=0,start=0,end=10000)
pop = Slider(title='Po',value=0,start=1,end=100000)
year = Slider(title='Ye',value=0,start=5,end=100)
x_axis = Select(title="X Axis", options=sorted(axis_map.keys()), value="Inc")
y_axis = Select(title="Y Axis", options=sorted(axis_map.keys()), value="Pop")

s = ColumnDataSource(data=dict(x=[], y=[], lif=[], incm=[], popul=[], yr=[]))
 
p = figure(title="", toolbar_location='above', title_location='left', tools=[h])
p.circle(x='x', y='y', source=s, legend='region')
p.legend.border_line_color=None; p.legend.location=(0,0); p.right.append(p.legend[0])

def selected():
    data = dfr[(dfr['life']>=life.value) & (dfr['income']>=inc.value) &\
        (dfr['population']>=pop.value) & (dfr['Year']>=year.value)]
    return data

def update():
    data = selected()
    x_name = axis_map[x_axis.value];  y_name = axis_map[y_axis.value]
    p.xaxis.axis_label = x_axis.value;  p.yaxis.axis_label = y_axis.value

    s.data = dict(x=df[x_name], y=df[y_name],
        lif=df["life"], incm=df["income"],
        popul=df["population"], yr=df["Year"])

controls = [life,inc,pop,year]
for c in controls:
    c.on_change('value', lambda attr, old, new: update())

sizing_mode = 'fixed'
inputs = widgetbox(*controls, sizing_mode=sizing_mode)
l = layout([
    [inputs, p],
    ], sizing_mode=sizing_mode)    
update()    
curdoc().add_root(l)
curdoc().title = y_axis.value

``

Running this script, gives this output:

Traceback (most recent call last):
  File "/home/userD/test.py", line 55, in <module>
    update()
  File "/home/userD/test.py", line 36, in update
    df = selected()
  File "/home/userD/test.py", line 32, in selected
    df = dfr[(dfr['life']>=l.value) & (dfr['income']>=i.value) &\
        (dfr['population']>=po.value) & (dfr['Year']>=ye.value)]
AttributeError: 'Column' object has no attribute 'value'

``

This seems to suggest there is a problem with the data source. All the columns in the variable source have sliders and so I specified all the columns in update() and selected(). However, I am not sure if I have implemented the ColumnDataSource() correctly. Should the columns not be placed in a dict? From going through the code, this seems like it could be the problem with this code and the unknown attribute.

Is there something specific about the value attribute in the Bokeh movies main.py script? Or is my source not defined correctly?

I re-ran this script on Windows 7 and the same error occurred. It seems it has something to do with the code itself and I think it is how the column data source is defined.

I have attached here an image showing what I am looking for in the slider layout for this dataset.

Any help would be greatly appreciated. If you require any further info, please let me know.

···

On Thursday, May 18, 2017 at 9:27:59 AM UTC-4, ElD wrote:

Hi, I was working through the gapminder data set (I used this *.csv file as is, with no changes). I wish to have sliders for the year, life, population and income columns, to select minimum value for each. Also, I require a selection menu to choose x and y from any of year, life, population and income columns of the dataset.

I took the IMDB Bokeh Gallery and I have modified the main.py source code as below:

from bokeh.plotting import figure
from bokeh.layouts import layout, widgetbox
from bokeh.models import ColumnDataSource
from bokeh.io import curdoc
from bokeh.models.widgets import Slider, Select
import pandas as pd

dfr = pd.read_csv('gapminder.csv',thousands=',')

axis_map = {"Pop":"population", "Life":"life", "Inc":"income", "Year":"Year"}

life = Slider(title='Li',value=0,start=0,end=40)
inc = Slider(title='In',value=0,start=0,end=10000)
pop = Slider(title='Po',value=0,start=1,end=100000)
year = Slider(title='Ye',value=0,start=5,end=100)
x_axis = Select(title="X Axis", options=sorted(axis_map.keys()), value="Inc")
y_axis = Select(title="Y Axis", options=sorted(axis_map.keys()), value="Pop")

s = ColumnDataSource(data=dict(x=[], y=[], lif=[], incm=[], popul=[], yr=[]))
 
p = figure(title="", toolbar_location='above', title_location='left', tools=[h])
p.circle(x='x', y='y', source=s, legend='region')
p.legend.border_line_color=None; p.legend.location=(0,0); p.right.append(p.legend[0])

def selected():
    data = dfr[(dfr['life']>=life.value) & (dfr['income']>=inc.value) &\
        (dfr['population']>=pop.value) & (dfr['Year']>=year.value)]
    return data

def update():
    data = selected()
    x_name = axis_map[x_axis.value];  y_name = axis_map[y_axis.value]
    p.xaxis.axis_label = x_axis.value;  p.yaxis.axis_label = y_axis.value

    s.data = dict(x=df[x_name], y=df[y_name],
        lif=df["life"], incm=df["income"],
        popul=df["population"], yr=df["Year"])

controls = [life,inc,pop,year]
for c in controls:
    c.on_change('value', lambda attr, old, new: update())

sizing_mode = 'fixed'
inputs = widgetbox(*controls, sizing_mode=sizing_mode)
l = layout([
    [inputs, p],
    ], sizing_mode=sizing_mode)    
update()    
curdoc().add_root(l)
curdoc().title = y_axis.value

``

Running this script, gives this output:

Traceback (most recent call last):
  File "/home/userD/test.py", line 55, in <module>
    update()
  File "/home/userD/test.py", line 36, in update
    df = selected()
  File "/home/userD/test.py", line 32, in selected
    df = dfr[(dfr['life']>=l.value) & (dfr['income']>=i.value) &\
        (dfr['population']>=po.value) & (dfr['Year']>=ye.value)]
AttributeError: 'Column' object has no attribute 'value'

``

This seems to suggest there is a problem with the data source. All the columns in the variable source have sliders and so I specified all the columns in update() and selected(). However, I am not sure if I have implemented the ColumnDataSource() correctly. Should the columns not be placed in a dict? From going through the code, this seems like it could be the problem with this code and the unknown attribute.

Is there something specific about the value attribute in the Bokeh movies main.py script? Or is my source not defined correctly?

There are several things wrong with the code you posted:

* df is undefined in the update function (assume you meant "data")

* the "h" tool is undefined

If I fix those things, the example works, i.e. the plot updates in response to the sliders. I'm not able to reproduce the error you show.

However, even moving all the sliders to the right, ~4k points still remain so there's not a lot of change in the plot. Also there is no built in throttling yet on bokeh server sliders, so the updates queue up and this makes it a bit sluggish. You might want to search here or StackOverlow for a workaround solution to throttle bokeh app sliders (sorry its late, I have to sleep or I'd dig it up) or increase the slider increment to reduce undesirable queueing.

Thanks,

Bryan

···

On May 18, 2017, at 22:54, ElD <[email protected]> wrote:

I re-ran this script on Windows 7 and the same error occurred. It seems it has something to do with the code itself and I think it is how the column data source is defined.

I have attached here an image showing what I am looking for in the slider layout for this dataset.

Any help would be greatly appreciated. If you require any further info, please let me know.

On Thursday, May 18, 2017 at 9:27:59 AM UTC-4, ElD wrote:
Hi, I was working through the gapminder data set (I used this *.csv file as is, with no changes). I wish to have sliders for the year, life, population and income columns, to select minimum value for each. Also, I require a selection menu to choose x and y from any of year, life, population and incomecolumns of the dataset.

I took the IMDB Bokeh Gallery and I have modified the main.py source code as below:

    from bokeh.plotting import figure
    from bokeh.layouts import layout, widgetbox
    from bokeh.models import ColumnDataSource
    from bokeh.io import curdoc
    from bokeh.models.widgets import Slider, Select
    import pandas as pd

    dfr = pd.read_csv('gapminder.csv',thousands=',')

    axis_map = {"Pop":"population", "Life":"life", "Inc":"income", "Year":"Year"}
    
    life = Slider(title='Li',value=0,start=0,end=40)
    inc = Slider(title='In',value=0,start=0,end=10000)
    pop = Slider(title='Po',value=0,start=1,end=100000)
    year = Slider(title='Ye',value=0,start=5,end=100)
    x_axis = Select(title="X Axis", options=sorted(axis_map.keys()), value="Inc")
    y_axis = Select(title="Y Axis", options=sorted(axis_map.keys()), value="Pop")
    
    s = ColumnDataSource(data=dict(x=, y=, lif=, incm=, popul=, yr=))
     
    p = figure(title="", toolbar_location='above', title_location='left', tools=[h])
    p.circle(x='x', y='y', source=s, legend='region')
    p.legend.border_line_color=None; p.legend.location=(0,0); p.right.append(p.legend[0])
    
    def selected():
        data = dfr[(dfr['life']>=life.value) & (dfr['income']>=inc.value) &\
            (dfr['population']>=pop.value) & (dfr['Year']>=year.value)]
        return data
    
    def update():
        data = selected()
        x_name = axis_map[x_axis.value]; y_name = axis_map[y_axis.value]
        p.xaxis.axis_label = x_axis.value; p.yaxis.axis_label = y_axis.value
    
        s.data = dict(x=df[x_name], y=df[y_name],
            lif=df["life"], incm=df["income"],
            popul=df["population"], yr=df["Year"])
    
    controls = [life,inc,pop,year]
    for c in controls:
        c.on_change('value', lambda attr, old, new: update())
    
    sizing_mode = 'fixed'
    inputs = widgetbox(*controls, sizing_mode=sizing_mode)
    l = layout([
        [inputs, p],
        ], sizing_mode=sizing_mode)
    update()
    curdoc().add_root(l)
    curdoc().title = y_axis.value

Running this script, gives this output:

    Traceback (most recent call last):
      File "/home/userD/test.py", line 55, in <module>
        update()
      File "/home/userD/test.py", line 36, in update
        df = selected()
      File "/home/userD/test.py", line 32, in selected
        df = dfr[(dfr['life']>=l.value) & (dfr['income']>=i.value) &\
            (dfr['population']>=po.value) & (dfr['Year']>=ye.value)]
    AttributeError: 'Column' object has no attribute 'value'

This seems to suggest there is a problem with the data source. All the columns in the variable `source` have sliders and so I specified all the columns in `update()` and `selected()`. However, I am not sure if I have implemented the ColumnDataSource() correctly. Should the columns not be placed in a dict? From going through the code, this seems like it could be the problem with this code and the unknown attribute.

Is there something specific about the value attribute in the Bokeh movies main.py script? Or is my source not defined correctly?

--
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/0c1c59f8-d745-45de-b1ef-9c3408d65f10%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
<output_wanted_gap.png>

Hi Brian,

Many thanks! I took your suggestions and I got it to work as well. That is great! Apologies for the missed coding errors. Ok thanks about the throttling issue. I will look it up on SO.

I noticed that the 2 dropdown menus - to select x and y - are completely missing. Did you also see this?

Also, the line:

curdoc().title = y_axis.value

``

assigns the correct plot title Pop in this case. However, when I try to change the legend location to:

p.legend.location=(0,0.5*y_axis.end)

``

it does not work (running bokeh serve … displays a blank webpage). I am trying to center the legend based on the adjustable y_axis value. Is there a way to position the legend when the y_axis is flexible, like it is here?

···

On Friday, May 19, 2017 at 1:13:48 AM UTC-4, Bryan Van de ven wrote:

There are several things wrong with the code you posted:

  • df is undefined in the update function (assume you meant “data”)

  • the “h” tool is undefined

If I fix those things, the example works, i.e. the plot updates in response to the sliders. I’m not able to reproduce the error you show.

However, even moving all the sliders to the right, ~4k points still remain so there’s not a lot of change in the plot. Also there is no built in throttling yet on bokeh server sliders, so the updates queue up and this makes it a bit sluggish. You might want to search here or StackOverlow for a workaround solution to throttle bokeh app sliders (sorry its late, I have to sleep or I’d dig it up) or increase the slider increment to reduce undesirable queueing.

Thanks,

Bryan

On May 18, 2017, at 22:54, ElD [email protected] wrote:

I re-ran this script on Windows 7 and the same error occurred. It seems it has something to do with the code itself and I think it is how the column data source is defined.

I have attached here an image showing what I am looking for in the slider layout for this dataset.

Any help would be greatly appreciated. If you require any further info, please let me know.

On Thursday, May 18, 2017 at 9:27:59 AM UTC-4, ElD wrote:

Hi, I was working through the gapminder data set (I used this *.csv file as is, with no changes). I wish to have sliders for the year, life, population and income columns, to select minimum value for each. Also, I require a selection menu to choose x and y from any of year, life, population and incomecolumns of the dataset.

I took the IMDB Bokeh Gallery and I have modified the main.py source code as below:

from bokeh.plotting import figure
from bokeh.layouts import layout, widgetbox
from bokeh.models import ColumnDataSource
from [bokeh.io](http://bokeh.io) import curdoc
from bokeh.models.widgets import Slider, Select
import pandas as pd
dfr = pd.read_csv('gapminder.csv',thousands=',')
axis_map = {"Pop":"population", "Life":"life", "Inc":"income", "Year":"Year"}
life = Slider(title='Li',value=0,start=0,end=40)
inc = Slider(title='In',value=0,start=0,end=10000)
pop = Slider(title='Po',value=0,start=1,end=100000)
year = Slider(title='Ye',value=0,start=5,end=100)
x_axis = Select(title="X Axis", options=sorted(axis_map.keys()), value="Inc")
y_axis = Select(title="Y Axis", options=sorted(axis_map.keys()), value="Pop")
s = ColumnDataSource(data=dict(x=[], y=[], lif=[], incm=[], popul=[], yr=[]))
p = figure(title="", toolbar_location='above', title_location='left', tools=[h])
p.circle(x='x', y='y', source=s, legend='region')
p.legend.border_line_color=None; p.legend.location=(0,0); p.right.append(p.legend[0])
def selected():
    data = dfr[(dfr['life']>=life.value) & (dfr['income']>=inc.value) &\
        (dfr['population']>=pop.value) & (dfr['Year']>=year.value)]
    return data
def update():
    data = selected()
    x_name = axis_map[x_axis.value];  y_name = axis_map[y_axis.value]
    p.xaxis.axis_label = x_axis.value;  p.yaxis.axis_label = y_axis.value
    s.data = dict(x=df[x_name], y=df[y_name],
        lif=df["life"], incm=df["income"],
        popul=df["population"], yr=df["Year"])
controls = [life,inc,pop,year]
for c in controls:
    c.on_change('value', lambda attr, old, new: update())
sizing_mode = 'fixed'
inputs = widgetbox(*controls, sizing_mode=sizing_mode)
l = layout([
    [inputs, p],
    ], sizing_mode=sizing_mode)    
update()    
curdoc().add_root(l)
curdoc().title = y_axis.value

Running this script, gives this output:

Traceback (most recent call last):
  File "/home/userD/test.py", line 55, in <module>
    update()
  File "/home/userD/test.py", line 36, in update
    df = selected()
  File "/home/userD/test.py", line 32, in selected
    df = dfr[(dfr['life']>=l.value) & (dfr['income']>=i.value) &\
        (dfr['population']>=po.value) & (dfr['Year']>=ye.value)]
AttributeError: 'Column' object has no attribute 'value'

This seems to suggest there is a problem with the data source. All the columns in the variable source have sliders and so I specified all the columns in update() and selected(). However, I am not sure if I have implemented the ColumnDataSource() correctly. Should the columns not be placed in a dict? From going through the code, this seems like it could be the problem with this code and the unknown attribute.

Is there something specific about the value attribute in the Bokeh movies main.py script? Or is my source not defined correctly?


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/0c1c59f8-d745-45de-b1ef-9c3408d65f10%40continuum.io.

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

<output_wanted_gap.png>

Hi,

The x and y selects don't appear because you aren't ever putting them in a layout passed to add_root, as far as I can tell.

Outside legend positioning currently has a regression bug, you might be seeing that. If so, see here for a workaround:

  Regression in Legend positioning · Issue #6142 · bokeh/bokeh · GitHub

Thanks,

Bryan

···

On May 19, 2017, at 09:32, ElD <[email protected]> wrote:

Hi Brian,

Many thanks! I took your suggestions and I got it to work as well. That is great! Apologies for the missed coding errors. Ok thanks about the throttling issue. I will look it up on SO.

I noticed that the 2 dropdown menus - to select x and y - are completely missing. Did you also see this?

Also, the line:

curdoc().title = y_axis.value

assigns the correct plot title Pop in this case. However, when I try to change the legend location to:

p.legend.location=(0,0.5*y_axis.end)

it does not work (running bokeh serve ... displays a blank webpage). I am trying to center the legend based on the adjustable y_axis value. Is there a way to position the legend when the y_axis is flexible, like it is here?

On Friday, May 19, 2017 at 1:13:48 AM UTC-4, Bryan Van de ven wrote:
There are several things wrong with the code you posted:

* df is undefined in the update function (assume you meant "data")

* the "h" tool is undefined

If I fix those things, the example works, i.e. the plot updates in response to the sliders. I'm not able to reproduce the error you show.

However, even moving all the sliders to the right, ~4k points still remain so there's not a lot of change in the plot. Also there is no built in throttling yet on bokeh server sliders, so the updates queue up and this makes it a bit sluggish. You might want to search here or StackOverlow for a workaround solution to throttle bokeh app sliders (sorry its late, I have to sleep or I'd dig it up) or increase the slider increment to reduce undesirable queueing.

Thanks,

Bryan

> On May 18, 2017, at 22:54, ElD <[email protected]> wrote:
>
> I re-ran this script on Windows 7 and the same error occurred. It seems it has something to do with the code itself and I think it is how the column data source is defined.
>
> I have attached here an image showing what I am looking for in the slider layout for this dataset.
>
> Any help would be greatly appreciated. If you require any further info, please let me know.
>
>
> On Thursday, May 18, 2017 at 9:27:59 AM UTC-4, ElD wrote:
> Hi, I was working through the gapminder data set (I used this *.csv file as is, with no changes). I wish to have sliders for the year, life, population and income columns, to select minimum value for each. Also, I require a selection menu to choose x and y from any of year, life, population and incomecolumns of the dataset.
>
> I took the IMDB Bokeh Gallery and I have modified the main.py source code as below:
>
> from bokeh.plotting import figure
> from bokeh.layouts import layout, widgetbox
> from bokeh.models import ColumnDataSource
> from bokeh.io import curdoc
> from bokeh.models.widgets import Slider, Select
> import pandas as pd
>
> dfr = pd.read_csv('gapminder.csv',thousands=',')
>
> axis_map = {"Pop":"population", "Life":"life", "Inc":"income", "Year":"Year"}
>
> life = Slider(title='Li',value=0,start=0,end=40)
> inc = Slider(title='In',value=0,start=0,end=10000)
> pop = Slider(title='Po',value=0,start=1,end=100000)
> year = Slider(title='Ye',value=0,start=5,end=100)
> x_axis = Select(title="X Axis", options=sorted(axis_map.keys()), value="Inc")
> y_axis = Select(title="Y Axis", options=sorted(axis_map.keys()), value="Pop")
>
> s = ColumnDataSource(data=dict(x=, y=, lif=, incm=, popul=, yr=))
>
> p = figure(title="", toolbar_location='above', title_location='left', tools=[h])
> p.circle(x='x', y='y', source=s, legend='region')
> p.legend.border_line_color=None; p.legend.location=(0,0); p.right.append(p.legend[0])
>
> def selected():
> data = dfr[(dfr['life']>=life.value) & (dfr['income']>=inc.value) &\
> (dfr['population']>=pop.value) & (dfr['Year']>=year.value)]
> return data
>
> def update():
> data = selected()
> x_name = axis_map[x_axis.value]; y_name = axis_map[y_axis.value]
> p.xaxis.axis_label = x_axis.value; p.yaxis.axis_label = y_axis.value
>
> s.data = dict(x=df[x_name], y=df[y_name],
> lif=df["life"], incm=df["income"],
> popul=df["population"], yr=df["Year"])
>
> controls = [life,inc,pop,year]
> for c in controls:
> c.on_change('value', lambda attr, old, new: update())
>
> sizing_mode = 'fixed'
> inputs = widgetbox(*controls, sizing_mode=sizing_mode)
> l = layout([
> [inputs, p],
> ], sizing_mode=sizing_mode)
> update()
> curdoc().add_root(l)
> curdoc().title = y_axis.value
>
> Running this script, gives this output:
>
> Traceback (most recent call last):
> File "/home/userD/test.py", line 55, in <module>
> update()
> File "/home/userD/test.py", line 36, in update
> df = selected()
> File "/home/userD/test.py", line 32, in selected
> df = dfr[(dfr['life']>=l.value) & (dfr['income']>=i.value) &\
> (dfr['population']>=po.value) & (dfr['Year']>=ye.value)]
> AttributeError: 'Column' object has no attribute 'value'
>
> This seems to suggest there is a problem with the data source. All the columns in the variable `source` have sliders and so I specified all the columns in `update()` and `selected()`. However, I am not sure if I have implemented the ColumnDataSource() correctly. Should the columns not be placed in a dict? From going through the code, this seems like it could be the problem with this code and the unknown attribute.
>
> Is there something specific about the value attribute in the Bokeh movies main.py script? Or is my source not defined correctly?
>
> --
> 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/0c1c59f8-d745-45de-b1ef-9c3408d65f10%40continuum.io\.
> For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
> <output_wanted_gap.png>

--
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/586dcc20-64a8-47e9-b914-f143c45123c6%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.