Получить выпадающее значение Bokeh без взаимодействия - PullRequest
0 голосов
/ 15 апреля 2019

Ниже приведен код небольшого рабочего примера панели инструментов Bokeh.

Когда вы делаете выбор в первом раскрывающемся меню, второе обновляется динамически, а диаграмма обновляется новым источником. Это работает для опций A1 / A2, потому что массивы данных имеют одинаковую длину.

После выбора опции B1 в первом раскрывающемся списке второй раскрывающийся список изменяется на B2.

Но обновление источника не происходит, потому что вы не можете получить Yselector.value.

Как вы можете извлечь 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'}

Моя цель - чтобы пользователь мог сделать выбор из выпадающих меню, а для другого выпадающего списка показать только соответствующие варианты выбора, основанные на первом выборе.

Данные, использованные для оси ', будут обновлены в зависимости от выбора.

Спасибо за любой совет.

1 Ответ

1 голос
/ 15 апреля 2019

Изменение значений виджета Select вместо его параметров.Если вы измените параметры, убедитесь, что их значение является одним из параметров.

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' 
...