使用 Pandas 和 ipywidgets 创建交互式图表,利用数据框列中的值作为输入。

4
我有一个Pandas数据框,其中列出了许多公司、它们在一个月内收到的消费者投诉数量和投诉接收的月份:

Company complaints

我试图创建一个交互式图表,在下拉菜单中显示“company”下的所有值,并且当用户选择一个公司时,一条折线图会自动更新以查看该公司随时间收到的投诉数。在某种程度上,我已经构建了各个组件:
dropdown = widgets.Dropdown(options = sorted(list(set(df['company']))))

将显示

下拉菜单

然后,我可以执行以下代码,使用dropdown.value来显示一个图表,可以使用df.plotdf.iplot

df.plot 示例:

def line_plot(df, company):

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

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

line_plot(df, dropdown.value)

df.plot示例

df.iplot示例:

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

df.iplot示例

我遇到的问题是如何将公司名称用作我要生成的绘图的输入。我一直在阅读ipywidgets的相关文档,但我发现所有的示例都使用数据框列本身作为下拉菜单值,而不是特定的列值。我尝试了以下方法:

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

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

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

并且获取这个回溯信息:

---------------------------------------------------------------------------
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

除此之外:

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

并接收

---------------------------------------------------------------------------
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

我是否正在正确的方向上前进,或者我想要实现的内容是否可能通过ipywidgets实现?我将继续探究这个问题。


你为什么要将line_plot函数的company参数默认值设置为sorted(df['company'].unique())列表?我认为此时可能df还没有初始化。对于像列表这样的容器,要小心使用默认函数参数,这总是很棘手的。 - CrazyElf
1个回答

2
我已经想出了一种方法(有点)实现它,尽管理想情况下我希望“列”下拉菜单不可见:

可能的解决方案


1
如果您使用 column = widgets.fixed(['company']),那个下拉菜单将会被隐藏。 - dmvianna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接