PV8
PV8

Reputation: 6260

Using interact from ipywidgets with a dataframe

i am new to ipywidgets and trying to use the interactfrom this library in combination with a dataframe. My dataframe is:

df
KundenNR    Kundengruppe    Wertpapierart   Erlös   Kosten A    Kosten B
1   1   A   100     30  10
1   1   B   200     30  15
1   1   C   300     30  20

As far I did the following:

from ipywidgets import widgets, interact, interactive, fixed, interact_manual
from IPython.display import display
def f(x):
    df1 = df.copy()
    df1['Kosten A'] = x
    y = x*x
    print(df1, y)

interact(f, x=(10,50,5))

Which succesfully gives me the desired outcome, which means that I see the datframe and the column Kosten A is changed with the interaction button: enter image description here

I really wonder how can I pass the dataframe directly to the function, instead creating a copy out of it. Is there a solution for it?

Upvotes: 3

Views: 6558

Answers (2)

Tomasz Gandor
Tomasz Gandor

Reputation: 8823

Using fixed pseudo-widget is a way of passing extra arguments to the interacted function, which are not displayed as widgets. See: https://ipywidgets.readthedocs.io/en/latest/examples/Using%20Interact.html#Fixing-arguments-using-fixed

However, the implementation of fixed is very simple (interaction.py):

from traitlets import HasTraits, Any, Unicode

class fixed(HasTraits):
    """A pseudo-widget whose value is fixed and never synced to the client."""
    value = Any(help="Any Python object")
    description = Unicode('', help="Any Python object")
    def __init__(self, value, **kwargs):
        super(fixed, self).__init__(value=value, **kwargs)
    def get_interact_value(self):
        """Return the value for this widget which should be passed to
        interactive functions. Custom widgets can change this method
        to process the raw value ``self.value``.
        """
        return self.value

Thus, you can write your own pseudo-widget, fixed_copy:

import pandas as pd
from ipywidgets import interact, fixed

df = pd.DataFrame([1,2,3])

class fixed_copy(fixed):
    def get_interact_value(self):
        return self.value.copy()

@interact(x=(10, 50, 5), df=fixed_copy(df))
def f(x, df):
    df['Kosten A'] = x
    y = x*x
    return (df, y)

it shows the modified df nicely, but after that, the value of df is still:

   0
0  1
1  2
2  3

Upvotes: 1

ac24
ac24

Reputation: 5565

Pass the dataframe as an argument to the function wrapped with fixed. You should be able to call your dataframe afterwards and any changes due to your interact should be permanent.

    import pandas as pd
    from ipywidgets import widgets, interact, interactive, fixed, interact_manual
    from IPython.display import display

    df = pd.DataFrame([1,2,3])

    def f(x, df):
        df
        df['Kosten A'] = x
        y = x*x
        print(df, y)

    interact(f, x=(10,50,5), df = fixed(df))

Upvotes: 3

Related Questions