手把手教你做交互式数据分析报告

Jupyter-Book学习笔记(一)入门

源起

起初是领导让俺们编制一份轨道客流分析报告,传统做法就是画图,然后写word,事实上我们也是这么做的,然而我发现报告中的地理可视化图片只能看个大体情况,更何况有些地方还会被遮挡,无法进一步分析,就像下面这个样子,这就造成了做图时间花了很久,然而实际效果只有一瞬,并没有真正达到可视化的效果。

image.png

图 word中的地理可视化图片样例
于是我就想有没有一种快速简洁的方法可以制作一种网页化的分析报告,通过代码既可以实现周期性的更新,又可以像echarts那样制作可缩放、可交互的地理可视化,问题有了,说干就干。
前面也提到了我是一名交通行业从业者,对地理可视化的需求较多,而且在可视化美观度上要求较高,虽然Python目前支持地理图表的库有很多,但我还是首推三个:pyechartskepler.glplotly,下面重点围绕美观性和可交互性进行对比:

  • pyecharts和echarts比较类似,但在交互方面较之echarts还有所欠缺,但其地图可视化效果还是很值得夸赞的,尤其是支持js语言,并且网上教程很多;
  • kepler.gl是建立在mapbox的基础上开发的地图可视化系统,其可视化效果好,操作简单,并且有jupyter拓展包,和python衔接较好,但其定制化程度较低,一般情况下也够用;
  • 最后是plotly,plotly是一个非常强大的可视化工具包,尤其和其原生可视化框架Dash结合起来可以制作非常酷炫的交互式网页图表,其在地图可视化方面也很强,包含mapbox地图API,但地图制作较为繁琐,虽然灵活度方面较前者kepler.gl更高,但制作起来着实麻烦。

那么有没有工具可以将三者都融合进来呢?起先我想到了Python的Web可视化框架Dash,利用其开放的资料库可以很快的copy出一个数据报告页面,如下图所示,三者都可以集成到flask框架下,但如何在同一个页面中出现不同可视化框架的图表又是一个问题,对于一个几乎没有前端知识的我来说还是难度太大,无奈只能搁置(如果有读者可以指导一下万分感激)。直到我遇到了jupyter-book这款工具,它可以从 .ipynb.md 文件中构建美观、具有出版质量的书籍和文档,在官方教程的指导下,终于探索出了一条完整的交互式数据分析报告生成流程,完美的兼容了诸多可视化工具,在可视化呈现的同时可以实现必要的交互操作。下面就让我简单带大家回顾一下Jupyter-Book的学习历程。

image.png

图 Dash框架构建的分析报告样例

简述

Jupyter Book是一个开源项目,用于从 .ipynb.md 文件中构建美观,具有出版质量的书籍和文档。
特色

  • 在Markdown中编写具有出版物质量的内容

您可以使用Jupyter Markdown或其他Markdown工具(如:Typora等)来编写。这包括对丰富语法的支持,例如引文和交叉引用,数学和方程式以及图形。

  • 直接在Jupyter Notebook中编写内容

这使您可以将代码和输出包括在书中。您还可以完全在Markdown中编写代码,这些代码在构建书本时便会执行。

  • 可以将Jupyter Notebook中的输出插入到书籍中

在生成文档时生成输出结果,并将它们与您的内容跨页插入。

  • 获得多样化的输出

书籍可以输出成网页、PDF、ipynb等文件形式

  • 构造简单

使用简单的命令行即可构建书籍,像这样: jupyter-notebook build mybook/
输出结果:

image.png

安装

  • Juypter Notebook 或者 Jupyter Lab
  • pip install jupyter-book

基本工作流程

创建书籍

书籍目录中需要包含以下几个文件:

  • 配置文件(_config.yml)
  • 目录文件(_toc.yml)
  • 书籍内容(.md 、.ipynb)

新手可以通过简单命令行构建一个demo书籍,以便更好的了解书籍的构造内容:

jupyter-book create mybook/

模板书籍目录树:
├─mybook
│ content.md
│ intro.md
│ logo.png
│ markdown.md
│ notebooks.ipynb
│ references.bib
│ requirements.txt
│ _config.yml
│ _toc.yml

_config.yml 文件记录了在构建书籍所有的配置,其默认配置如下:

#######################################################################################
# A default configuration that will be loaded for all jupyter books
# Users are expected to override these values in their own `_config.yml` file.
# This is also the "master list" of all allowed keys and values.

#######################################################################################
# Book settings
title                       : My Jupyter Book  # The title of the book. Will be placed in the left navbar.
author                      : The Jupyter Book community  # The author of the book
copyright                   : "2020"  # Copyright year to be placed in the footer
logo                        : ""  # A path to the book logo
# Patterns to skip when building the book. Can be glob-style (e.g. "*skip.ipynb")
exclude_patterns            : [_build, Thumbs.db, .DS_Store, "**.ipynb_checkpoints"]

#######################################################################################
# Execution settings
execute:
  execute_notebooks         : auto  # Whether to execute notebooks at build time. Must be one of ("auto", "force", "cache", "off")
  cache                     : ""    # A path to the jupyter cache that will be used to store execution artifacs. Defaults to `_build/.jupyter_cache/`
  exclude_patterns          : []    # A list of patterns to *skip* in execution (e.g. a notebook that takes a really long time)
  timeout                   : 30    # The maximum time (in seconds) each notebook cell is allowed to run.
  run_in_temp               : false # If `True`, then a temporary directory will be created and used as the command working directory (cwd),
                                    # otherwise the notebook's parent directory will be the cwd.
  allow_errors              : false # If `False`, when a code cell raises an error the execution is stopped, otherwise all cells are always run.
  stderr_output             : show  # One of 'show', 'remove', 'remove-warn', 'warn', 'error', 'severe'

#######################################################################################
# Parse and render settings
parse:
  myst_extended_syntax      : false  # enable MyST extended syntax support (see documents for details)
  myst_url_schemes          : [mailto, http, https]  # URI schemes that will be recognised as external URLs in Markdown links

#######################################################################################
# HTML-specific settings
html:
  favicon                   : ""  # A path to a favicon image
  use_edit_page_button      : false  # Whether to add an "edit this page" button to pages. If `true`, repository information in repository: must be filled in
  use_repository_button     : false  # Whether to add a link to your repository button
  use_issues_button         : false  # Whether to add an "open an issue" button
  extra_navbar              : Powered by Jupyter Book  # Will be displayed underneath the left navbar.
  extra_footer              : ""  # Will be displayed underneath the footer.
  google_analytics_id       : ""  # A GA id that can be used to track book views.
  home_page_in_navbar       : true  # Whether to include your home page in the left Navigation Bar
  baseurl                   : ""  # The base URL where your book will be hosted. Used for creating image previews and social links. e.g.: https://mypage.com/mybook/
  comments:
    hypothesis              : false
    utterances              : false

#######################################################################################
# LaTeX-specific settings
latex:
  latex_engine              : pdflatex  # one of 'pdflatex', 'xelatex' (recommended for unicode), 'luatex', 'platex', 'uplatex'

#######################################################################################
# Launch button settings
launch_buttons:
  notebook_interface        : classic  # The interface interactive links will activate ["classic", "jupyterlab"]
  binderhub_url             : https://mybinder.org  # The URL of the BinderHub (e.g., https://mybinder.org)
  jupyterhub_url            : ""  # The URL of the JupyterHub (e.g., https://datahub.berkeley.edu)
  thebe                     : false  # Add a thebe button to pages (requires the repository to run on Binder)
  colab_url                 : "" # The URL of Google Colab (https://colab.research.google.com)

repository:
  url                       : https://github.com/executablebooks/jupyter-book  # The URL to your book's repository
  path_to_book              : ""  # A path to your book's folder, relative to the repository root.
  branch                    : master  # Which branch of the repository should be used when creating links

#######################################################################################
# Advanced and power-user settings
sphinx:
  extra_extensions          :   # A list of extra extensions to load by Sphinx (added to those already used by JB).
  local_extensions          :   # A list of local extensions to load by sphinx specified by "name: path" items
  config                    :   # key-value pairs to directly over-ride the Sphinx configuration

创建目录

jupyter-book的目录树是由 _toc.yml 文件控制的,目录组织如下:

  • _toc.yml文件的第一个条目是书的简介。这是书籍HTML的到达网页。
  • 随后的条目定义了本书的各部分或各章。这些构成了本书的主要结构。
  • 每章都可以选择包含由单独文件定义的部分。这些嵌套在本章首页的下面。
  • 在整个_toc.yml文件中, -file :条目指向构成书籍内容的文本文件。它们的路径是相对于本书的根源而言的,这些文件在目录文件中的名字是不带拓展名的

目录示例:

- file: myintro # 定义您的书籍的简介页。
  numbered: true # 对本书的所有部分进行编号,也可以单独在某一个部分、章节下面设置

- part: Get started # -part:# 将章节分为几类
  chapters: # 每一个part都要有一个chapters
  - file: start/overview
  - file: start/build

- part: Reference and test pages
  chapters:
  - file: test_pages/test
    sections: # 指定嵌套在文件下的部分
      - file: test_pages/layout_elements
      - file: test_pages/equations

创建内容

jupyter-book内含了两种解析引擎,一个是解析markdown文件的,一个是解析ipynb文件的

样式美化

jupyter-book默认使用Sphinx里面的主题,但其支持自定义CSS或者JavaScript来更改网页布局样式。
在此处添加静态文件:

├── _config.yml
├── _toc.yml
├── page1.md
└── _static
    └── myfile.css  #该文件就是我们自定义的css文件

例如:myfile.css

/* 设置表格样式 */
/* TABLES
=============================================================================*/
table {
    width: 100%; /*表格宽度*/
    max-width: 65em; /*表格最大宽度,避免表格过宽*/
    border: 1px solid #dedede; /*表格外边框设置*/
    margin: 15px auto; /*外边距*/
    border-collapse: collapse; /*使用单一线条的边框*/
    empty-cells: show; /*单元格无内容依旧绘制边框*/
}
table th {
    white-space: nowrap; /*表头内容强制在一行显示*/
    font-weight: bold; /*加粗*/
    text-align: center; /*内容居中,加上 !important 避免被 Markdown 样式覆盖*/
    background: rgba(158,188,226,0.2); /*背景色*/
}
table td {
  box-sizing: border-box;
  text-align: center;/*表格文字居中*/
}
table tbody tr:nth-child(2n) {
    background: rgba(158,188,226,0.12); /*设置偶数行背景颜色*/
}
table tr:hover {
    background: #efefef; /*鼠标悬停颜色*/
}
table td:nth-child(1) {
    white-space: nowrap; 
}

构造书籍

构造命令:

jupyter-book build mybook/

成功构造书籍后的目录树为:

│  content.md
│  intro.md
│  logo.png
│  markdown.md
│  notebooks.ipynb
│  references.bib
│  requirements.txt
│  _config.yml
│  _toc.yml
│  
└─_build
    ├─.doctrees
    │      content.doctree
    │      environment.pickle
    │      glue_cache.json
    │      intro.doctree
    │      markdown.doctree
    │      notebooks.doctree
    │      
    ├─html
    │  │  .buildinfo
    │  │  content.html
    │  │  genindex.html
    │  │  index.html
    │  │  intro.html
    │  │  markdown.html
    │  │  notebooks.html
    │  │  objects.inv
    │  │  search.html
    │  │  searchindex.js
    │  │  
    │  ├─_images
    │  │      notebooks_2_0.png
    │  │      
    │  ├─_panels_static
    │  │      panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css
    │  │      panels-variables.06eb56fa6e07937060861dad626602ad.css
    │  │      
    │  ├─_sources
    │  │      content.md
    │  │      intro.md
    │  │      markdown.md
    │  │      notebooks.ipynb
    │  │      
    │  └─_static
    │      │  basic.css
    │      │  clipboard.min.js
    │      │  copy-button.svg
    │      │  copybutton.css
    │      │  copybutton.js
    │      │  copybutton_funcs.js
    │      │  doctools.js
    │      │  documentation_options.js
    │      │  file.png
    │      │  jquery-3.5.1.js
    │      │  jquery.js
    │      │  language_data.js
    │      │  logo.png
    │      │  minus.png
    │      │  mystnb.css
    │      │  panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css
    │      │  panels-variables.06eb56fa6e07937060861dad626602ad.css
    │      │  plus.png
    │      │  pygments.css
    │      │  searchtools.js
    │      │  sphinx-book-theme.40e2e510f6b7d1648584402491bb10fe.css
    │      │  sphinx-book-theme.css
    │      │  sphinx-book-theme.d31b09fe5c1d09cb49b26a786de4a05d.js
    │      │  sphinx-thebe.css
    │      │  sphinx-thebe.js
    │      │  togglebutton.css
    │      │  togglebutton.js
    │      │  underscore-1.3.1.js
    │      │  underscore.js
    │      │  webpack-macros.html
    │      │  __init__.py
    │      │  
    │      ├─css
    │      │      index.73d71520a4ca3b99cfee5594769eaaae.css
    │      │      
    │      ├─images
    │      │      logo_binder.svg
    │      │      logo_colab.png
    │      │      logo_jupyterhub.svg
    │      │      
    │      ├─js
    │      │      index.3da636dd464baa7582d2.js
    │      │      
    │      ├─vendor
    │      │  ├─fontawesome
    │      │  │  └─5.13.0
    │      │  │      │  LICENSE.txt
    │      │  │      │  
    │      │  │      ├─css
    │      │  │      │      all.min.css
    │      │  │      │      
    │      │  │      └─webfonts
    │      │  │              fa-brands-400.eot
    │      │  │              fa-brands-400.svg
    │      │  │              fa-brands-400.ttf
    │      │  │              fa-brands-400.woff
    │      │  │              fa-brands-400.woff2
    │      │  │              fa-regular-400.eot
    │      │  │              fa-regular-400.svg
    │      │  │              fa-regular-400.ttf
    │      │  │              fa-regular-400.woff
    │      │  │              fa-regular-400.woff2
    │      │  │              fa-solid-900.eot
    │      │  │              fa-solid-900.svg
    │      │  │              fa-solid-900.ttf
    │      │  │              fa-solid-900.woff
    │      │  │              fa-solid-900.woff2
    │      │  │              
    │      │  ├─lato_latin-ext
    │      │  │  └─1.44.1
    │      │  │      │  index.css
    │      │  │      │  LICENSE.md
    │      │  │      │  
    │      │  │      └─files
    │      │  │              lato-latin-ext-100-italic.woff
    │      │  │              lato-latin-ext-100-italic.woff2
    │      │  │              lato-latin-ext-100.woff
    │      │  │              lato-latin-ext-100.woff2
    │      │  │              lato-latin-ext-300-italic.woff
    │      │  │              lato-latin-ext-300-italic.woff2
    │      │  │              lato-latin-ext-300.woff
    │      │  │              lato-latin-ext-300.woff2
    │      │  │              lato-latin-ext-400-italic.woff
    │      │  │              lato-latin-ext-400-italic.woff2
    │      │  │              lato-latin-ext-400.woff
    │      │  │              lato-latin-ext-400.woff2
    │      │  │              lato-latin-ext-700-italic.woff
    │      │  │              lato-latin-ext-700-italic.woff2
    │      │  │              lato-latin-ext-700.woff
    │      │  │              lato-latin-ext-700.woff2
    │      │  │              lato-latin-ext-900-italic.woff
    │      │  │              lato-latin-ext-900-italic.woff2
    │      │  │              lato-latin-ext-900.woff
    │      │  │              lato-latin-ext-900.woff2
    │      │  │              
    │      │  └─open-sans_all
    │      │      └─1.44.1
    │      │          │  index.css
    │      │          │  LICENSE.md
    │      │          │  
    │      │          └─files
    │      │                  open-sans-all-400-italic.woff
    │      │                  open-sans-all-400-italic.woff2
    │      │                  open-sans-all-400.woff
    │      │                  open-sans-all-400.woff2
    │      │                  
    │      └─__pycache__
    │              __init__.cpython-37.pyc
    │              
    └─jupyter_execute
            notebooks.ipynb
            notebooks.py
            notebooks_2_0.png
            

书籍发布

书籍可以上传至自己的GitHub仓库中,如果需要自己制作本地的JupyterBook,请参考这篇文章:自己制作本地的Jupyter Book -

你可能感兴趣的:(手把手教你做交互式数据分析报告)