Skip to main content

A Very Opiniated Publication-Ready Plotting Library

PyPI version codecov pytest mypy-lint ruff-lint ruff-format


I love TikZ (btw). I love tikzplotlib. I've been an advocate for the latter (proof). However, tikzplotlib is as good as dead. I need to move on.

Examples

Left: ICML (letter size), single-column layout. Right: A0 landscape poster, 3-column layout.

       

import pub_ready_plots as prp

...

prp.get_context(
-   layout=prp.Layout.ICML,
+   layout=prp.Layout.POSTER_LANDSCAPE,

...

Installation

Still with me? Still want to use this library? Here's how:

pip install --upgrade pub-ready-plots

Quick usage

Wrap you current plotting script with the following with statement. By default, this will create a full-width, 0.15\textheight figure that conforms to the specified template.

By doing this, your figure is guaranteed to have the correct scaling, dimensions, font faces, and font sizes. All in all, this makes your figure "blends" with the target venue's main template---your paper overall will look more professional!

import pub_ready_plots as prp

with prp.get_context(layout=prp.Layout.ICLR) as (fig, axs):
    # Do whatever you want with `fig` and `axs`, e.g.:
    x = np.linspace(-1, 1)
    axs.plot(x, np.cos(x))

    # Once your done, save it, but do NOT set `tight_layout=True`!
    fig.savefig("filename.pdf")

Then in your LaTeX file, include the plot as follows:

\includegraphics[width=\linewidth]{filename.pdf}

The argument width=\linewidth is crucial! Also, do not specify the height option! Otherwise, your plot is distorted. (All measurements have been done in pub-ready-plots.)

If you set the width_frac argument when you call prp.get_context(), you need to put the same scaling factor in your LaTeX code. E.g., if you call prp.get_context(..., width_frac=0.5, ...), then you include it via \includegraphics[width=0.5\linewidth]{...}.

That's it! But you should use TikZ more. Anyway, see the full, runnable example in examples/simple_plot.py See here for available options for get_context()!

Supported Layouts

ICML, NeurIPS, ICLR, AISTATS, UAI, ProbML, JMLR, TMLR, A0 Poster (Landscape), A1 Poster (Portrait), 16:9 Beamer Slides, 16:9 Tuoying (Typst) Slides.

See: this file.

Advanced usages

Creating a figure with multiple subplots

To create a figure with multiple subplots do the following. Note that in your LaTeX doc, you still include the pdf via \includegraphics[width=\linewidth], without any scaling factor.

with prp.get_context(
    layout=prp.Layout.NEURIPS,
    width_frac=1,
    height_frac=0.15,
    nrows=1,
    ncols=2,
    sharey=True,
) as (fig, axs):
    # As an example, we plot sine and cosine functions
    x = np.linspace(-1, 1, 100)

    axs[0].plot(x, np.sin(x))
    axs[0].set_title("Sine")
    axs[0].set_xlabel(r"$x$")
    axs[0].set_ylabel(r"$\mathrm{sin}(x)$")

    axs[1].plot(x, np.cos(x))
    axs[1].plot(x, 2 * np.cos(x))
    axs[1].set_title("Cosine")
    axs[1].set_xlabel(r"$x$")
    axs[1].set_ylabel(r"$\mathrm{cos}(x)$")

    fig.savefig("subplots.pdf")

Subplots that span rows or columns

Pass mosaic to get a layout from plt.subplot_mosaic. Then axs is a dict keyed by the labels. nrows and ncols are ignored (with a warning) when mosaic is set.

with prp.get_context(layout=prp.Layout.NEURIPS, mosaic="AAB;CCB") as (fig, axs):
    axs["A"].plot(x, np.sin(x))  # top left, two columns wide
    axs["B"].plot(x, np.tanh(x))  # right, two rows tall
    axs["C"].plot(x, np.cos(x))  # bottom left, two columns wide
    fig.savefig("mosaic.pdf")

This also covers what plt.subplot2grid does. See the full example in examples/mosaic.py.

Creating plots for \wrapfigure

Say we want to have an inline figure of size 0.4\textwidth and height 0.15\textheight in our NeurIPS paper. Then all we have to do is the following:

import pub_ready_plots as prp

with prp.get_context(
    layout=prp.Layout.NEURIPS,
    width_frac=0.4,
    height_frac=0.15,
) as (fig, axs):
    # Your plot here!
    ...
    fig.savefig("mywrapfigure.pdf")

In our LaTeX doc, we can then use the wrapfig package and do the following:

Some paragraph.

\begin{wrapfigure}[11]{r}{0.4\textwidth}
  \centering
  \includegraphics[width=\linewidth]{mywrapfigure.pdf}
  ...
\end{wrapfigure}

Some other paragraph.

Usage with Seaborn

This library is compatible with Seaborn, see example. The most important thing to remember is to always pass the axis returned by prp.get_context() to Seaborn's plotting functions. Example:

import seaborn as sns
import pub_ready_plots as prp

with prp.get_context(layout=prp.Layout.SLIDES_196) as (fig, ax):
    sns.histplot(
        data=sns.load_dataset("planets"), x="distance", log_scale=True
        ax=ax  # !! IMPORTANT !!
    )

Fonts too bold?

You might encounter this problem on MacOS, e.g., when using Avenir Next Condensed font. On MacOS, the font format is .ttc and Matplotlib has issue with it. So, please install the more standard .ttf or .otf version.

You can also easily change the font, e.g.:

import pub_ready_plots as prp

with prp.get_context(
    ...
    override_rc_params={"font.sans-serif": "YOUR_FONT_NAME"},
    ...
) as (fig, axs):
    ...

All available options

import pub_ready_plots as prp

with prp.get_context(
    layout=prp.Layout.ICML,  # check `Layout` for all available layouts
    width_frac=1,  # multiplier for `\linewidth`
    height_frac=0.15,  # multiplier for `\textheight`
    single_col=False,  # only works for the ICML, UAI, AISTATS layouts
    nrows=1,  # depending on your subplots, default = 1
    ncols=2,  # depending on your subplots, default = 1
    mosaic=None,  # e.g. "AAB;CCB" for `plt.subplot_mosaic`, overrides nrows & ncols
    override_rc_params={"lines.linewidth": 4.123},  # Overriding rcParams
    sharey=True,  # Additional keyword args for `plt.subplots`
) as (fig, axs):
    ...

    fig.savefig("filename.pdf")

Sharing a style file across many scripts

If a project has many plotting scripts (I have one per figure in my lecture slides), put your rcParams tweaks in one JSON file and pass them via override_rc_params. E.g., plotstyle.json:

{
  "font.family": "sans-serif",
  "font.sans-serif": ["cmss10"],
  "mathtext.fontset": "cm",
  "axes.formatter.use_mathtext": false,
  "legend.fancybox": false,
  "legend.edgecolor": "k",
  "legend.framealpha": 1
}

Then in each script:

import json

import pub_ready_plots as prp

with open("plotstyle.json", "r") as f:
    rc_params = json.load(f)

with prp.get_context(
    layout=prp.Layout.TUOYING_169,
    width_frac=0.382,
    height_frac=0.8,
    override_rc_params=rc_params,
) as (fig, ax):
    ...
    fig.savefig("myplot.pdf")

override_rc_params is applied after the layout's rcParams, so the JSON values take precedence. To restyle all figures, edit the file and rerun the scripts. See examples/style_file.py and examples/plotstyle.json.

Using your own styles

Two options:

  1. Use this library and update the resulting rc_params dict with your styles.
  2. Fork this repo and modify things as you wish.

Dev's Guide

  1. Install uv.
  2. Create a virtualenv:
    uv venv
    
  3. Install dependencies:
    uv sync
    
  4. Run with, e.g.:
    uv run python examples/simple_plot.py
    
  5. If you want to use it in another (local) project:
    uv pip install -e .
    

Other libraries

Check out tueplots if you want a more complex library. My library is designed to achieve what I want in my papers and posters, with as little code as possible. Because of this, it is very forkable and hackable.

Metadata

Release files for pub-ready-plots 1.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pub-ready-plots 1.6
File Size Uploaded Provenance Actions
pub_ready_plots-1.6.tar.gz 8.0 kB Without provenance Details for pub_ready_plots-1.6.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pub-ready-plots 1.6
File Interpreter ABI Platform Actions
pub_ready_plots-1.6-py3-none-any.whl Python 3 none any Details for pub_ready_plots-1.6-py3-none-any.whl

Total release size: 16.9 kB

Release files / pub_ready_plots-1.6.tar.gz

Download URL pub_ready_plots-1.6.tar.gz
Size 8.0 kB
Tags Source
SHA-256 checksum
How to use checksums
bb513edaa3befaadf11f2343dc377a432aebd71aabd63c44f340089de92bae81
BLAKE2b-256 checksum
How to use checksums
4f99487b5dca50762ad023f9b56a6bd3423ad8128212c4add72f3711d4c53092
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.05","id":"yarara","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / pub_ready_plots-1.6-py3-none-any.whl

Download URL pub_ready_plots-1.6-py3-none-any.whl
Size 8.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d1927437e639148be64a98e1b1e35f296827c2b61d346cfcad3848e9b378850e
BLAKE2b-256 checksum
How to use checksums
4c2057cecc7d76b32602611ef699345401f3bbf6bc4bde6d7007513804f2243a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.05","id":"yarara","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for pub-ready-plots 1.6

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page