Skip to content Skip to sidebar Skip to footer

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

Solution 1:

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)

Post a Comment for "How To Replace The Legend In Interactive Bokeh Graph, Rather Than Augment The Legend?"