Bug - bokeh wedge legend interactivity is wrong

We have run into a bug in Bokeh: Wedge (pie) legend inteactivity does not work. If we attach a slider to a pie with and update the ColumnDataSource’s data dict, the pie gets updated, but 1) the legend labels are not updating, even though tooltips are; 2) the color is not updated only on the first update; subsequent updates reflect a new color.

The following example is using Bokeh inside Panel, but the Panel team says this is a Bokeh issue and referred it to you.

import panel as pn
pn.extension()
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, Slider, TextInput
from bokeh.transform import cumsum
import numpy as np
from math import pi
from bokeh.palettes import Category20c, Category20
from bokeh.plotting import figure
from bokeh.transform import cumsum
import collections

x = [
    ('United States', 157),
    ('United Kingdom', 93),
    ('Japan', 89),
    ('China', 63),
    ('Germany', 44),
    ('India', 42),
]

data = {}
data["country"] = np.array([item[0] for item in x])
data["value"]= np.array([item[1] for item in x])
data['angle'] = data['value']/data['value'].sum() * 2*pi
data['color'] = np.array(Category20c[len(x)])
source = ColumnDataSource(data=data)

p = figure(height=350, title="Pie Chart", toolbar_location=None,
           tools="hover", tooltips="@country: @value", x_range=(-0.5, 1.0))
p.wedge(x=0, y=1, radius=0.4,
        start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
        color='color', legend_field='country', source=source)
p.axis.axis_label=None
p.axis.visible=False
p.grid.grid_line_color = None

amplitude = Slider(title="amplitude", value=1.0, start=0.5, end=2.0, step=0.1)

def update_data(attrname, old, new):
    data["country"][0] = "My String"
    data["value"][0] = 100 * new
    data['angle'] = data['value']/data['value'].sum() * 2*pi
    source.data = dict((k, v.copy()) for k, v in data.items())
    data["color"][0] = "#000000"
    p.legend.items[0].visible = False
    p.legend.items[0].visible = True
    
amplitude.on_change('value', update_data)

bokeh_app = pn.Row(amplitude, p)
bokeh_app

In the example, when the amplitude slider changes value, the first legend item never changes to “My String”. The corresponding color stays blue. On the second update the color changes to black in the pie and in the legend but the string is still the old value.

  1. Any help would be greatly appreciated. We spent countless hours manually going into Bokeh objects (creating LegendItems, GlyphRenderes manually) and trying workarounds but the effects of changing these objects on the plot are uncontrollable.

@Oren_Livne I wanted to investigate this but I see it is a Panel app. I don’t know how to run this code. If you can provide a pure-Bokeh Minimal Reproducible Example (what would be appropriate for this forum) then I am happy to try to take a closer look.

Otherwise, the only general observation I can make is that IIRC the legend_field feature is only considered once at glyph initialization time. I think if you want dynamic updates like this you would need to manage the legend and its items completely manually. without using legend_field.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.