如何在不加倍代码的情况下重用小部件?

时间:2019-05-21 12:19:45

标签: python jupyter-notebook ipywidgets

我正在用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]))

Screenshot

如果您能给我提供一个简单的例子,那将是很好的

0 个答案:

没有答案