python - 如何替换交互式散景图中的图例,而不是增加图例?
问题描述
我正在使用 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)
解决方案
您应该更新用于绘制矩形的 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)
推荐阅读
- dart - 如何在飞镖脚本中从键盘重定向标准输入?
- r - 根据一个因素出现的次数绘制两个因素变量
- python - 更改 Seaborn 应用调色板的轴
- c# - 如何在 C#、.net 中找到 JObject 的必填字段?
- c++ - 带参数的 C++ 宏
- c++ - 报错:使用 StartServiceCtrlDispatcher(entrytable) 时访问冲突
- html - 如何让悬停时出现的文本显示在 div 的中心(水平和垂直)
- java - 从 mongo 集合 collection.find(query) 中检索数据
- rake - db:migrate 看起来它不能加载我的 rake 文件的一部分
- python - 使用 tf.lite.Optimize.DEFAULT 后,并非 DNN 模型中的所有值都被量化