Retour au blog

Preserve Matplotlib Charts and LaTeX Math When Converting IPYNB to PDF

Code converts to PDF easily — charts and equations don't. Here's how to ensure your matplotlib figures, plotly widgets, pandas tables, and LaTeX math survive the IPYNB to PDF conversion intact.

  • #matplotlib
  • #latex
  • #charts
  • #guide

Code cells convert to PDF cleanly in almost any tool. The hard part of Jupyter Notebook PDF conversion is everything else: matplotlib charts that come out fuzzy, plotly widgets that disappear entirely, pandas DataFrames that get clipped at the right margin, and LaTeX equations that render as raw $x^2$ text instead of typeset math.

This guide covers how to make all four survive the conversion intact, regardless of which tool you use.

Matplotlib Charts

The Problem

By default, matplotlib renders at 100 DPI and embeds PNG images in the notebook. When nbconvert or an online converter renders those PNGs to PDF, they often look pixelated — especially on print.

The Fix

Set matplotlib to higher DPI and use vector formats when possible.

In the first cell of your notebook:

import matplotlib.pyplot as plt
plt.rcParams.update({
    "figure.dpi": 150,        # screen DPI
    "savefig.dpi": 300,       # saved-file DPI
    "font.size": 14,          # larger fonts for print
    "figure.figsize": (8, 5), # wider figures
    "axes.grid": True,
})
%matplotlib inline

For figures you'll embed manually, save as SVG (vector) instead of PNG:

plt.savefig("chart.svg", bbox_inches="tight")

nbconvert and most online converters handle SVG embeds natively, producing crisp output at any zoom level.

Backend Matters

On headless servers or inside Docker, set the backend explicitly:

import matplotlib
matplotlib.use("Agg")  # non-interactive, required on servers

If you don't do this and there's no display, the first chart will throw TclError: no display name.

Converting with --execute

If your notebook doesn't have outputs saved (e.g., you ran "Restart Kernel" before exporting), tell nbconvert to execute it:

jupyter nbconvert --to pdf --execute notebook.ipynb

Without --execute, charts will simply be missing from the PDF.

Plotly Figures

Plotly is trickier because its default output is an interactive JavaScript widget. PDFs don't run JavaScript.

Option 1 — Static Image Export

Convert plotly figures to PNG before exporting the notebook:

import plotly.io as pio

fig = px.scatter(df, x="x", y="y")
pio.write_image(fig, "plot.png", width=1200, height=600, scale=2)

The scale=2 doubles the resolution for retina-quality output. You'll need the kaleido package:

pip install kaleido

Then reference the saved image in a markdown cell:

![My Plot](plot.png)

Option 2 — Plotly's Static Renderer

In a code cell:

fig.show("png", width=1200, height=600)

This renders the figure as a static PNG inline, which survives PDF conversion. Requires kaleido.

Option 3 — Convert to Matplotlib

For simple plots, the easiest path is to skip plotly and use matplotlib directly. For complex interactive figures, accept that PDF won't preserve interactivity — produce a static PNG and link to the live notebook separately.

pandas DataFrames

The Problem

Wide DataFrames get clipped at the page edge. Tall DataFrames span multiple pages with no header continuation.

Fix 1 — Trim Before Export

The simplest fix: don't try to export 50 columns. Limit to what fits:

df.iloc[:50, :10]  # first 50 rows, first 10 columns

Fix 2 — Transpose for Wide Tables

If your table is wide but short, transpose it:

df.describe().T

Fix 3 — HTML with Horizontal Scroll

For HTML-based conversions, wrap the table in a scrollable div:

from IPython.display import HTML
HTML(df.to_html(classes='table-scroll'))

With CSS:

.table-scroll {
  overflow-x: auto;
  display: block;
  max-width: 100%;
}

ipynbtopdf.org and most online converters handle wide-table scrolling natively — they detect the overflow and either wrap or paginate intelligently.

Fix 4 — Use df.to_markdown() for Clean Text Tables

import tabulate
print(df.head().to_markdown(index=False))

Produces a clean markdown table that converts beautifully to PDF.

LaTeX Math

The Problem

nbconvert's --to pdf path handles math natively because it goes through LaTeX. But webpdf, HTML export, and most online converters use KaTeX instead, and KaTeX needs to be configured correctly.

The Fix

Most modern converters handle KaTeX out of the box. If your math renders as raw $x^2$ text, check:

  1. Delimiters are paired. Every $ must have a matching $. Inline math: $E = mc^2$. Display math: $$\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}$$.
  2. No stray $ signs in code or text. A $5 latte in a markdown cell will confuse the parser. Escape with \$.
  3. The converter supports KaTeX. ipynbtopdf.org and most modern converters do. Older nbconvert versions don't — upgrade with pip install --upgrade nbconvert.

Common Math Examples

These should all render correctly in any decent PDF converter:

Inline: The energy-mass equivalence is E=mc2E = mc^2, where cc is the speed of light.

Display:

ρt+(ρv)=0\frac{\partial \rho}{\partial t} + \nabla \cdot (\rho \mathbf{v}) = 0

Aligned equations:

f(x)=(x+1)2=x2+2x+1\begin{aligned} f(x) &= (x + 1)^2 \\ &= x^2 + 2x + 1 \end{aligned}

Matrices:

A=(123456789)A = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{pmatrix}

If any of these render as raw text in your PDF, switch converters.

Code Cell Tips

While code usually converts cleanly, a few habits improve PDF output:

  1. Limit line length to 79 characters. Long lines either get clipped or wrap ugly. Use textwrap.fill() for long strings.
  2. Avoid interactive prompts (input() calls). They hang nbconvert.
  3. Clear sys.stdout before the last cell so the PDF doesn't end with pages of intermediate output.
  4. Use markdown headings (#, ##) to give the PDF structure.

A Pre-Export Checklist

Before exporting, run through this list:

  • All cells executed, outputs present
  • matplotlib dpi=300 and font.size=14
  • Plotly figures converted to static images
  • Wide DataFrames trimmed or transposed
  • LaTeX delimiters paired and escaped
  • Code lines under 79 characters
  • Markdown headings give the notebook structure

Conclusion

Charts, tables, and math are the parts of a notebook that actually carry information. Code is just the recipe — the figures and equations are the result. Taking the time to set matplotlib DPI, convert plotly to static images, trim DataFrames, and validate LaTeX delimiters will make every PDF conversion — whether via nbconvert, webpdf, or an online tool — produce output worth sharing.

Preserve Matplotlib Charts and LaTeX Math When Converting IPYNB to PDF | Convertisseur IPYNB vers PDF