提交 4c4b685e 编写于 作者: W wizardforcel

2021-03-06 22:42:55

上级 dfc12328
......@@ -134,7 +134,7 @@ HTTP 方法
鉴于没有运行 JavaScript 代码且未加载任何外部资源,在这里,我们将尽可能地看到呈现的 HTML。 例如,不会呈现在`jupyter.org`服务器上的图像,而是显示`alt`文本:**编程图标圆圈**,**jupyter 徽标**等,依此类推。
9. 让我们将其与实时网站进行比较,可以使用 IFrame 在 Jupyter 中打开它。 通过运行以下代码来执行此操作:
9. 让我们将其与实时网站进行比较,可以使用`IFrame`在 Jupyter 中打开它。 通过运行以下代码来执行此操作:
```py
from IPython.display import IFrame
......@@ -143,9 +143,9 @@ HTTP 方法
![Handling HTTP requests Jupyter NotebooksHTTP requests, handling with Pythonwith Python in a Jupyter Notebook](img/image3_07.jpg)
在这里,我们看到了完整的网站,包括 JavaScript 和外部资源。 实际上,我们甚至可以单击超链接并将这些页面加载到 IFrame 中,就像常规浏览会话一样。
在这里,我们看到了完整的网站,包括 JavaScript 和外部资源。 实际上,我们甚至可以单击超链接并将这些页面加载到`IFrame`中,就像常规浏览会话一样。
10. 在使用 IFrame 后,最好关闭它。 这样可以防止它耗尽内存和处理能力。 可以通过从 Jupyter笔记本的“单元格”菜单中选择单元格并单击“当前输出 | 清除”来关闭它。
10. 在使用`IFrame`后,最好关闭它。 这样可以防止它耗尽内存和处理能力。 可以通过从 Jupyter笔记本的“单元格”菜单中选择单元格并单击“当前输出 | 清除”来关闭它。
回想一下我们如何使用准备好的请求和会话在 Python 中以字符串形式请求此内容。 通常,这是使用速记方法来完成的。 缺点是我们没有太多的请求标头自定义,但这通常很好。
......@@ -402,7 +402,7 @@ HTTP 方法
页面应在笔记本电脑中加载。 向下滚动,我们可以看到按人口标题显示的世界**国家及其人口**表。 我们将从此表中刮取前三列,以获取国家/地区,人口和年度人口变化。
4. 通过选择单元格并从 Jupyter 笔记本的**单元格**菜单中单击**当前输出 | 清空**,关闭 IFrame
4. 通过选择单元格并从 Jupyter 笔记本的**单元格**菜单中单击**当前输出 | 清空**,关闭`IFrame`
5. 通过运行以下代码来请求页面并将其作为`BeautifulSoup`对象加载:
```py
......
......@@ -71,7 +71,7 @@ app.run()
**注意**:允许在片段中使用 CSS 和 JavaScript。
* `@route`装饰器可以具有一个或多个关键字参数,这些参数必须为 String 类型。 可以将这些关键字参数视为请求参数,PixieApp 框架在内部使用这些参数根据以下规则将的请求分发到最匹配的路由:
* `@route`装饰器可以具有一个或多个关键字参数,这些参数必须为字符串类型。 可以将这些关键字参数视为请求参数,PixieApp 框架在内部使用这些参数根据以下规则将的请求分发到最匹配的路由:
* 带有最多参数的路由始终首先​​被评估。
* 所有参数都必须匹配才能选择路由。
......@@ -331,7 +331,7 @@ def do_search(self, query):
</div>
```
我们在`pd_options`属性中使用`$val()`指令来动态检索 ID 等于`"query{{prefix}}"`的输入框的值,并将其存储在 query 参数中。
我们在`pd_options`属性中使用`$val()`指令来动态检索 ID 等于`"query{{prefix}}"`的输入框的值,并将其存储在`query`参数中。
## 在表格中显示搜索结果
......@@ -395,7 +395,7 @@ def do_search(self, query):
前面的代码示例显示了 PixieApps 的一个非常重要的属性,即您可以通过简单地将数据存储到类变量中来维护应用程序整个生命周期中的状态。 在这种情况下,我们使用`self.first_url``self.prev_url``self.next_url``self.last_url`。 这些变量对分页小部件中的每个按钮使用`pd_options`属性,并在每次调用`do_retrieve_page`路由时更新。 `do_search`返回的片段现在返回带有主体占位符的表,该表由`body{{prefix}},`标识,该表成为每个按钮的`pd_target`。 我们还使用`invoke_route`方法来确保在首次显示表格时获得第一页。
我们之前已经看到路由返回的 HTML 片段用于替换整个页面,但是在前面的代码中,我们使用`pd_target="body{{prefix}}"`属性表示 HTML 片段将被注入到表的 body 元素中 具有`body{{prefix}}` ID。 如果需要,您还可以通过创建一个或多个`<target>`元素作为可点击源元素的子元素来为用户操作定义多个目标。 每个`<target>`元素本身都可以使用所有 PixieApp 自定义属性来配置内核请求。
我们之前已经看到路由返回的 HTML 片段用于替换整个页面,但是在前面的代码中,我们使用`pd_target="body{{prefix}}"`属性表示 HTML 片段将被注入到表的 BODY 元素中 具有`body{{prefix}}` ID。 如果需要,您还可以通过创建一个或多个`<target>`元素作为可点击源元素的子元素来为用户操作定义多个目标。 每个`<target>`元素本身都可以使用所有 PixieApp 自定义属性来配置内核请求。
这是一个例子:
......@@ -574,9 +574,9 @@ class RepoAnalysis():
操作按钮链接由`<a>`标记定义,并使用`pd_options`访问具有一个称为`analyse_type`以及`pd_target`指向`"analyse_vis{{prefix}}"`占位符`<div>,`的自变量的路由。 在以下相同的 HTML 片段中定义。
## 使用 pd_entity 属性调用 PixieDust display()API
## 使用`pd_entity`属性调用 PixieDust `display()` API
当使用`pd_options`属性创建内核请求时,PixieApp 框架将当前 PixieApp 类用作目标。 但是,您可以通过指定`pd_entity`属性来更改此目标。 例如,您可以指向另一个 PixieApp,或更有趣的是,指向`display()` API 支持的数据结构,例如Pandas或 Spark `DataFrame`。 在这种情况下,如果您提供了`display()` API 预期的正确选项,则生成的输出将为图表本身(对于 Matplotlib,为图像;对于 Mapbox,为 Iframe;对于 Mapbox,则为 SVG 散景)。 一种获取正确选项的简单方法是在其自己的单元格中调用`display()` API,使用菜单将其配置为所需的图表,然后通过单击**编辑元数据**复制可用的单元格元数据 JSON 片段。 按钮。 (您可能首先需要使用菜单**视图 | 单元格工具栏 | 编辑元数据**来启用按钮)。
当使用`pd_options`属性创建内核请求时,PixieApp 框架将当前 PixieApp 类用作目标。 但是,您可以通过指定`pd_entity`属性来更改此目标。 例如,您可以指向另一个 PixieApp,或更有趣的是,指向`display()` API 支持的数据结构,例如Pandas或 Spark `DataFrame`。 在这种情况下,如果您提供了`display()` API 预期的正确选项,则生成的输出将为图表本身(对于 Matplotlib,为图像;对于 Mapbox,为 IFRAME;对于 Mapbox,则为 SVG 散景)。 一种获取正确选项的简单方法是在其自己的单元格中调用`display()` API,使用菜单将其配置为所需的图表,然后通过单击**编辑元数据**复制可用的单元格元数据 JSON 片段。 按钮。 (您可能首先需要使用菜单**视图 | 单元格工具栏 | 编辑元数据**来启用按钮)。
您也可以指定`pd_entity`,不带任何值。 在这种情况下,PixieApp 框架将使用传递为用于启动 PixieApp 应用程序的`run`方法的第一个参数的实体。 例如,以`cars`为Pandas的`my_pixieapp.run(cars)`或通过`pixiedust.sampleData()`方法创建的 Spark `DataFrame``pd_entity`的值也可以是返回实体的函数调用。 当您要在渲染之前动态计算实体时,这很有用。 与其他变量一样,`pd_entity`的范围可以是 PixieApp 类或在笔记本中声明的任何变量。
......@@ -623,7 +623,7 @@ test.run()
在前面的代码中,为简单起见,我将密钥硬编码为`'prefix'`,然后将其作为练习使用输入控件和`$val()`指令使其可用户定义。
值得注意的另一件事是在显示图表的 div 中使用`pd_render_onload`属性。 此属性告诉 PixieApp 在将元素加载到浏览器 DOM 中后立即执行该元素定义的内核请求。
值得注意的另一件事是在显示图表的 DIV 中使用`pd_render_onload`属性。 此属性告诉 PixieApp 在将元素加载到浏览器 DOM 中后立即执行该元素定义的内核请求。
以下屏幕快照显示了先前 PixieApp 的结果:
......@@ -686,7 +686,7 @@ def load_commit_activity(owner, repo_name):
![Invoking the PixieDust display() API using pd_entity attribute](img/00058.jpeg)
在单独的单元格中使用 display()获取可视化配置
在单独的单元格中使用`display()`获取可视化配置
要获取上述图表,您需要选择**折线图**,然后在**选项**对话框中,将`week`列拖放到**键**框和`total`列到**值**框。 您还需要选择 Bokeh 作为渲染器。 完成后,请注意,PixieDust 将自动检测到`x`轴为日期时间,并将相应地调整渲染。
......@@ -694,7 +694,7 @@ def load_commit_activity(owner, repo_name):
![Invoking the PixieDust display() API using pd_entity attribute](img/00059.jpeg)
捕获 display()JSON 配置
捕获`display()` JSON 配置
然后在`load_commit_activity`有效载荷中返回它:
......@@ -734,7 +734,7 @@ def do_analyse_type(self, analyse_type):
[您可以在此处找到代码文件](https://github.com/DTAIEB/Thoughtful-Data-Science/blob/master/chapter%203/sampleCode12.py)
路由有一个名为`analyse_type,`的参数,我们将其用作在`analyses`数组中查找 load 函数的键(注意,我再次使用列表推导来快速进行搜索)。 然后,我们调用传递回购所有者和名称的此函数来获取`vis_info` JSON 有效负载,并将 Pandas`DataFrame`存储到名为`pdf`的类变量中。 然后,返回的 HTML 片段将`pdf`用作`pd_entity`值,将`vis_info["chart_options"]`用作`pd_optio` `ns`。 在这里,我使用[`tojson` Jinja2 过滤器](http://jinja.pocoo.org/docs/templates/#list-of-builtin-filters)来确保在生成的 HTML 中正确进行了转义 。 即使已在堆栈上声明了`vis_info`变量,也允许我使用它,因为我为函数使用了`@templateArgs`装饰器。
路由有一个名为`analyse_type,`的参数,我们将其用作在`analyses`数组中查找`load`函数的键(注意,我再次使用列表推导来快速进行搜索)。 然后,我们调用传递回购所有者和名称的此函数来获取`vis_info` JSON 有效负载,并将 Pandas`DataFrame`存储到名为`pdf`的类变量中。 然后,返回的 HTML 片段将`pdf`用作`pd_entity`值,将`vis_info["chart_options"]`用作`pd_optio` `ns`。 在这里,我使用[`tojson` Jinja2 过滤器](http://jinja.pocoo.org/docs/templates/#list-of-builtin-filters)来确保在生成的 HTML 中正确进行了转义 。 即使已在堆栈上声明了`vis_info`变量,也允许我使用它,因为我为函数使用了`@templateArgs`装饰器。
在测试改进的应用程序之前,要做的最后一件事是确保主要的`GitHubTracking` PixieApp 类继承自`RepoAnalysis` PixieApp:
......@@ -947,7 +947,7 @@ GitHub 存储库的摘要统计信息
[您可以在此处找到`Github Tracking`应用程序第 3 部分的完整笔记本](https://github.com/DTAIEB/Thoughtful-Data-Science/blob/master/chapter%203/GitHub%20Tracking%20Application/GitHub%20Sample%20Application%20-%20Part%203.ipynb)
## 使用 pd_refresh 使应用程序响应更快
## 使用`pd_refresh`使应用程序响应更快
我们希望通过使**显示统计信息**按钮直接显示统计信息表格,而不是让用户再次单击菜单来改善用户体验。 类似于加载**提交活动**的菜单,我们可以向复选框添加`pd_options`属性,其中`pd_target`属性指向`analyse_vis{{prefix}}`元素。 无需在触发新显示的每个控件中复制`pd_options`,我们可以将其添加到`analyse_vis{{prefix}}`一次,并使用`pd_refresh`属性对其进行更新。
......@@ -955,7 +955,7 @@ GitHub 存储库的摘要统计信息
![Making the application more responsive with pd_refresh](img/00062.jpeg)
有和没有 pd_refresh 的序列图
有和没有`pd_refresh`的序列图
在这两种情况下,步骤 1 都是在服务器端更新某些状态。 在步骤 2 中显示的**控件**调用路由的情况下,请求规范存储在控件本身中,触发步骤 3,该步骤将生成 HTML 片段并将其注入目标元素中 。 使用`pd_refresh`,控件不知道`pd_options`来调用路由,相反,它仅使用`pd_refresh`来向目标元素发信号,从而依次调用路由。 在这种设计中,我们只需要在目标元素中指定一次请求,并且用户控件只需要在触发刷新之前更新状态即可。 这使实现更易于维护。
......
......@@ -82,7 +82,7 @@ app.run()
[您可以在此处找到代码](https://github.com/DTAIEB/Thoughtful-Data-Science/blob/master/chapter%205/sampleCode1.py)
注意,只需将`@captureOutput`装饰器添加到`generate_word_cloud`路由,我们不再需要返回 HTML 片段字符串。 我们可以简单地调用 Matplotlib `imshow()`函数,该函数将图像发送到系统输出。 PixieApp 框架将负责捕获输出并将其打包为 HTML 片段字符串,并将其插入正确的 div 占位符中。 结果如下:
注意,只需将`@captureOutput`装饰器添加到`generate_word_cloud`路由,我们不再需要返回 HTML 片段字符串。 我们可以简单地调用 Matplotlib `imshow()`函数,该函数将图像发送到系统输出。 PixieApp 框架将负责捕获输出并将其打包为 HTML 片段字符串,并将其插入正确的 DIV 占位符中。 结果如下:
### 注意
......@@ -134,7 +134,7 @@ PixieApp 使用@captureOutput 和 Markdown
* 具有`pd_app`属性的动态调用其他 PixieApps
* 将应用程序的一部分打包为可重用的小部件
使用`pd_app`属性,您可以通过其完全限定的类名动态调用另一个 PixieApp(从此处开始,将其称为子 PixieApp)。 子 PixieApp 的输出通过使用`runInDialog=true`选项放置在宿主 HTML 元素(通常是 div 元素)或对话框中。 您也可以使用`pd_options`属性初始化子 PixieApp,在这种情况下,框架将调用相应的路由。
使用`pd_app`属性,您可以通过其完全限定的类名动态调用另一个 PixieApp(从此处开始,将其称为子 PixieApp)。 子 PixieApp 的输出通过使用`runInDialog=true`选项放置在宿主 HTML 元素(通常是 DIV 元素)或对话框中。 您也可以使用`pd_options`属性初始化子 PixieApp,在这种情况下,框架将调用相应的路由。
为了更好地理解`pd_app`的工作原理,让我们通过重构在自己的 PixieApp 中生成`WordCloud`图像的代码(我们称为`WCChildApp`)来重写`WordCloud`应用程序。
......@@ -196,7 +196,7 @@ app.run()
* `pd_app="WCChildApp"`:使用子 PixieApp 的类名。 请注意,如果您的孩子 PixieApp 生活在导入的 Python 模块中,则需要使用完全限定的名称。
* `pd_options="url=$val(url{{prefix}})"`:将用户输入的 URL 作为初始化选项存储到子 PixieApp。
* `pd_target="wordcloud{{prefix}}"`:告诉 PixieDust 将子 PixieApp 的输出放在 ID 为`wordcloud{{prefix}}`div 中。
* `pd_target="wordcloud{{prefix}}"`:告诉 PixieDust 将子 PixieApp 的输出放在 ID 为`wordcloud{{prefix}}`DIV 中。
通过封装组件的逻辑和表示,`pd_app`属性是一种将代码模块化的强大方法。 `pd_widget`属性提供了另一种获得相似结果的方法,但是这次该组件不是在外部调用,而是通过继承调用。
......@@ -217,7 +217,7 @@ app.run()
1. 创建一个 PixieApp 类,该类包含标记有名为`widget`的特殊参数的路由
2. 使主类继承自 PixieApp 小部件
3. 使用 div 元素上的`pd_widget`属性调用窗口小部件
3. 使用 DIV 元素上的`pd_widget`属性调用窗口小部件
再次,作为说明,让我们用小部件重写`WordCloud`应用程序:
......@@ -244,7 +244,7 @@ class WCChildApp():
[您可以在此处找到代码文件](https://github.com/DTAIEB/Thoughtful-Data-Science/blob/master/chapter%205/sampleCode4.py)
注意,在前面的代码中,`url`现在被引用为类变量,因为我们假设基类将提供它。 代码必须测试`url`是否为`None,`,这在启动时就是这种情况。 我们以这种方式实现它,因为`pd_widget`是无法轻易动态生成的属性(您将不得不使用带有`pd_widget`属性生成 div 片段的辅助路由)。
注意,在前面的代码中,`url`现在被引用为类变量,因为我们假设基类将提供它。 代码必须测试`url`是否为`None,`,这在启动时就是这种情况。 我们以这种方式实现它,因为`pd_widget`是无法轻易动态生成的属性(您将不得不使用带有`pd_widget`属性生成 DIV 片段的辅助路由)。
现在,主要的 PixieApp 类如下所示:
......@@ -275,7 +275,7 @@ app.run()
[您可以在此处找到代码文件](https://github.com/DTAIEB/Thoughtful-Data-Science/blob/master/chapter%205/sampleCode5.py)
包含`pd_widget`属性的 div 在开始时就会呈现,但是由于`url`仍然是`None`,因此实际上没有生成词云。 `Go`按钮具有`pd_script`属性,该属性将`self.url`设置为用户提供的值。 它还具有`pd_widget` div`pd_refresh`属性集,该属性将再次调用`wordcloud`小部件,但是这次 URL 初始化为正确的值。
包含`pd_widget`属性的 DIV 在开始时就会呈现,但是由于`url`仍然是`None`,因此实际上没有生成词云。 `Go`按钮具有`pd_script`属性,该属性将`self.url`设置为用户提供的值。 它还具有`pd_widget` DIV`pd_refresh`属性集,该属性将再次调用`wordcloud`小部件,但是这次 URL 初始化为正确的值。
在本节中,我们已经看到了两种用于模块化代码以供重用的方法,以及两种方法的利弊。 我强烈建议您使用代码,以获取何时使用每种技术的感觉。 如果您觉得这仍然有些模糊,请不要担心。 当我们在前面各章的示例代码中使用这些技术时,希望它将变得更加清晰。
......@@ -416,7 +416,7 @@ display(adapter)
[您可以在此处找到代码文件](https://github.com/DTAIEB/Thoughtful-Data-Science/blob/master/chapter%205/sampleCode9.py)
前一个 div 通过`pd_entity`属性绑定到`avgChannelData`实体,并负责创建每秒更新一次的实时图表(`pd_refresh_rate = 1000 ms`)。 依次通过对`getStreamingChannel(),`的调用来创建`avgChannelData`实体,该调用将传递给`self``computeAverage`功能负责更新所有流数据的平均值。 重要的是要注意,`avgChannelData`是从`StreamingDataAdapter`继承的类,因此可以传递给`display()`框架以构建实时图表。
前一个 DIV 通过`pd_entity`属性绑定到`avgChannelData`实体,并负责创建每秒更新一次的实时图表(`pd_refresh_rate = 1000 ms`)。 依次通过对`getStreamingChannel(),`的调用来创建`avgChannelData`实体,该调用将传递给`self``computeAverage`功能负责更新所有流数据的平均值。 重要的是要注意,`avgChannelData`是从`StreamingDataAdapter`继承的类,因此可以传递给`display()`框架以构建实时图表。
最后一个难题是让 PixieApp 返回`display()`框架所需的`displayHandler`。 这是通过重写`newDisplayHandler()`方法来完成的,如下所示:
......@@ -547,7 +547,7 @@ PixieApp 框架支持使用浏览器中可用的发布-订阅模式在不同组
在组件之间发送/接收事件
在以下代码示例中,我们通过构建两个发布者(一个按钮元素和一个表,其中每行都是一个事件源)来说明 PixieDust 事件系统。 我们还有两个实现为 div 元素的侦听器:
在以下代码示例中,我们通过构建两个发布者(一个按钮元素和一个表,其中每行都是一个事件源)来说明 PixieDust 事件系统。 我们还有两个实现为 DIV 元素的侦听器:
```py
from pixiedust.display.app import *
......
......@@ -1159,7 +1159,7 @@ print("Number of tweets received: {}".format(streams_manager.twitter_stream.list
* 我们调用三个不同的路由(`display_metric1`,`display_metric2`和`display_wc`),分别显示三个小部件。
`display_metric1`和`display_metric2`路由非常相似。 他们返回一个带有`parquet_df`作为`pd_entity`的 div 和一个自定义`<pd_options>`子元素,该子元素包含传递给 PixieDust `display()`层的 JSON 配置。
`display_metric1`和`display_metric2`路由非常相似。 他们返回一个带有`parquet_df`作为`pd_entity`的 DIV 和一个自定义`<pd_options>`子元素,该子元素包含传递给 PixieDust `display()`层的 JSON 配置。
以下代码显示了`display_metric1`路由的实现:
......
......@@ -1055,7 +1055,7 @@ $("[id^=slider][id$={{prefix}}]").each(function() {
[您可以在此处找到代码文件](https://github.com/DTAIEB/Thoughtful-Data-Science/blob/master/chapter%208/sampleCode19.py)
`MovingAverageSubApp`中,我们使用`add_ticker_selection_markup`装饰器并将`chart{{prefix}}`作为默认路由的参数,以添加股票选择器选项卡,并添加一个名为`lag_slider``<div>`元素,其中包含`<pd_event_handler>`设置`self.lag`变量并刷新`chart` div。 `chart` div`pd_entity`属性与调用`rolling`方法的[`get_moving_average_df()`方法](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.rolling.html)一起使用,从选定的Pandas `DataFrame`返回滚动均值,并在其上调用`mean()`方法。 由于 PixieDust `display()`尚不支持 Pandas 系列,因此我们将系列索引用作名为`x`的列来构建 Pandas `DataFrame`,并以`get_moving_average_df()`方法返回它。
`MovingAverageSubApp`中,我们使用`add_ticker_selection_markup`装饰器并将`chart{{prefix}}`作为默认路由的参数,以添加股票选择器选项卡,并添加一个名为`lag_slider``<div>`元素,其中包含`<pd_event_handler>`设置`self.lag`变量并刷新`chart` div。 `chart` DIV`pd_entity`属性与调用`rolling`方法的[`get_moving_average_df()`方法](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.rolling.html)一起使用,从选定的Pandas `DataFrame`返回滚动均值,并在其上调用`mean()`方法。 由于 PixieDust `display()`尚不支持 Pandas 系列,因此我们将系列索引用作名为`x`的列来构建 Pandas `DataFrame`,并以`get_moving_average_df()`方法返回它。
以下代码显示了`MovingAverageSubApp`子 PixieApp 的实现
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册