首页 > 解决方案 > Bokeh Python CustomJS Callback Update Select Widget to filter Scatterplot

问题描述

Hi my aim is to create a dropdown menu to select the week, and filter the data based on the selected week. I first find the last 5 weeks using the unique() then I use these weeks in my filtering.

What am I missing here? I can see the dropdown and the scatterplot but once I select the week I do not see anything filtered.

import pandas as pd
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, CustomJS, Select
from bokeh.plotting import figure, show

import numpy as np
import pandas as pd
index = [0,1,2,3,4,5]
w = pd.Series([202045,202031,202001,202023,202024,202006],index= index)
s = pd.Series(['S1','S2','S3','S4','S5','S6'],index= index)
t = pd.Series([2,4,6,8,10,12],index= index)
df = pd.DataFrame(s,columns = ["ABC"])
df["DFG"] =t
df["SWW"] = w

unique_WW_1,unique_WW_2, unique_WW_3, unique_WW_4, unique_WW_5  = sorted(df['SWW'].unique())[-5:]

source_unique_WW_1 = ColumnDataSource(data=df.loc[df['SWW'] == unique_WW_1])
source_unique_WW_2 = ColumnDataSource(data=df.loc[df['SWW'] == unique_WW_2])
source_unique_WW_3 = ColumnDataSource(data=df.loc[df['SWW'] == unique_WW_3])
source_unique_WW_4 = ColumnDataSource(data=df.loc[df['SWW'] == unique_WW_4])
source_unique_WW_5 = ColumnDataSource(data=df.loc[df['SWW'] == unique_WW_5])

source_ALL = ColumnDataSource(data=df)
source_fill = ColumnDataSource(data=df)

  
select = Select(title='Selected WEEK:', value='ALL', options=[str(unique_WW_1),str(unique_WW_2), str(unique_WW_3), str(unique_WW_4), str(unique_WW_5), 'ALL'])

update = CustomJS(args=dict(source_fill=source_fill, source_unique_WW_1=source_unique_WW_1,
        source_unique_WW_2=source_unique_WW_2, source_unique_WW_3 = source_unique_WW_3, source_unique_WW_4 = source_unique_WW_4, source_unique_WW_5=source_unique_WW_5, source_ALL=source_ALL,
        unique_WW_1 = unique_WW_1, unique_WW_2 = unique_WW_2, unique_WW_3 = unique_WW_3, unique_WW_4 = unique_WW_4, unique_WW_5 = unique_WW_5), code="""

    var data_unique_WW_1 = source_unique_WW_1.data;
    var data_unique_WW_2 = source_unique_WW_2.data;
    var data_unique_WW_3 = source_unique_WW_3.data;
    var data_unique_WW_4 = source_unique_WW_4.data;
    var data_unique_WW_5 = source_unique_WW_5.data;
    var String(unique_WW_5) = unique_WW_5;
    var String(unique_WW_4) = unique_WW_4;
    var String(unique_WW_3) = unique_WW_3;
    var String(unique_WW_2) = unique_WW_2;
    var String(unique_WW_1) = unique_WW_1;


    var data_ALL  = source_ALL.data;

    
    var data_fill = source_fill.data;
    
    var f = cb_obj.value;

    if (f =='ALL') {
        source_fill.data=source_ALL.data;
    }
    if (f == String(%unique_WW_1)) {
        source_fill.data=source_unique_WW_1.data;
    }
    if (f == String(%unique_WW_2)) {
        source_fill.data=source_unique_WW_2.data;
    }  
    if (f == String(%unique_WW_3)) {
        source_fill.data=source_unique_WW_3.data;
    } 
     
    if (f == String(%unique_WW_4)) {
        source_fill.data=source_unique_WW_4.data;
    } 
     
    if (f == String(%unique_WW_5)) {
        source_fill.data=source_unique_WW_5.data;
    } 
     
    source_fill.change.emit();
    """
    )

select.js_on_change('value', update)

boxwhisker = hv.BoxWhisker(df, ['ABC'], 'DFG', label='COMBINED')
boxwhisker.opts(show_legend=False, width=600)

hover = bmo.HoverTool(
    tooltips=[('ABC', '@ABC')])

scatter = hv.Points(df, ['ABC', 'DFG'], label='COMBINED' )

scatter.opts(size=7,color = 'black',
                 show_grid=True, tools = [hover])

p = boxwhisker*scatter
p.opts(show_legend=True, height = 1000,  width=1700, xrotation= 90)

p = hv.render(p)

p = column(select, p)

show(p)

标签: javascriptpythonwidgetbokehholoviews

解决方案


我很难理解你的例子,因为它的代码太多了。

希望这会对您有所帮助。我正在使用构建在holoviews之上的 hvplot 来为一年中的最后五周创建一个选择器:

import pandas as pd
import holoviews as hv
hv.extension('bokeh')
import hvplot.pandas

df = pd.DataFrame({
    'SWW': [202045,202031,202001,202023,202024,202006],
    'ABC': ['S1','S2','S3','S4','S5','S6'],
    'DFG': [2,4,6,8,10,12],
})

(df
    .sort_values(by='SWW') # sort df by week
    .iloc[-5:, ]  # take only the last 5 week 
    .hvplot.scatter(
        x='ABC', 
        y='DFG', 
        groupby='SWW',  # this creates the dropdown 
        dynamic=False, 
        ylim=(0, 14),
    )
)

结果图:

过去 5 周的 hvplot 下拉菜单


推荐阅读