Fix: matplotlib charts missing from a notebook PDF
If your notebook exports to PDF with the code but no plots, the cause is almost always one of two things, and neither is a bug in the converter: either the notebook's cells were not run (or not saved) before export, so there is no plot stored in the file, or you used the %matplotlib notebook / %matplotlib widget interactive backend, which produces a live JavaScript widget instead of a static image, and static exports cannot capture it. The fix in both cases: switch to %matplotlib inline, run all cells, save, then export. Because a PDF is built from the outputs saved inside the .ipynb, if a chart is not sitting in the file as a static image, no converter (including PDFMoka's ipynb to PDF tool) can show it. Here is how to make sure it is.
Why this happens: PDF export reads saved outputs, not live plots
A .ipynb file stores each cell's outputs inside it as data, images are embedded as base64-encoded PNGs (or SVGs) in the notebook JSON. Any PDF or HTML export reads those saved outputs and lays them out. It does not re-run your code, and it cannot capture anything that only exists as a live, interactive object in a running kernel.
That single fact explains both failure modes below.
Cause 1: the interactive backend (%matplotlib notebook / widget)
This is the most common cause. If your notebook starts with:
%matplotlib notebook # or: %matplotlib widget
then matplotlib renders each figure as an interactive JavaScript widget (zoom, pan, live updates). That is great on screen, but the widget is not a static image, and static exporters have nothing to embed. The result is exactly what people report: a PDF with code and no pictures.
Fix: switch to the inline backend, which renders each figure as a static PNG that gets saved into the notebook:
%matplotlib inline
Then restart the kernel and run all cells (Kernel → Restart & Run All), so every figure is regenerated as a static image, and save the notebook. Now export. The plots will be there.
If you specifically need the interactive backend while working, keep %matplotlib notebook for exploration, but switch to %matplotlib inline and re-run before exporting. There is no way to put a live widget into a static PDF; the inline static image is what a PDF can hold.
Cause 2: cells were never run, or the notebook wasn't saved after running
Even with the inline backend, a plot only lands in the file if the cell actually ran and you saved afterward. Two frequent slip-ups:
- You ran the notebook, saw the plots on screen, but exported (especially from the command line,
jupyter nbconvert) before saving, so the on-disk file still has empty outputs. - You are converting a notebook that was cleared of outputs (many Git workflows strip outputs on commit), so the committed file genuinely has no plots in it.
Fix: Kernel → Restart & Run All, confirm every chart is visible in the notebook, then save (Ctrl/Cmd+S), then export. If you are scripting the conversion, either save from the UI first, or run jupyter nbconvert --execute ... so nbconvert runs the cells itself before converting:
jupyter nbconvert --to pdf --execute notebook.ipynb
verify against your workflow:
--executere-runs the notebook at convert time, which needs the right kernel and dependencies available, and it will overwrite existing outputs. Confirm it behaves as expected on your notebook before relying on it in a pipeline.
Cause 3 (rarer): SVG output and a converter that can't handle it
If you set matplotlib to emit SVG figures:
import matplotlib_inline
matplotlib_inline.backend_inline.set_matplotlib_formats('svg')
the figures are stored as SVG rather than PNG, and some converters or LaTeX paths do not embed inline SVG cleanly, giving you a blank where the plot should be. If you hit this, revert to the default PNG output (remove that line) and re-run, PNG is the most broadly compatible embedded format for exports.
The reliable checklist
- Ensure the first cell is
%matplotlib inline, notnotebookorwidget. - Kernel → Restart & Run All.
- Confirm every chart is actually visible in the notebook.
- Save the notebook (Ctrl/Cmd+S).
- Export to PDF.
Once the static images are saved in the file, conversion is reliable. PDFMoka's ipynb to PDF converter reads those embedded images and renders them in your browser (no upload, no LaTeX); if a chart shows in the notebook but not the PDF, this checklist is almost always the fix. For the related "why do I even need LaTeX" question, see convert a notebook to PDF without LaTeX.
References
- jupyter/nbconvert issue #1081 (plots not shown; inline vs notebook backend): https://github.com/jupyter/nbconvert/issues/1081
- matplotlib/matplotlib issue #10380 (PDF export empty with
%matplotlib notebook): https://github.com/matplotlib/matplotlib/issues/10380 - Matplotlib backends documentation: https://matplotlib.org/stable/users/explain/figure/backends.html