{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Fastpages Notebook 博客示例\n", "\n", "> fastai的项目fastpages,可以直接将 Jupyter notebooks以博客发布\n", "\n", "- toc: true \n", "- badges: true\n", "- comments: true\n", "- categories: [jupyter]\n", "- image: images/chart-preview.png" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 简介\n", "\n", "以下内容演示[fastpages](https://github.com/fastai/fastpages)处理notebook的能力\n", "\n", "\n", "在你的`fastpages`代码仓库中,将jupyter notebook保存到`_notebooks`文件夹并提交到master分支,就可以借助GitHub的actions自己生成Jekyll博客啦!\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Front matter模板设置\n", "\n", "Jupyter Notebook第一个单元格,或markdown文件的最前面需要配置metadata。示例如下:\n", "\n", "```\n", "# \"My Title\"\n", "> \"Awesome summary\"\n", "\n", "- toc: true- branch: master- badges: true\n", "- comments: true\n", "- author: Hamel Husain & Jeremy Howard\n", "- categories: [fastpages, jupyter]\n", "```\n", "\n", "- `toc: true` 自动生成目录\n", "- `badges: true` 自动配置带徽章的GitHub、ninder和Google Colab链接\n", "- `comments: true` 支持github issue评论,借助[utterances](https://github.com/utterance/utterances)实现\n", "\n", "如果标题中包含特殊字符(如冒号),可以用双引号括起来。关于Front matter的更多详情参考[front matter section](https://github.com/fastai/fastpages#front-matter-related-options)的README文件。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Markdown快捷方式" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在单元格上方加`#hide`,**可以在博客中同时隐藏输入和输出**\n", "\n", "在单元格上方加`#hide_input`**在博客中仅隐藏输入**" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The comment #hide_input was used to hide the code that produced this.\n" ] } ], "source": [ "#hide_input\n", "print('The comment #hide_input was used to hide the code that produced this.')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在单元格上方加`#collapse-hide`可以实现默认**隐藏**内容的控件,点击按钮可以显示:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "#collapse-hide\n", "import pandas as pd\n", "import altair as alt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在单元格上方加`#collapse-show`可以实现默认**显示**内容的控件,点击按钮可以隐藏:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "#collapse-show\n", "cars = 'https://vega.github.io/vega-datasets/data/cars.json'\n", "movies = 'https://vega.github.io/vega-datasets/data/movies.json'\n", "sp500 = 'https://vega.github.io/vega-datasets/data/sp500.csv'\n", "stocks = 'https://vega.github.io/vega-datasets/data/stocks.csv'\n", "flights = 'https://vega.github.io/vega-datasets/data/flights-5k.json'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 与Altair交互\n", "\n", "Altair支持交互图形,下面示例取自[项目](https://github.com/uwdata/visualization-curriculum),都在[这个notebook](https://github.com/uwdata/visualization-curriculum/blob/master/altair_interaction.ipynb)里面。" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# hide\n", "df = pd.read_json(movies) # load movies data\n", "genres = df['Major_Genre'].unique() # get unique field values\n", "genres = list(filter(lambda d: d is not None, genres)) # filter out None values\n", "genres.sort() # sort alphabetically" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "#hide\n", "mpaa = ['G', 'PG', 'PG-13', 'R', 'NC-17', 'Not Rated']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 示例 1: DropDown" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "" ], "text/plain": [ "alt.Chart(...)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# single-value selection over [Major_Genre, MPAA_Rating] pairs\n", "# use specific hard-wired values as the initial selected values\n", "selection = alt.selection_single(\n", " name='Select',\n", " fields=['Major_Genre', 'MPAA_Rating'],\n", " init={'Major_Genre': 'Drama', 'MPAA_Rating': 'R'},\n", " bind={'Major_Genre': alt.binding_select(options=genres), 'MPAA_Rating': alt.binding_radio(options=mpaa)}\n", ")\n", " \n", "# scatter plot, modify opacity based on selection\n", "alt.Chart(movies).mark_circle().add_selection(\n", " selection\n", ").encode(\n", " x='Rotten_Tomatoes_Rating:Q',\n", " y='IMDB_Rating:Q',\n", " tooltip='Title:N',\n", " opacity=alt.condition(selection, alt.value(0.75), alt.value(0.05))\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 示例 2: Tooltips" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "" ], "text/plain": [ "alt.Chart(...)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "alt.Chart(movies).mark_circle().add_selection(\n", " alt.selection_interval(bind='scales', encodings=['x'])\n", ").encode(\n", " x='Rotten_Tomatoes_Rating:Q',\n", " y=alt.Y('IMDB_Rating:Q', axis=alt.Axis(minExtent=30)), # use min extent to stabilize axis title placement\n", " tooltip=['Title:N', 'Release_Date:N', 'IMDB_Rating:Q', 'Rotten_Tomatoes_Rating:Q']\n", ").properties(\n", " width=600,\n", " height=400\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 示例 3: More Tooltips" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# select a point for which to provide details-on-demand\n", "label = alt.selection_single(\n", " encodings=['x'], # limit selection to x-axis value\n", " on='mouseover', # select on mouseover events\n", " nearest=True, # select data point nearest the cursor\n", " empty='none' # empty selection includes no data points\n", ")\n", "\n", "# define our base line chart of stock prices\n", "base = alt.Chart().mark_line().encode(\n", " alt.X('date:T'),\n", " alt.Y('price:Q', scale=alt.Scale(type='log')),\n", " alt.Color('symbol:N')\n", ")\n", "\n", "alt.layer(\n", " base, # base line chart\n", " \n", " # add a rule mark to serve as a guide line\n", " alt.Chart().mark_rule(color='#aaa').encode(\n", " x='date:T'\n", " ).transform_filter(label),\n", " \n", " # add circle marks for selected time points, hide unselected points\n", " base.mark_circle().encode(\n", " opacity=alt.condition(label, alt.value(1), alt.value(0))\n", " ).add_selection(label),\n", "\n", " # add white stroked text to provide a legible background for labels\n", " base.mark_text(align='left', dx=5, dy=-5, stroke='white', strokeWidth=2).encode(\n", " text='price:Q'\n", " ).transform_filter(label),\n", "\n", " # add text labels for stock prices\n", " base.mark_text(align='left', dx=5, dy=-5).encode(\n", " text='price:Q'\n", " ).transform_filter(label),\n", " \n", " data=stocks\n", ").properties(\n", " width=700,\n", " height=400\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 表格\n", "\n", "notebook代码生成表格可以直接在博客中显示:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TitleWorldwide_GrossProduction_BudgetDistributorMPAA_RatingIMDB_RatingRotten_Tomatoes_Rating
0The Land Girls146083.08000000.0GramercyR6.1NaN
1First Love, Last Rites10876.0300000.0StrandR6.9NaN
2I Married a Strange Person203134.0250000.0LionsgateNone6.8NaN
3Let's Talk About Sex373615.0300000.0Fine LineNoneNaN13.0
4Slam1087521.01000000.0TrimarkR3.462.0
\n", "
" ], "text/plain": [ " Title Worldwide_Gross Production_Budget Distributor \\\n", "0 The Land Girls 146083.0 8000000.0 Gramercy \n", "1 First Love, Last Rites 10876.0 300000.0 Strand \n", "2 I Married a Strange Person 203134.0 250000.0 Lionsgate \n", "3 Let's Talk About Sex 373615.0 300000.0 Fine Line \n", "4 Slam 1087521.0 1000000.0 Trimark \n", "\n", " MPAA_Rating IMDB_Rating Rotten_Tomatoes_Rating \n", "0 R 6.1 NaN \n", "1 R 6.9 NaN \n", "2 None 6.8 NaN \n", "3 None NaN 13.0 \n", "4 R 3.4 62.0 " ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "movies = 'https://vega.github.io/vega-datasets/data/movies.json'\n", "df = pd.read_json(movies)\n", "# display table with pandas\n", "df[['Title', 'Worldwide_Gross', \n", " 'Production_Budget', 'Distributor', 'MPAA_Rating', 'IMDB_Rating', 'Rotten_Tomatoes_Rating']].head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 图像\n", "\n", "### 本地图像\n", "\n", "\n", "可以引用本地图片,它们会被自动复制并在博客中渲染。可以用markdown实现:\n", "\n", "`![](my_icons/fastai_logo.png)`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](my_icons/fastai_logo.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 远程图片\n", "\n", "远程图片语法如下:\n", "\n", "`![](https://image.flaticon.com/icons/svg/36/36686.svg)`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](https://image.flaticon.com/icons/svg/36/36686.svg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Gif动画\n", "\n", "Gif动画,当日没问题!\n", "\n", "`![](https://upload.wikimedia.org/wikipedia/commons/7/71/ChessPawnSpecialMoves.gif)`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](https://upload.wikimedia.org/wikipedia/commons/7/71/ChessPawnSpecialMoves.gif)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 图片说明(Caption)\n", "\n", "图片说明可以用下面markdown语法实现:\n", "\n", "```\n", "![](https://www.fast.ai/images/fastai_paper/show_batch.png \"Credit: https://www.fast.ai/2020/02/13/fastai-A-Layered-API-for-Deep-Learning/\")\n", "```\n", "\n", "\n", "![](https://www.fast.ai/images/fastai_paper/show_batch.png \"Credit: https://www.fast.ai/2020/02/13/fastai-A-Layered-API-for-Deep-Learning/\")\n", "\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 其他元素" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## GitHub Flavored Emojis\n", "\n", "输入 `I give this post two :+1:!` 渲染颜文字:\n", "\n", "I give this post two :+1:!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tweet卡片\n", "\n", "输入 `> twitter: https://twitter.com/jakevdp/status/1204765621767901185?s=20` 渲染推文:\n", "\n", "> twitter: https://twitter.com/jakevdp/status/1204765621767901185?s=20" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Youtube视频\n", "\n", "输入 `> youtube: https://youtu.be/XfoYk_Z5AkI` 渲染视频:\n", "\n", "\n", "> youtube: https://youtu.be/XfoYk_Z5AkI" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 提示文字(Boxes / Callouts )\n", "\n", "输入 `> Warning: There will be no second warning!` 效果:\n", "\n", "\n", "> Warning: There will be no second warning!\n", "\n", "\n", "\n", "输入 `> Important: Pay attention! It's important.` 效果:\n", "\n", "> Important: Pay attention! It's important.\n", "\n", "\n", "\n", "输入 `> Tip: This is my tip.` 效果:\n", "\n", "> Tip: This is my tip.\n", "\n", "\n", "\n", "输入 `> Note: Take note of this.` 效果:\n", "\n", "> Note: Take note of this.\n", "\n", "\n", "\n", "输入 `> Note: A doc link to [an example website: fast.ai](https://www.fast.ai/) should also work fine.` 效果:\n", "\n", "> Note: A doc link to [an example website: fast.ai](https://www.fast.ai/) should also work fine." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 尾注\n", "\n", "可以在notebook里加尾注,但不是用markdown语法实现,[具体语法请看说明](https://github.com/fastai/fastpages/blob/master/_fastpages_docs/NOTEBOOK_FOOTNOTES.md)。\n", "\n", "```\n", "{% raw %}For example, here is a footnote {% fn 1 %}.\n", "And another {% fn 2 %}\n", "{{ 'This is the footnote.' | fndetail: 1 }}\n", "{{ 'This is the other footnote. You can even have a [link](www.github.com)!' | fndetail: 2 }}{% endraw %}\n", "```\n", "\n", "For example, here is a footnote {% fn 1 %}.\n", "\n", "And another {% fn 2 %}\n", "\n", "{{ 'This is the footnote.' | fndetail: 1 }}\n", "{{ 'This is the other footnote. You can even have a [link](www.github.com)!' | fndetail: 2 }}" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": false, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": false, "toc_window_display": false }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 4 }