我正在用jupyter笔记本5.7.8(使用ipywidgets 7.4.2和pytables 3.5.1)编写Python应用程序,并且遇到了生成多个视觉上相同的ui控件(组合为多个下拉菜单,滑块和按钮)的问题,每个ui控制组与不同的用户数据进行交互。
为避免编写18次相同的代码(对于18个ui控制组),我想知道如何以一种通用的方式解决此问题,这意味着编写一次代码(如“蓝图”),并建立18个代码来自该“蓝图”的不同ui控制组...?
这是代码,我有:
import pandas as pd
import ipywidgets as widgets
from ipywidgets import Layout, HBox, VBox
from IPython.display import clear_output
data_df = pd.DataFrame({
'SUBJECT': [1,2],
'SIDE': ['left', 'right'],
'ACTIVITY': [1,2],
'DATA': [1,2],
'ABS_TIME': [1,2],
'REL_TIME': [1,2],
'VAL1': [1,2],
'VAL2': [1,2],
'VAL3': [1,2]})
subject_ui_values = [''] + data_df['SUBJECT'].unique().tolist()
side_ui_values = [''] + data_df['SIDE'].unique().tolist()
activity_ui_values = [''] + data_df['ACTIVITY'].unique().tolist()
userdata_ui_values = [''] + data_df['DATA'].unique().tolist()
axis_ui_values = ['', 'ABS_TIME', 'REL_TIME', 'VAL1', 'VAL2', 'VAL3']
# Flag whether to plot data or not
plot_data = True
def update_sample_range_plt1(args):
# Update value range of slider 'sample_plt1_sldr', if (not empty) values were specified at dropdowns:
# 'SUBJECT' and 'SIDE' and 'ACTIVITY' and 'USERDATA'
if ((subject_plt1_drpdwn.value != "") and (side_plt1_drpdwn.value != "") and
(activity_plt1_drpdwn.value != "") and (userdata_plt1_drpdwn.value != "")):
##### SET / GET UI CONTROL PROPERTIES (SLIDER DESCRIPTION, SLIDER VALUE, ...) #####
print("")
else: # If any values in dropdowns 'SUBJECT' and 'SIDE' and 'ACTIVITY' and 'USERDATA' are empty
##### SET / GET UI CONTROL PROPERTIES (SLIDER DESCRIPTION, SLIDER VALUE, ...) #####
print("")
def update_sample_range_plt2(args):
# Update value range of slider 'sample_plt2_sldr', if (not empty) values were specified at dropdowns:
# 'SUBJECT' and 'SIDE' and 'ACTIVITY' and 'USERDATA'
if ((subject_plt2_drpdwn.value != "") and (side_plt2_drpdwn.value != "") and
(activity_plt2_drpdwn.value != "") and (userdata_plt2_drpdwn.value != "")):
##### SET / GET UI CONTROL PROPERTIES (SLIDER DESCRIPTION, SLIDER VALUE, ...) #####
print("")
else: # If any values in dropdowns 'SUBJECT' and 'SIDE' and 'ACTIVITY' and 'USERDATA' are empty
##### SET / GET UI CONTROL PROPERTIES (SLIDER DESCRIPTION, SLIDER VALUE, ...) #####
print("")
def filter_data_df_plt1(_):
with output1:
def aux_filter_df(ui_element_value, label_num, data_df, df_column):
##### GET / SET UI CONTROL VALUES AND MAKE A QUERY ON A PANDAS DATAFRAME 'data_df'
print("")
# Clear output of ipywidget
clear_output()
# Display filtered results in jupyter cell (output1)
display(filtered_data_df_1)
def filter_data_df_plt2(_):
with output1:
def aux_filter_df(ui_element_value, label_num, data_df, df_column):
##### GET / SET UI CONTROL VALUES AND MAKE A QUERY ON A PANDAS DATAFRAME 'data_df'
print("")
# Clear output of ipywidget
clear_output()
# Display filtered results in jupyter cell (output1)
display(filtered_data_df_2)
def plot_filtered_data_plt1():
##### PLOT DATA USING VISDOM #####
print("")
def plot_filtered_data_plt2():
##### PLOT DATA USING VISDOM #####
print("")
def clear_plot_plt1(_):
##### CLEAR PLOT IN VISDOM #####
print("")
def clear_plot_plt2(_):
##### CLEAR PLOT IN VISDOM #####
print("")
# Set output1 of ipywidget
output1 = widgets.Output()
output2 = widgets.Output()
if plot_data:
query_plt1_btn_description = 'Query and Plot 1'
query_plt2_btn_description = 'Query and Plot 2'
else:
query_plt1_btn_description = 'Query 1'
query_plt2_btn_description = 'Query 2'
# Define new button ui controls 'query_plt1_btn', 'clear_plt1_btn'
query_plt1_btn = widgets.Button(description=query_plt1_btn_description)
query_plt2_btn = widgets.Button(description=query_plt2_btn_description)
clear_plt1_btn = widgets.Button(description='Clear Plot 1', disabled=True)
clear_plt2_btn = widgets.Button(description='Clear Plot 2', disabled=True)
# Define new dropdown ui controls
subject_plt1_drpdwn = widgets.Dropdown(options=subject_ui_values, value='', description='Subject 1:')
side_plt1_drpdwn = widgets.Dropdown(options=side_ui_values, value='', description='Side 1:')
activity_plt1_drpdwn = widgets.Dropdown(options=activity_ui_values, value='', description='Activity 1:')
userdata_plt1_drpdwn = widgets.Dropdown(options=userdata_ui_values, value='', description='User Data 1:')
x_axis_plt1_drpdwn = widgets.Dropdown(options=axis_ui_values, value='', description='Plot 1 (X):',
disabled=(not plot_data))
y_axis_plt1_drpdwn = widgets.Dropdown(options=axis_ui_values, value='', description='Plot 1 (Y):',
disabled=(not plot_data))
subject_plt2_drpdwn = widgets.Dropdown(options=subject_ui_values, value='', description='Subject 2:')
side_plt2_drpdwn = widgets.Dropdown(options=side_ui_values, value='', description='Side 2:')
activity_plt2_drpdwn = widgets.Dropdown(options=activity_ui_values, value='', description='Activity 2:')
userdata_plt2_drpdwn = widgets.Dropdown(options=userdata_ui_values, value='', description='User Data 2:')
x_axis_plt2_drpdwn = widgets.Dropdown(options=axis_ui_values, value='', description='Plot 2 (X):',
disabled=(not plot_data))
y_axis_plt2_drpdwn = widgets.Dropdown(options=axis_ui_values, value='', description='Plot 2 (Y):',
disabled=(not plot_data))
# Define new slider ui control
sample_plt1_sldr = widgets.IntRangeSlider(min=1, max=1, value=[1,1], step=1, description='Sample 1:',
disabled=True, continuous_update=False, orientation='horizontal',
layout=Layout(width='62%'))
sample_plt2_sldr = widgets.IntRangeSlider(min=1, max=1, value=[1,1], step=1, description='Sample 2:',
disabled=True, continuous_update=False, orientation='horizontal',
layout=Layout(width='62%'))
# Execute function 'filter_data_df_plt1', if 'filter_data_df_plt2' was clicked
query_plt1_btn.on_click(filter_data_df_plt1)
query_plt2_btn.on_click(filter_data_df_plt2)
# Execute function 'clear_plot_plt1', if 'clear_plt2_btn' was clicked
clear_plt1_btn.on_click(clear_plot_plt1)
clear_plt2_btn.on_click(clear_plot_plt2)
# Monitor values of dropdowns, and execute function 'update_sample_range_plt1', if value changed
subject_plt1_drpdwn.observe(update_sample_range_plt1, 'value')
side_plt1_drpdwn.observe(update_sample_range_plt1, 'value')
activity_plt1_drpdwn.observe(update_sample_range_plt1, 'value')
userdata_plt1_drpdwn.observe(update_sample_range_plt1, 'value')
subject_plt2_drpdwn.observe(update_sample_range_plt2, 'value')
side_plt2_drpdwn.observe(update_sample_range_plt2, 'value')
activity_plt2_drpdwn.observe(update_sample_range_plt2, 'value')
userdata_plt2_drpdwn.observe(update_sample_range_plt2, 'value')
# Define layout of ui controls
ui_elements1 = VBox([widgets.VBox([HBox([subject_plt1_drpdwn, side_plt1_drpdwn, activity_plt1_drpdwn]),
HBox([userdata_plt1_drpdwn, sample_plt1_sldr]),
HBox([x_axis_plt1_drpdwn, y_axis_plt1_drpdwn, clear_plt1_btn]),
HBox([query_plt1_btn])])])
ui_elements2 = VBox([widgets.VBox([HBox([subject_plt2_drpdwn, side_plt2_drpdwn, activity_plt2_drpdwn]),
HBox([userdata_plt2_drpdwn, sample_plt2_sldr]),
HBox([x_axis_plt2_drpdwn, y_axis_plt2_drpdwn, clear_plt2_btn]),
HBox([query_plt2_btn])])])
# Display ui controls as well as the output1
display(widgets.VBox([ui_elements1, ui_elements2, output1, output2]))
如果您能给我提供一个简单的例子,那将是很好的