Home > Software design >  Collect text data through ipywidgets and update a pandas dataframe
Collect text data through ipywidgets and update a pandas dataframe

Time:06-02

I am trying to collect data through ipywidgets. The objective once all the fields are filled , pressing the submit button should populate a row in a data frame. I wrote the following code

class record():
    def __init__(self):
        self.id = widgets.Text(description='id')
        self.paper = widgets.Text(description='paper')
        self.objective = widgets.Text(description='objective')
        self.language = widgets.Text(description='language')
        self.citations = widgets.Text(description='citations')
        self.notes = widgets.Text(description='notes')
        self.button = widgets.Button(description="Submit")
        self.button.on_click(self.on_button_clicked)
        display(self.id, self.paper, self.objective, self.language,self.citations,self.notes,self.button)

    def on_button_clicked(self,b):
        data = ('|').join([self.id.value,self.paper.value,self.objective.value,self.language.value,self.citations.value,self.notes.value])
        populate(data)

r =record()

The populate method has the code to populate the entries to the dataframe. id, paper, objective, language, citations, and notes are the column names of the data frame. Populate methods reads a saved dataframe adds an additional row and saves it. I am new to using ipywidgets how to call the populate function on button press?

CodePudding user response:

You could create an empty pandas dataframe at the beginning: df = pd.DataFrame(columns=('id', 'paper', 'objective','language','citations','notes')) and populate it each time the record button is being pressed:

def on_button_clicked(self,b):
    data = {'id':self.id.value,'paper':self.paper.value,'objective':self.objective.value,'language':self.language.value,'citations':self.citations.value,'notes':self.notes.value} #create a dictionary with the values from the widgets
    df.loc[len(df)]=data #append a new row at the end of the dataframe

And here is the full code:

import ipywidgets as widgets
import pandas as pd

df = pd.DataFrame(columns=('id', 'paper', 'objective','language','citations','notes'))
class record():
    def __init__(self):
        self.id = widgets.Text(description='id')
        self.paper = widgets.Text(description='paper')
        self.objective = widgets.Text(description='objective')
        self.language = widgets.Text(description='language')
        self.citations = widgets.Text(description='citations')
        self.notes = widgets.Text(description='notes')
        self.button = widgets.Button(description="Submit")
        self.button.on_click(self.on_button_clicked)
        display(self.id, self.paper, self.objective, self.language,self.citations,self.notes,self.button)

    def on_button_clicked(self,b):
        data = {'id':self.id.value,'paper':self.paper.value,'objective':self.objective.value,'language':self.language.value,'citations':self.citations.value,'notes':self.notes.value}
        df.loc[len(df)]=data
        print(df)
        
r =record()

Below is an example of the dataframe being populated over 3 iterations:

df after first iteration:

  id paper objective language citations notes
0  a     b         c        d         e     f

df second iteration:

  id paper objective language citations notes
0  a     b         c        d         e     f
1  g     h         i        j         k     l

and df after third time:

  id paper objective language citations notes
0  a     b         c        d         e     f
1  g     h         i        j         k     l
2  m     n         o        p         q     r

CodePudding user response:

IIUC, you can use the following code and it will populate the data frame df every time Submit button is clicked:

from ipywidgets import interact_manual
import ipywidgets as widgets
import pandas as pd

df = pd.DataFrame(columns=('ID', 'paper', 'objective','language','citations','notes'))

def populate(data):
    df.loc[len(df.index)] = data
    print(df)

def call_populate(ID, paper, objective, language, citations, notes):
    data = [ID, paper, objective, language, citations, notes]
    populate(data)
                  
im = interact_manual(call_populate, ID=widgets.Text(), paper=widgets.Text(), objective=widgets.Text(), \
                     language=widgets.Text(), citations=widgets.Text(), notes=widgets.Text())

im.widget.children[6].description = "Submit"

The widgets looks like this in Jupyter Notebook: enter image description here

I have not used id in this code because it's a reserved word for built-in function in Python.

If Submit is clicked when ID = 1, paper = Diamond, objective = History, language = Urdu, citations = 421, notes = None is entered into the text boxes, df becomes:

  ID     paper objective language citations notes
0  1  Diamond    History     Urdu       421  None

When Submit is clicked with ID = 2, paper = Brain and behavior, objective = Neuroscience, language = English, citations = 101, notes = Biology is entered, df becomes:

  ID               paper     objective language citations    notes
0  1            Diamond        History     Urdu       421     None
1  2  Brain and behavior  Neuroscience  English       101  Biology

If you can modify argument of populate from data to ID, paper, objective, language, citations, notes, you can directly use widget to invoke populate. In that case, the function declaration of populate would like:

def populate(ID, paper, objective, language, citations, notes):
   # Transform inputs to data and pass that to df
   ...

In this case, your widget will need to call populate directly, keeping everything else same in the code written above for widget:

im = interact_manual(populate, ...)
  • Related