How to replace the legend in interactive Bokeh graph, rather than augment the legend?
I am using a selection dropdown in Bokeh to change what the chart shows. I'd also like the chart's legend to change accordingly. However, what happens instead is the legend becomes augmented every time the user selects a new dropdown value. Eventually, the legend displays every value from every possible dropdown option simultaneously. How do I "clear" the old legend on every new dropdown select?
import numpy as np
import pandas as pd
import os
from bokeh.plotting import figure
from bokeh.io import output_file, show, save, curdoc
from bokeh.models import HoverTool, CategoricalColorMapper, BoxSelectTool
from bokeh.models import ColumnDataSource, Select, Range1d
from bokeh.layouts import row, column, gridplot
from bokeh.models.widgets import Panel, Tabs
from bokeh.transform import factor_cmap
team = ['Bears', 'Bears', 'Bears', 'Bears', 'Bears']
player = ['Charles Leno', 'James Daniels', 'Cody Whitehair', 'Kyle Long', 'Bobby Massie']
position = ['LT', 'LG', 'C', 'RG', 'RT']
year_acquired = [2014, 2018, 2016, 2013, 2016]
round_drafted = [7, 2, 2, 1, np.NaN]
star=[False, False, False, True, False]
position_loc_x = [-4, -2, 0, 2, 4]
position_loc_y = [0, 0, 0, 0, 0]
year_acquired_color = ['green', 'yellow', 'blue', 'purple', 'blue']
round_drafted_color = ['grey', 'green', 'green', 'purple', np.NaN]
star_color = ['black', 'black', 'black', 'red', 'black']
df = pd.DataFrame({'team':team, 'player':player, 'position':position, 'year_acquired':year_acquired,
'round_drafted':round_drafted, 'star':star, 'position_loc_x':position_loc_x,
'position_loc_y':position_loc_y, 'year_acquired_color':year_acquired_color,
'round_drafted_color':round_drafted_color, 'star_color':star_color})
p = figure(x_range=[-5,5], y_range=[-5, 5])
source = ColumnDataSource(data=df)
p.rect(source=source, x='position_loc_x', y=0, width=1, height=1, line_width=5, line_color=None,
fill_color='round_drafted_color', legend='round_drafted')
hover = HoverTool(tooltips=[('Name', '@player'), ('Round', '@round_drafted'), ('Year', '@year_acquired')])
p.add_tools(hover)
def update():
p.rect(source=source, x='position_loc_x', y=0, width=1, height=1, line_width=5, line_color=None,
fill_color=select.value, legend=select.value.rpartition('_')[0])
select = Select(title='choose an attribute', options=['round_drafted_color', 'year_acquired_color', 'star_color'],
value = 'round_drafted_color')
select.on_change('value', lambda attr, old, new: update())
p.legend.click_policy="hide"
layout = column(select, p)
curdoc().add_root(layout)
python bokeh
add a comment |
I am using a selection dropdown in Bokeh to change what the chart shows. I'd also like the chart's legend to change accordingly. However, what happens instead is the legend becomes augmented every time the user selects a new dropdown value. Eventually, the legend displays every value from every possible dropdown option simultaneously. How do I "clear" the old legend on every new dropdown select?
import numpy as np
import pandas as pd
import os
from bokeh.plotting import figure
from bokeh.io import output_file, show, save, curdoc
from bokeh.models import HoverTool, CategoricalColorMapper, BoxSelectTool
from bokeh.models import ColumnDataSource, Select, Range1d
from bokeh.layouts import row, column, gridplot
from bokeh.models.widgets import Panel, Tabs
from bokeh.transform import factor_cmap
team = ['Bears', 'Bears', 'Bears', 'Bears', 'Bears']
player = ['Charles Leno', 'James Daniels', 'Cody Whitehair', 'Kyle Long', 'Bobby Massie']
position = ['LT', 'LG', 'C', 'RG', 'RT']
year_acquired = [2014, 2018, 2016, 2013, 2016]
round_drafted = [7, 2, 2, 1, np.NaN]
star=[False, False, False, True, False]
position_loc_x = [-4, -2, 0, 2, 4]
position_loc_y = [0, 0, 0, 0, 0]
year_acquired_color = ['green', 'yellow', 'blue', 'purple', 'blue']
round_drafted_color = ['grey', 'green', 'green', 'purple', np.NaN]
star_color = ['black', 'black', 'black', 'red', 'black']
df = pd.DataFrame({'team':team, 'player':player, 'position':position, 'year_acquired':year_acquired,
'round_drafted':round_drafted, 'star':star, 'position_loc_x':position_loc_x,
'position_loc_y':position_loc_y, 'year_acquired_color':year_acquired_color,
'round_drafted_color':round_drafted_color, 'star_color':star_color})
p = figure(x_range=[-5,5], y_range=[-5, 5])
source = ColumnDataSource(data=df)
p.rect(source=source, x='position_loc_x', y=0, width=1, height=1, line_width=5, line_color=None,
fill_color='round_drafted_color', legend='round_drafted')
hover = HoverTool(tooltips=[('Name', '@player'), ('Round', '@round_drafted'), ('Year', '@year_acquired')])
p.add_tools(hover)
def update():
p.rect(source=source, x='position_loc_x', y=0, width=1, height=1, line_width=5, line_color=None,
fill_color=select.value, legend=select.value.rpartition('_')[0])
select = Select(title='choose an attribute', options=['round_drafted_color', 'year_acquired_color', 'star_color'],
value = 'round_drafted_color')
select.on_change('value', lambda attr, old, new: update())
p.legend.click_policy="hide"
layout = column(select, p)
curdoc().add_root(layout)
python bokeh
add a comment |
I am using a selection dropdown in Bokeh to change what the chart shows. I'd also like the chart's legend to change accordingly. However, what happens instead is the legend becomes augmented every time the user selects a new dropdown value. Eventually, the legend displays every value from every possible dropdown option simultaneously. How do I "clear" the old legend on every new dropdown select?
import numpy as np
import pandas as pd
import os
from bokeh.plotting import figure
from bokeh.io import output_file, show, save, curdoc
from bokeh.models import HoverTool, CategoricalColorMapper, BoxSelectTool
from bokeh.models import ColumnDataSource, Select, Range1d
from bokeh.layouts import row, column, gridplot
from bokeh.models.widgets import Panel, Tabs
from bokeh.transform import factor_cmap
team = ['Bears', 'Bears', 'Bears', 'Bears', 'Bears']
player = ['Charles Leno', 'James Daniels', 'Cody Whitehair', 'Kyle Long', 'Bobby Massie']
position = ['LT', 'LG', 'C', 'RG', 'RT']
year_acquired = [2014, 2018, 2016, 2013, 2016]
round_drafted = [7, 2, 2, 1, np.NaN]
star=[False, False, False, True, False]
position_loc_x = [-4, -2, 0, 2, 4]
position_loc_y = [0, 0, 0, 0, 0]
year_acquired_color = ['green', 'yellow', 'blue', 'purple', 'blue']
round_drafted_color = ['grey', 'green', 'green', 'purple', np.NaN]
star_color = ['black', 'black', 'black', 'red', 'black']
df = pd.DataFrame({'team':team, 'player':player, 'position':position, 'year_acquired':year_acquired,
'round_drafted':round_drafted, 'star':star, 'position_loc_x':position_loc_x,
'position_loc_y':position_loc_y, 'year_acquired_color':year_acquired_color,
'round_drafted_color':round_drafted_color, 'star_color':star_color})
p = figure(x_range=[-5,5], y_range=[-5, 5])
source = ColumnDataSource(data=df)
p.rect(source=source, x='position_loc_x', y=0, width=1, height=1, line_width=5, line_color=None,
fill_color='round_drafted_color', legend='round_drafted')
hover = HoverTool(tooltips=[('Name', '@player'), ('Round', '@round_drafted'), ('Year', '@year_acquired')])
p.add_tools(hover)
def update():
p.rect(source=source, x='position_loc_x', y=0, width=1, height=1, line_width=5, line_color=None,
fill_color=select.value, legend=select.value.rpartition('_')[0])
select = Select(title='choose an attribute', options=['round_drafted_color', 'year_acquired_color', 'star_color'],
value = 'round_drafted_color')
select.on_change('value', lambda attr, old, new: update())
p.legend.click_policy="hide"
layout = column(select, p)
curdoc().add_root(layout)
python bokeh
I am using a selection dropdown in Bokeh to change what the chart shows. I'd also like the chart's legend to change accordingly. However, what happens instead is the legend becomes augmented every time the user selects a new dropdown value. Eventually, the legend displays every value from every possible dropdown option simultaneously. How do I "clear" the old legend on every new dropdown select?
import numpy as np
import pandas as pd
import os
from bokeh.plotting import figure
from bokeh.io import output_file, show, save, curdoc
from bokeh.models import HoverTool, CategoricalColorMapper, BoxSelectTool
from bokeh.models import ColumnDataSource, Select, Range1d
from bokeh.layouts import row, column, gridplot
from bokeh.models.widgets import Panel, Tabs
from bokeh.transform import factor_cmap
team = ['Bears', 'Bears', 'Bears', 'Bears', 'Bears']
player = ['Charles Leno', 'James Daniels', 'Cody Whitehair', 'Kyle Long', 'Bobby Massie']
position = ['LT', 'LG', 'C', 'RG', 'RT']
year_acquired = [2014, 2018, 2016, 2013, 2016]
round_drafted = [7, 2, 2, 1, np.NaN]
star=[False, False, False, True, False]
position_loc_x = [-4, -2, 0, 2, 4]
position_loc_y = [0, 0, 0, 0, 0]
year_acquired_color = ['green', 'yellow', 'blue', 'purple', 'blue']
round_drafted_color = ['grey', 'green', 'green', 'purple', np.NaN]
star_color = ['black', 'black', 'black', 'red', 'black']
df = pd.DataFrame({'team':team, 'player':player, 'position':position, 'year_acquired':year_acquired,
'round_drafted':round_drafted, 'star':star, 'position_loc_x':position_loc_x,
'position_loc_y':position_loc_y, 'year_acquired_color':year_acquired_color,
'round_drafted_color':round_drafted_color, 'star_color':star_color})
p = figure(x_range=[-5,5], y_range=[-5, 5])
source = ColumnDataSource(data=df)
p.rect(source=source, x='position_loc_x', y=0, width=1, height=1, line_width=5, line_color=None,
fill_color='round_drafted_color', legend='round_drafted')
hover = HoverTool(tooltips=[('Name', '@player'), ('Round', '@round_drafted'), ('Year', '@year_acquired')])
p.add_tools(hover)
def update():
p.rect(source=source, x='position_loc_x', y=0, width=1, height=1, line_width=5, line_color=None,
fill_color=select.value, legend=select.value.rpartition('_')[0])
select = Select(title='choose an attribute', options=['round_drafted_color', 'year_acquired_color', 'star_color'],
value = 'round_drafted_color')
select.on_change('value', lambda attr, old, new: update())
p.legend.click_policy="hide"
layout = column(select, p)
curdoc().add_root(layout)
python bokeh
python bokeh
asked Jan 20 at 3:45
gnotnekgnotnek
637
637
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Instead of plotting the rectangle again with a new color/legendname, you should update the ColumnDataSource used to plot the rectangles. You can do this by editing the source.data
dictionary.
#!/usr/bin/python3
import numpy as np
import pandas as pd
import os
from bokeh.plotting import figure
from bokeh.io import output_file, show, save, curdoc
from bokeh.models import HoverTool, CategoricalColorMapper, BoxSelectTool
from bokeh.models import ColumnDataSource, Select, Range1d
from bokeh.layouts import row, column, gridplot
from bokeh.models.widgets import Panel, Tabs
from bokeh.transform import factor_cmap
team = ['Bears', 'Bears', 'Bears', 'Bears', 'Bears']
player = ['Charles Leno', 'James Daniels', 'Cody Whitehair', 'Kyle Long', 'Bobby Massie']
position = ['LT', 'LG', 'C', 'RG', 'RT']
year_acquired = [2014, 2018, 2016, 2013, 2016]
round_drafted = [7, 2, 2, 1, np.NaN]
star=[False, False, False, True, False]
position_loc_x = [-4, -2, 0, 2, 4]
position_loc_y = [0, 0, 0, 0, 0]
year_acquired_color = ['green', 'yellow', 'blue', 'purple', 'blue']
round_drafted_color = ['grey', 'green', 'green', 'purple', np.NaN]
star_color = ['black', 'black', 'black', 'red', 'black']
df = pd.DataFrame({'team':team, 'player':player, 'position':position, 'year_acquired':year_acquired,
'round_drafted':round_drafted, 'star':star, 'position_loc_x':position_loc_x,
'position_loc_y':position_loc_y, 'year_acquired_color':year_acquired_color,
'round_drafted_color':round_drafted_color, 'star_color':star_color, 'legend':round_drafted, 'color':round_drafted_color})
p = figure(x_range=[-5,5], y_range=[-5, 5])
source = ColumnDataSource(data=df)
glyph = p.rect(source=source, x='position_loc_x', y=0, width=1, height=1, line_width=5, line_color=None,
fill_color='color', legend='legend')
hover = HoverTool(tooltips=[('Name', '@player'), ('Round', '@round_drafted'), ('Year', '@year_acquired')])
p.add_tools(hover)
def update():
#Use select.value to get the right key from the dictionary and set its list as color/legend item
source.data['color'] = source.data[select.value]
source.data['legend'] = source.data[select.value.replace('_color', '')]
select = Select(title='choose an attribute', options=['round_drafted_color', 'year_acquired_color', 'star_color'],
value = 'round_drafted_color')
select.on_change('value', lambda attr, old, new: update())
p.legend.click_policy="hide"
layout = column(select, p)
curdoc().add_root(layout)
Thank you, that works! But there is another remaining problem that I thought would be fixed: clicking on a legend element to hide it instead hides the entire legend. Any suggestions? I think my brain just doesn't get the basics of how Bokeh works in general, and there doesn't appear to be much good documentation out there. The official docs provide only the most simplistic examples, and once I need to use a combo of 2+ Bokeh features at once, I'm lost.
– gnotnek
Jan 21 at 19:15
bokeh.pydata.org/en/latest/docs/user_guide/interaction/… ~ "Interactive legend features currently work on “per-glyph” legends. Legends that are created by specifying a column to automatically group do no yet work with the features described below". It is possible to work around this problem by using some CustomJS and checkboxes as explained in this question: stackoverflow.com/questions/45380781/…
– Jasper
Jan 22 at 7:49
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54273406%2fhow-to-replace-the-legend-in-interactive-bokeh-graph-rather-than-augment-the-le%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Instead of plotting the rectangle again with a new color/legendname, you should update the ColumnDataSource used to plot the rectangles. You can do this by editing the source.data
dictionary.
#!/usr/bin/python3
import numpy as np
import pandas as pd
import os
from bokeh.plotting import figure
from bokeh.io import output_file, show, save, curdoc
from bokeh.models import HoverTool, CategoricalColorMapper, BoxSelectTool
from bokeh.models import ColumnDataSource, Select, Range1d
from bokeh.layouts import row, column, gridplot
from bokeh.models.widgets import Panel, Tabs
from bokeh.transform import factor_cmap
team = ['Bears', 'Bears', 'Bears', 'Bears', 'Bears']
player = ['Charles Leno', 'James Daniels', 'Cody Whitehair', 'Kyle Long', 'Bobby Massie']
position = ['LT', 'LG', 'C', 'RG', 'RT']
year_acquired = [2014, 2018, 2016, 2013, 2016]
round_drafted = [7, 2, 2, 1, np.NaN]
star=[False, False, False, True, False]
position_loc_x = [-4, -2, 0, 2, 4]
position_loc_y = [0, 0, 0, 0, 0]
year_acquired_color = ['green', 'yellow', 'blue', 'purple', 'blue']
round_drafted_color = ['grey', 'green', 'green', 'purple', np.NaN]
star_color = ['black', 'black', 'black', 'red', 'black']
df = pd.DataFrame({'team':team, 'player':player, 'position':position, 'year_acquired':year_acquired,
'round_drafted':round_drafted, 'star':star, 'position_loc_x':position_loc_x,
'position_loc_y':position_loc_y, 'year_acquired_color':year_acquired_color,
'round_drafted_color':round_drafted_color, 'star_color':star_color, 'legend':round_drafted, 'color':round_drafted_color})
p = figure(x_range=[-5,5], y_range=[-5, 5])
source = ColumnDataSource(data=df)
glyph = p.rect(source=source, x='position_loc_x', y=0, width=1, height=1, line_width=5, line_color=None,
fill_color='color', legend='legend')
hover = HoverTool(tooltips=[('Name', '@player'), ('Round', '@round_drafted'), ('Year', '@year_acquired')])
p.add_tools(hover)
def update():
#Use select.value to get the right key from the dictionary and set its list as color/legend item
source.data['color'] = source.data[select.value]
source.data['legend'] = source.data[select.value.replace('_color', '')]
select = Select(title='choose an attribute', options=['round_drafted_color', 'year_acquired_color', 'star_color'],
value = 'round_drafted_color')
select.on_change('value', lambda attr, old, new: update())
p.legend.click_policy="hide"
layout = column(select, p)
curdoc().add_root(layout)
Thank you, that works! But there is another remaining problem that I thought would be fixed: clicking on a legend element to hide it instead hides the entire legend. Any suggestions? I think my brain just doesn't get the basics of how Bokeh works in general, and there doesn't appear to be much good documentation out there. The official docs provide only the most simplistic examples, and once I need to use a combo of 2+ Bokeh features at once, I'm lost.
– gnotnek
Jan 21 at 19:15
bokeh.pydata.org/en/latest/docs/user_guide/interaction/… ~ "Interactive legend features currently work on “per-glyph” legends. Legends that are created by specifying a column to automatically group do no yet work with the features described below". It is possible to work around this problem by using some CustomJS and checkboxes as explained in this question: stackoverflow.com/questions/45380781/…
– Jasper
Jan 22 at 7:49
add a comment |
Instead of plotting the rectangle again with a new color/legendname, you should update the ColumnDataSource used to plot the rectangles. You can do this by editing the source.data
dictionary.
#!/usr/bin/python3
import numpy as np
import pandas as pd
import os
from bokeh.plotting import figure
from bokeh.io import output_file, show, save, curdoc
from bokeh.models import HoverTool, CategoricalColorMapper, BoxSelectTool
from bokeh.models import ColumnDataSource, Select, Range1d
from bokeh.layouts import row, column, gridplot
from bokeh.models.widgets import Panel, Tabs
from bokeh.transform import factor_cmap
team = ['Bears', 'Bears', 'Bears', 'Bears', 'Bears']
player = ['Charles Leno', 'James Daniels', 'Cody Whitehair', 'Kyle Long', 'Bobby Massie']
position = ['LT', 'LG', 'C', 'RG', 'RT']
year_acquired = [2014, 2018, 2016, 2013, 2016]
round_drafted = [7, 2, 2, 1, np.NaN]
star=[False, False, False, True, False]
position_loc_x = [-4, -2, 0, 2, 4]
position_loc_y = [0, 0, 0, 0, 0]
year_acquired_color = ['green', 'yellow', 'blue', 'purple', 'blue']
round_drafted_color = ['grey', 'green', 'green', 'purple', np.NaN]
star_color = ['black', 'black', 'black', 'red', 'black']
df = pd.DataFrame({'team':team, 'player':player, 'position':position, 'year_acquired':year_acquired,
'round_drafted':round_drafted, 'star':star, 'position_loc_x':position_loc_x,
'position_loc_y':position_loc_y, 'year_acquired_color':year_acquired_color,
'round_drafted_color':round_drafted_color, 'star_color':star_color, 'legend':round_drafted, 'color':round_drafted_color})
p = figure(x_range=[-5,5], y_range=[-5, 5])
source = ColumnDataSource(data=df)
glyph = p.rect(source=source, x='position_loc_x', y=0, width=1, height=1, line_width=5, line_color=None,
fill_color='color', legend='legend')
hover = HoverTool(tooltips=[('Name', '@player'), ('Round', '@round_drafted'), ('Year', '@year_acquired')])
p.add_tools(hover)
def update():
#Use select.value to get the right key from the dictionary and set its list as color/legend item
source.data['color'] = source.data[select.value]
source.data['legend'] = source.data[select.value.replace('_color', '')]
select = Select(title='choose an attribute', options=['round_drafted_color', 'year_acquired_color', 'star_color'],
value = 'round_drafted_color')
select.on_change('value', lambda attr, old, new: update())
p.legend.click_policy="hide"
layout = column(select, p)
curdoc().add_root(layout)
Thank you, that works! But there is another remaining problem that I thought would be fixed: clicking on a legend element to hide it instead hides the entire legend. Any suggestions? I think my brain just doesn't get the basics of how Bokeh works in general, and there doesn't appear to be much good documentation out there. The official docs provide only the most simplistic examples, and once I need to use a combo of 2+ Bokeh features at once, I'm lost.
– gnotnek
Jan 21 at 19:15
bokeh.pydata.org/en/latest/docs/user_guide/interaction/… ~ "Interactive legend features currently work on “per-glyph” legends. Legends that are created by specifying a column to automatically group do no yet work with the features described below". It is possible to work around this problem by using some CustomJS and checkboxes as explained in this question: stackoverflow.com/questions/45380781/…
– Jasper
Jan 22 at 7:49
add a comment |
Instead of plotting the rectangle again with a new color/legendname, you should update the ColumnDataSource used to plot the rectangles. You can do this by editing the source.data
dictionary.
#!/usr/bin/python3
import numpy as np
import pandas as pd
import os
from bokeh.plotting import figure
from bokeh.io import output_file, show, save, curdoc
from bokeh.models import HoverTool, CategoricalColorMapper, BoxSelectTool
from bokeh.models import ColumnDataSource, Select, Range1d
from bokeh.layouts import row, column, gridplot
from bokeh.models.widgets import Panel, Tabs
from bokeh.transform import factor_cmap
team = ['Bears', 'Bears', 'Bears', 'Bears', 'Bears']
player = ['Charles Leno', 'James Daniels', 'Cody Whitehair', 'Kyle Long', 'Bobby Massie']
position = ['LT', 'LG', 'C', 'RG', 'RT']
year_acquired = [2014, 2018, 2016, 2013, 2016]
round_drafted = [7, 2, 2, 1, np.NaN]
star=[False, False, False, True, False]
position_loc_x = [-4, -2, 0, 2, 4]
position_loc_y = [0, 0, 0, 0, 0]
year_acquired_color = ['green', 'yellow', 'blue', 'purple', 'blue']
round_drafted_color = ['grey', 'green', 'green', 'purple', np.NaN]
star_color = ['black', 'black', 'black', 'red', 'black']
df = pd.DataFrame({'team':team, 'player':player, 'position':position, 'year_acquired':year_acquired,
'round_drafted':round_drafted, 'star':star, 'position_loc_x':position_loc_x,
'position_loc_y':position_loc_y, 'year_acquired_color':year_acquired_color,
'round_drafted_color':round_drafted_color, 'star_color':star_color, 'legend':round_drafted, 'color':round_drafted_color})
p = figure(x_range=[-5,5], y_range=[-5, 5])
source = ColumnDataSource(data=df)
glyph = p.rect(source=source, x='position_loc_x', y=0, width=1, height=1, line_width=5, line_color=None,
fill_color='color', legend='legend')
hover = HoverTool(tooltips=[('Name', '@player'), ('Round', '@round_drafted'), ('Year', '@year_acquired')])
p.add_tools(hover)
def update():
#Use select.value to get the right key from the dictionary and set its list as color/legend item
source.data['color'] = source.data[select.value]
source.data['legend'] = source.data[select.value.replace('_color', '')]
select = Select(title='choose an attribute', options=['round_drafted_color', 'year_acquired_color', 'star_color'],
value = 'round_drafted_color')
select.on_change('value', lambda attr, old, new: update())
p.legend.click_policy="hide"
layout = column(select, p)
curdoc().add_root(layout)
Instead of plotting the rectangle again with a new color/legendname, you should update the ColumnDataSource used to plot the rectangles. You can do this by editing the source.data
dictionary.
#!/usr/bin/python3
import numpy as np
import pandas as pd
import os
from bokeh.plotting import figure
from bokeh.io import output_file, show, save, curdoc
from bokeh.models import HoverTool, CategoricalColorMapper, BoxSelectTool
from bokeh.models import ColumnDataSource, Select, Range1d
from bokeh.layouts import row, column, gridplot
from bokeh.models.widgets import Panel, Tabs
from bokeh.transform import factor_cmap
team = ['Bears', 'Bears', 'Bears', 'Bears', 'Bears']
player = ['Charles Leno', 'James Daniels', 'Cody Whitehair', 'Kyle Long', 'Bobby Massie']
position = ['LT', 'LG', 'C', 'RG', 'RT']
year_acquired = [2014, 2018, 2016, 2013, 2016]
round_drafted = [7, 2, 2, 1, np.NaN]
star=[False, False, False, True, False]
position_loc_x = [-4, -2, 0, 2, 4]
position_loc_y = [0, 0, 0, 0, 0]
year_acquired_color = ['green', 'yellow', 'blue', 'purple', 'blue']
round_drafted_color = ['grey', 'green', 'green', 'purple', np.NaN]
star_color = ['black', 'black', 'black', 'red', 'black']
df = pd.DataFrame({'team':team, 'player':player, 'position':position, 'year_acquired':year_acquired,
'round_drafted':round_drafted, 'star':star, 'position_loc_x':position_loc_x,
'position_loc_y':position_loc_y, 'year_acquired_color':year_acquired_color,
'round_drafted_color':round_drafted_color, 'star_color':star_color, 'legend':round_drafted, 'color':round_drafted_color})
p = figure(x_range=[-5,5], y_range=[-5, 5])
source = ColumnDataSource(data=df)
glyph = p.rect(source=source, x='position_loc_x', y=0, width=1, height=1, line_width=5, line_color=None,
fill_color='color', legend='legend')
hover = HoverTool(tooltips=[('Name', '@player'), ('Round', '@round_drafted'), ('Year', '@year_acquired')])
p.add_tools(hover)
def update():
#Use select.value to get the right key from the dictionary and set its list as color/legend item
source.data['color'] = source.data[select.value]
source.data['legend'] = source.data[select.value.replace('_color', '')]
select = Select(title='choose an attribute', options=['round_drafted_color', 'year_acquired_color', 'star_color'],
value = 'round_drafted_color')
select.on_change('value', lambda attr, old, new: update())
p.legend.click_policy="hide"
layout = column(select, p)
curdoc().add_root(layout)
answered Jan 21 at 10:21
JasperJasper
43417
43417
Thank you, that works! But there is another remaining problem that I thought would be fixed: clicking on a legend element to hide it instead hides the entire legend. Any suggestions? I think my brain just doesn't get the basics of how Bokeh works in general, and there doesn't appear to be much good documentation out there. The official docs provide only the most simplistic examples, and once I need to use a combo of 2+ Bokeh features at once, I'm lost.
– gnotnek
Jan 21 at 19:15
bokeh.pydata.org/en/latest/docs/user_guide/interaction/… ~ "Interactive legend features currently work on “per-glyph” legends. Legends that are created by specifying a column to automatically group do no yet work with the features described below". It is possible to work around this problem by using some CustomJS and checkboxes as explained in this question: stackoverflow.com/questions/45380781/…
– Jasper
Jan 22 at 7:49
add a comment |
Thank you, that works! But there is another remaining problem that I thought would be fixed: clicking on a legend element to hide it instead hides the entire legend. Any suggestions? I think my brain just doesn't get the basics of how Bokeh works in general, and there doesn't appear to be much good documentation out there. The official docs provide only the most simplistic examples, and once I need to use a combo of 2+ Bokeh features at once, I'm lost.
– gnotnek
Jan 21 at 19:15
bokeh.pydata.org/en/latest/docs/user_guide/interaction/… ~ "Interactive legend features currently work on “per-glyph” legends. Legends that are created by specifying a column to automatically group do no yet work with the features described below". It is possible to work around this problem by using some CustomJS and checkboxes as explained in this question: stackoverflow.com/questions/45380781/…
– Jasper
Jan 22 at 7:49
Thank you, that works! But there is another remaining problem that I thought would be fixed: clicking on a legend element to hide it instead hides the entire legend. Any suggestions? I think my brain just doesn't get the basics of how Bokeh works in general, and there doesn't appear to be much good documentation out there. The official docs provide only the most simplistic examples, and once I need to use a combo of 2+ Bokeh features at once, I'm lost.
– gnotnek
Jan 21 at 19:15
Thank you, that works! But there is another remaining problem that I thought would be fixed: clicking on a legend element to hide it instead hides the entire legend. Any suggestions? I think my brain just doesn't get the basics of how Bokeh works in general, and there doesn't appear to be much good documentation out there. The official docs provide only the most simplistic examples, and once I need to use a combo of 2+ Bokeh features at once, I'm lost.
– gnotnek
Jan 21 at 19:15
bokeh.pydata.org/en/latest/docs/user_guide/interaction/… ~ "Interactive legend features currently work on “per-glyph” legends. Legends that are created by specifying a column to automatically group do no yet work with the features described below". It is possible to work around this problem by using some CustomJS and checkboxes as explained in this question: stackoverflow.com/questions/45380781/…
– Jasper
Jan 22 at 7:49
bokeh.pydata.org/en/latest/docs/user_guide/interaction/… ~ "Interactive legend features currently work on “per-glyph” legends. Legends that are created by specifying a column to automatically group do no yet work with the features described below". It is possible to work around this problem by using some CustomJS and checkboxes as explained in this question: stackoverflow.com/questions/45380781/…
– Jasper
Jan 22 at 7:49
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54273406%2fhow-to-replace-the-legend-in-interactive-bokeh-graph-rather-than-augment-the-le%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown