Matplotlib/seaborn style presets matching scientific journal requirements, with validation, export safety, and preview capabilities.
Project description
plotstyle
Publication-ready scientific figures — one line of code.
PlotStyle configures Matplotlib (and optionally Seaborn) so your figures match the exact typographic, dimensional, and export requirements of major academic journals — out of the box.
Getting a figure accepted often means matching a journal's precise column width, font size range, line weight, DPI, and export format. PlotStyle encodes those requirements as TOML specs and applies them automatically, so you spend time on your science rather than your figure settings.
Current release:
v0.1.0a1(alpha)
Table of Contents
Features
- One-line journal presets —
plotstyle.use("nature")sets fonts, sizes, line widths, and export parameters in Matplotlib'srcParams. Wrap it in awithblock and everything is restored automatically when the block exits. - Correctly-sized figures —
plotstyle.figure()andplotstyle.subplots()create figures at the exact column width and maximum height specified by each journal. - Auto panel labels — multi-panel figures get (a), (b), (c), … labels placed and styled according to each journal's conventions.
- Colorblind-safe palettes — built-in Okabe–Ito, Tol Bright/Vibrant/Muted, and grayscale-safe palettes via
plotstyle.palette(). - Accessibility previews — simulate deuteranopia, protanopia, and tritanopia; preview grayscale rendering.
- Pre-submission validation — check figure dimensions, font sizes, line weights, color accessibility, and export settings against the target journal's spec before you submit.
- Submission-ready export —
plotstyle.savefig()enforces TrueType font embedding and minimum DPI;plotstyle.export_submission()batch-exports to every format the journal requires. - Spec diffing & migration — compare two journal specs side-by-side; re-target a figure from one journal to another with
plotstyle.migrate(). - Seaborn compatibility — a patch layer ensures PlotStyle's
rcParamssurvivesns.set_theme()calls. - Typed, schema-validated specs — journal requirements are stored as TOML files validated by immutable typed dataclasses.
- CLI —
plotstyle list,plotstyle info,plotstyle validate, and more — no Python script needed.
Supported Journals
| Key | Journal | Publisher |
|---|---|---|
acs |
ACS (JACS) | American Chemical Society |
cell |
Cell | Cell Press |
elsevier |
Elsevier | Elsevier |
ieee |
IEEE Transactions | IEEE |
nature |
Nature | Springer Nature |
plos |
PLOS ONE | Public Library of Science |
prl |
Physical Review Letters | American Physical Society |
science |
Science | AAAS |
springer |
Springer | Springer |
wiley |
Wiley | Wiley |
Need another journal? See CONTRIBUTING.md for how to add one.
Installation
Requires Python 3.10+ and Matplotlib ≥ 3.9.
pip install plotstyle
Optional extras
# Colorblind / grayscale preview (needs Pillow)
pip install "plotstyle[color]"
# Font subsetting / inspection
pip install "plotstyle[fonttools]"
# Seaborn integration
pip install "plotstyle[seaborn]"
# Everything
pip install "plotstyle[all]"
Development install
git clone https://github.com/rahulkaushal04/plotstyle.git
cd plotstyle
pip install -e ".[dev]"
Quick Start
import numpy as np
import plotstyle
# plotstyle.use() applies the journal's rcParams (fonts, sizes, line widths).
# The `with` block ensures they are restored automatically when plotting is done.
with plotstyle.use("nature"):
# Creates a figure at Nature's exact single-column width (89 mm).
# Use columns=2 for double-column (full text width).
fig, ax = plotstyle.figure("nature", columns=1)
x = np.linspace(0, 2 * np.pi, 200)
ax.plot(x, np.sin(x), label="sin(x)")
ax.plot(x, np.cos(x), label="cos(x)")
ax.set_xlabel("Phase (rad)")
ax.set_ylabel("Amplitude (a.u.)")
ax.legend()
# Enforces Nature's minimum DPI (300) and embeds TrueType fonts.
plotstyle.savefig(fig, "quickstart_nature.pdf", journal="nature")
The with block is the recommended pattern — rcParams are always restored on exit, even if an exception occurs inside the block.
If you need to manage the style manually:
style = plotstyle.use("ieee")
try:
fig, ax = plotstyle.figure("ieee", columns=1)
ax.plot([1, 2, 3])
plotstyle.savefig(fig, "fig_ieee.eps", journal="ieee")
finally:
style.restore() # always restore, even on error
Usage
Multi-panel figures
plotstyle.subplots() works like plt.subplots() but sizes the figure to the journal spec and adds panel labels automatically.
Note: Unlike
plt.subplots(),plotstyle.subplots()always returns a 2-D NumPy array of axes — even for a single panel. Useaxes[0, 0]to access a single axes, oraxes.flatto iterate over all panels.
import plotstyle
with plotstyle.use("science"):
fig, axes = plotstyle.subplots("science", nrows=2, ncols=2, columns=2)
# axes has shape (2, 2); each panel is labelled (a), (b), (c), (d)
for ax in axes.flat:
ax.plot([1, 2, 3])
plotstyle.savefig(fig, "multipanel.pdf", journal="science")
Pass panels=False to suppress the automatic labels.
Color palettes
# A list of 4 hex color strings from Nature's recommended palette
colors = plotstyle.palette("nature", n=4)
# With linestyles and markers — useful for accessible line plots
styled = plotstyle.palette("ieee", n=3, with_markers=True)
# styled is a list of (color, linestyle, marker) tuples
for color, ls, marker in styled:
ax.plot(x, y, color=color, linestyle=ls, marker=marker)
Validation
report = plotstyle.validate(fig, journal="nature")
print(report) # formatted table of all checks
print(report.passed) # True if no checks failed
for failure in report.failures:
print(failure.message) # what failed
print(failure.fix_suggestion) # how to fix it
Submission export
export_submission() writes the figure in every format the journal requires (PDF, TIFF, EPS, etc.) and applies journal-specific naming conventions.
paths = plotstyle.export_submission(
fig,
"figure1",
journal="ieee",
author_surname="Kaushal", # IEEE prepends the first 5 chars of the surname
output_dir="submission_ieee",
)
# Produces: submission_ieee/kaush_figure1.pdf (and any other IEEE-required formats)
Spec diffing and migration
# Compare two journals — useful when retargeting a figure
result = plotstyle.diff("nature", "science")
print(result) # aligned two-column table of differences
# Re-target a figure to a different journal in place
plotstyle.migrate(fig, from_journal="nature", to_journal="science")
plotstyle.savefig(fig, "figure_science.pdf", journal="science")
Accessibility previews
# Simulate how a figure looks under three types of color blindness
comp = plotstyle.preview_colorblind(fig)
comp.savefig("colorblind_check.png", dpi=150)
# Preview grayscale rendering
gs = plotstyle.preview_grayscale(fig)
gs.savefig("grayscale_check.png", dpi=150)
Seaborn integration
sns.set_theme() normally overwrites the rcParams that PlotStyle set. Pass seaborn_compatible=True to prevent that:
import seaborn as sns
import plotstyle
with plotstyle.use("nature", seaborn_compatible=True):
fig, ax = plotstyle.figure("nature", columns=1)
sns.lineplot(x=[1, 2, 3], y=[4, 5, 6], ax=ax)
plotstyle.savefig(fig, "seaborn_figure.pdf", journal="nature")
CLI
plotstyle list # List all journal presets
plotstyle info <journal> # Show spec details
plotstyle diff <journal_a> <journal_b> # Compare two journals
plotstyle fonts --journal <journal> # Check font availability
plotstyle validate <file> --journal <journal> # Validate a saved figure
plotstyle export <file> --journal <journal> # Re-export in required formats
Examples
Working examples are in the examples/ directory:
| # | File | Topic |
|---|---|---|
| 01 | 01_quickstart.py | Basic publication-ready figure |
| 02 | 02_multi_panel_figure.py | 2×2 subplot grid with auto panel labels |
| 03 | 03_color_palettes.py | Journal-specific and universal palettes |
| 04 | 04_accessibility_checks.py | Colorblind and grayscale previews |
| 05 | 05_validation.py | Pre-submission validation |
| 06 | 06_export_submission.py | Batch submission export |
| 07 | 07_spec_diff_and_migrate.py | Spec comparison and figure migration |
| 08 | 08_gallery_preview.py | Gallery preview generation |
| 09 | 09_registry_and_spec.py | Registry and spec access |
| 10 | 10_context_manager_patterns.py | Context manager usage patterns |
Contributing
See CONTRIBUTING.md for development setup, adding journal specs, code style, and pull request guidelines.
License
MIT © 2026 Rahul Kaushal
Project details
Release history Release notifications | RSS feed
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 plotstyle-0.1.0a2.tar.gz.
File metadata
- Download URL: plotstyle-0.1.0a2.tar.gz
- Upload date:
- Size: 232.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
24edc0cf574a89e91c4d2ac9157f5c0101f38a2d10cfa8cbf815e9bf48ab484a
|
|
| MD5 |
664403f30dfef7c67d5b8f40fb887e3e
|
|
| BLAKE2b-256 |
0339359563aba37e4a6d2073f678514bcd0b91568f1698d0732813c43343b149
|
Provenance
The following attestation bundles were made for plotstyle-0.1.0a2.tar.gz:
Publisher:
release.yml on rahulkaushal04/plotstyle
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
plotstyle-0.1.0a2.tar.gz -
Subject digest:
24edc0cf574a89e91c4d2ac9157f5c0101f38a2d10cfa8cbf815e9bf48ab484a - Sigstore transparency entry: 1280491886
- Sigstore integration time:
-
Permalink:
rahulkaushal04/plotstyle@58171fb56668fe753a75e44386cb59051b6604bd -
Branch / Tag:
refs/tags/v0.1.0a2 - Owner: https://github.com/rahulkaushal04
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@58171fb56668fe753a75e44386cb59051b6604bd -
Trigger Event:
push
-
Statement type:
File details
Details for the file plotstyle-0.1.0a2-py3-none-any.whl.
File metadata
- Download URL: plotstyle-0.1.0a2-py3-none-any.whl
- Upload date:
- Size: 132.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf639327e874fc91fa1506ce9205f37f2417d3f99f3f113159645d0a0b2236b5
|
|
| MD5 |
0526a77f9075bf9cb241f63a1552a4bc
|
|
| BLAKE2b-256 |
cdfda6b178af0457f2d590f9d21030c49cba4fd9e44305de22c794092c5e82b2
|
Provenance
The following attestation bundles were made for plotstyle-0.1.0a2-py3-none-any.whl:
Publisher:
release.yml on rahulkaushal04/plotstyle
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
plotstyle-0.1.0a2-py3-none-any.whl -
Subject digest:
cf639327e874fc91fa1506ce9205f37f2417d3f99f3f113159645d0a0b2236b5 - Sigstore transparency entry: 1280491894
- Sigstore integration time:
-
Permalink:
rahulkaushal04/plotstyle@58171fb56668fe753a75e44386cb59051b6604bd -
Branch / Tag:
refs/tags/v0.1.0a2 - Owner: https://github.com/rahulkaushal04
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@58171fb56668fe753a75e44386cb59051b6604bd -
Trigger Event:
push
-
Statement type: