当我使用Bokeh和单选按钮在图之间切换时,会显示多个图例。如何删除旧的图例,仅显示当前活动的图例?
我正在提供简化的代码,并在完整版本中使用CategoricalColorMappers,其中颜色根据因素而变化。我尝试了legend.visible = False选项,但没有成功。
from bokeh.plotting import figure, show,reset_output
from bokeh.io import output_notebook, curdoc
from bokeh.models import ColumnDataSource, Range1d, LabelSet, Label,CustomJS,CategoricalColorMapper
from bokeh.layouts import row,widgetbox
from bokeh.models.widgets import CheckboxGroup, RadioGroup,RadioButtonGroup
import pandas as pd
import numpy as np
#create data
source_points = ColumnDataSource(dict(
x=[1, 2, 1, 2, 1, 2,1,2],
y=[1, 1, 2, 2, 3, 3,4,4],
category=['hi', 'lo', 'hi', 'lo', 'hi', 'lo', 'hi', 'lo'],
size=['big','small','big','small','big','small','big','small'],
weight=['light','heavy','very heavy','light','heavy','very heavy','light','heavy'] ))
#create graph
p=figure(x_range=(0, 4), y_range=(0, 5))
p.square(x='x',y='y',source=source_points, legend='category')
p.legend.orientation = "horizontal"
p.legend.location = "top_left"
#Adding Radio button
radio = RadioButtonGroup(labels=['category','weight','size'], active=0)
inputs = widgetbox(radio)
#update plots
def update_plot(attrname, old, new):
plt = radio.active
print(plt)
# Generate the new curve
if plt is 0:
p.square(x='x',y='y',source=source_points, legend='category',color='blue')
p.legend.orientation = "horizontal"
p.legend.location = "top_left"
elif plt is 1:
p.square(x='x',y='y',source=source_points, legend='weight',color='blue')
p.legend.orientation = "horizontal"
p.legend.location = "top_left"
else:
p.square(x='x',y='y',source=source_points, legend='size',color='black')
p.legend.orientation = "horizontal"
p.legend.location = "top_left"
# event and function linkage
radio.on_change('active', update_plot)
#link everything together
curdoc().add_root(row(inputs, p, width=800))
我只想显示活动图例并隐藏/删除旧图例。对散景图例问题有任何建议/帮助吗?
答案 0 :(得分:1)
您应该更新用于绘制矩形的ColumnDataSource
,而不是再次绘制矩形。您可以通过编辑source.data词典来做到这一点。
#!/usr/bin/python3
from bokeh.plotting import figure, show
from bokeh.io import curdoc
from bokeh.models import ColumnDataSource
from bokeh.layouts import row, widgetbox
from bokeh.models.widgets import CheckboxGroup, RadioButtonGroup
from bokeh.transform import factor_cmap
from bokeh.palettes import Spectral7
#create data
source_points = ColumnDataSource(dict(
x=[1, 2, 1, 2, 1, 2,1,2],
y=[1, 1, 2, 2, 3, 3,4,4],
legend=['hi', 'lo', 'hi', 'lo', 'hi', 'lo', 'hi', 'lo'],
category=['hi', 'lo', 'hi', 'lo', 'hi', 'lo', 'hi', 'lo'],
size=['big','small','big','small','big','small','big','small'],
weight=['light','heavy','very heavy','light','heavy','very heavy','light','heavy']))
legend=list(set(source_points.data['category'] + source_points.data['size'] + source_points.data['weight']))
#create graph
p=figure(x_range=(0, 4), y_range=(0, 5))
p.square(x='x',y='y',source=source_points, legend='legend', color=factor_cmap('legend', palette=Spectral7, factors=legend))
p.legend.orientation = "horizontal"
p.legend.location = "top_left"
#Adding Radio button
radio = RadioButtonGroup(labels=['category','weight','size'], active=0)
inputs = widgetbox(radio)
#update plots
def update_plot(attrname, old, new):
plt = radio.active
newSource = source_points.data
if radio.active is 0:
newSource['legend'] = newSource['category']
elif radio.active is 1:
newSource['legend'] = newSource['weight']
else:
newSource['legend'] = newSource['size']
source_points.data = newSource
# event and function linkage
radio.on_change('active', update_plot)
#link everything together
curdoc().add_root(row(inputs, p, width=800))