Struggle to loop CDS and update colors and legends

Hi,

I try to do the following: a simple setup where I can choose data from a MultiSelect: case1, case2 or case1+case2. If only one case is chosen (either case1 or case2) then the glyphs should be navy in color. If both cases are chosen, case1+case2, then case1 should be navy and the other case green.

I am using CDS for the data as I understand this is the most efficient way to update plots. However, I’m not able to loop over the cases in order to get correct legend entry and get correct colors if more than one case have been chosen. Any help appreciated. Thanks.

Kind regards,

Jonas

···

import pandas as pd
from bokeh.plotting import figure
from bokeh.io import curdoc
from bokeh.models import CDSView, GroupFilter, ColumnDataSource
from bokeh.models.widgets import MultiSelect, Select
from bokeh.layouts import row, widgetbox

setup some data

data_df = pd.DataFrame()
x = range(1,6)

for i in range(1,3):
tmp_df = pd.DataFrame(x, columns = [‘x’])
tmp_df[‘y’] = tmp_df.x**i
tmp_df[‘case’] = ‘case’ + str(i)
data_df = data_df.append(tmp_df)

data_df[‘id’] = ‘A’
data_df.loc[data_df.x > 3, ‘id’] = ‘B’

print data_df

def plot_data():
plot = figure(plot_width = 300, plot_height = 300)
plot.min_border_left = 50
plot.title.text = id_select.value

colors = [ ‘navy’, ‘green’]

for i, case in enumerate(global_vals[‘cases’]):
print i, case

loop in order to set legends and line glyph correct - not working…

plot.line(x = ‘x’, y = ‘y’, color = colors[i], line_width = 2, legend = case, source = source)

r_circ = plot.circle(x = ‘x’, y = ‘y’, color = colors[i], size = 4, legend = case, source = source)

return plot

def update_cases():
case = multi_select.value

reset id selector

id = id_select.options[0]
id_select.value = id
df = data_df[(data_df.case.isin(case)) & (data_df.id == id) ]
print df
source.data = ColumnDataSource(df).data

global_vals[‘cases’] = case
print global_vals[‘cases’]

def update_id(attr, old, new):
case = multi_select.value
df = data_df[(data_df.case.isin(case)) & (data_df.id == new) ]

plot.title.text = id_select.value
source.data = ColumnDataSource(df).data

cases = data_df.case.unique().tolist()
id_list = data_df.id.unique().tolist()

source = ColumnDataSource(data_df)

global variable for cases

global_vals = dict( cases = cases)

selectors

multi_select = MultiSelect(
title = ‘Select case(s)’,
value = [str(cases[0])],
options = cases, size = 5)

id_select = Select(title = ‘ID’, value = id_list[0], options = id_list)

multi_select.on_change(‘value’, lambda attr, old, new: update_cases() )
id_select.on_change(‘value’, update_id)

Initial plot

update_cases()
plot = plot_data()

widgets = widgetbox([multi_select, id_select])
layout = row(widgets, plot)

curdoc().add_root(layout)
curdoc().title = “Plot”

Hi,

Somewhere along the line all the formatting (i.e. indentation) has been lost in your message. Please re-post with correct formatting so that the code can be run, or put the code in a gist, or ask on Stack Overflow (https://stackoverflow.com/) which supports the best code formatting options.

Thanks,

Bryan

···

On Oct 16, 2017, at 13:15, Jonas Grave Kristensen <[email protected]> wrote:

Hi,

I try to do the following: a simple setup where I can choose data from a MultiSelect: case1, case2 or case1+case2. If only one case is chosen (either case1 or case2) then the glyphs should be navy in color. If both cases are chosen, case1+case2, then case1 should be navy and the other case green.

I am using CDS for the data as I understand this is the most efficient way to update plots. However, I'm not able to loop over the cases in order to get correct legend entry and get correct colors if more than one case have been chosen. Any help appreciated. Thanks.

Kind regards,
Jonas
----

import pandas as pd
from bokeh.plotting import figure
from bokeh.io import curdoc
from bokeh.models import CDSView, GroupFilter, ColumnDataSource
from bokeh.models.widgets import MultiSelect, Select
from bokeh.layouts import row, widgetbox

# setup some data
data_df = pd.DataFrame()
x = range(1,6)

for i in range(1,3):
tmp_df = pd.DataFrame(x, columns = ['x'])
tmp_df['y'] = tmp_df.x**i
tmp_df['case'] = 'case' + str(i)
data_df = data_df.append(tmp_df)

data_df['id'] = 'A'
data_df.loc[data_df.x > 3, 'id'] = 'B'

print data_df

def plot_data():
plot = figure(plot_width = 300, plot_height = 300)
plot.min_border_left = 50
plot.title.text = id_select.value

colors = [ 'navy', 'green']

for i, case in enumerate(global_vals['cases']):
print i, case
# loop in order to set legends and line glyph correct - not working...
plot.line(x = 'x', y = 'y', color = colors[i], line_width = 2, legend = case, source = source)

r_circ = plot.circle(x = 'x', y = 'y', color = colors[i], size = 4, legend = case, source = source)

return plot

def update_cases():
case = multi_select.value

# reset id selector
id = id_select.options[0]
id_select.value = id
df = data_df[(data_df.case.isin(case)) & (data_df.id == id) ]
print df
source.data = ColumnDataSource(df).data

global_vals['cases'] = case
print global_vals['cases']

def update_id(attr, old, new):
case = multi_select.value
df = data_df[(data_df.case.isin(case)) & (data_df.id == new) ]

plot.title.text = id_select.value
source.data = ColumnDataSource(df).data

cases = data_df.case.unique().tolist()
id_list = data_df.id.unique().tolist()

source = ColumnDataSource(data_df)
# global variable for cases
global_vals = dict( cases = cases)

# selectors
multi_select = MultiSelect(
title = 'Select case(s)',
value = [str(cases[0])],
options = cases, size = 5)

id_select = Select(title = 'ID', value = id_list[0], options = id_list)

multi_select.on_change('value', lambda attr, old, new: update_cases() )
id_select.on_change('value', update_id)

# Initial plot
update_cases()
plot = plot_data()

widgets = widgetbox([multi_select, id_select])
layout = row(widgets, plot)

curdoc().add_root(layout)
curdoc().title = "Plot"
  
--
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/1f686179-6cab-45b6-b546-23f22839ef64%40me.com.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Ok, sorry about that. Lets try again:

import pandas as pd
from bokeh.plotting import figure
from bokeh.io import curdoc
from bokeh.models import CDSView, GroupFilter, ColumnDataSource
from bokeh.models.widgets import MultiSelect, Select
from bokeh.layouts import row, widgetbox

setup some data

data_df = pd.DataFrame()
x = range(1,6)

for i in range(1,3):
tmp_df = pd.DataFrame(x, columns = [‘x’])
tmp_df[‘y’] = tmp_df.x**i
tmp_df[‘case’] = ‘case’ + str(i)
data_df = data_df.append(tmp_df)

data_df[‘id’] = ‘A’
data_df.loc[data_df.x > 3, ‘id’] = ‘B’

print data_df

def plot_data():
plot = figure(plot_width = 300, plot_height = 300)
plot.min_border_left = 50
plot.title.text = id_select.value

colors = [ 'navy', 'green']

for i, case in enumerate(global_vals['cases']):
    print i, case
    # loop in order to set legends and line glyph correct - not working...
    plot.line(x = 'x', y = 'y', color = colors[i], line_width = 2, legend = case, source = source)
   
    r_circ = plot.circle(x = 'x', y = 'y', color = colors[i], size = 4, legend = case, source = source)

return plot

def update_cases():
case = multi_select.value

# reset id selector
id = id_select.options[0]
id_select.value = id
df = data_df[(data_df.case.isin(case)) & (data_df.id == id) ]
print df
source.data = ColumnDataSource(df).data

global_vals['cases'] = case
print global_vals['cases']

def update_id(attr, old, new):
case = multi_select.value
df = data_df[(data_df.case.isin(case)) & (data_df.id == new) ]

plot.title.text = id_select.value
source.data = ColumnDataSource(df).data

cases = data_df.case.unique().tolist()
id_list = data_df.id.unique().tolist()

source = ColumnDataSource(data_df)

global variable for cases

global_vals = dict( cases = cases)

selectors

multi_select = MultiSelect(
title = ‘Select case(s)’,
value = [str(cases[0])],
options = cases, size = 5)

id_select = Select(title = ‘ID’, value = id_list[0], options = id_list)

multi_select.on_change(‘value’, lambda attr, old, new: update_cases() )
id_select.on_change(‘value’, update_id)

Initial plot

update_cases()
plot = plot_data()

widgets = widgetbox([multi_select, id_select])
layout = row(widgets, plot)

curdoc().add_root(layout)
curdoc().title = “Plot”

``

Kind regards,

Jonas

···

Den mandag den 16. oktober 2017 kl. 20.34.25 UTC+2 skrev Bryan Van de ven:

Hi,

Somewhere along the line all the formatting (i.e. indentation) has been lost in your message. Please re-post with correct formatting so that the code can be run, or put the code in a gist, or ask on Stack Overflow (https://stackoverflow.com/) which supports the best code formatting options.

Thanks,

Bryan

On Oct 16, 2017, at 13:15, Jonas Grave Kristensen [email protected] wrote:

Hi,

I try to do the following: a simple setup where I can choose data from a MultiSelect: case1, case2 or case1+case2. If only one case is chosen (either case1 or case2) then the glyphs should be navy in color. If both cases are chosen, case1+case2, then case1 should be navy and the other case green.

I am using CDS for the data as I understand this is the most efficient way to update plots. However, I’m not able to loop over the cases in order to get correct legend entry and get correct colors if more than one case have been chosen. Any help appreciated. Thanks.

Kind regards,

Jonas


import pandas as pd

from bokeh.plotting import figure

from bokeh.io import curdoc

from bokeh.models import CDSView, GroupFilter, ColumnDataSource

from bokeh.models.widgets import MultiSelect, Select

from bokeh.layouts import row, widgetbox

setup some data

data_df = pd.DataFrame()

x = range(1,6)

for i in range(1,3):

tmp_df = pd.DataFrame(x, columns = [‘x’])

tmp_df[‘y’] = tmp_df.x**i

tmp_df[‘case’] = ‘case’ + str(i)

data_df = data_df.append(tmp_df)

data_df[‘id’] = ‘A’

data_df.loc[data_df.x > 3, ‘id’] = ‘B’

print data_df

def plot_data():

plot = figure(plot_width = 300, plot_height = 300)

plot.min_border_left = 50

plot.title.text = id_select.value

colors = [ ‘navy’, ‘green’]

for i, case in enumerate(global_vals[‘cases’]):
print i, case

loop in order to set legends and line glyph correct - not working…

plot.line(x = ‘x’, y = ‘y’, color = colors[i], line_width = 2, legend = case, source = source)

r_circ = plot.circle(x = ‘x’, y = ‘y’, color = colors[i], size = 4, legend = case, source = source)

return plot

def update_cases():

case = multi_select.value

reset id selector

id = id_select.options[0]

id_select.value = id

df = data_df[(data_df.case.isin(case)) & (data_df.id == id) ]

print df

source.data = ColumnDataSource(df).data

global_vals[‘cases’] = case

print global_vals[‘cases’]

def update_id(attr, old, new):
case = multi_select.value

df = data_df[(data_df.case.isin(case)) & (data_df.id == new) ]

plot.title.text = id_select.value

source.data = ColumnDataSource(df).data

cases = data_df.case.unique().tolist()

id_list = data_df.id.unique().tolist()

source = ColumnDataSource(data_df)

global variable for cases

global_vals = dict( cases = cases)

selectors

multi_select = MultiSelect(

title = ‘Select case(s)’,

value = [str(cases[0])],

options = cases, size = 5)

id_select = Select(title = ‘ID’, value = id_list[0], options = id_list)

multi_select.on_change(‘value’, lambda attr, old, new: update_cases() )

id_select.on_change(‘value’, update_id)

Initial plot

update_cases()

plot = plot_data()

widgets = widgetbox([multi_select, id_select])

layout = row(widgets, plot)

curdoc().add_root(layout)

curdoc().title = “Plot”


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/1f686179-6cab-45b6-b546-23f22839ef64%40me.com.

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