Bokeh-hovertool не отражает CDSView в тепловой карте - PullRequest
0 голосов
/ 07 мая 2018

У меня есть 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)

Все работает нормально, кроме случаев, когда я переключаю ТИПЫ, данные при наведении остаются неизменными. Я попытался встроить hovertool в функцию обратного вызова переключателя для каждого If, но безрезультатно.

1 Ответ

0 голосов
/ 08 мая 2018

Вы можете создать прямоугольный GlyphRenderer один раз и изменить свойство group фильтра в обратном вызове JavaScript:

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))
...