0

I'm looking for help to add two dynamically generated dataframes. Both DataFrames have a column computed on input from an intslider ipywidget. the third Dataframe should update dynamically on changes of any of above Dataframes

import pandas as pd
from ipywidgets import interact
@interact(x=(0,1000,10))
def df_draw_one(x):
    data = {"A":[1,2,3,4,5]}
    df_one = pd.DataFrame(data)
    df_one['B'] = df_one['A']*x
    print(df_one)
@interact(x=(0,1000,10))
def df_draw_two(x):
    data = {"A":[6,7,8,9,10]}
    df_two = pd.DataFrame(data)
    df_two['B'] = df_two['A']*x
    print(df_two)
df_res = df_one+df_two

I understand with the current code, df_one and two are local and hence result in:

NameError: name 'df_one' is not defined

but I'm at loss on how to make them accessible. Any pointer would be appreciated

CodeRed
  • 905
  • 1
  • 6
  • 24

1 Answers1

0

You can have your functions return the two dataframe adding a return statement.

import pandas as pd
from ipywidgets import interact


@interact(x=(0, 1000, 10))
def df_draw_one(x):
    data = {"A": [1, 2, 3, 4, 5]}
    df_one = pd.DataFrame(data)
    df_one['B'] = df_one['A'] * x
    print(df_one)
    return df_one


@interact(x=(0, 1000, 10))
def df_draw_two(x):
    data = {"A": [6, 7, 8, 9, 10]}
    df_two = pd.DataFrame(data)
    df_two['B'] = df_two['A'] * x
    print(df_two)
    return df_two


df_one = df_draw_one(1)
df_two = df_draw_two(1)

df_res = df_one + df_two
print(df_res)

Another way is to have df_one and df_two as global variables, but it's dirty and not really necessary.

Update One idea could be to have both widget generated in the same function, then everything becomes more easy to handle.

import pandas as pd
from ipywidgets import interact


@interact()
def df_draw_one(x=(0, 1000, 10), y=(0, 1000, 10)):

    data = {"A": [1, 2, 3, 4, 5]}
    df_one = pd.DataFrame(data)
    df_one['B'] = df_one['A'] * x

    data2 = {"A": [6, 7, 8, 9, 10]}
    df_two = pd.DataFrame(data2)
    df_two['B'] = df_two['A'] * y

    display(df_one)
    display(df_two)
    df_res = df_one + df_two
    display(df_res)

Here my result:

Here my result

mucio
  • 7,014
  • 1
  • 21
  • 33
  • I had that one at some point. the catch is that x in both dataframes df_res is set to x. – Stefan Spycher Sep 27 '19 at 11:50
  • (appending to previous comment) ` A B 0 7 7 1 9 9 2 11 11 3 13 13 4 15 15 ` – Stefan Spycher Sep 27 '19 at 12:00
  • do understand better, you want both the df to be controlled by the same slider? – mucio Sep 27 '19 at 12:29
  • good question. no. i want both df's to be independably adjustable, and df_res should dynamically update on any individual changes of df_one or df_two – Stefan Spycher Sep 27 '19 at 13:10
  • I think if you put both in the same function everything become more easy :) – mucio Sep 27 '19 at 13:31
  • thanks a lot! your update is *exactly* what i was looking for. works like a charm. there's heavy flickering while dragging the sliders, but that's (for now) neglectable. KUDOS – Stefan Spycher Sep 27 '19 at 13:52
  • You welcome, I am using SO questions as an opportunity to learn more Python, about the flickering you can take a look at the [documentation](https://ipywidgets.readthedocs.io/en/latest/examples/Using%20Interact.html#Flickering-and-jumping-output). – mucio Sep 27 '19 at 13:55