下面是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'}
我的目标是让用户能够从下拉列表中进行选择,而另一个下拉列表则仅根据第一个选择显示相应的选择。
用于轴'的数据将根据选择进行更新。
谢谢你的任何建议。
更改“选择”窗口小部件值而不是其选项。如果更改选项,则必须确保其值为其中一个选项。
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'