Publication-oriented Matplotlib figure export and LaTeX layout helpers
Project description
pubify-mpl
pubify-mpl is a small Python tool for exporting Matplotlib figures at sizes that match your LaTeX document, so the figures drop cleanly into papers, theses, and proceedings without trial-and-error resizing.
It combines two parts of a publication workflow:
- Python helpers for exporting Matplotlib figures using document-aware sizes
- a LaTeX package,
pubify.sty, for arranging exported figures into common panel layouts
This package is meant for researchers who already use Matplotlib and LaTeX and want a cleaner path from Python plots to publication-ready figures. It is not a replacement for Matplotlib. It sits at the export and layout stage.
Requirements
- Python 3.10+
- Matplotlib and NumPy
- a working LaTeX installation
save_fig() uses text.usetex=True, so LaTeX must be available when you export figures from Python.
On macOS, a common choice is MacTeX. If you want a smaller install, BasicTeX can also work, but you may need to add missing packages yourself.
LaTeX package requirements:
pubify.stydepends ongraphicx,subcaption, andetoolbox- the staged gallery/debug workspace also uses
lipsum, so minimal TeX installs may need that package separately
How It Works
Technically, save_fig(...) does not modify your original Matplotlib figure in place. Instead it:
- makes a copy of the figure
- applies publication styling and any requested cleanup only to that copy
- resizes the copy to match the requested width or named LaTeX layout
- saves the copy to PDF
That means your original interactive figure stays unchanged in Python. This is important if you want to keep using the same figure object in a notebook or script after export.
On the export side, save_fig(...) can:
- remove titles, labels, annotations, grids, or colorbars from the exported copy
- scales your copied figure to match the named layout
- use LaTeX text rendering during export so fonts and math match the document more closely
Quick Start
Install the package:
pip install pubify-mpl
Export a figure into a LaTeX project:
import matplotlib.pyplot as plt
from pubify_mpl import prepare, save_fig
paper_dir = "~/my-paper"
figures_dir = "~/my-paper/figures"
template = {
# Values for the default LaTeX article class example.
"textwidth_in": 5.39643,
"textheight_in": 7.58960,
"base_fontsize_pt": 12.0,
"caption_lineheight_pt": 13.6,
"subcaption_lineheight_pt": 13.6,
}
fig, ax = plt.subplots()
ax.plot([0, 1], [0, 1])
ax.set_xlabel("x")
ax.set_ylabel("y")
prepare(paper_dir, template=template)
save_fig(fig, "onewide", f"{figures_dir}/plot.pdf", template=template)
Then in LaTeX:
\usepackage{pubify}
Note that prepare(...) generates pubify-template.tex, and it contains specs that pubify.sty uses on the LaTeX side. Keep pubify-template.tex next to pubify.sty. Your paper directory will usually look like:
main.tex
pubify.sty
pubify-template.tex
figures/plot.pdf
If you do not already know your document dimensions and typography settings, first run prepare(...) so pubify.sty is available in the LaTeX project. Then add \figprintlayoutspec to the LaTeX document once and compile it. That prints the current textwidth, textheight, base font size, and caption/subcaption line heights, which you can then copy into the Python template dictionary.
pubify-mpl is fully compatible with Overleaf. If your LaTeX project is synced locally, the same folder layout works directly. If you do not have local sync set up, copy pubify.sty, pubify-template.tex, and the exported figure PDFs into the Overleaf project manually.
Examples
- examples/quickstart.ipynb: notebook version of the minimal quick-start example, writing into the tracked example project at examples/tex/main.tex
- gallery/layout-gallery-examples.tex: sample LaTeX source showing the supported panel layouts and macro usage
Layouts
See layout options in gallery/layout-gallery.pdf including:
"one": one large panel"onewide": one short wide panel"two": two stacked panels"twowide": two side-by-side panels"three": three stacked panels"threewide": three side-by-side panels"four": 2x2 grid"six": 2x3 grid"sixwide": 3x2 grid"nine": 3x3 grid"twelve": 3x4 grid"twelvewide": 4x3 grid"fifteen": 3x5 grid"sixteen": 4x4 grid"twenty": 4x5 grid
Typical Workflow
- Run
prepare(...)to installpubify.styand write an initialpubify-template.tex. - Measure your real LaTeX document using
\figprintlayoutspec. - Update the template with the values printed by
\figprintlayoutspec. - Export your figures with
save_fig(...). - Include them in LaTeX with
\figfloat,\fig, and the layout macros.
Advanced Python Usage
This is an alternative way to use pubify-mpl when you export many figures for the same document or keep several document templates in Python.
Define a common set of templates:
PUBIFY_TEMPLATES = {
"article": {
"textwidth_in": 5.39643,
"textheight_in": 7.58960,
"base_fontsize_pt": 12.0,
"caption_lineheight_pt": 13.6,
"subcaption_lineheight_pt": 13.6,
},
"thesis": {
"textwidth_in": 6.5,
"textheight_in": 8.5,
"base_fontsize_pt": 11.0,
"caption_lineheight_pt": 13.0,
"subcaption_lineheight_pt": 13.0,
},
}
Then when you export many figures for the same document, use_template(...) lets you set a default template inside a with block:
import matplotlib.pyplot as plt
from pubify_mpl import prepare, save_fig, use_template
paper_dir = "~/mythesis"
figures_dir = "~/mythesis/figures"
# do this once
prepare(paper_dir, template=PUBIFY_TEMPLATES["thesis"])
# create your figures
with use_template(PUBIFY_TEMPLATES["thesis"]):
save_fig(fig1, "one", f"{figures_dir}/plot-1.pdf")
save_fig(fig2, "twowide", f"{figures_dir}/plot-2.pdf")
Lower-level figure adjustment helpers and prepare_copy(...) are available in the Python API reference for advanced use.
Template Keys
The template dictionary tells pubify-mpl how much space is available in your LaTeX document and what spacing pubify.sty should use around figure rows, subcaptions, and captions.
Exported figures use the standard LaTeX serif face; the template controls typography sizes, not font family.
| Key | Meaning | Default |
|---|---|---|
textwidth_in |
document \textwidth in inches |
required |
textheight_in |
document \textheight in inches |
required |
caption_lineheight_pt |
measured line height used to estimate main caption height | 13.6pt |
subcaption_lineheight_pt |
measured line height used to estimate subcaption height | 13.6pt |
base_fontsize_pt |
base font size used when styling the exported figure copy | 12pt |
axes_labelsize_pt |
axis-label font size; when unset, defaults to base_fontsize_pt, and -1 leaves existing axis-label sizes unchanged |
base_fontsize_pt |
tick_labelsize_pt |
tick-label font size; when unset, defaults to base_fontsize_pt - 1, and -1 leaves existing tick-label sizes unchanged |
base_fontsize_pt - 1 |
legend_fontsize_pt |
legend font size; when unset, defaults to base_fontsize_pt - 1, and -1 leaves existing legend sizes unchanged |
base_fontsize_pt - 1 |
title_fontsize_pt |
axes-title font size; when unset, defaults to base_fontsize_pt + 1, and -1 leaves existing title sizes unchanged |
base_fontsize_pt + 1 |
line_width_pt |
stroke width for plotted lines and compatible collections; -1 leaves existing line widths unchanged |
-1pt |
axes_line_width_pt |
stroke width for axes spines and tick marks; -1 leaves existing axes and tick stroke widths unchanged |
0.8pt |
tick_length_pt |
tick length; -1 leaves existing tick lengths unchanged |
3.0pt |
caption_allowance_in |
extra buffer added beyond the estimated main caption text height | 0.08in |
subcaption_allowance_in |
extra buffer added beyond the estimated subcaption text height | 0.08in |
single_row_layout_max_height_in |
maximum total layout height budget used for single-row layouts such as "onewide" or "twowide" |
textheight_in / 3 |
subcaption_skip_in |
vertical space between a panel and its subcaption | 0.08in |
row_skip_in |
vertical space between rows in stacked layouts | 0.11in |
caption_skip_in |
vertical space between the figure body and the main caption | 0.11in |
post_caption_skip_in |
additional vertical space after the main caption | 0in |
col_gap_in |
horizontal space between columns | 0.02 * textwidth_in |
For the best match to a real document, copy textwidth_in, textheight_in, base_fontsize_pt, caption_lineheight_pt, and subcaption_lineheight_pt from \figprintlayoutspec.
Most Common save_fig() Options
Some save_fig() options control how the exported figure fits into the LaTeX layout:
caption_lines=...: estimate how many lines the main caption will usesubcaption_lines=...: estimate how many lines each subcaption will useforce_width=...: force a smaller export width, as long as it still fits inside the selected layoutforce_aspect=...: force a specific aspect ratio for the exported copy
Other options let you simplify the exported figure content without changing the original figure in Python:
hide_labels=True: remove axis labels from the exported copyhide_grid=True: disable the grid on the exported copyhide_cbar=True: remove a colorbar when exporting a single-axes panelhide_annotations=True: removeax.text(...)annotations from the exported copy
LaTeX Macros
pubify.sty separates LaTeX figure layout into three pieces:
\figfloat[placement]{body}[caption][label]creates the outer floatingfigureenvironment and adds the main caption and label.- the layout macros such as
\figonewide,\figtwowide, and\figfourarrange one or more\fig{...}panels into a specific layout. \fig{file}[subcaption][label]describes one exported panel. The optional subcaption and label are for subcaptions.
In normal use, you place one layout macro inside \figfloat. For example:
\figfloat[b!]
{\figonewide{\fig{figures/plot.pdf}}}
[A simple exported plot.]
[fig:plot]
For small multi-panel figures, you can use a direct panel-by-panel form:
\figfloat[t]
{
\figtwowide
{\fig{figures/left.pdf}[Left panel][fig:left]}
{\fig{figures/right.pdf}[Right panel][fig:right]}
}
[Two-panel figure.]
[fig:two-panel]
All layouts also support the row-grouped form. For larger grids, that is the normal pattern:
\figfloat[t]
{
\figfour
{{\fig{figures/a.pdf}}{\fig{figures/b.pdf}}}
{{\fig{figures/c.pdf}}{\fig{figures/d.pdf}}}
}
[Four-panel figure.]
[fig:four-panel]
The supported layout macros are:
\figone,\figonewide\figtwo,\figtwowide\figthree,\figthreewide\figfour,\figsix,\figsixwide\fignine,\figtwelve,\figtwelvewide\figfifteen,\figsixteen,\figtwenty
Troubleshooting
- If Python export fails with a LaTeX error, check that your TeX installation is available from the command line and includes the required packages.
- If exported figure sizes do not match your document, print
\figprintlayoutspecfrom the real document and update your Python template values from that output. - If LaTeX reports that a figure float is too large for the page, the usual fixes are to shorten the caption, choose a less tall layout, or adjust the template spacing and allowance values.
Python API Reference
Detailed Python API documentation is at nvnunes.github.io/pubify-mpl/api/.
LaTeX Package Reference
Common forms:
\usepackage{pubify}
\usepackage[template=path/pubify-template.tex]{pubify}
\usepackage[debug]{pubify}
\usepackage[template=path/pubify-template.tex,debug]{pubify}
Package options:
template=...: load an explicit template filedebug: add figure borders and print layout diagnostics to the LaTeX log
Template resolution:
- if
template=...is given,pubify.styloads that file - otherwise,
pubify.styloadspubify-template.texif it is present next topubify.sty - otherwise,
pubify.styfalls back to its built-in default lengths
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pubify_mpl-1.0.3.tar.gz.
File metadata
- Download URL: pubify_mpl-1.0.3.tar.gz
- Upload date:
- Size: 22.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3e07ce3632f2721b374eed7c4447c191b517ff8ae1af7ffa270b08ca12adcb85
|
|
| MD5 |
8842b79e99ed7097472069304aaff19d
|
|
| BLAKE2b-256 |
0d09f2422bba1884650dc2963c323c20d95fe3fd537e8eec6a97eeaedb3f7c9f
|
File details
Details for the file pubify_mpl-1.0.3-py3-none-any.whl.
File metadata
- Download URL: pubify_mpl-1.0.3-py3-none-any.whl
- Upload date:
- Size: 18.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f7c6da24af2aaf433b813ada5f0b75574aed3784a75a36a7630fd6686f7b8fc
|
|
| MD5 |
4ba4d9970f7093ee5060d792d0c53d62
|
|
| BLAKE2b-256 |
72f2e61a6591920940ce68d87e90786e29fc7ad4f4f4d5113ee1dbd024d44d1f
|