前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用交互组件(ipywidgets)“盘活”Jupyter Notebook(上)

使用交互组件(ipywidgets)“盘活”Jupyter Notebook(上)

作者头像
AiTechYun
发布2019-05-15 14:36:55
13.2K1
发布2019-05-15 14:36:55
举报
文章被收录于专栏:ATYUN订阅号ATYUN订阅号

扩展Jupyter的用户界面

传统上,每次需要修改笔记本单元格的输出时,都需要更改代码并重新运行受影响的单元格。这可能很繁琐、低效甚至容易出错,对于非技术用户来说,甚至是不切实际的。这就是ipywidgets发挥作用的地方:它们可以嵌入到笔记本中,并提供一个用户友好的界面来收集用户输入并查看更改对数据/结果的影响,而不必与代码交互;你的笔记本可以从静态文档转换为动态仪表盘——非常适合显示你的数据故事!

范围:ipywidgets上的资源有限,很少有教程是不完整的,或者只关注交互功能/装饰器。这是一个完整的教程,介绍如何完全控制小部件来创建强大的仪表盘。我们将从基础开始:添加一个小部件并解释事件如何工作,然后逐步开发一个仪表盘。我将一步一步地指导你,以我们正在进行的示例为基础。

什么是小部件?

如果你曾经创建过图形用户界面(GUI),那么你已经知道小部件是什么。但让我们快速定义一下:

小部件是GUI元素,如按钮、下拉菜单或文本框,它驻留在浏览器中,允许我们通过响应事件和调用指定的处理程序来控制代码和数据。

可以组装和定制这些GUI元素来创建复杂的仪表盘。

演示:一些最流行的小部件

在本文中,我们将看到其中一些方法的实际应用。

准备好了吗?

开始

要开始使用这个库,我们需要安装ipywidgets扩展。如果使用conda,我们在终端输入这个命令:

代码语言:javascript
复制
1conda install -c conda-forge ipywidgets

对于pip,这将是一个两步的过程:1、安装和2、启用:

代码语言:javascript
复制
1pip install ipywidgetsjupyter nbextension enable --py widgetsnbextension

添加小部件

为了在笔记本中加入小部件,我们必须导入模块,如下图所示:

代码语言:javascript
复制
1import ipywidgets as widgets

要添加滑块,我们可以定义最小值和最大值、间隔大小(步骤)、说明和初始值:

代码语言:javascript
复制
1widgets.IntSlider(
2min=0,
3max=10,
4step=1,
5description='Slider:',
6value=3
7)

演示:滑块

显示

函数的作用是:在输入单元格中呈现小部件对象。

首先导入:

代码语言:javascript
复制
1from IPython.display import display

然后在display()函数中传递小部件作为参数:

代码语言:javascript
复制
1slider = widgets.IntSlider()
2display(slider)

获取/设置它的值

要读取小部件的值,我们将查询它的value属性。同样,我们可以设置小部件的值:

演示:值

连接两个小部件

我们可以使用jslink()函数同步两个小部件的值。

代码语言:javascript
复制
1slider = widgets.IntSlider()
2text = widgets.IntText()
3display(slider, text)widgets.jslink((slider, 'value'), (text, 'value'))

演示:链接

小部件列表

有关小部件的完整列表,你可以查看文档,或运行以下命令:

代码语言:javascript
复制
1print(dir(widgets))

处理小部件事件

小部件可以响应事件,这些事件在用户与它们交互时引发。一个简单的例子是点击一个按钮——我们期待一个动作发生。

让我们看看这是怎么工作的…

根据其特定的特性,每个小部件公开不同的事件。每次触发事件时都将执行事件处理程序。

事件处理程序是响应事件的回调函数,它异步操作并处理接收到的输入。

这里我们将创建一个名为btn的简单按钮。单击按钮时调用on_click方法。

我们的事件处理程序btn_eventhandler将打印一条带有按钮标题的短消息——注意,处理程序的输入参数obj是按钮对象本身,它允许我们访问它的属性。

要将事件与处理程序绑定,我们将后者分配给按钮的on_click方法。

代码语言:javascript
复制
1btn = widgets.Button(description='Medium')
2display(btn)def btn_eventhandler(obj):
3print('Hello from the {} button!'.format(obj.description))btn.on_click(btn_eventhandler)

演示:按钮事件处理程序

下一节我们将很好地了解到,输出与按钮本身显示在同一个单元格中。所以,让我们继续看看如何为我们的笔记本增加更多的灵活性!

控制部件的输出

在本节中,我们将探索如何使用小部件来控制dataframe。我选择的样本数据集是“前往伦敦的国际游客数量”(Number of International Visitors to London),它显示了伦敦游客在不同年份、不同季度、不同目的、不同持续时间、不同模式和不同国家的夜晚、访问次数和消费情况。

首先,我们将获取数据并将其加载到一个dataframe中:

代码语言:javascript
复制
1import pandas as pd
2import numpy as npurl = "https://data.london.gov.uk/download/number-international-visitors-london/b1e0f953-4c8a-4b45-95f5-e0d143d5641e/international-visitors-london-raw.csv"df_london = pd.read_csv(url)

df_london.样本

假设我们想按年过滤数据帧。我们首先定义一个下拉列表,并用唯一的年份值列表填充它。

为了做到这一点,我们将创建一个通用函数,unique-sorted-values-plus-all,它将找到唯一的值,对它们进行排序,然后在开始时添加all项,这样用户就可以删除过滤器。

代码语言:javascript
复制
1ALL = 'ALL'def unique_sorted_values_plus_ALL(array):
2unique = array.unique().tolist()
3unique.sort()
4unique.insert(0, ALL)
5return unique

现在我们将初始化下拉框:

代码语言:javascript
复制
1dropdown_year = widgets.Dropdown(options =    unique_sorted_values_plus_ALL(df_london.year))

下拉菜单小部件公开了observer方法,该方法接受一个函数,当下拉菜单的值发生更改时将调用该函数。因此,我们接下来将创建观察者处理程序来根据所选的值过滤数据aframe——注意,处理程序的输入参数change包含有关发生的更改的信息,这些更改允许我们访问新值(change.new)。

如果新值是所有我们删除过滤器,否则我们应用它:

代码语言:javascript
复制
1def dropdown_year_eventhandler(change):
2if (change.new == ALL):
3display(df_london)
4else:
5display(df_london[df_london.year == change.new])

然后我们将处理程序绑定到下拉列表:

代码语言:javascript
复制
1dropdown_year.observe(dropdown_year_eventhandler, names='value')

使用下拉列表筛选数据帧

到目前为止还不错,但是所有查询的输出都在这个非常相同的单元格中累积;也就是说,如果我们从下拉列表中选择一个新的年份,新的数据框将呈现在第一个单元格的下面,在同一个单元格上。

不过,理想的行为是每次刷新数据帧的内容。

捕获小部件输出

解决方法是在一种特殊的小部件(即输出)中捕获单元输出,然后将其显示在另一个单元中。

我们将稍微调整代码以:

  • 创建输出的新实例
代码语言:javascript
复制
1output_year = widgets.Output()
  • 调用事件处理程序中的clear_output方法,在每次迭代中清除先前的选择,并在with块中捕获数据帧的输出。
代码语言:javascript
复制
1def dropdown_year_eventhandler(change):
2output_year.clear_output()
3with output_year:
4display(df_london[df_london.year == change.new])
  • 然后我们将在一个新的单元格中显示输出:
代码语言:javascript
复制
1display(output_year)

这就是它的工作原理:

演示:捕获新单元格中的输出

正如你所看到的,输出在一个新的单元格中呈现,过滤工作正常!

好了,今天先学习到这里,剩下的部分我们下次继续~

End

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ATYUN订阅号 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 扩展Jupyter的用户界面
  • 开始
  • 处理小部件事件
  • 控制部件的输出
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档