我有一个包含分类数据的数据框。
A1 = ["cat",'apple','red',1,2]
A2 = ['dog','grape','blue',3,4]
A3 = ['rat','grape','gray',5,6]
A4 = ['toad','kiwi','yellow',7,8]
df_MD = pd.DataFrame([A1,A2,A3,A4],columns= ["animal","fruit","color","length","weight"])
animal fruit color length weight
0 cat apple red 1 2
1 dog grape blue 3 4
2 rat grape gray 5 6
3 toad kiwi yellow 7 8
我想使用bokeh serve
最终创建交互式图。
我实施了this suggestion on how to add listeners:
tgtCol1 = 'animal'
catList = list(np.unique(df_MD[tgtCol1]))
def updatexy(tgtCol1,catList,df_MD):
'''creates x and y values based on whether the entry is found in catlist'''
mybool = df_MD[tgtCol1]==catList[0]
for cc in catList:
mybool = (mybool) | ( df_MD[tgtCol1]== cc)
df_MD_mybool = df_MD[mybool].copy()
x = df_MD_mybool['length'].copy()
y = df_MD_mybool['weight'].copy()
return(x,y)
x,y = updatexy(tgtCol1,catList,df_MD)
#create dropdown menu for column selection
menu = [x for x in zip(df_MD.columns,df_MD.columns)]
dropdown = Dropdown(label="select column", button_type="success", menu=menu)
def function_to_call(attr, old, new):
print(dropdown.value)
dropdown.on_change('value', function_to_call)
dropdown.on_click(function_to_call)
#create buttons for category selection
catList = np.unique(df_MD[tgtCol1].dropna())
checkbox = CheckboxGroup(labels=catList)
def function_to_call2(attr, old, new):
print(checkbox.value)
checkbox.on_change('value', function_to_call2)
checkbox.on_click(function_to_call2)
#slap everything together
layout = column(dropdown,checkbox)
#add it to the layout
curdoc().add_root(layout)
curdoc().title = "Selection Histogram"
这可以创建初始菜单集。但是当我尝试更改列或选择不同的类别时,我收到错误:
TypeError("function_to_call() missing 2 required positional arguments: 'old' and 'new'",)
所以我甚至无法打电话给"听众"功能
一旦我调用了监听器函数,如何更新复选框值列表,以及x和y?
我可以在function_to_call1
和function_to_call2
的范围内更新它们,但x
,y
,tgtCol1
和{{1}的全局值不变!
答案 0 :(得分:0)
我无法找到关于听众如何工作的任何指南或文档,但经过一些实验后我发现听众的结构是错误的。它应该如下
myWdiget = <some widget>(<arguments>)
def function_to_call(d):
<actions, where d is a string or object corresponding to the widget state>
myWdiget.on_click(function_to_call) #add a event listener to myWdiget
所以,我的代码原来是
dropdown = Dropdown(label="select column", button_type="success", menu=menu)
def function_to_call(d): #only one argument, the selection from the dropdown
catList = list(np.unique(df_MD[d].dropna()))
checkbox.labels=catList
checkbox.active = [] #makes it so nothing is checked
dropdown.on_click(function_to_call)
#create buttons for category selection
checkbox = CheckboxGroup(labels=catList)
def function_to_call2(cb):
tempindex = [x for x in cb] #cb is some bokeh object, we convert it to a list
#tgtCol1 is a global variable referring to the currently active column
#not an ideal solution
catList = np.unique(df_MD[tgtCol1].dropna())
if len(tempindex) != 0: catList = list(catList[tempindex])
x,y = updatexy(tgtCol1,catList,df_MD) #gets new data based on desired column, category set, and dataframe
s.data = dict(x = x,y = y) #'source' object to update a plot I made, unrelated to this answer, so I'm not showing it
checkbox.on_click(function_to_call2)