Боке: скрытие элементов легенды в обратном вызове JavaScript - PullRequest
0 голосов
/ 01 сентября 2018

У меня есть график боке, который начинается с 7 рядов в графике. Выбранный виджет изменяет данные и показывает только 4 серии через обратный вызов customjs

for i in range(7):
    if i < 4:
        js_code += """data['y%d']=data.%s;""" % (i,newseriesnames[i])
    js_code += """line%d.visible = %s;""" % (i,'true' if i < 4 else 'false')
js_code += 'source.change.emit();'
callback = CustomJS(args = args,code=js_code)
select.js_on_change('value',callback)

, где line0 - line6 - линии на графике, связанные с объектами данных, data['y0'] - data['y6'], а select - виджет селектора боке.

Это прекрасно работает на самой диаграмме боке, но не обновляет легенду. Легенда всегда та же, что и при первом отображении. Он сохраняет 7 элементов. Даже когда они скрыты на графике.

Вещи, которые я пытался обновить легенду:

  1. Настройка legend.items[4].renderers[0].visible=false
  2. Настройка legend.items[4].visible=false
  3. Вызов legend.change.emit(), legend.items[4].change.emit() и legend.items[4].renderers[0].change.emit()
  4. Перезапись легенды другой легендой, созданной с использованием питона боке Legend() метод

Обратите внимание, что я не получаю никаких ошибок при этих вызовах, они просто не дают никакой разницы в легенде. Добавление нескольких легенд и скрытие / отображение их работает, за исключением того, что их размещение неправильно при использовании plot.add_layout()

Я бы предпочел не делать это с помощью интерактивного сервера, а скорее использовал бы клиентскую сторону для переключения. Мой вариант использования часто повторяется и может потребовать автономной работы.

Кто-нибудь может указать мне правильное направление? Я протестировал это в боке 0.12.16 и 0.13.0 в питоне 3.6.5.

Спасибо

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

По состоянию на 0.13.0 это все еще открытый вопрос, и не представляется возможным:

https://github.com/bokeh/bokeh/issues/589

0 голосов
/ 05 сентября 2018

Одним из возможных решений является сделать все легенды заранее и спрятать их все

for group_name in group_names:
    legend_items[group_name] = make_legend(group_name)
    plot.add_layout(legend_items[group_name], 'right')
for g in legend_items:
    legend_items[g].visible = False
legend_items[group_names[0]].visible = True

и затем в обратном вызове

for f in group_names:
    js_code += """legend_items['%s'].visible = false;""" % f
js_code += 'legend_items[f].visible = true;'

Я не думаю, что это особенно хорошее решение, но оно основано на том факте, что я не могу обновить легенду динамически.

...