IPywidgets bind dynamically widgets to Output

1.4k views Asked by At

I'm writing a function for Jupyter notebooks, where a user will be able to obtain data as Pandas Dataframe (irrelevant for this question) and display it with filters he could create when needed.

My problem is that I can't "link" the interact filter to the data itself. I had no problems to define manually the filters in the code, but not from the user side. I researched a lot questions from Stackoverflow, Google, project Github and docs before posting here.

Here is the POC:

import pandas as pd
import ipywidgets as widgets
from ipywidgets import *
from IPython.display import display
import numpy as np

np.random.seed(0)

# Data example
my_columns = list('ABCD')
df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))


# Encapsulate Table inside Output widget

table_out = widgets.Output()

with table_out:
    display(df)


# Filter for ints
def filter_int(column, x):
    return df.loc[df[column] > x]

# Our filter generator
def generate_filter(button):
    # Check if exist before creating
    if not select_definition.value in [ asd.children[0].description for asd in filters.children ]:
        # Not exist. Create this filter
        new_filter = interactive(
            filter_int, # Our filter for ints
            column=fixed(select_definition.value), # Which column as filter
            x=widgets.IntSlider(min=0, max=100, step=1, value=10, description=select_definition.value) # Value from the user
        )
        # Append created filter
        filters.children=tuple(list(filters.children) + [new_filter])

# Define button and event
button = widgets.Button(description="Add")
button.on_click(generate_filter)

# Define Dropdown 
select_definition = widgets.Dropdown(options=my_columns, layout=Layout(width='10%'))

# Put Dropdown and button together
choose_filter = widgets.HBox([select_definition, button])

# Where we will put all our filters
filters = widgets.HBox()

display(choose_filter, filters, table_out)

Which will create this:

enter image description here

I'm able to create the filters for the columns dynamically, but I'm not sure how to make them update the table and link together (so the table will be updated based on multiple filters).

The expected result is to be able create filters for column A and B and update the table with values defined by them, as shown in the image below:

enter image description here

Any help is appreciated!

Note: The last image was generated with df.loc[(df['A'] > 22) & (df['B'] > 92)]

0

There are 0 answers