如何根据下拉菜单更新数据源?

时间:2019-09-29 08:14:59

标签: javascript python bokeh

我从选择小部件的js_on_change函数附带的回调中获得了p1图所需的输出。它会在javascript控制台上显示正确的数据,但不会在p1图上进行更新。我有一个类似的问题,以前已经解决过,但无论出于何种原因,它在这种情况下均不起作用。可能与select.js_on_change有关,但我不确定。

source = ColumnDataSource(data={
        'CAUSE' : df.cause_of_death,
        'AGE_GROUP' : df.AGE_GROUP,
        'YEAR' : df.YEAR, 
        'DEATHS' : df.deaths, 
        'RATE' : df.rate, 
        })

rangeMax = 1800

#converting matplotlib colour map to fkin bokeh ones >:(
colormap =cm.get_cmap("gist_heat_r") #choose any matplotlib colormap here
bokehpalette = [plt.colors.rgb2hex(m) for m in colormap(np.arange(colormap.N))]

mapper = LinearColorMapper(palette = bokehpalette, low=min(df.deaths), high=rangeMax)

age_group = list(df.AGE_GROUP)

p1 = figure(title="Deaths caused by lung cancer in Australia from ({0} - {1})".format(yearMin, yearMax),
           x_range=[yearMin, yearMax], 
           y_range=[age_group[0], age_group[1], age_group[2], age_group[3], age_group[4], age_group[5], age_group[6], age_group[7], age_group[8], 
                    age_group[9], age_group[10], age_group[11], age_group[12], age_group[13], age_group[14], age_group[15]], 
                    plot_width = 800, 
                    plot_height = 350, 
                    tools = TOOLS, toolbar_location=None)

p1.grid.grid_line_color = None
p1.axis.axis_line_color = None
p1.axis.major_tick_line_color = None
p1.xaxis.axis_label = 'Year'
p1.yaxis.axis_label = 'Age Group'
p1.axis.major_label_text_font_size = "8pt"
p1.axis.major_label_standoff = 0
p1.xaxis.major_label_orientation = pi / 3

rc = p1.rect(x="YEAR", y="AGE_GROUP", width=1, height=1,
       source=source, 
       fill_color={'field': 'DEATHS', 'transform': mapper},
       line_color='white')


callback = CustomJS(args = {'rect': rc.data_source.data, 'source': source}, 
code = """
var x = source.data
var select = cb_obj.value


var data = {"AGE_GROUP": [],  "CAUSE": [], "DEATHS": [], "RATE": [], "YEAR": []}

var indices = x.CAUSE.map((e,i) => e === select ? i : '').filter(x => x)


for (var i = 0; i < indices.length; i++){     
    data.AGE_GROUP.push(x.AGE_GROUP[indices[i]])
}
for (var i = 0; i < indices.length; i++){     
    data.CAUSE.push(x.CAUSE[indices[i]])
}
for (var i = 0; i < indices.length; i++){     
    data.DEATHS.push(x.DEATHS[indices[i]])
}
for (var i = 0; i < indices.length; i++){     
    data.RATE.push(x.RATE[indices[i]])
}
for (var i = 0; i < indices.length; i++){     
    data.YEAR.push(x.YEAR[indices[i]])
}
console.log(x)
rect = {"AGE_GROUP": data.AGE_GROUP, "CAUSE": data.CAUSE, "DEATHS": data.DEATHS, "RATE": data.RATE, "YEAR": data.YEAR, }
console.log(rect)
"""
)

menu = ["Lung cancer (ICD-10 C33, C34)", "Prostate cancer (ICD-10 C61)", "Colorectal cancer (ICD-10 C18–C20, C26.0)", "Breast cancer (ICD-10 C50)"]
select = Select(title="Option:", value=menu[0], options=menu)
select.js_on_change('value', callback)

理想的解决方案是,当有人单击下拉菜单上的一个选项时,它会基于该值填充rect图,即肺癌将显示肺癌数据。 如果有人需要更深入的研究,请附上代码和数据。 https://drive.google.com/drive/folders/11jfrpQnDOsECyjB96CXxgUK4cDhJIbcK?usp=sharing

1 个答案:

答案 0 :(得分:0)

您正在创建一个新的局部变量 data,然后对其进行任何操作。当回调代码结束时,它将被无效丢弃。当设置其对象属性时,Bokeh会通过分配对象的 属性来响应,而您并没有这样做。如果source是驱动要更新的字形的数据源,则需要执行以下操作:

source.data = data

rect也是如此。您正在制作新的局部变量。它们存在于回调函数代码的范围内,然后消失。散景无法看到这些或对其进行任何处理。