Skip to content

DOC: Stop rendering plot directive figures to PDF, speeding up documentation builds - #884

Merged
rgommers merged 1 commit into
PyWavelets:mainfrom
agriyakhetarpal:stop-pdf-plot-directive
Oct 1, 2026
Merged

rgommers merged 1 commit into
PyWavelets:mainfrom
agriyakhetarpal:stop-pdf-plot-directive

Conversation

@agriyakhetarpal

Copy link
Copy Markdown
Collaborator

This PR is part of an exercise that @Schefflera-Arboricola, @melissawm, and I are performing to find speedups in docs builds. I ran sphinx-benchmark over a documentation build for PyWavelets, through the output of which I found that a Matplotlib stream that builds PDFs of plots as requested by .. plot:: directives is consuming 66% of the build time in the gap between the object-description-transform and the doctree-read events.

Within that, most of it comes from the CWT page. See this comment as well:

.. Sphinx seems to take a long time to generate this plot, even though the
.. corresponding script is relatively fast when run on its own.

These PDFs are placed into a temporary build directory next to the doctrees, are not used anywhere as part of the PDF build pipeline because PyWavelets does not build PDF documentation (whether via the Sphinx PDF builder or any other tooling), and are later discarded. So I figured that we can perhaps just drop it, until/unless we consider building PDF documentation someday?

Without sphinx-benchmark, i.e., using a regular Sphinx build (because sphinx-benchmark currently requires a non-parallel build), here are the results from two runs (both with a cold cache) on my macOS machine locally with Sphinx 9 and Python 3.13:

plot_formats Wall time (seconds) CPU time (user + system) (seconds)
[('png', 96), 'pdf'] 34.3 30.6
[('png', 96)] 16.2 12.5
Percentage change -53% -59%

Therefore, this is a 53% reduction in wall time (34.3s to 16.2s), or, equivalently, the old build took 2.1x as long as the new one! 🚀

I am aware that PyWavelets' docs are not time-consuming by any means in comparison to a much bigger Python library/project, so this doesn't help much in practice, but it's still nice that experimenting here allows us to devise a bit of a playbook for how sphinx-benchmark can be extended to optimise docs builds for other projects, sometimes in simple ways like this. @melissawm, I believe, found another similar improvement that can be made to the Matplotlib plot directive directly IIRC, and is working on upstreaming it in the meantime?

Note that the CPU time drops more than the wall time, because the ~4 seconds of kernel startup and JupyterLite subprocess waiting in the build are unaffected.

xref Quansight/Quansight-website#1011

Co-Authored-By: Melissa Weber Mendonça <melissawm@gmail.com>
Co-Authored-By: Aditi Juneja <91629733+schefflera-arboricola@users.noreply.github.com>
@agriyakhetarpal

Copy link
Copy Markdown
Collaborator Author

While comparing with a single run doesn't prove a lot; the previous PR ( https://app.readthedocs.org/api/v2/build/34868538.txt) vs this PR ( https://app.readthedocs.org/api/v2/build/34872370.txt):

Build The python -m sphinx -b html step (seconds) Whole job (seconds)
Then 82 167
Now 36 124
Net change -56% -26%

@agriyakhetarpal

Copy link
Copy Markdown
Collaborator Author

@Schefflera-Arboricola suggested confirming a bit more reliably since this can go into her blog post, so these are the results from hyperfine from 5 cold runs on my machine:

Benchmark 1: PDF on: plot_formats png+pdf
  Time (mean ± σ):     33.340 s ±  0.779 s    [User: 28.346 s, System: 1.970 s]
  Range (min … max):   32.359 s … 34.478 s    5 runs

Benchmark 2: PDF off: plot_formats png
  Time (mean ± σ):     12.897 s ±  0.335 s    [User: 8.949 s, System: 1.464 s]
  Range (min … max):   12.647 s … 13.439 s    5 runs

Summary
  PDF off ran 2.59 ± 0.09 times faster than PDF on
Command Mean [s] Min [s] Max [s] Relative
PDF on: plot_formats png+pdf 33.340 ± 0.779 32.359 34.478 2.59 ± 0.09
PDF off: plot_formats png 12.897 ± 0.335 12.647 13.439 1.00

To reproduce:

# setup
git clone https://github.com/PyWavelets/pywt.git
cd pywt

python3.13 -m venv .venv-docs
source .venv-docs/bin/activate
python -m pip install --upgrade pip
python -m pip install -r util/readthedocs/requirements.txt
python -m pip install .
# run
cd doc
hyperfine --runs 5 --warmup 0 --export-markdown pdf-vs-png.md \
  --prepare 'make clean' \
  -n 'PDF on: plot_formats png+pdf' \
     'sphinx-build -q -b html -D intersphinx_timeout=3 -D plot_formats=png:96,pdf -d build/doctrees source build/html' \
  -n 'PDF off: plot_formats png' \
     'sphinx-build -q -b html -D intersphinx_timeout=3 -D plot_formats=png:96 -d build/doctrees source build/html'

@rgommers rgommers left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thank you!

@rgommers
rgommers merged commit c9b542b into PyWavelets:main Oct 1, 2026
20 checks passed
@agriyakhetarpal
agriyakhetarpal deleted the stop-pdf-plot-directive branch October 1, 2026 21:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants