本文介绍了如何替换交互式散景图中的图例,而不是扩大图例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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)

推荐答案

您应该更新用于绘制矩形的ColumnDataSource,而不是使用新的颜色/图例名称再次绘制矩形.您可以通过编辑 source.data 字典来做到这一点.

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)

这篇关于如何替换交互式散景图中的图例,而不是扩大图例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 04:08