{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Fastpages Notebook Blog Post\n", "> A tutorial of fastpages for 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": [ "# About\n", "\n", "This notebook is a demonstration of some of capabilities of [fastpages](https://github.com/fastai/fastpages) with notebooks.\n", "\n", "\n", "With `fastpages` you can save your jupyter notebooks into the `_notebooks` folder at the root of your repository, and they will be automatically be converted to Jekyll compliant blog posts!\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Front Matter\n", "\n", "The first cell in your Jupyter Notebook or markdown blog post contains front matter. Front matter is metadata that can turn on/off options in your Notebook. It is formatted like this:\n", "\n", "```\n", "# 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", "- Setting `toc: true` will automatically generate a table of contents\n", "- Setting `badges: true` will automatically include GitHub and Google Colab links to your notebook.\n", "- Setting `comments: true` will enable commenting on your blog post, powered by [utterances](https://github.com/utterance/utterances).\n", "\n", "More details and options for front matter can be viewed on the [front matter section](https://github.com/fastai/fastpages#front-matter-related-options) of the README." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Markdown Shortcuts" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A `#hide` comment at the top of any code cell will hide **both the input and output** of that cell in your blog post.\n", "\n", "A `#hide_input` comment at the top of any code cell will **only hide the input** of that cell." ] }, { "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": [ "put a `#collapse-hide` flag at the top of any cell if you want to **hide** that cell by default, but give the reader the option to show it:" ] }, { "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": [ "put a `#collapse-show` flag at the top of any cell if you want to **show** that cell by default, but give the reader the option to hide it:" ] }, { "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": [ "## Interactive Charts With Altair\n", "\n", "Charts made with Altair remain interactive. Example charts taken from [this repo](https://github.com/uwdata/visualization-curriculum), specifically [this 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": [ "### Example 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": [ "### Example 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": [ "### Example 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": [ "## Data Tables\n", "\n", "You can display tables per the usual way in your blog:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " | Title | \n", "Worldwide_Gross | \n", "Production_Budget | \n", "Distributor | \n", "MPAA_Rating | \n", "IMDB_Rating | \n", "Rotten_Tomatoes_Rating | \n", "
---|---|---|---|---|---|---|---|
0 | \n", "The Land Girls | \n", "146083.0 | \n", "8000000.0 | \n", "Gramercy | \n", "R | \n", "6.1 | \n", "NaN | \n", "
1 | \n", "First Love, Last Rites | \n", "10876.0 | \n", "300000.0 | \n", "Strand | \n", "R | \n", "6.9 | \n", "NaN | \n", "
2 | \n", "I Married a Strange Person | \n", "203134.0 | \n", "250000.0 | \n", "Lionsgate | \n", "None | \n", "6.8 | \n", "NaN | \n", "
3 | \n", "Let's Talk About Sex | \n", "373615.0 | \n", "300000.0 | \n", "Fine Line | \n", "None | \n", "NaN | \n", "13.0 | \n", "
4 | \n", "Slam | \n", "1087521.0 | \n", "1000000.0 | \n", "Trimark | \n", "R | \n", "3.4 | \n", "62.0 | \n", "