- 数据可视化
- 数据分析
【免费下载链接】plotly.py
The interactive graphing library for Python :sparkles:
plotly.py 是 Python 生态中最流行的交互式绘图库之一,而其官网教程(https://plotly.com/python/)与 API 参考文档(https://plotly.com/python-api-reference/)并非手工维护的静态页面,而是由仓库内doc/目录中的 Markdown 教程、Sphinx 配置与一套 CI/CD 流水线自动生成并部署的。本文以仓库根目录下的 doc/README.md 为核心,结合 doc/Makefile、doc/apidoc/Makefile、doc/requirements.txt 与 .github/workflows/build-doc.yml 等源码级证据,完整讲解 plotly.py 文档系统的目录结构、本地构建环境、教程 frontmatter 规范、双分支发布策略、API 文档生成机制以及 CI/CD 自动部署链路。读完本文,你将具备在本地搭建文档环境、新建/修改教程页面、单页调试构建、理解并排查文档 CI 失败的完整能力。
一、文档体系总览:doc/目录的两大组成部分
根据 doc/README.md 的说明,doc目录保存了 plotly.py 全部文档的源文件,由两个相互独立的部分组成:
| 子目录 | 内容 | 对应线上站点 |
|---|---|---|
| doc/python/ | 按主题组织的使用教程(Tutorials) | https://plotly.com/python/ |
| doc/apidoc/ | 生成 API 参考文档的配置文件(Sphinx + autodoc) | https://plotly.com/python-api-reference/ |
教程部分是 Markdown(.md)文件,每个文件对应一个主题页面,例如 bar-charts.md、heatmaps.md、line-charts.md 等,目前仓库中已有上百个主题文件;此外doc/unconverted/python/中保留了一批尚未转换的旧版主题(如userguide.md、cmocean-colorscales.md等),它们主要用于生成 v3 旧版文档的跳转页面。
API 参考部分则使用 Sphinx 及其autodoc扩展,从 plotly.py 的 Python 源码 docstring 中自动提取 API 文档,采用 reST(reStructuredText)标记语言,配置位于 doc/apidoc/ 目录内。
构建文档所需的全部 Python 依赖被锁定在 doc/requirements.txt 中,其中既有构建工具(如jupytext==1.16.4、nbconvert==5.6.1、sphinx==3.5.4),也有教程示例运行时依赖的各种数据科学库(pandas==1.4.0、numpy==1.22.4、scipy==1.9.1、geopandas==0.8.1、datashader==0.14.4、statsmodels==0.14.2等),还固定了文档构建环境所对应的 plotly 发布版本(当前为plotly==7.0.0)。
二、本地环境搭建:用 uv 建立文档专用虚拟环境
构建文档需要一套与日常开发隔离的专用环境。官方推荐的流程基于uv(一个高性能的 Python 包管理器),并明确要求 Python 3.9:
cd doc uv venv --python 3.9 source .venv/bin/activate uv pip install -r requirements.txt重要系统依赖:
requirements.txt中geopandas==0.8.1的构建需要系统级 GDAL 库(gdal.org)。如果系统缺少gdal,上述uv pip install步骤会直接失败,安装前请先通过系统包管理器安装 GDAL。
为未发布的新功能编写文档:editable install
如果你正在为尚未发布的新功能撰写文档,还必须将本地代码库以可编辑模式(editable install)安装,使本地源码修改能即时反映到文档示例中:
uv pip uninstall plotly # 移除 requirements.txt 安装的 PyPI 版本 uv pip install -e .. # 从本地 checkout 安装这样做的好处是:修改源码后只需重启 Jupyter kernel,无需重新安装即可让新功能出现在教程示例中。而发布后(或doc-prod分支)的文档构建则直接使用requirements.txt中固定的plotly==版本,这也是发布前必须同步更新该版本号的原因(详见下文"分支同步"一节)。
三、教程写作:Markdown + Jupyter 的双格式工作流
doc/python/下的每个教程都是一个 Markdown 文件,但它并非普通 Markdown——通过安装 jupytext(requirements.txt中锁定为jupytext==1.16.4),同一个文件可以在 Jupyter Notebook / JupyterLab 中直接打开,代码块被识别为 Notebook 单元格。这种"文本优先、双格式共存"的方式让文档既能用 Git 精确 diff,又能像 Notebook 一样交互执行。
3.1 分支策略:doc-prod与main双轨运行
文档更新采用两条长期分支并行管理的策略:
doc-prod分支:承载线上实时文档。任何合并到doc-prod的改动会立即部署并公开展示。main分支:承载尚未发布的文档(例如为下一个 plotly.py 版本的新功能准备的教程)。
由此产生两种工作流:
| 场景 | 从哪个分支切出 | PR 合入哪个分支 |
|---|---|---|
| 为已发布功能更新文档 | doc-prod | doc-prod(合并即上线) |
| 为未发布新功能编写文档 | main | main(随版本发布时合入doc-prod) |
保持两分支同步:doc-prod的改动不会自动回流到main,需要定期通过 PR(例如命名为merge-doc-prod-to-main-branch的分支)手动合并,防止分叉。而在发布时刻,同步是双向的:
doc-prod→main:把近期仅限文档的修复合并进main;main→doc-prod:把包含新功能文档的main合并进doc-prod,使新功能文档随版本上线;- 发布站点:更新
plotly/graphing-library-docs的 "Update documentation site" 一节。
发布前检查:将
main同步进doc-prod时,务必同步更新 doc/requirements.txt 中的plotly==版本锁定。doc-prod构建使用的是锁定版本而非 editable 安装,若版本号过旧,依赖新特性的示例会构建失败。
3.2 教程文件格式:YAML frontmatter 详解
教程文件头部包含一段 YAML frontmatter,承载两类元数据:Jupyter 元数据(供 jupytext 识别为 Notebook)与plotly 专用元数据(供文档站点用于导航、SEO 与分类)。以 doc/python/bar-charts.md 为例,其 frontmatter 结构如下:
--- jupyter: jupytext: notebook_metadata_filter: all text_representation: extension: .md format_name: markdown format_version: '1.3' jupytext_version: 1.17.3 kernelspec: display_name: Python 3 (ipykernel) 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.9.0 plotly: description: How to make Bar Charts in Python with Plotly. display_as: basic language: python layout: base name: Bar Charts order: 3 page_type: example_index permalink: python/bar-charts/ thumbnail: thumbnail/bar.jpg ---其中plotly元数据字段是创建/更新教程时最需要准确填写的部分:
| 字段 | 含义 |
|---|---|
name | 页面标题,显示在侧边栏与浏览器标签页 |
permalink | URL 路径,必须与文件名一致(如bar-charts.md→python/bar-charts/) |
description | 搜索引擎使用的页面摘要 |
display_as | 分类分组(如basic、statistical、scientific、maps、3d_charts、file_settings) |
order | 分类内的数字排序 |
page_type | 教程页面通常为example_index |
thumbnail | 缩略图路径 |
代码单元以带有python语言标记的围栏代码块(fenced code block)书写,每个代码块之间以空行分隔;Markdown 文本则作为普通文本写在代码块之间。转换时每个```python代码块会成为独立的 Jupyter 单元格。这些元数据最终会被 doc/nb.tpl 模板重新输出为 Jekyll 兼容的 frontmatter(见下文"构建过程")。
3.3 创建新教程页面的完整步骤
doc/README.md 给出了新建教程的六步流程:
- 复制一个现有教程:从 doc/python/ 复制已有文件作为起点,保证 frontmatter 结构正确;
- 更新 frontmatter:至少修改
name、permalink、description、display_as、order,并确保permalink与文件名匹配(my-feature.md→python/my-feature/); - 编写示例:使用围栏
python代码块,每个代码块在转换后成为独立 Jupyter 单元格; - 在 Jupyter 中测试:安装 jupytext 后直接用 JupyterLab 打开文件并逐个运行单元格验证示例:
jupyter lab doc/python/my-feature.md - (可选)单页构建:只构建当前页面而非整套文档:
cd doc make build/html/2019-07-03-my-feature.html - 检查 CI 通过:推送分支并开启 PR,CI 会构建所有页面并对 frontmatter 与页面排序做校验。
3.4 写作准则
文档项目对教程示例有一套明确的质量要求:示例应短小、独立、近乎自解释,且多数示例聚焦单一特性。写作检查清单如下:
- 每个示例有清晰标题(标题用于导航栏并被搜索引擎索引);
- 包导入与示例代码写在同一个单元格中,便于读者复制单个单元格即可复现;
- 变量命名与其他示例保持一致(
fig表示Figure对象、df表示 pandas DataFrame 等); - 示例执行时间不宜过长(通常 < 10 秒)——文档构建是 CI 流程的一部分,执行过久的示例需先在 issue 中讨论能否被接受。
四、构建流程:jupytext + nbconvert 的幕后机制
4.1 全量构建所有教程
从doc目录、激活虚拟环境后,一条make命令即可构建全部教程:
cd doc source .venv/bin/activate make在 doc/Makefile 中,构建管线对python/下每个.md文件依次执行以下步骤:
- 拼接页脚:将 what_about_dash.md("What About Dash?" 章节,介绍如何把
fig.show()的图表放进 Dash 应用)追加到每个教程末尾; - Markdown → Notebook:用jupytext将 Markdown 转换为 Jupyter notebook(输出到
build/ipynb/):@cat $< what_about_dash.md | jupytext --to notebook --quiet --output $@ - 执行并转 HTML:用nbconvert执行 notebook 并以自定义模板 doc/nb.tpl 渲染为 HTML(默认每 notebook 10 分钟超时,即
--ExecutePreprocessor.timeout=600); - 输出 HTML:写入
build/html/,文件名带2019-07-03-日期前缀; - 生成跳转页:为 v3 旧文档(基于
unconverted/python/,指向https://plot.ly/python/v3/...,见 doc/next_redirect.tpl 与 Makefile 中v3-redir规则)和"下一版本"预览(redirect-next,permalink 替换为python/next/)生成重定向页面。
doc/nb.tpl模板的作用是把 notebook 元数据中的plotly字段重新输出为 Jekyll 兼容的 frontmatter(---包裹的键值对),并用{% raw %}包裹正文防止 Jekyll Liquid 引擎误解析 Python 代码中的模板语法。
并行构建(CI 采用的方式):
make -kj8其中-k让 make 在某个目标失败后继续构建其余目标,-j8同时运行 8 个构建任务。
4.2 单页构建
开发调试时只需构建单个页面:
make build/html/2019-07-03-bar-charts.html文件名遵循2019-07-03-<markdown 文件名去掉扩展名>.html的模式。
为什么用
2019-07-03-前缀?下游graphing-library-docs站点基于 Jekyll,其_posts/集合只处理符合YYYY-MM-DD-title.ext模式的文件,其余文件会被静默忽略。这个具体日期只是任意占位符,其值从不显示,仅用于满足 Jekyll 的文件名解析器。
4.3 构建输出目录
| 目录 | 内容 |
|---|---|
doc/build/ipynb/ | 中间产物 Jupyter notebook 文件 |
doc/build/html/ | 最终 HTML 教程页面 |
doc/build/html/redir/ | 重定向页面(v3 与 next-version) |
doc/build/failures/ | 构建失败页面的 stderr 日志 |
若某个页面构建失败,前往doc/build/failures/<page-name>查看完整错误输出。
五、API 参考文档:Sphinx + autodoc 的生成机制
API 参考部分(对应线上 python-api-reference)使用 Sphinx 及其autodoc扩展,从源码 docstring 自动生成,标记语言为 reST。关键配置文件包括:
- doc/apidoc/conf.py:Sphinx 配置(主题、扩展等);
- doc/apidoc/_static/:CSS 等静态资源;
- doc/apidoc/_templates/:reST 模板,决定各类型对象的 autodoc 外观(如 trace.rst、class_figure.rst)。
5.1 构建 API 文档
API 文档构建要求 plotly 为editable 安装,因为构建过程会临时修改源文件(把 Sphinx 无法解析的graph_objects交叉引用改写为内部名称graph_objs,构建结束后再还原):
cd doc source .venv/bin/activate uv pip uninstall plotly uv pip install -e .. cd apidoc make html输出写入apidoc/_build/html/。
5.2 构建过程七步拆解
doc/apidoc/Makefile 中完整实现了以下步骤:
- 用
sed临时将plotly/graph_objs/下所有:class:\plotly.graph_objects交叉引用改写为plotly.graph_objs`(覆盖 1~4 层嵌套子目录),使 Sphinx 能正确解析; - 把
_plotly_utils/colors/下的sequential.py、diverging.py、qualitative.py、cyclical.py、colorbrewer.py、carto.py、cmocean.py复制到plotly/colors/与plotly/express/colors/,使这些颜色模块的 docstring 能被收录进 API 文档; - 运行
sphinx-apidoc自动从 Python 源码生成.rst存根,排除validators/、tests/、matplotlylib/、offline/、api/等目录; - 运行
sphinx-build从.rst生成 HTML; - 用
git checkout还原graph_objs的源码修改; - 清理临时复制的颜色文件;
- 用
rename与sed把生成 HTML 及相关文件中的所有graph_objs引用改回graph_objects(含*.html、*.inv、*.js及generated/子目录)。
5.3 添加新的 API 对象
需要被文档化的对象清单位于各子模块对应的.rst文件中:
| 文件 | 对应模块 |
|---|---|
| doc/apidoc/plotly.express.rst | plotly.express(高层 API) |
| doc/apidoc/plotly.graph_objects.rst | plotly.graph_objects(trace、layout) |
| doc/apidoc/plotly.io.rst | plotly.io(显示、读写) |
| doc/apidoc/plotly.subplots.rst | plotly.subplots(子图辅助) |
| doc/apidoc/plotly.figure_factory.rst | plotly.figure_factory |
| doc/apidoc/basefigure.rst | BaseFigure类 |
当公开 API 新增对象时,必须将其加入对应的.rst文件才会出现在 API 文档中。从源码结构看,这些.rst是 Sphinx autodoc 指令的入口,最终指向 plotly/basedatatypes.py 中BaseFigure等类的 docstring,这也解释了为何 API 文档能保持与源码 docstring 严格同步。
六、CI/CD 流水线:从 PR 到线上站点
文档的构建与部署由 GitHub Actions 工作流 .github/workflows/build-doc.yml 自动完成。
6.1 触发条件
| 事件 | 行为 |
|---|---|
| Pull request(任意分支) | 构建并校验教程(doc/python下的 Markdown),构建产物上传但不部署 |
Push 到doc-prod | 全量构建:教程构建、校验并部署;API 文档同步构建并部署 |
6.2 构建步骤
- 环境准备:安装 Python 3.9、
uv与系统依赖(rename工具); - 安装文档依赖:在
doc/内执行uv pip install -r requirements.txt; - editable 安装 plotly(仅非
doc-prod分支):用本地 checkout 替换 PyPI 上的 plotly,使开发中的新特性可用于文档示例; - 构建 HTML 教程:运行
make -kj8(执行两遍以重试瞬时失败),随后从plotly/graphing-library-docs下载并运行校验脚本:front-matter-ci.py:校验所有已构建页面的 YAML frontmatter;check-or-enforce-order.py:校验分类内页面排序;
- 上传构建产物:将 HTML 作为名为
doc-html的 GitHub Actions artifact 上传,供人工检查。
6.3 部署目标(仅 doc-prod)
推送doc-prod时,工作流将产物部署到plotly/plotly.py-docs仓库的三个分支:
| 目标分支 | 内容 |
|---|---|
built | 最终 HTML 教程页面 |
built_ipynb | 中间 Jupyter notebook 文件 |
gh-pages | API 参考 HTML(Sphinx 构建) |
部署完成后,工作流通过推送一个空 commit 触发下游仓库plotly/graphing-library-docs的重建,最终生成 https://plotly.com/python 线上站点。
6.4 完整部署链路
doc/python/*.md (源文件) ↓ make(jupytext + nbconvert) doc/build/html/*.html (构建后的教程) ↓ CI 部署到 plotly/plotly.py-docs@built plotly/graphing-library-docs (触发的下游重建) ↓ Jekyll 站点生成 https://plotly.com/python/ (线上站点)从这条链路可以清晰地看到:仓库中的 doc/python/ 是唯一内容源,doc/Makefile 定义转换逻辑,.github/workflows/build-doc.yml 负责执行与分发,而最终站点渲染交给下游 Jekyll 工程——这正是"源文件、构建、部署"三层解耦的文档工程实践。
七、故障排查指南
doc/README.md 的最后一部分针对文档构建中最高频的几类失败给出了诊断路径:
7.1 单个页面构建失败
查看doc/build/failures/<page-name>中的完整错误输出。常见原因:
- 缺少导入或数据集:确认所有 import 与远程数据 URL 正确;
- 超时:默认超时为 600 秒(10 分钟)。若示例确实需要更长时间,先在 issue 中讨论,不要擅自调大超时。
7.2make立即失败
- 确认在
doc/目录且虚拟环境已激活; - 检查
jupytext与nbconvert是否已安装:jupytext --version与jupyter nbconvert --version。
7.3 API 文档构建在graph_objs引用上报错
API 文档构建会临时修改 plotly/graph_objs/ 下的文件。若上一次构建被中断,这些文件可能处于脏状态,用 Git 还原即可:
git checkout -- plotly/graph_objs7.4 CI 的 frontmatter 校验失败
CI 会对构建产物运行front-matter-ci.py与check-or-enforce-order.py。请确保教程的 YAML frontmatter 包含全部必填字段(name、permalink、description、display_as、order、layout、language),且order值与同一display_as分类下的既有页面不冲突。
八、总结
plotly.py 的文档体系是一个典型的"文本源 + 双格式执行 + 自动化发布"工程:教程以带 YAML frontmatter 的 Markdown 书写、借助 jupytext 双开为 Notebook、由 make + nbconvert 构建为带 Jekyll 日期前缀的 HTML;API 参考则由 Sphinx autodoc 从源码 docstring 生成,构建时通过临时改名与还原巧妙绕开了graph_objects的引用解析问题;doc-prod与main双分支配合 CI 流水线,实现了"已发布功能即时上线、未发布功能随版本发布"的精准节奏。掌握这套体系后,无论是修复一个 typo、新增一个教程页面,还是为 API 变更补充文档,你都能在本地复现完整构建链路,并通过build/failures/与 CI 校验脚本快速定位问题,为 plotly.py 的文档生态贡献高质量内容。
- 数据可视化
- 数据分析
【免费下载链接】plotly.py
The interactive graphing library for Python :sparkles:
相关推荐
Mojo 文档站构建管道深度解析:从 stdlib 源码到线上 API 文档的完整流水线
Mojo 文档站构建管道深度解析:从 stdlib 源码到线上 API 文档的完整流水线 导读 本篇指南以仓库中 Mojo/docs/site/README.m
人工智能模型推理服务算子库编程语言编译器Podman 文档体系解析:从 Markdown 源码到在线手册的完整构建指南
Podman 文档体系解析:从 Markdown 源码到在线手册的完整构建指南 导读 本文以 Podman 仓库的 docs/README.md https:/
容器运行时云原生CLIJoplin 官方网站构建系统深度解析:从 Markdown 到静态站点的完整流水线
Joplin 官方网站构建系统深度解析:从 Markdown 到静态站点的完整流水线 Joplin 的官方网站(joplinapp.org)并非手工维护的静态
知识管理跨平台插件系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考