我正在使用Bokeh中的选择下拉列表来更改图表显示的内容。我也希望图表的图例进行相应的更改。但是,每当用户选择新的下拉值时,图例就会增加。最终,图例会同时显示每个可能的下拉选项中的每个值。如何在每个新的下拉菜单中“清除”旧图例?
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)
答案 0 :(得分:1)
您应该更新用于绘制矩形的ColumnDataSource,而不是使用新的颜色/图例名称再次绘制矩形。您可以通过编辑source.data
字典来完成此操作。
#!/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)