我有一个ColumnDataSource,如:
MONTH | YEAR | TYPE | COUNT
1 2018 A 5
3 2019 A 3
2 2018 B 6
....
5 2018 C 1
5 2017 C 4
我创建了一个带有hovertool和单选按钮的热图,这些按钮交替显示不同的TYPE视图,即
heat_source=ColumnDataSource(data=df)
A_view= CDSView(source=heat_source, filters=[GroupFilter(column_name="TYPE", group="A")])
B_view= CDSView(source=heat_source, filters=[GroupFilter(column_name="TYPE", group="B")])
p_heat= figure(x_range=months, y_range=years,
y_axis_type='datetime',plot_width=405, plot_height=650, toolbar_location=None)
h=HoverTool(tooltips=[('Type','@TYPE'),('Transactions','@COUNT{0,0}'),
('Date','@MONTH-@YEAR')])
p_heat.add_tools(h)
radio_group=RadioGroup(labels=["A","B",'C'], active=0)
radio_group.on_change('active',lambda attr,old,new: update())
def update():
if radio_group.active==0:
p_heat.rect(x="MONTH",y="YEAR", width=1, height=1, source=heat_source, view=A_view,line_color=None)
if radio_group.active==1:
p_heat.rect(x="MONTH",y="YEAR", width=1, height=1, source=heat_source, view=B_view,line_color=None)
一切正常,除非我切换TYPE,悬停数据仍然没有变化。我尝试在每个If的单选按钮回调中嵌入hovertool,但没有用。
答案 0 :(得分:0)
您可以创建一次rect GlyphRenderer,并在javascript回调中更改过滤器的group
属性:
from bokeh.plotting import figure, output_notebook, show
from bokeh.models import ColumnDataSource, CDSView, GroupFilter, RadioGroup, CustomJS, HoverTool
from bokeh.palettes import viridis
from bokeh.transform import linear_cmap
from bokeh.layouts import column
import pandas as pd
import numpy as np
from itertools import product
output_notebook()
df = pd.DataFrame(list(product(range(1, 13), range(2000, 2018), ["A", "B"])), columns=["MONTH", "YEAR", "TYPE"])
df["COUNT"] = np.random.randint(0, 100, size=df.shape[0])
heat_source=ColumnDataSource(data=df)
view= CDSView(source=heat_source, filters=[GroupFilter(column_name="TYPE", group="A")])
p_heat= figure(plot_width=405, plot_height=650, toolbar_location=None)
h=HoverTool(tooltips=[('Type','@TYPE'),('Transactions','@COUNT{0,0}'),
('Date','@MONTH-@YEAR')])
p_heat.add_tools(h)
rect = p_heat.rect(x="MONTH",y="YEAR", width=1, height=1, source=heat_source, view=view,line_color=None,
fill_color=linear_cmap("COUNT", viridis(256), 0, 100))
type_widget = RadioGroup(labels=["A", "B"], active=0)
def callback(source=heat_source, filter=view.filters[0], cmap=rect.glyph.fill_color["transform"]):
filter.group = cb_obj.labels[cb_obj.active]
if filter.group == "A":
cmap.low=0
cmap.high=100
else:
cmap.low=-100
cmap.high=200
source.change.emit()
type_widget.js_on_change("active", CustomJS.from_py_func(callback))
show(column(type_widget, p_heat))