plotstyle 0.1.0a2__tar.gz → 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/.gitignore +3 -0
- plotstyle-1.1.0/CHANGELOG.md +102 -0
- plotstyle-1.1.0/PKG-INFO +367 -0
- plotstyle-1.1.0/README.md +306 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/pyproject.toml +18 -2
- plotstyle-1.1.0/src/plotstyle/__init__.py +53 -0
- plotstyle-1.1.0/src/plotstyle/_utils/io.py +49 -0
- plotstyle-1.1.0/src/plotstyle/_utils/warnings.py +13 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/_version.py +2 -2
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/cli/main.py +42 -223
- plotstyle-1.1.0/src/plotstyle/color/__init__.py +11 -0
- plotstyle-1.1.0/src/plotstyle/color/_rendering.py +39 -0
- plotstyle-1.1.0/src/plotstyle/color/accessibility.py +198 -0
- plotstyle-1.1.0/src/plotstyle/color/grayscale.py +158 -0
- plotstyle-1.1.0/src/plotstyle/color/palettes.py +168 -0
- plotstyle-1.1.0/src/plotstyle/core/export.py +362 -0
- plotstyle-1.1.0/src/plotstyle/core/figure.py +394 -0
- plotstyle-1.1.0/src/plotstyle/core/migrate.py +408 -0
- plotstyle-1.1.0/src/plotstyle/core/style.py +580 -0
- plotstyle-1.1.0/src/plotstyle/engine/fonts.py +166 -0
- plotstyle-1.1.0/src/plotstyle/engine/latex.py +154 -0
- plotstyle-1.1.0/src/plotstyle/engine/rcparams.py +180 -0
- plotstyle-1.1.0/src/plotstyle/integrations/seaborn.py +115 -0
- plotstyle-1.1.0/src/plotstyle/preview/__init__.py +11 -0
- plotstyle-1.1.0/src/plotstyle/preview/gallery.py +173 -0
- plotstyle-1.1.0/src/plotstyle/preview/print_size.py +135 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/specs/__init__.py +62 -79
- plotstyle-1.1.0/src/plotstyle/specs/schema.py +906 -0
- plotstyle-1.1.0/src/plotstyle/specs/units.py +445 -0
- plotstyle-1.1.0/src/plotstyle/validation/__init__.py +48 -0
- plotstyle-1.1.0/src/plotstyle/validation/checks/__init__.py +48 -0
- plotstyle-1.1.0/src/plotstyle/validation/checks/_base.py +50 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/validation/checks/colors.py +48 -150
- plotstyle-1.1.0/src/plotstyle/validation/checks/dimensions.py +107 -0
- plotstyle-1.1.0/src/plotstyle/validation/checks/export.py +145 -0
- plotstyle-1.1.0/src/plotstyle/validation/checks/lines.py +88 -0
- plotstyle-1.1.0/src/plotstyle/validation/checks/typography.py +125 -0
- plotstyle-1.1.0/src/plotstyle/validation/report.py +162 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_color/test_palettes.py +18 -17
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_core/test_migrate.py +0 -12
- plotstyle-0.1.0a2/CHANGELOG.md +0 -40
- plotstyle-0.1.0a2/PKG-INFO +0 -347
- plotstyle-0.1.0a2/README.md +0 -290
- plotstyle-0.1.0a2/src/plotstyle/__init__.py +0 -120
- plotstyle-0.1.0a2/src/plotstyle/_utils/io.py +0 -113
- plotstyle-0.1.0a2/src/plotstyle/_utils/warnings.py +0 -86
- plotstyle-0.1.0a2/src/plotstyle/color/__init__.py +0 -42
- plotstyle-0.1.0a2/src/plotstyle/color/_rendering.py +0 -86
- plotstyle-0.1.0a2/src/plotstyle/color/accessibility.py +0 -288
- plotstyle-0.1.0a2/src/plotstyle/color/grayscale.py +0 -285
- plotstyle-0.1.0a2/src/plotstyle/color/palettes.py +0 -259
- plotstyle-0.1.0a2/src/plotstyle/core/export.py +0 -416
- plotstyle-0.1.0a2/src/plotstyle/core/figure.py +0 -402
- plotstyle-0.1.0a2/src/plotstyle/core/migrate.py +0 -586
- plotstyle-0.1.0a2/src/plotstyle/core/style.py +0 -393
- plotstyle-0.1.0a2/src/plotstyle/engine/fonts.py +0 -309
- plotstyle-0.1.0a2/src/plotstyle/engine/latex.py +0 -287
- plotstyle-0.1.0a2/src/plotstyle/engine/rcparams.py +0 -352
- plotstyle-0.1.0a2/src/plotstyle/integrations/seaborn.py +0 -305
- plotstyle-0.1.0a2/src/plotstyle/preview/__init__.py +0 -50
- plotstyle-0.1.0a2/src/plotstyle/preview/gallery.py +0 -337
- plotstyle-0.1.0a2/src/plotstyle/preview/print_size.py +0 -304
- plotstyle-0.1.0a2/src/plotstyle/specs/schema.py +0 -1098
- plotstyle-0.1.0a2/src/plotstyle/specs/units.py +0 -761
- plotstyle-0.1.0a2/src/plotstyle/validation/__init__.py +0 -96
- plotstyle-0.1.0a2/src/plotstyle/validation/checks/__init__.py +0 -95
- plotstyle-0.1.0a2/src/plotstyle/validation/checks/_base.py +0 -149
- plotstyle-0.1.0a2/src/plotstyle/validation/checks/dimensions.py +0 -166
- plotstyle-0.1.0a2/src/plotstyle/validation/checks/export.py +0 -222
- plotstyle-0.1.0a2/src/plotstyle/validation/checks/lines.py +0 -147
- plotstyle-0.1.0a2/src/plotstyle/validation/checks/typography.py +0 -200
- plotstyle-0.1.0a2/src/plotstyle/validation/report.py +0 -300
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/LICENSE +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/_utils/__init__.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/cli/__init__.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/color/data/okabe_ito.json +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/color/data/safe_grayscale.json +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/color/data/tol_bright.json +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/color/data/tol_muted.json +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/color/data/tol_vibrant.json +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/core/__init__.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/engine/__init__.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/integrations/__init__.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/py.typed +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/specs/_templates.toml +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/specs/acs.toml +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/specs/cell.toml +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/specs/elsevier.toml +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/specs/ieee.toml +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/specs/nature.toml +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/specs/plos.toml +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/specs/prl.toml +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/specs/science.toml +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/specs/springer.toml +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/src/plotstyle/specs/wiley.toml +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/conftest.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_cli/test_main.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_color/test_accessibility.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_color/test_grayscale.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_color/test_rendering.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_core/test_export.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_core/test_figure.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_core/test_style.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_engine/test_fonts.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_engine/test_latex.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_engine/test_rcparams.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_integrations/test_seaborn.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_preview/test_gallery.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_preview/test_print_size.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_specs/test_registry.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_specs/test_schema.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_specs/test_units.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_utils/test_io.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_utils/test_warnings.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_validation/test_checks.py +0 -0
- {plotstyle-0.1.0a2 → plotstyle-1.1.0}/tests/test_validation/test_report.py +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to **plotstyle** will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [PEP 440](https://peps.python.org/pep-0440/) versioning.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## [Unreleased]
|
|
11
|
+
|
|
12
|
+
_Nothing yet._
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## [1.1.0] - 2026-04-16
|
|
17
|
+
|
|
18
|
+
Minor feature release : ergonomics improvements, hardened error handling, and spec updates.
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- **`quiet` parameter on `JournalStyle.export()`** : suppresses compliance summaries and manifest output for scripting workflows.
|
|
23
|
+
- **Pre-computed Type 3 font checks** : compliance summary now accepts a pre-computed result for Type 3 font detection, improving performance when the check has already been run by the caller.
|
|
24
|
+
- **`JournalSpec` key access** : `JournalSpec` now supports key-style access, and the dimension check message has been updated for clarity.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **`SpecNotFoundError` base classes** : now inherits from both `ValueError` and `KeyError` so existing `except ValueError` and `except KeyError` handlers catch it correctly; a custom `__str__` produces clearer diagnostic messages.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- **IEEE Transactions spec updated** : column widths, max height, font family, panel-label properties, and preferred output formats revised to match current IEEE author guidelines.
|
|
33
|
+
- **CI documentation build** : Sphinx `docs` job (`sphinx-build -W -n`) added to the CI workflow; rendered HTML is uploaded as an artifact on every push.
|
|
34
|
+
- **Module docstrings** : expanded and standardised across `__init__.py`, `_utils/`, `color/`, `core/`, and `validation/` for consistent Sphinx rendering.
|
|
35
|
+
- **Context-manager examples** : all `plotstyle.use()` call sites in docs and examples updated to the `with plotstyle.use(...) as style:` form to ensure correct `rcParams` restoration.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## [1.0.0] - 2026-04-12
|
|
40
|
+
|
|
41
|
+
First stable release — production-ready for scientific publication workflows.
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- **Stable release** — promoted from alpha (`0.1.0a2`) to stable (`1.0.0`); all public APIs are now considered stable and subject to semantic versioning guarantees.
|
|
46
|
+
- **PyPI classifiers** updated to `Development Status :: 5 - Production/Stable`.
|
|
47
|
+
- **Enhanced project metadata** — expanded keywords, classifiers, and project URLs in `pyproject.toml` for better PyPI discoverability.
|
|
48
|
+
- **README improvements** — added more badges (downloads, docs status, code style), expanded feature descriptions, and added star-history / citation section.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## [0.1.0a2] - 2026-04-12
|
|
53
|
+
|
|
54
|
+
Second alpha — full documentation suite, comprehensive test coverage, and hardened validation.
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- **Full documentation suite** — Sphinx/MyST docs covering installation, quickstart, concepts, CLI reference, complete API reference for every public symbol, how-to guides (accessibility, export, migration, multi-panel, palettes, seaborn), FAQ, and a journal comparison index.
|
|
59
|
+
- **ReadTheDocs integration** — `.readthedocs.yaml` added; docs build automatically on every push; Furo theme configured with custom CSS.
|
|
60
|
+
- **Comprehensive test suite** — new test modules added: `test_style`, `test_palettes`, `test_accessibility`, `test_grayscale`, `test_rendering`, `test_gallery`, `test_print_size`, `test_cli`, `test_io`, `test_warnings`, `test_checks`, `test_report`; existing modules `test_figure`, `test_export`, `test_migrate`, `test_fonts`, and `test_registry` substantially expanded.
|
|
61
|
+
- **Export DPI validation** — `validation/checks/export.py` now emits a hard `FAIL` (instead of a `WARN`) when `savefig.dpi` is a numeric value that is provably below the journal's minimum DPI requirement.
|
|
62
|
+
- **Dependabot** — `.github/dependabot.yml` added for automated dependency-update pull requests.
|
|
63
|
+
- **`_format_panel_label()` range guard** — raises `ValueError` for panel indices ≥ 702 (beyond the two-character `"zz"` label); valid range is now explicitly documented as 0–701.
|
|
64
|
+
|
|
65
|
+
### Changed
|
|
66
|
+
|
|
67
|
+
- CI workflow extended: a `docs` build job added to `.github/workflows/ci.yml` — runs `sphinx-build -W -n` on every push and uploads the rendered HTML as an artifact.
|
|
68
|
+
- Module docstring quick-start example in `__init__.py` updated to use the context-manager form (`with plotstyle.use(...) as style:`) and `plotstyle.figure()` instead of `plotstyle.subplots()`.
|
|
69
|
+
- Docstrings across `migrate.py`, `report.py`, `style.py`, `figure.py`, `export.py`, and `accessibility.py` converted to NumPy-style attribute sections for consistent Sphinx rendering.
|
|
70
|
+
- `FORMAT_EXTENSIONS` constant in `export.py` annotated as a module-level Sphinx data comment (`#:`) so it appears correctly in the API docs.
|
|
71
|
+
- `pyproject.toml` documentation extras updated: `furo` pinned to `>=2025.12.19` and `myst-parser` bumped to `>=5.0,<6`.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## [0.1.0a1] - 2026-04-07
|
|
76
|
+
|
|
77
|
+
First public alpha release.
|
|
78
|
+
|
|
79
|
+
### Added
|
|
80
|
+
|
|
81
|
+
- **Core style engine** — `plotstyle.use()` applies journal presets to Matplotlib's `rcParams`; works as a context manager with automatic restoration on exit.
|
|
82
|
+
- **Figure helpers** — `plotstyle.figure()` and `plotstyle.subplots()` create correctly-sized figures at the exact column width and max height specified by each journal.
|
|
83
|
+
- **Auto panel labels** — multi-panel figures receive **(a)**, **(b)**, **(c)**, … labels placed according to the journal's style rules.
|
|
84
|
+
- **Colorblind-safe palettes** — built-in Okabe–Ito, Tol Bright, Tol Vibrant, Tol Muted, and Safe Grayscale palettes (`plotstyle.palette()`).
|
|
85
|
+
- **Accessibility previews** — `plotstyle.preview_colorblind()` simulates deuteranopia, protanopia, and tritanopia; `plotstyle.preview_grayscale()` previews grayscale rendering.
|
|
86
|
+
- **Pre-submission validation** — `plotstyle.validate()` checks dimensions, typography, line weights, color accessibility, and export settings against a target journal spec.
|
|
87
|
+
- **Submission-ready export** — `plotstyle.savefig()` saves with font embedding and DPI enforcement; `plotstyle.export_submission()` batch-exports to all formats a journal accepts.
|
|
88
|
+
- **Spec diffing & migration** — `plotstyle.diff()` compares two journal specs; `plotstyle.migrate()` re-targets a figure from one journal to another.
|
|
89
|
+
- **Seaborn integration** — `patch_seaborn()` / `plotstyle_theme()` ensure PlotStyle `rcParams` survive `sns.set_theme()` calls.
|
|
90
|
+
- **Gallery & print-size preview** — `plotstyle.gallery()` generates sample figures; `plotstyle.preview_print_size()` opens an interactive scaled preview window.
|
|
91
|
+
- **Journal spec registry** — programmatic access via `plotstyle.registry`; specs are TOML files validated by immutable, typed dataclasses.
|
|
92
|
+
- **CLI** — `plotstyle list`, `plotstyle info`, `plotstyle diff`, `plotstyle fonts`, `plotstyle validate`, and `plotstyle export` sub-commands.
|
|
93
|
+
- **10 journal presets** — ACS, Cell, Elsevier, IEEE, Nature, PLOS, PRL, Science, Springer, Wiley.
|
|
94
|
+
- **10 working examples** — quick start, multi-panel, palettes, accessibility, validation, export, diff/migrate, gallery, registry, context manager patterns.
|
|
95
|
+
- **Dynamic versioning** — version derived from git tags via `hatch-vcs` and `importlib.metadata`.
|
|
96
|
+
- **CI/CD pipeline** — GitHub Actions workflows for lint, type-check, test matrix, and automated PyPI release via OIDC Trusted Publishing.
|
|
97
|
+
|
|
98
|
+
[Unreleased]: https://github.com/rahulkaushal04/plotstyle/compare/v1.1.0...HEAD
|
|
99
|
+
[1.1.0]: https://github.com/rahulkaushal04/plotstyle/compare/v1.0.0...v1.1.0
|
|
100
|
+
[1.0.0]: https://github.com/rahulkaushal04/plotstyle/compare/v0.1.0a2...v1.0.0
|
|
101
|
+
[0.1.0a2]: https://github.com/rahulkaushal04/plotstyle/compare/v0.1.0a1...v0.1.0a2
|
|
102
|
+
[0.1.0a1]: https://github.com/rahulkaushal04/plotstyle/releases/tag/v0.1.0a1
|
plotstyle-1.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: plotstyle
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Matplotlib/seaborn style presets matching scientific journal requirements, with validation, export safety, and preview capabilities.
|
|
5
|
+
Project-URL: Homepage, https://github.com/rahulkaushal04/plotstyle
|
|
6
|
+
Project-URL: Documentation, https://plotstyle.readthedocs.io
|
|
7
|
+
Project-URL: Repository, https://github.com/rahulkaushal04/plotstyle
|
|
8
|
+
Project-URL: Issues, https://github.com/rahulkaushal04/plotstyle/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/rahulkaushal04/plotstyle/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Download, https://pypi.org/project/plotstyle/
|
|
11
|
+
Author: Rahul Kaushal
|
|
12
|
+
License: MIT
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Keywords: academic,accessibility,colorblind,export,figures,ieee,journal,matplotlib,nature,plotting,publication,rcParams,research,science,scientific,seaborn,style,typesetting,validation,visualization
|
|
15
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
16
|
+
Classifier: Framework :: Matplotlib
|
|
17
|
+
Classifier: Intended Audience :: Education
|
|
18
|
+
Classifier: Intended Audience :: Science/Research
|
|
19
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
20
|
+
Classifier: Natural Language :: English
|
|
21
|
+
Classifier: Operating System :: OS Independent
|
|
22
|
+
Classifier: Programming Language :: Python :: 3
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
27
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
28
|
+
Classifier: Topic :: Scientific/Engineering
|
|
29
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
30
|
+
Classifier: Typing :: Typed
|
|
31
|
+
Requires-Python: >=3.10
|
|
32
|
+
Requires-Dist: matplotlib<4,>=3.9
|
|
33
|
+
Requires-Dist: tomli>=2.0; python_version < '3.11'
|
|
34
|
+
Provides-Extra: all
|
|
35
|
+
Requires-Dist: fonttools<5,>=4.55; extra == 'all'
|
|
36
|
+
Requires-Dist: pandas<3,>=2.2; extra == 'all'
|
|
37
|
+
Requires-Dist: pillow<13,>=11.0; extra == 'all'
|
|
38
|
+
Requires-Dist: seaborn<1,>=0.13.2; extra == 'all'
|
|
39
|
+
Provides-Extra: color
|
|
40
|
+
Requires-Dist: pillow<13,>=11.0; extra == 'color'
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: mypy<2,>=1.15; extra == 'dev'
|
|
43
|
+
Requires-Dist: pillow<13,>=11.0; extra == 'dev'
|
|
44
|
+
Requires-Dist: pre-commit<5,>=4.0; extra == 'dev'
|
|
45
|
+
Requires-Dist: pytest-cov<8,>=6.0; extra == 'dev'
|
|
46
|
+
Requires-Dist: pytest-mpl<1,>=0.18; extra == 'dev'
|
|
47
|
+
Requires-Dist: pytest<10,>=8.3; extra == 'dev'
|
|
48
|
+
Requires-Dist: ruff<1,>=0.15; extra == 'dev'
|
|
49
|
+
Provides-Extra: docs
|
|
50
|
+
Requires-Dist: furo>=2025.12.19; extra == 'docs'
|
|
51
|
+
Requires-Dist: myst-parser<6,>=5.0; extra == 'docs'
|
|
52
|
+
Requires-Dist: sphinx-autodoc-typehints<4,>=3.0; extra == 'docs'
|
|
53
|
+
Requires-Dist: sphinx-copybutton<1,>=0.5; extra == 'docs'
|
|
54
|
+
Requires-Dist: sphinx<10,>=9.0; extra == 'docs'
|
|
55
|
+
Provides-Extra: fonttools
|
|
56
|
+
Requires-Dist: fonttools<5,>=4.55; extra == 'fonttools'
|
|
57
|
+
Provides-Extra: seaborn
|
|
58
|
+
Requires-Dist: pandas<3,>=2.2; extra == 'seaborn'
|
|
59
|
+
Requires-Dist: seaborn<1,>=0.13.2; extra == 'seaborn'
|
|
60
|
+
Description-Content-Type: text/markdown
|
|
61
|
+
|
|
62
|
+
<p align="center">
|
|
63
|
+
<strong>plotstyle</strong>
|
|
64
|
+
</p>
|
|
65
|
+
|
|
66
|
+
<p align="center">
|
|
67
|
+
<em>Matplotlib figures formatted for journal submission, automatically.</em>
|
|
68
|
+
</p>
|
|
69
|
+
|
|
70
|
+
<p align="center">
|
|
71
|
+
<a href="https://pypi.org/project/plotstyle/"><img alt="PyPI version" src="https://img.shields.io/pypi/v/plotstyle?color=blue"></a>
|
|
72
|
+
<a href="https://pypi.org/project/plotstyle/"><img alt="Python versions" src="https://img.shields.io/pypi/pyversions/plotstyle"></a>
|
|
73
|
+
<a href="https://github.com/rahulkaushal04/plotstyle/blob/main/LICENSE"><img alt="License: MIT" src="https://img.shields.io/github/license/rahulkaushal04/plotstyle"></a>
|
|
74
|
+
<a href="https://github.com/rahulkaushal04/plotstyle/actions"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/rahulkaushal04/plotstyle/ci.yml?label=CI"></a>
|
|
75
|
+
<a href="https://plotstyle.readthedocs.io/en/stable/"><img alt="Docs" src="https://img.shields.io/readthedocs/plotstyle/stable?label=docs"></a>
|
|
76
|
+
</p>
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
**PlotStyle** makes it easy to produce Matplotlib figures that meet the exact typographic, dimensional, and export requirements of major academic journals. It also integrates with Seaborn, with more integrations planned. Pick a journal, create your figure, save it. PlotStyle handles the rest.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Table of Contents
|
|
85
|
+
|
|
86
|
+
- [Installation](#installation)
|
|
87
|
+
- [Quick Start](#quick-start)
|
|
88
|
+
- [Examples](#examples)
|
|
89
|
+
- [Multi-panel figures](#multi-panel-figures)
|
|
90
|
+
- [Color palettes](#color-palettes)
|
|
91
|
+
- [Colorblind and grayscale previews](#colorblind-and-grayscale-previews)
|
|
92
|
+
- [Validation and submission export](#validation-and-submission-export)
|
|
93
|
+
- [Supported Journals](#supported-journals)
|
|
94
|
+
- [CLI](#cli)
|
|
95
|
+
- [Documentation](#documentation)
|
|
96
|
+
- [Contributing](#contributing)
|
|
97
|
+
- [Citation](#citation)
|
|
98
|
+
- [License](#license)
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Installation
|
|
103
|
+
|
|
104
|
+
Requires **Python 3.10+** and **Matplotlib >= 3.9**.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
pip install plotstyle
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Optional extras:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
pip install "plotstyle[color]" # colorblind / grayscale previews
|
|
114
|
+
pip install "plotstyle[seaborn]" # seaborn integration
|
|
115
|
+
pip install "plotstyle[all]" # everything
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Quick Start
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
import numpy as np
|
|
124
|
+
import plotstyle
|
|
125
|
+
|
|
126
|
+
with plotstyle.use("nature") as style:
|
|
127
|
+
fig, ax = style.figure(columns=1) # sized to Nature's single-column width (89 mm)
|
|
128
|
+
|
|
129
|
+
x = np.linspace(0, 2 * np.pi, 200)
|
|
130
|
+
ax.plot(x, np.sin(x), label="sin(x)")
|
|
131
|
+
ax.plot(x, np.cos(x), label="cos(x)")
|
|
132
|
+
ax.set_xlabel("Phase (rad)")
|
|
133
|
+
ax.set_ylabel("Amplitude (a.u.)")
|
|
134
|
+
ax.legend()
|
|
135
|
+
|
|
136
|
+
style.savefig(fig, "figure.pdf") # 300 DPI minimum, TrueType fonts embedded
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
<p align="center">
|
|
140
|
+
<img src="examples/output/quickstart_nature.png" width="55%" alt="Quickstart output: sin and cos figure styled for Nature">
|
|
141
|
+
</p>
|
|
142
|
+
|
|
143
|
+
The `with` block is the recommended pattern. Matplotlib's `rcParams` are restored automatically when it exits, even if an exception occurs.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Examples
|
|
148
|
+
|
|
149
|
+
### Multi-panel figures
|
|
150
|
+
|
|
151
|
+
`style.subplots()` works like `plt.subplots()` but sizes the figure to the journal spec and adds panel labels automatically, styled to each journal's convention (**A**, **B**, **C** for Science; **a**, **b**, **c** for Nature; **(a)**, **(b)**, **(c)** for IEEE).
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
import numpy as np
|
|
155
|
+
import plotstyle
|
|
156
|
+
|
|
157
|
+
rng = np.random.default_rng(42)
|
|
158
|
+
|
|
159
|
+
with plotstyle.use("science") as style:
|
|
160
|
+
fig, axes = style.subplots(nrows=2, ncols=2, columns=2)
|
|
161
|
+
|
|
162
|
+
x = np.linspace(0, 10, 100)
|
|
163
|
+
axes[0, 0].plot(x, np.sin(x), label="sin")
|
|
164
|
+
axes[0, 0].plot(x, np.cos(x), label="cos")
|
|
165
|
+
axes[0, 0].set_xlabel("x")
|
|
166
|
+
axes[0, 0].set_ylabel("f(x)")
|
|
167
|
+
axes[0, 0].legend()
|
|
168
|
+
|
|
169
|
+
xs = rng.normal(0, 1, 60)
|
|
170
|
+
ys = 0.7 * xs + rng.normal(0, 0.3, 60)
|
|
171
|
+
axes[0, 1].scatter(xs, ys, s=12, alpha=0.7)
|
|
172
|
+
axes[0, 1].set_xlabel("Variable X")
|
|
173
|
+
axes[0, 1].set_ylabel("Variable Y")
|
|
174
|
+
|
|
175
|
+
axes[1, 0].bar(["A", "B", "C", "D"], [3.2, 5.8, 4.1, 6.5])
|
|
176
|
+
axes[1, 0].set_xlabel("Category")
|
|
177
|
+
axes[1, 0].set_ylabel("Count")
|
|
178
|
+
|
|
179
|
+
axes[1, 1].hist(rng.normal(0, 1, 500), bins=25, edgecolor="white", linewidth=0.5)
|
|
180
|
+
axes[1, 1].set_xlabel("Value")
|
|
181
|
+
axes[1, 1].set_ylabel("Frequency")
|
|
182
|
+
|
|
183
|
+
style.savefig(fig, "multi_panel.pdf")
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
<p align="center">
|
|
187
|
+
<img src="examples/output/multi_panel_science.png" width="70%" alt="2x2 multi-panel Science figure with automatic panel labels A B C D">
|
|
188
|
+
</p>
|
|
189
|
+
|
|
190
|
+
> `axes` is always a 2-D NumPy array. Use `axes[0, 0]` to access a single panel or `axes.flat` to iterate. Pass `panels=False` to suppress the automatic labels.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### Color palettes
|
|
195
|
+
|
|
196
|
+
Each journal has a recommended colorblind-safe palette. `plotstyle.palette()` returns hex color strings, cycling if you need more than the palette length.
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
import matplotlib.pyplot as plt
|
|
200
|
+
import plotstyle
|
|
201
|
+
|
|
202
|
+
journals = ["nature", "science", "ieee", "acs"]
|
|
203
|
+
fig, axes = plt.subplots(len(journals), 1, figsize=(6, 0.6 * len(journals)))
|
|
204
|
+
|
|
205
|
+
for ax, journal in zip(axes, journals):
|
|
206
|
+
pal = plotstyle.palette(journal, n=8)
|
|
207
|
+
for i, color in enumerate(pal):
|
|
208
|
+
ax.barh(0, 1, left=i, color=color, edgecolor="none", height=0.8)
|
|
209
|
+
ax.set_xlim(0, 8)
|
|
210
|
+
ax.set_yticks([])
|
|
211
|
+
ax.set_ylabel(journal, rotation=0, ha="right", va="center")
|
|
212
|
+
ax.set_xticks([])
|
|
213
|
+
|
|
214
|
+
fig.suptitle("Journal Color Palettes")
|
|
215
|
+
fig.tight_layout()
|
|
216
|
+
fig.savefig("palette_comparison.png", dpi=150)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
<p align="center">
|
|
220
|
+
<img src="examples/output/palette_comparison.png" width="70%" alt="Color swatch comparison for Nature, Science, IEEE, and ACS palettes">
|
|
221
|
+
</p>
|
|
222
|
+
|
|
223
|
+
Pass `with_markers=True` to get `(color, linestyle, marker)` tuples, useful for journals like IEEE that print in grayscale:
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
styled = plotstyle.palette("ieee", n=4, with_markers=True)
|
|
227
|
+
for color, ls, marker in styled:
|
|
228
|
+
ax.plot(x, y, color=color, linestyle=ls, marker=marker)
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
### Colorblind and grayscale previews
|
|
234
|
+
|
|
235
|
+
Build a figure, then simulate how it looks under color vision deficiency or grayscale printing before you submit.
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
import numpy as np
|
|
239
|
+
import plotstyle
|
|
240
|
+
|
|
241
|
+
with plotstyle.use("nature") as style:
|
|
242
|
+
colors = style.palette(n=4)
|
|
243
|
+
fig, ax = style.figure(columns=1)
|
|
244
|
+
x = np.linspace(0, 5, 80)
|
|
245
|
+
for i, c in enumerate(colors):
|
|
246
|
+
ax.plot(x, np.sin(x + i), color=c, linewidth=1.5, label=f"Series {i + 1}")
|
|
247
|
+
ax.set_xlabel("Time (s)")
|
|
248
|
+
ax.set_ylabel("Signal")
|
|
249
|
+
ax.legend()
|
|
250
|
+
|
|
251
|
+
cvd_fig = plotstyle.preview_colorblind(fig)
|
|
252
|
+
cvd_fig.savefig("accessibility_colorblind.png", dpi=150, bbox_inches="tight")
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
<p align="center">
|
|
256
|
+
<img src="examples/output/accessibility_colorblind.png" width="90%" alt="Colorblind simulation: original, deuteranopia, protanopia, tritanopia">
|
|
257
|
+
</p>
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
gray_fig = plotstyle.preview_grayscale(fig)
|
|
261
|
+
gray_fig.savefig("accessibility_grayscale.png", dpi=150, bbox_inches="tight")
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
<p align="center">
|
|
265
|
+
<img src="examples/output/accessibility_grayscale.png" width="60%" alt="Grayscale simulation: original vs grayscale rendering">
|
|
266
|
+
</p>
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
### Validation and submission export
|
|
271
|
+
|
|
272
|
+
Validate a figure against the journal's requirements, then export in all required formats at once.
|
|
273
|
+
|
|
274
|
+
```python
|
|
275
|
+
report = plotstyle.validate(fig, journal="nature")
|
|
276
|
+
print(report) # formatted compliance table
|
|
277
|
+
print(report.passed) # True if everything is OK
|
|
278
|
+
|
|
279
|
+
for failure in report.failures:
|
|
280
|
+
print(failure.message) # what failed
|
|
281
|
+
print(failure.fix_suggestion) # how to fix it
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
```python
|
|
285
|
+
paths = plotstyle.export_submission(
|
|
286
|
+
fig,
|
|
287
|
+
"figure1",
|
|
288
|
+
journal="ieee",
|
|
289
|
+
author_surname="Smith", # IEEE prepends the surname prefix to filenames
|
|
290
|
+
output_dir="submission/",
|
|
291
|
+
)
|
|
292
|
+
# Produces: submission/smith_figure1.pdf (and any other IEEE-required formats)
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Supported Journals
|
|
298
|
+
|
|
299
|
+
| Key | Journal | Publisher |
|
|
300
|
+
|-----|---------|-----------|
|
|
301
|
+
| `acs` | ACS (JACS) | American Chemical Society |
|
|
302
|
+
| `cell` | Cell | Cell Press |
|
|
303
|
+
| `elsevier` | Elsevier | Elsevier |
|
|
304
|
+
| `ieee` | IEEE Transactions | IEEE |
|
|
305
|
+
| `nature` | Nature | Springer Nature |
|
|
306
|
+
| `plos` | PLOS ONE | Public Library of Science |
|
|
307
|
+
| `prl` | Physical Review Letters | American Physical Society |
|
|
308
|
+
| `science` | Science | AAAS |
|
|
309
|
+
| `springer` | Springer | Springer |
|
|
310
|
+
| `wiley` | Wiley | Wiley |
|
|
311
|
+
|
|
312
|
+
> Need another journal? See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## CLI
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
plotstyle list # list all journal presets
|
|
320
|
+
plotstyle info <journal> # show spec details
|
|
321
|
+
plotstyle diff <journal_a> <journal_b> # compare two journals
|
|
322
|
+
plotstyle fonts --journal <journal> # check font availability
|
|
323
|
+
plotstyle validate <file> --journal <journal> # validate a saved figure
|
|
324
|
+
plotstyle export <file> --journal <journal> # print snippet for re-exporting
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Documentation
|
|
330
|
+
|
|
331
|
+
Full documentation at **[plotstyle.readthedocs.io](https://plotstyle.readthedocs.io)**:
|
|
332
|
+
|
|
333
|
+
- [Installation guide](https://plotstyle.readthedocs.io/en/stable/installation.html)
|
|
334
|
+
- [Quick start tutorial](https://plotstyle.readthedocs.io/en/stable/quickstart.html)
|
|
335
|
+
- [API reference](https://plotstyle.readthedocs.io/en/stable/api/index.html)
|
|
336
|
+
- [CLI reference](https://plotstyle.readthedocs.io/en/stable/cli.html)
|
|
337
|
+
- [FAQ](https://plotstyle.readthedocs.io/en/stable/faq.html)
|
|
338
|
+
|
|
339
|
+
Working examples are in the [`examples/`](examples/) directory.
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## Contributing
|
|
344
|
+
|
|
345
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, adding journal specs, and pull request guidelines.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## Citation
|
|
350
|
+
|
|
351
|
+
If PlotStyle helps your research, a citation or star is appreciated:
|
|
352
|
+
|
|
353
|
+
```bibtex
|
|
354
|
+
@misc{plotstyle,
|
|
355
|
+
author = {Kaushal, Rahul},
|
|
356
|
+
title = {PlotStyle: Publication-ready scientific figure presets for Matplotlib},
|
|
357
|
+
year = {2026},
|
|
358
|
+
url = {https://github.com/rahulkaushal04/plotstyle},
|
|
359
|
+
note = {Version 1.1.0},
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## License
|
|
366
|
+
|
|
367
|
+
[MIT](LICENSE) © 2026 Rahul Kaushal
|