下面是Bokeh仪表板的一个小工作示例的代码。
在第一个下拉菜单中进行选择时,第二个将动态更新,并且图表将使用新来源进行更新。这适用于选项A1 / A2,因为数据数组的长度相同。
在第一个下拉菜单中选择选项B1后,第二个下拉菜单将更改为B2。
但是源更新不会发生,因为您无法获得Yselector.value
。
如何在不使用Bokeh的Yselector.value
方法的情况下检索on_change
并将其传递给类似source_selector
的函数?
import numpy as np
import pandas as pd
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import Tabs, Select
from bokeh.layouts import column, row, Spacer
from bokeh.io import curdoc
from bokeh.plotting import figure, curdoc, show
#Plotting points on initial chart.
df_AB = pd.DataFrame(np.random.randint(0,100,size=(500, 2)), columns=list('XY'), index=[str(i) for i in range(1,500+1)])
pointchart=figure(plot_width=800, plot_height=700, tools=['lasso_select','box_select','wheel_zoom'],title="Point scatter")
pointchart_source= ColumnDataSource(df_AB[["X","Y"]])
pointchart.circle("X","Y",source=pointchart_source)
#Dropdown X
selectoroptions=['','Series A1', 'Series A2','Series B1','Series B2']
Xselector = Select(title="Dropdown X:", value="", options=selectoroptions)
#Dropdown Y
selectoroptions=['','Series A1', 'Series A2','Series B1','Series B2']
Yselector = Select(title="Dropdown Y:", value="", options=selectoroptions)
#Will list multiple sources to feed the chart based on dropdown selection.
def source_selector(selection):
if selection=='Series A1':
newvalues= pd.Series(list(np.random.randint(100, size=500)),name="")
elif selection=='Series A2':
newvalues= pd.Series(list(np.random.randint(200, size=500)),name="")
elif selection=='Series B1':
newvalues= pd.Series(list(np.random.randint(20, size=20)),name="")
elif selection=='Series B2':
newvalues= pd.Series(list(np.random.randint(10, size=20)),name="")
return newvalues
#Once dropdown X seelction is made, the options of dropdown Y will dynamically change.
#Data used for X axis is updated.
def X_switch_selection_and_source(attr, old, new):
if new == '':
pointchart_source.data = ColumnDataSource(df_AB[["X","Y"]]).data
#Other dropdown changed dynamically
elif new=='Series A1':
Yselector.options=['Series A2']
elif new=='Series A2':
Yselector.options=['Series A1']
elif new=='Series B1':
Yselector.options=['Series B2']
elif new=='Series B2':
Yselector.options=['Series B1']
#Updating source based on this dropdown's selection/ X values.
new_x_values=source_selector(new)
#Issue is right here. This line will only work if y is the same length as new x.
new_y_values=list(pointchart_source.data["Y"])
#If the lenghths are different I want to update the source for y by getting the y dropdown value.
if len(new_x_values)!= len(new_y_values):
new_y_values=source_selector(Yselector.value) # Does not get the dynamically changed value in the Y dropdown.
sourcedf=pd.DataFrame({"X":new_x_values,"Y":new_y_values})
pointchart_source.data= ColumnDataSource(sourcedf).data
Xselector.on_change("value", X_switch_selection_and_source)
#Show
layout=row(column(Xselector,Yselector, Spacer(width=400, height=500)),pointchart)
curdoc().add_root(layout)
!powershell -command {'bokeh serve --show Bokeh_dropdown_helped_v2.ipynb'}
我的目标是使用户能够从下拉列表中进行选择,而另一个下拉列表仅根据第一个选择显示适当的选择。
用于轴的数据将根据选择进行更新。
谢谢您的建议。
答案 0 :(得分:1)
更改“选择”小部件的值,而不是其选项。如果更改选项,则必须确保其值为选项之一。
elif new=='Series A1':
Yselector.value='Series A2'
elif new=='Series A2':
Yselector.value='Series A1'
elif new=='Series B1':
Yselector.value='Series B2'
elif new=='Series B2':
Yselector.value='Series B1'