doc/README.md
The doc directory contains the source files of the documentation of plotly.py.
It is composed of two parts:
python/ directory, tutorials corresponding to https://plotly.com/python/apidoc/ directory, configuration files for generating
the API reference documentation (hosted on https://plotly.com/python-api-reference/)Python packages required to build the docs are listed in
requirements.txt in the doc directory.
Before building the documentation locally, you need to set up a dedicated environment with the doc-specific dependencies.
cd doc
uv venv --python 3.9
source .venv/bin/activate
uv pip install -r requirements.txt
If you are documenting a feature that has not yet been released, you also need an editable install of plotly so your local changes are reflected:
uv pip uninstall plotly # remove the PyPI version installed by requirements.txt
uv pip install -e .. # install from your local checkout
Several geographic examples require a free Mapbox public token. Without it, those specific pages will fail to build.
doc/python/.mapbox_tokenThe Makefile symlinks this token into the build directory automatically.
python directory)Each tutorial is a markdown (.md) file, which can be opened in Jupyter
Notebook or in JupyterLab by installing jupytext.
For small edits (e.g., correcting typos) to an existing tutorial, you can simply click on the "edit this page on GitHub" link at the top right of the page (e.g. clicking on this link on https://plotly.com/python/bar-charts/ will take you to https://github.com/plotly/plotly.py/edit/doc-prod/doc/python/bar-charts.md, where you can edit the page on GitHub).
For more important edits where you need to run the notebook to check the output,
clone the repository and setup an environment as described in the main
contributing notes. If you're writing documentation at the
same time as you are developing a feature, make sure to install with editable
install (pip install -e, as described in main
contributing notes), so that you only need to restart
the Jupyter kernel when you have changed the source code of the feature.
doc-prod branch contains the live docs which are available on the website. As soon as a change is merged into doc-prod, the updated docs are deployed and made publicly available.main branch contains docs which have been written but are not ready to be released, such as for an upcoming feature in the next plotly.py release.When updating the docs, two workflows are possible:
doc-prod branch and open your pull request into the doc-prod branch.main and open your pull request into main, so that the documentation of the feature is only deployed when it is available in a released version of plotly.py. The main branch will be merged into doc-prod at release time, as described below.main and doc-prod in syncChanges to doc-prod are not automatically merged back into main. To
prevent the branches from diverging, doc-prod should be merged into main on
a regular basis via a pull request (e.g., a branch named
merge-doc-prod-to-main-branch merged into main).
At release time the synchronization is bidirectional (see also
RELEASE.md):
doc-prod → main — merge any outstanding doc-only fixes into main
(if not already done recently).main → doc-prod — merge main into doc-prod so that documentation
for newly released features is deployed to the live site.graphing-library-docs
repo to bump the plotly.py and plotly.js versions and rebuild the Algolia
search indexes. See the
Update documentation site
section of RELEASE.md for the full procedure.Release prep: When synchronizing
mainintodoc-prodfor a new release, update theplotly==version pin indoc/requirements.txtto match the newly released version. Thedoc-prodbuild uses this pinned version (not an editable install), so examples that rely on new features will fail if the pin is stale.
Tutorial files are Markdown files with a YAML frontmatter block that contains Jupyter notebook metadata (used by jupytext) and plotly-specific metadata (used by the documentation site for navigation, SEO, and categorization).
Here is an annotated example of the 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: Short description for SEO and page previews.
display_as: basic # Category: basic, statistical, scientific, maps, 3d, etc.
language: python
layout: base
name: Page Title # Displayed in the navigation sidebar
order: 3 # Position within the display_as category
page_type: example_index
permalink: python/my-page/ # URL path on the documentation site
thumbnail: thumbnail/my-page.jpg
---
The plotly metadata fields are the most important to enter correctly when creating/updating a tutorial:
| Field | Description |
|---|---|
name | Page title shown in the sidebar and browser tab |
permalink | URL slug — must match the filename (e.g., bar-charts.md → python/bar-charts/) |
description | Short description used by search engines |
display_as | Category grouping (e.g., basic, statistical, scientific, maps, 3d_charts, file_settings) |
order | Numeric sort order within the category |
page_type | Typically example_index for tutorial pages |
thumbnail | Path to the thumbnail image |
Code cells are written as fenced code blocks with the python language tag.
Each code cell is separated by a blank line and starts with ```python.
Markdown cells are written as regular Markdown text between code blocks.
doc/python/ as a starting point to get
the frontmatter structure right.name, permalink,
description, display_as, and order. Make sure permalink matches the
filename (e.g., my-feature.md → python/my-feature/).python code blocks. Each block becomes a
separate Jupyter cell when the file is converted.jupyter lab doc/python/my-feature.md
cd doc
make build/html/2019-07-03-my-feature.html
We try to write short, standalone and (almost) self-explaining examples. Most examples should focus on a single feature.
Checklist
fig for a Figure object, df for a pandas dataframe, etc.From the doc directory, with the virtual environment activated:
cd doc
source .venv/bin/activate
make
This runs through every .md file in python/ and:
what_about_dash.mdbuild/html/ with a 2019-07-03- date prefixTo build in parallel (as CI does):
make -kj8
The -k flag continues past failures and -j8 runs 8 jobs in parallel.
To build only one page (useful during development):
make build/html/2019-07-03-bar-charts.html
The filename follows the pattern 2019-07-03-<markdown-filename-without-extension>.html.
Why the
2019-07-03-prefix? The downstreamgraphing-library-docssite uses Jekyll, whose_posts/collection only processes files matching the patternYYYY-MM-DD-title.extand silently ignores anything else. The specific date is an arbitrary placeholder — its value is never displayed; it just satisfies Jekyll's filename parser.
| Directory | Contents |
|---|---|
build/ipynb/ | Intermediate Jupyter notebook files |
build/html/ | Final HTML tutorial pages |
build/html/redir/ | Redirect pages (v3 and next-version) |
build/failures/ | Stderr logs for pages that failed to build |
If a build fails, check build/failures/<page-name> for the error output.
apidoc directory)We use sphinx and its autodoc
extension
in order to generate the documentation of the API. Sphinx uses the reST markup
language.
The API docs require an editable install of plotly because the build process
temporarily modifies source files (renaming graph_objects references to the
internal graph_objs name for Sphinx, then reverting afterward).
cd doc
source .venv/bin/activate
uv pip uninstall plotly
uv pip install -e ..
cd apidoc
make html
The output is written to apidoc/_build/html/.
The apidoc/Makefile performs several steps:
:class: cross-references in plotly/graph_objs/ to
use the internal graph_objs name so Sphinx can resolve them.plotly/colors/ and plotly/express/colors/
so their docstrings are picked up.sphinx-apidoc to auto-generate .rst stubs from the Python source,
excluding validators/, tests/, matplotlylib/, offline/, and api/.sphinx-build to produce HTML from the .rst files.graph_objs source changes with git checkout.graph_objs references back to graph_objects in the generated
HTML and related files.Lists of objects to be documented are found in .rst files corresponding to
submodules:
| File | Module |
|---|---|
plotly.express.rst | plotly.express (high-level API) |
plotly.graph_objects.rst | plotly.graph_objects (traces, layout) |
plotly.io.rst | plotly.io (display, read, write) |
plotly.subplots.rst | plotly.subplots (subplot helpers) |
plotly.figure_factory.rst | plotly.figure_factory |
basefigure.rst | BaseFigure class |
When a new object is added to the exposed API, it needs to be added to the
corresponding .rst file to appear in the API doc.
css files are found in _static_templates. .rst templates describe how the
autodoc of the different objects should look like.conf.py contains the Sphinx configuration (theme, extensions, etc.)Documentation is built and deployed automatically by the GitHub Actions workflow
defined in .github/workflows/build-doc.yml.
| Event | What happens |
|---|---|
| Pull request (any branch) | Tutorials (markdown files in doc/python) are built and validated. The build artifact is uploaded but not deployed. |
Push to doc-prod | Full build: tutorials are built, validated, and deployed. API docs are also built and deployed. |
uv, and system dependencies (rename
utility) are installed.uv pip install -r requirements.txt inside
doc/.doc-prod branches only) — Replaces the
PyPI plotly with the local checkout so that in-development features are
available.make -kj8 (twice, to retry transient
failures). Then downloads and runs validation scripts from
plotly/graphing-library-docs:
front-matter-ci.py validates the YAML frontmatter of all built pages.check-or-enforce-order.py verifies page ordering within categories.doc-html for inspection.When changes are pushed to doc-prod, the workflow deploys to three branches
of the plotly/plotly.py-docs
repository:
| Target branch | Contents |
|---|---|
built | Final HTML tutorial pages |
built_ipynb | Intermediate Jupyter notebook files |
gh-pages | API reference HTML (built by Sphinx) |
After deploying, the workflow triggers a downstream build in
plotly/graphing-library-docs
by pushing an empty commit. That repository generates the final
https://plotly.com/python site.
doc/python/*.md (source)
↓ make (jupytext + nbconvert)
doc/build/html/*.html (built tutorials)
↓ CI deploys to plotly/plotly.py-docs@built
plotly/graphing-library-docs (triggered rebuild)
↓ Jekyll site generation
https://plotly.com/python/ (live site)
Check build/failures/<page-name> for the full error output. Common causes:
doc/python/.mapbox_token does not exist.make fails immediatelydoc/ directory with the virtual
environment activated.jupytext and nbconvert are installed: jupytext --version
and jupyter nbconvert --version.graph_objs referencesThe API doc build temporarily modifies files under plotly/graph_objs/. If a
previous build was interrupted, those files may be in a dirty state. Reset them
with:
git checkout -- plotly/graph_objs
The CI runs front-matter-ci.py and check-or-enforce-order.py against the
built HTML. Ensure your tutorial's YAML frontmatter includes all required
fields (name, permalink, description, display_as, order, layout,
language) and that the order value does not conflict with existing pages in
the same display_as category.