plotstyle 1.2.0__tar.gz → 1.2.2__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-1.2.2/CHANGELOG.md +182 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/PKG-INFO +125 -28
- {plotstyle-1.2.0 → plotstyle-1.2.2}/README.md +124 -27
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/__init__.py +1 -1
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/_compat/mpl_style.py +2 -2
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/_version.py +2 -2
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/cli/main.py +3 -3
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/_rendering.py +2 -3
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/accessibility.py +1 -1
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/core/export.py +12 -7
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/core/figure.py +3 -3
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/core/migrate.py +7 -7
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/core/style.py +14 -14
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/engine/fonts.py +9 -8
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/engine/latex.py +2 -2
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/engine/rcparams.py +5 -5
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/__init__.py +2 -2
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/schema.py +3 -3
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/preview/print_size.py +1 -1
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/specs/__init__.py +27 -24
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/specs/_templates.toml +1 -1
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/specs/schema.py +2 -2
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/specs/units.py +2 -2
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/validation/checks/__init__.py +1 -1
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/validation/checks/_base.py +1 -1
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/validation/checks/dimensions.py +2 -2
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/validation/checks/typography.py +1 -1
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/validation/report.py +1 -1
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_cli/test_main.py +3 -3
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_color/test_accessibility.py +1 -1
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_color/test_grayscale.py +1 -1
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_engine/test_rcparams.py +13 -13
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_integrations/test_seaborn.py +3 -3
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_preview/test_gallery.py +1 -1
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_preview/test_print_size.py +1 -1
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_specs/test_registry.py +3 -3
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_specs/test_schema.py +6 -6
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_specs/test_units.py +8 -8
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_utils/test_io.py +5 -5
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_utils/test_warnings.py +1 -1
- plotstyle-1.2.0/CHANGELOG.md +0 -135
- {plotstyle-1.2.0 → plotstyle-1.2.2}/.gitignore +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/LICENSE +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/pyproject.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/_compat/__init__.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/_utils/__init__.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/_utils/io.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/_utils/warnings.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/cli/__init__.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/__init__.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/data/okabe_ito.json +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/data/safe_grayscale.json +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/data/tol_bright.json +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/data/tol_high_contrast.json +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/data/tol_light.json +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/data/tol_muted.json +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/data/tol_rainbow_10.json +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/data/tol_rainbow_12.json +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/data/tol_rainbow_4.json +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/data/tol_rainbow_6.json +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/data/tol_rainbow_8.json +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/data/tol_vibrant.json +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/grayscale.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/color/palettes.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/core/__init__.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/engine/__init__.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/integrations/__init__.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/integrations/seaborn.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/bar.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/cjk-japanese.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/cjk-korean.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/cjk-simplified.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/cjk-traditional.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/grid.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/high-vis.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/latex-sans.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/minimal.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/no-latex.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/notebook.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/okabe-ito.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/pgf.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/presentation.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/russian.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/safe-grayscale.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/scatter.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/tol-bright.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/tol-high-contrast.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/tol-light.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/tol-muted.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/tol-rainbow-10.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/tol-rainbow-12.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/tol-rainbow-4.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/tol-rainbow-6.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/tol-rainbow-8.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/tol-vibrant.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/overlays/turkish.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/preview/__init__.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/preview/gallery.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/py.typed +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/specs/acs.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/specs/cell.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/specs/elsevier.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/specs/ieee.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/specs/nature.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/specs/plos.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/specs/prl.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/specs/science.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/specs/springer.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/specs/wiley.toml +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/validation/__init__.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/validation/checks/colors.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/validation/checks/export.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/src/plotstyle/validation/checks/lines.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/conftest.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_color/test_palettes.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_color/test_rendering.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_core/test_export.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_core/test_figure.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_core/test_migrate.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_core/test_style.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_engine/test_fonts.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_engine/test_latex.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_validation/test_checks.py +0 -0
- {plotstyle-1.2.0 → plotstyle-1.2.2}/tests/test_validation/test_report.py +0 -0
|
@@ -0,0 +1,182 @@
|
|
|
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.2.2] - 2026-04-27
|
|
17
|
+
|
|
18
|
+
Patch release: docs improvements, README example quality, and CI action bump.
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- **`LatexNotFoundError` catch pattern in API docs** (`docs/api/style.md`): new "Catching LaTeX errors" section shows how to import and handle `LatexNotFoundError` directly, with a note on catching the base `RuntimeError` as an alternative.
|
|
23
|
+
- **`examples/output/accessibility_deuteranopia.png`**: new reference output image generated by the `simulate_cvd` section of `04_accessibility_checks.py`.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **README overlay examples use realistic data**: notebook and okabe-ito overlay snippets now use `np.linspace` / `np.sin` / `np.cos` plots instead of trivial `[1, 2, 3]` lists; axes labels updated to match.
|
|
28
|
+
- **README overlay snippet import cleanup**: removed stray `import matplotlib.pyplot as plt` from the minimal overlay example where it was unused.
|
|
29
|
+
- **README validation report output updated**: sample terminal output now reflects a two-column figure width rather than a single-column one.
|
|
30
|
+
- **README `diff` output adds `Avoid: none`**: accessibility block in the `plotstyle diff` sample output now shows the `Avoid` field.
|
|
31
|
+
- **`download-artifact` action bumped to v8** in `.github/workflows/release.yml` (was v4).
|
|
32
|
+
- **Version references bumped to 1.2.2** in `README.md` (citation note) and `docs/installation.md` (version-check snippet).
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **HiDPI/Retina crash in `_fig_to_rgb_array`** (`src/plotstyle/color/_rendering.py`): `get_width_height()` now passes `physical=True` so the returned pixel dimensions match the `buffer_rgba()` byte count on high-DPI displays, preventing a `ValueError` during the reshape.
|
|
37
|
+
- **Same HiDPI fix in `simulate_cvd` example** (`examples/04_accessibility_checks.py`): the inline canvas-to-array snippet now uses `get_width_height(physical=True)` to stay consistent with the library fix above.
|
|
38
|
+
- **Typo in `06_export_submission.py` docstring**: `"smit_"` author prefix corrected to `"smith_"`.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## [1.2.1] - 2026-04-26
|
|
43
|
+
|
|
44
|
+
Patch release: `simulate_cvd` example, warning quality improvements, and docs/example content fixes.
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- **`simulate_cvd` example in `04_accessibility_checks.py`**: demonstrates low-level CVD simulation by rendering a figure to an RGB array and applying a single `CVDType` matrix directly via `simulate_cvd()`.
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
|
|
52
|
+
- **`SpecAssumptionWarning` deduplication**: each spec now emits the assumption warning at most once per session. A `_warned_specs` set on `SpecRegistry` tracks which specs have already warned; `reset()` clears it alongside the spec cache.
|
|
53
|
+
- **Clearer `OverlaySizeWarning`**: the message now names the journal, the overlay, the actual width, the limit, and the fix action, replacing the previous vague description.
|
|
54
|
+
- **Improved font-fallback warning**: lists font names in a readable comma-separated form and adds a hint to rebuild the Matplotlib font cache after installing a new font.
|
|
55
|
+
- **FontTools log suppression during PDF export**: `savefig()` temporarily sets the `fontTools` logger to `ERROR` level during `fig.savefig()` to suppress low-level font subsetting noise.
|
|
56
|
+
- **`SpecRegistry.get()` uses `_silent=True` during background style registration**: prevents the assumption warning from firing during the import-time `register_all_styles()` call.
|
|
57
|
+
- **Docs and example content fixes**: factual errors corrected across API reference, guides, CLI docs, and Jupyter notebooks; overlay guide expanded with additional coverage.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## [1.2.0] - 2026-04-23
|
|
62
|
+
|
|
63
|
+
Feature release: **overlays**, **units & conversions**, **Seaborn integration**, improved **font/LaTeX controls**, plus major CLI/docs/example expansion.
|
|
64
|
+
|
|
65
|
+
### Added
|
|
66
|
+
|
|
67
|
+
- **Style overlays** (`plotstyle.overlays`, `plotstyle.list_overlays()`): additive layers that can be composed with a base journal preset.
|
|
68
|
+
- Categories: `color`, `context`, `rendering`, `plot-type`, `script`.
|
|
69
|
+
- Built-in overlays include `minimal`, `notebook`, `presentation`, `high-vis`, `grid`, `bar`, `scatter`, `no-latex`, `pgf`, `latex-sans`, `okabe-ito`, `safe-grayscale`, and `tol-*` palette overlays, plus CJK/Turkish/Russian script overlays.
|
|
70
|
+
- **New CLI commands for overlays**
|
|
71
|
+
- `plotstyle overlays [--category <category>]` to list overlays.
|
|
72
|
+
- `plotstyle overlay-info <overlay>` to inspect overlay metadata and `rcParams`.
|
|
73
|
+
- **Font checks for overlays**: `plotstyle fonts --overlay <overlay>` (in addition to `--journal`).
|
|
74
|
+
- **Seaborn integration**: helpers to keep PlotStyle `rcParams` consistent when using Seaborn themes (`patch_seaborn()`, `plotstyle_theme()`, `unpatch_seaborn()`).
|
|
75
|
+
- **Units & conversions**: new/expanded utilities and docs for consistent size specification across specs and helpers.
|
|
76
|
+
- **Matplotlib-native styles compatibility**: support for registering/using PlotStyle presets as Matplotlib styles where applicable.
|
|
77
|
+
- **New examples & previews**: additional example scripts including overlays, Seaborn integration, units/conversions, print-size preview, Matplotlib native styles, and LaTeX/fonts.
|
|
78
|
+
|
|
79
|
+
### Changed
|
|
80
|
+
|
|
81
|
+
- **CLI UX improvements**
|
|
82
|
+
- `plotstyle fonts` now supports `--journal` *or* `--overlay` (mutually exclusive, required).
|
|
83
|
+
- More robust argument parsing (e.g. ignores empty entries in `--formats`).
|
|
84
|
+
- Friendlier output for empty registries (journals/overlays) and clearer reporting for overlay font availability.
|
|
85
|
+
- **Docs & README expansion**: new/expanded guides and API reference for overlays, units, warnings, Seaborn, preview tooling, and updated patterns/examples.
|
|
86
|
+
|
|
87
|
+
### Fixed
|
|
88
|
+
|
|
89
|
+
- **CLI stability**: avoid noisy/unclear behavior in edge cases (empty registry listings, malformed format lists) and improve error messaging around missing overlay keys.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## [1.1.0] - 2026-04-16
|
|
94
|
+
|
|
95
|
+
Minor feature release : ergonomics improvements, hardened error handling, and spec updates.
|
|
96
|
+
|
|
97
|
+
### Added
|
|
98
|
+
|
|
99
|
+
- **`quiet` parameter on `JournalStyle.export()`** : suppresses compliance summaries and manifest output for scripting workflows.
|
|
100
|
+
- **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.
|
|
101
|
+
- **`JournalSpec` key access** : `JournalSpec` now supports key-style access, and the dimension check message has been updated for clarity.
|
|
102
|
+
|
|
103
|
+
### Fixed
|
|
104
|
+
|
|
105
|
+
- **`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.
|
|
106
|
+
|
|
107
|
+
### Changed
|
|
108
|
+
|
|
109
|
+
- **IEEE Transactions spec updated** : column widths, max height, font family, panel-label properties, and preferred output formats revised to match current IEEE author guidelines.
|
|
110
|
+
- **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.
|
|
111
|
+
- **Module docstrings** : expanded and standardised across `__init__.py`, `_utils/`, `color/`, `core/`, and `validation/` for consistent Sphinx rendering.
|
|
112
|
+
- **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.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## [1.0.0] - 2026-04-12
|
|
117
|
+
|
|
118
|
+
First stable release: production-ready for scientific publication workflows.
|
|
119
|
+
|
|
120
|
+
### Changed
|
|
121
|
+
|
|
122
|
+
- **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.
|
|
123
|
+
- **PyPI classifiers** updated to `Development Status :: 5 - Production/Stable`.
|
|
124
|
+
- **Enhanced project metadata**: expanded keywords, classifiers, and project URLs in `pyproject.toml` for better PyPI discoverability.
|
|
125
|
+
- **README improvements**: added more badges (downloads, docs status, code style), expanded feature descriptions, and added star-history / citation section.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## [0.1.0a2] - 2026-04-12
|
|
130
|
+
|
|
131
|
+
Second alpha: full documentation suite, comprehensive test coverage, and hardened validation.
|
|
132
|
+
|
|
133
|
+
### Added
|
|
134
|
+
|
|
135
|
+
- **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.
|
|
136
|
+
- **ReadTheDocs integration**: `.readthedocs.yaml` added; docs build automatically on every push; Furo theme configured with custom CSS.
|
|
137
|
+
- **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.
|
|
138
|
+
- **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.
|
|
139
|
+
- **Dependabot**: `.github/dependabot.yml` added for automated dependency-update pull requests.
|
|
140
|
+
- **`_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.
|
|
141
|
+
|
|
142
|
+
### Changed
|
|
143
|
+
|
|
144
|
+
- 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.
|
|
145
|
+
- 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()`.
|
|
146
|
+
- 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.
|
|
147
|
+
- `FORMAT_EXTENSIONS` constant in `export.py` annotated as a module-level Sphinx data comment (`#:`) so it appears correctly in the API docs.
|
|
148
|
+
- `pyproject.toml` documentation extras updated: `furo` pinned to `>=2025.12.19` and `myst-parser` bumped to `>=5.0,<6`.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## [0.1.0a1] - 2026-04-07
|
|
153
|
+
|
|
154
|
+
First public alpha release.
|
|
155
|
+
|
|
156
|
+
### Added
|
|
157
|
+
|
|
158
|
+
- **Core style engine**: `plotstyle.use()` applies journal presets to Matplotlib's `rcParams`; works as a context manager with automatic restoration on exit.
|
|
159
|
+
- **Figure helpers**: `plotstyle.figure()` and `plotstyle.subplots()` create correctly-sized figures at the exact column width and max height specified by each journal.
|
|
160
|
+
- **Auto panel labels**: multi-panel figures receive **(a)**, **(b)**, **(c)**, … labels placed according to the journal's style rules.
|
|
161
|
+
- **Colorblind-safe palettes**: built-in Okabe–Ito, Tol Bright, Tol Vibrant, Tol Muted, and Safe Grayscale palettes (`plotstyle.palette()`).
|
|
162
|
+
- **Accessibility previews**: `plotstyle.preview_colorblind()` simulates deuteranopia, protanopia, and tritanopia; `plotstyle.preview_grayscale()` previews grayscale rendering.
|
|
163
|
+
- **Pre-submission validation**: `plotstyle.validate()` checks dimensions, typography, line weights, color accessibility, and export settings against a target journal spec.
|
|
164
|
+
- **Submission-ready export**: `plotstyle.savefig()` saves with font embedding and DPI enforcement; `plotstyle.export_submission()` batch-exports to all formats a journal accepts.
|
|
165
|
+
- **Spec diffing & migration**: `plotstyle.diff()` compares two journal specs; `plotstyle.migrate()` re-targets a figure from one journal to another.
|
|
166
|
+
- **Seaborn integration**: `patch_seaborn()` / `plotstyle_theme()` ensure PlotStyle `rcParams` survive `sns.set_theme()` calls.
|
|
167
|
+
- **Gallery & print-size preview**: `plotstyle.gallery()` generates sample figures; `plotstyle.preview_print_size()` opens an interactive scaled preview window.
|
|
168
|
+
- **Journal spec registry**: programmatic access via `plotstyle.registry`; specs are TOML files validated by immutable, typed dataclasses.
|
|
169
|
+
- **CLI**: `plotstyle list`, `plotstyle info`, `plotstyle diff`, `plotstyle fonts`, `plotstyle validate`, and `plotstyle export` sub-commands.
|
|
170
|
+
- **10 journal presets**: ACS, Cell, Elsevier, IEEE, Nature, PLOS, PRL, Science, Springer, Wiley.
|
|
171
|
+
- **10 working examples**: quick start, multi-panel, palettes, accessibility, validation, export, diff/migrate, gallery, registry, context manager patterns.
|
|
172
|
+
- **Dynamic versioning**: version derived from git tags via `hatch-vcs` and `importlib.metadata`.
|
|
173
|
+
- **CI/CD pipeline**: GitHub Actions workflows for lint, type-check, test matrix, and automated PyPI release via OIDC Trusted Publishing.
|
|
174
|
+
|
|
175
|
+
[Unreleased]: https://github.com/rahulkaushal04/plotstyle/compare/v1.2.2...HEAD
|
|
176
|
+
[1.2.2]: https://github.com/rahulkaushal04/plotstyle/compare/v1.2.1...v1.2.2
|
|
177
|
+
[1.2.1]: https://github.com/rahulkaushal04/plotstyle/compare/v1.2.0...v1.2.1
|
|
178
|
+
[1.2.0]: https://github.com/rahulkaushal04/plotstyle/compare/v1.1.0...v1.2.0
|
|
179
|
+
[1.1.0]: https://github.com/rahulkaushal04/plotstyle/compare/v1.0.0...v1.1.0
|
|
180
|
+
[1.0.0]: https://github.com/rahulkaushal04/plotstyle/compare/v0.1.0a2...v1.0.0
|
|
181
|
+
[0.1.0a2]: https://github.com/rahulkaushal04/plotstyle/compare/v0.1.0a1...v0.1.0a2
|
|
182
|
+
[0.1.0a1]: https://github.com/rahulkaushal04/plotstyle/releases/tag/v0.1.0a1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plotstyle
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: Matplotlib/seaborn style presets matching scientific journal requirements, with validation, export safety, and preview capabilities.
|
|
5
5
|
Project-URL: Homepage, https://github.com/rahulkaushal04/plotstyle
|
|
6
6
|
Project-URL: Documentation, https://plotstyle.readthedocs.io
|
|
@@ -244,21 +244,38 @@ fig.savefig("palette_comparison.png", dpi=150)
|
|
|
244
244
|
Pass `with_markers=True` to get `(color, linestyle, marker)` tuples, useful for journals like IEEE that print in grayscale:
|
|
245
245
|
|
|
246
246
|
```python
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
247
|
+
import numpy as np
|
|
248
|
+
import plotstyle
|
|
249
|
+
|
|
250
|
+
x = np.linspace(0, 2 * np.pi, 100)
|
|
251
|
+
curves = [np.sin(x + i * 0.5) for i in range(4)]
|
|
252
|
+
|
|
253
|
+
with plotstyle.use("ieee") as style:
|
|
254
|
+
fig, ax = style.figure(columns=1)
|
|
255
|
+
styled = plotstyle.palette("ieee", n=4, with_markers=True)
|
|
256
|
+
for i, (color, ls, marker) in enumerate(styled):
|
|
257
|
+
ax.plot(x, curves[i], color=color, linestyle=ls, marker=marker,
|
|
258
|
+
markevery=20, label=f"Series {i + 1}")
|
|
259
|
+
ax.set_xlabel("x")
|
|
260
|
+
ax.set_ylabel("y")
|
|
261
|
+
ax.legend()
|
|
262
|
+
style.savefig(fig, "ieee_markers.pdf")
|
|
250
263
|
```
|
|
251
264
|
|
|
252
265
|
```text
|
|
253
|
-
# styled
|
|
266
|
+
# styled: one (color, linestyle, marker) tuple per series:
|
|
254
267
|
[('#000000', '-', 'o'), ('#333333', '--', 's'), ('#666666', '-.', '^'), ('#999999', ':', 'D')]
|
|
255
268
|
```
|
|
256
269
|
|
|
270
|
+
<p align="center">
|
|
271
|
+
<img src="https://raw.githubusercontent.com/rahulkaushal04/plotstyle/main/examples/output/palette_styled_ieee.png" width="55%" alt="IEEE figure with per-series color, linestyle, and marker combinations">
|
|
272
|
+
</p>
|
|
273
|
+
|
|
257
274
|
---
|
|
258
275
|
|
|
259
276
|
### Overlays
|
|
260
277
|
|
|
261
|
-
Overlays are additive patches that layer on top of a journal preset. They let you adjust one aspect of a figure
|
|
278
|
+
Overlays are additive patches that layer on top of a journal preset. They let you adjust one aspect of a figure (the colour palette, the context, the chart type) without changing the base journal settings.
|
|
262
279
|
|
|
263
280
|
Pass overlay names in the same list as the journal key:
|
|
264
281
|
|
|
@@ -268,21 +285,60 @@ import plotstyle
|
|
|
268
285
|
# Strip top/right spines for a clean editorial look
|
|
269
286
|
with plotstyle.use(["nature", "minimal"]) as style:
|
|
270
287
|
fig, ax = style.figure(columns=1)
|
|
271
|
-
ax.plot([1, 2, 3])
|
|
272
|
-
|
|
288
|
+
ax.plot([1, 2, 3], label="data")
|
|
289
|
+
ax.set_xlabel("x")
|
|
290
|
+
ax.set_ylabel("y")
|
|
291
|
+
ax.legend()
|
|
292
|
+
style.savefig(fig, "minimal_figure.pdf")
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
<p align="center">
|
|
296
|
+
<img src="https://raw.githubusercontent.com/rahulkaushal04/plotstyle/main/examples/output/overlay_minimal.png" width="45%" alt="Nature figure with minimal overlay: no top/right spines">
|
|
297
|
+
</p>
|
|
298
|
+
|
|
299
|
+
```python
|
|
300
|
+
import numpy as np
|
|
301
|
+
import matplotlib.pyplot as plt
|
|
302
|
+
import plotstyle
|
|
303
|
+
|
|
304
|
+
x = np.linspace(0, 2 * np.pi, 100)
|
|
273
305
|
|
|
274
306
|
# Larger figure and fonts for Jupyter notebooks
|
|
275
307
|
with plotstyle.use(["nature", "notebook"]) as style:
|
|
276
|
-
import matplotlib.pyplot as plt
|
|
277
308
|
fig, ax = plt.subplots() # plt.subplots() picks up the notebook figsize
|
|
278
|
-
ax.plot(
|
|
309
|
+
ax.plot(x, np.sin(x), label="sin(x)")
|
|
310
|
+
ax.plot(x, np.cos(x), label="cos(x)")
|
|
311
|
+
ax.set_xlabel("Phase (rad)")
|
|
312
|
+
ax.set_ylabel("Amplitude")
|
|
313
|
+
ax.legend()
|
|
314
|
+
style.savefig(fig, "notebook_figure.pdf")
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
<p align="center">
|
|
318
|
+
<img src="https://raw.githubusercontent.com/rahulkaushal04/plotstyle/main/examples/output/overlay_notebook.png" width="60%" alt="Nature figure with notebook overlay: larger fonts and figure size">
|
|
319
|
+
</p>
|
|
320
|
+
|
|
321
|
+
```python
|
|
322
|
+
import numpy as np
|
|
323
|
+
import plotstyle
|
|
324
|
+
|
|
325
|
+
x = np.linspace(0, 2 * np.pi, 100)
|
|
279
326
|
|
|
280
327
|
# Swap the colour cycle to a specific palette
|
|
281
328
|
with plotstyle.use(["ieee", "okabe-ito"]) as style:
|
|
282
329
|
fig, ax = style.figure(columns=1)
|
|
283
|
-
|
|
330
|
+
for i in range(4):
|
|
331
|
+
ax.plot(x, np.sin(x + i * 0.5), label=f"Series {i + 1}")
|
|
332
|
+
ax.set_xlabel("x")
|
|
333
|
+
ax.set_ylabel("y")
|
|
334
|
+
ax.legend()
|
|
335
|
+
style.savefig(fig, "okabe_ito_figure.pdf")
|
|
284
336
|
```
|
|
285
337
|
|
|
338
|
+
<p align="center">
|
|
339
|
+
<img src="https://raw.githubusercontent.com/rahulkaushal04/plotstyle/main/examples/output/overlay_okabe_ito.png" width="55%" alt="IEEE figure with okabe-ito colorblind-safe palette">
|
|
340
|
+
</p>
|
|
341
|
+
|
|
286
342
|
| Category | Purpose | Examples |
|
|
287
343
|
|----------|---------|---------|
|
|
288
344
|
| `color` | Swap the colour cycle | `okabe-ito`, `tol-bright`, `safe-grayscale` |
|
|
@@ -353,28 +409,54 @@ with plotstyle.use("nature") as style:
|
|
|
353
409
|
Validate a figure against the journal's requirements, then export in all required formats at once.
|
|
354
410
|
|
|
355
411
|
```python
|
|
412
|
+
import numpy as np
|
|
413
|
+
import matplotlib.pyplot as plt
|
|
414
|
+
import plotstyle
|
|
415
|
+
|
|
416
|
+
x = np.linspace(0, 2 * np.pi, 100)
|
|
417
|
+
|
|
418
|
+
# Outside plotstyle.use() — some checks will fail
|
|
419
|
+
fig, ax = plt.subplots()
|
|
420
|
+
ax.plot(x, np.sin(x), label="sin(x)")
|
|
421
|
+
ax.set_xlabel("Phase (rad)")
|
|
422
|
+
ax.set_ylabel("Amplitude")
|
|
423
|
+
ax.legend()
|
|
424
|
+
|
|
356
425
|
report = plotstyle.validate(fig, journal="nature")
|
|
357
426
|
print(report) # formatted compliance table
|
|
358
|
-
print(report.passed) #
|
|
427
|
+
print(report.passed) # False — rcParams not configured
|
|
359
428
|
|
|
360
429
|
for failure in report.failures:
|
|
361
430
|
print(failure.message) # what failed
|
|
362
431
|
print(failure.fix_suggestion) # how to fix it
|
|
432
|
+
plt.close(fig)
|
|
433
|
+
|
|
434
|
+
# Inside plotstyle.use() — all checks pass
|
|
435
|
+
with plotstyle.use("nature") as style:
|
|
436
|
+
fig, ax = style.figure(columns=1)
|
|
437
|
+
ax.plot(x, np.sin(x), label="sin(x)")
|
|
438
|
+
ax.set_xlabel("Phase (rad)")
|
|
439
|
+
ax.set_ylabel("Amplitude")
|
|
440
|
+
ax.legend()
|
|
441
|
+
|
|
442
|
+
report = plotstyle.validate(fig, journal="nature")
|
|
443
|
+
print(report)
|
|
444
|
+
print(report.passed) # True
|
|
363
445
|
```
|
|
364
446
|
|
|
365
447
|
```text
|
|
366
448
|
┌──────────────────────────────────────────────────────┐
|
|
367
|
-
│ PlotStyle Validation Report
|
|
449
|
+
│ PlotStyle Validation Report: Nature │
|
|
368
450
|
├──────────┬───────────────────────────────────────────┤
|
|
369
|
-
│
|
|
370
|
-
│ ✓ PASS │ Figure height
|
|
451
|
+
│ ✗ FAIL │ Figure width 162.6mm does not match Nat...│
|
|
452
|
+
│ ✓ PASS │ Figure height 121.9mm is within the Nat...│
|
|
371
453
|
│ ✗ FAIL │ pdf.fonttype = 3; must be 42 for TrueTy...│
|
|
372
454
|
│ ✗ FAIL │ ps.fonttype = 3; must be 42 for TrueTyp...│
|
|
373
455
|
│ ⚠ WARN │ savefig.dpi = 'figure'; Nature requires...│
|
|
374
456
|
│ ✓ PASS │ All plotted lines and spines meet the N...│
|
|
375
|
-
│ ✗ FAIL │
|
|
457
|
+
│ ✗ FAIL │ 23 text element(s) outside the Nature r...│
|
|
376
458
|
└──────────┴───────────────────────────────────────────┘
|
|
377
|
-
|
|
459
|
+
2/7 checks passed, 1 warning(s), 4 failure(s)
|
|
378
460
|
|
|
379
461
|
passed: False
|
|
380
462
|
|
|
@@ -387,7 +469,7 @@ When called inside `plotstyle.use()`, all checks pass:
|
|
|
387
469
|
|
|
388
470
|
```text
|
|
389
471
|
┌──────────────────────────────────────────────────────┐
|
|
390
|
-
│ PlotStyle Validation Report
|
|
472
|
+
│ PlotStyle Validation Report: Nature │
|
|
391
473
|
├──────────┬───────────────────────────────────────────┤
|
|
392
474
|
│ ✓ PASS │ Figure width 89.0mm matches single colu...│
|
|
393
475
|
│ ✓ PASS │ Figure height 55.0mm is within the Natu...│
|
|
@@ -403,14 +485,28 @@ passed: True
|
|
|
403
485
|
```
|
|
404
486
|
|
|
405
487
|
```python
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
)
|
|
413
|
-
|
|
488
|
+
import numpy as np
|
|
489
|
+
import os
|
|
490
|
+
import plotstyle
|
|
491
|
+
|
|
492
|
+
os.makedirs("submission", exist_ok=True)
|
|
493
|
+
|
|
494
|
+
with plotstyle.use("ieee") as style:
|
|
495
|
+
fig, ax = style.figure(columns=1)
|
|
496
|
+
x = np.linspace(0, 2 * np.pi, 100)
|
|
497
|
+
ax.plot(x, np.sin(x), label="sin(x)")
|
|
498
|
+
ax.set_xlabel("Phase (rad)")
|
|
499
|
+
ax.set_ylabel("Amplitude")
|
|
500
|
+
ax.legend()
|
|
501
|
+
|
|
502
|
+
paths = plotstyle.export_submission(
|
|
503
|
+
fig,
|
|
504
|
+
"figure1",
|
|
505
|
+
journal="ieee",
|
|
506
|
+
author_surname="Smith", # IEEE prepends the surname prefix to filenames
|
|
507
|
+
output_dir="submission/",
|
|
508
|
+
)
|
|
509
|
+
print(paths)
|
|
414
510
|
```
|
|
415
511
|
|
|
416
512
|
```text
|
|
@@ -490,6 +586,7 @@ Export:
|
|
|
490
586
|
Accessibility:
|
|
491
587
|
Colorblind safe: Not required
|
|
492
588
|
Grayscale safe: Not required
|
|
589
|
+
Avoid: none
|
|
493
590
|
```
|
|
494
591
|
|
|
495
592
|
**`plotstyle diff nature science`**
|
|
@@ -498,7 +595,7 @@ Nature → Science
|
|
|
498
595
|
──────────────────────────────────────────────────
|
|
499
596
|
Column Width (single): 89.0mm → 86.4mm
|
|
500
597
|
Column Width (double): 183.0mm → 177.8mm
|
|
501
|
-
Max Height: 247.0mm →
|
|
598
|
+
Max Height: 247.0mm → -
|
|
502
599
|
Font Family: Helvetica, Arial → Minion Pro, Benton Sans Condensed
|
|
503
600
|
Min Font Size: 5.0pt → 7.5pt
|
|
504
601
|
Max Font Size: 7.0pt → 10.0pt
|
|
@@ -583,7 +680,7 @@ If PlotStyle helps your research, a citation or star is appreciated:
|
|
|
583
680
|
title = {PlotStyle: Publication-ready scientific figure presets for Matplotlib},
|
|
584
681
|
year = {2026},
|
|
585
682
|
url = {https://github.com/rahulkaushal04/plotstyle},
|
|
586
|
-
note = {Version 1.2.
|
|
683
|
+
note = {Version 1.2.2},
|
|
587
684
|
}
|
|
588
685
|
```
|
|
589
686
|
|