Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating an interactive plot with pandas and ipywidgets, using values from dataframe column as inputs

I have a Pandas dataframe which lists a number of companies, the number of consumer complaints which they have received within the month, and the month when they were received:

Company complaints

I am trying to create an interactive plot where all of the values under 'company' are displayed in a dropdown menu, and when a user chooses a company string, a line plot will automatically update to see how many complaints the company has received over time. I have the separate components built to some extent:

dropdown = widgets.Dropdown(options = sorted(list(set(df['company']))))

will display

dropdown

And then I can execute the following code to display a plot with the dropdown.value, either with df.plot or df.iplot:

df.plot example:

def line_plot(df, company):

    df = df[df['company'] == company]

    df.set_index('month').plot()

line_plot(df, dropdown.value)

df.plot example

df.iplot example:

df1 = df[df['company'] == dropdown.value]
df1.iplot(kind = 'line', x = 'month', y = 'complaints')

df.iplot example

Where I am having trouble is actually figuring out how to use the company name as an input for the plot that I want to generate. I have been reading up on ipywidgets and all of the examples I find use the dataframe columns themselves as the dropdown menu values rather than particular column values. I've tried the following:

@interact
def line_plot(company = sorted(df['company'].unique())):

    df = df[df['company'] == company]

    df.iplot(kind = 'line', x = company)

And get this traceback:

---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
/Applications/anaconda3/lib/python3.7/site-packages/ipywidgets/widgets/interaction.py in update(self, *args)
    254                     value = widget.get_interact_value()
    255                     self.kwargs[widget._kwarg] = value
--> 256                 self.result = self.f(**self.kwargs)
    257                 show_inline_matplotlib_plots()
    258                 if self.auto_display and self.result is not None:

<ipython-input-1040-3e3ff8e76afe> in line_plot(company)
      2 def line_plot(company = sorted(df['company'].unique())):
      3 
----> 4     df = df[df['company'] == company]
      5 
      6     df.iplot(kind = 'line', x = company)

UnboundLocalError: local variable 'df' referenced before assignment

As well as:

interactive_plot = interactive(line_plot, df = df, company = sorted(list(set(df['company']))))
interactive_plot

And receive

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/Applications/anaconda3/lib/python3.7/site-packages/ipywidgets/widgets/interaction.py in update(self, *args)
    254                     value = widget.get_interact_value()
    255                     self.kwargs[widget._kwarg] = value
--> 256                 self.result = self.f(**self.kwargs)
    257                 show_inline_matplotlib_plots()
    258                 if self.auto_display and self.result is not None:

<ipython-input-1026-e7a7c82e3c6b> in line_plot(df, company)
      1 def line_plot(df, company):
      2 
----> 3     df = df[df['company'] == company]
      4 
      5     df.set_index('month').plot()

TypeError: string indices must be integers

Am I heading in the right direction, or is what I am trying to achieve even possible with ipywidgets? I will continue to investigate how this might work.

like image 636
njrob Avatar asked Oct 25 '25 14:10

njrob


1 Answers

I have figured out a way to (kind of) achieve it, although ideally I would like that 'column' dropdown to not be visible:

Possible solution

like image 118
njrob Avatar answered Oct 28 '25 06:10

njrob



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!