plotstyle 1.2.1__tar.gz → 1.2.3__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.1 → plotstyle-1.2.3}/.gitignore +2 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/CHANGELOG.md +53 -1
- {plotstyle-1.2.1 → plotstyle-1.2.3}/PKG-INFO +75 -25
- {plotstyle-1.2.1 → plotstyle-1.2.3}/README.md +74 -24
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/_version.py +2 -2
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/cli/main.py +2 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/_rendering.py +2 -3
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/core/style.py +8 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/engine/rcparams.py +22 -3
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/preview/gallery.py +2 -2
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/specs/nature.toml +1 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/specs/schema.py +26 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_core/test_style.py +107 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_engine/test_rcparams.py +177 -3
- {plotstyle-1.2.1 → plotstyle-1.2.3}/LICENSE +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/pyproject.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/__init__.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/_compat/__init__.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/_compat/mpl_style.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/_utils/__init__.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/_utils/io.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/_utils/warnings.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/cli/__init__.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/__init__.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/accessibility.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/data/okabe_ito.json +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/data/safe_grayscale.json +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/data/tol_bright.json +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/data/tol_high_contrast.json +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/data/tol_light.json +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/data/tol_muted.json +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/data/tol_rainbow_10.json +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/data/tol_rainbow_12.json +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/data/tol_rainbow_4.json +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/data/tol_rainbow_6.json +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/data/tol_rainbow_8.json +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/data/tol_vibrant.json +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/grayscale.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/color/palettes.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/core/__init__.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/core/export.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/core/figure.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/core/migrate.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/engine/__init__.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/engine/fonts.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/engine/latex.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/integrations/__init__.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/integrations/seaborn.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/__init__.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/bar.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/cjk-japanese.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/cjk-korean.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/cjk-simplified.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/cjk-traditional.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/grid.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/high-vis.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/latex-sans.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/minimal.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/no-latex.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/notebook.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/okabe-ito.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/pgf.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/presentation.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/russian.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/safe-grayscale.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/scatter.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/schema.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/tol-bright.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/tol-high-contrast.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/tol-light.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/tol-muted.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/tol-rainbow-10.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/tol-rainbow-12.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/tol-rainbow-4.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/tol-rainbow-6.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/tol-rainbow-8.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/tol-vibrant.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/overlays/turkish.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/preview/__init__.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/preview/print_size.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/py.typed +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/specs/__init__.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/specs/_templates.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/specs/acs.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/specs/cell.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/specs/elsevier.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/specs/ieee.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/specs/plos.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/specs/prl.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/specs/science.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/specs/springer.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/specs/units.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/specs/wiley.toml +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/validation/__init__.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/validation/checks/__init__.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/validation/checks/_base.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/validation/checks/colors.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/validation/checks/dimensions.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/validation/checks/export.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/validation/checks/lines.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/validation/checks/typography.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/src/plotstyle/validation/report.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/conftest.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_cli/test_main.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_color/test_accessibility.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_color/test_grayscale.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_color/test_palettes.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_color/test_rendering.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_core/test_export.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_core/test_figure.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_core/test_migrate.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_engine/test_fonts.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_engine/test_latex.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_integrations/test_seaborn.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_preview/test_gallery.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_preview/test_print_size.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_specs/test_registry.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_specs/test_schema.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_specs/test_units.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_utils/test_io.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_utils/test_warnings.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_validation/test_checks.py +0 -0
- {plotstyle-1.2.1 → plotstyle-1.2.3}/tests/test_validation/test_report.py +0 -0
|
@@ -13,6 +13,56 @@ _Nothing yet._
|
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
+
## [1.2.3] - 2026-04-30
|
|
17
|
+
|
|
18
|
+
Minor release: automatic journal color cycle, `target_font_pt` typography field, Nature-specific rcParams, CLI improvements, a full documentation and example audit, and a new doc image generation script.
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- **Automatic journal palette as default color cycle** (`plotstyle.use()`): calling `use("nature")` (or any journal key) now sets the journal's recommended palette as `axes.prop_cycle` automatically. Every `ax.plot()`, `ax.bar()`, and `ax.scatter()` call draws from it without any `color=` argument. A color overlay applied in the same `use()` call overrides this default.
|
|
23
|
+
- **`target_font_pt` field on `TypographySpec`**: optional `float | None` field that records a journal's explicitly stated target font size (as opposed to only a min/max range). When set, `build_rcparams()` uses it as `font.size` instead of the midpoint of the range. `nature.toml` sets `target_font_pt = 7.0` (Nature's guidelines explicitly state 7 pt as the standard text size).
|
|
24
|
+
- **`plotstyle info` CLI shows `Target size:`**: when `target_font_pt` is set for a journal, the `plotstyle info <journal>` command now prints a `Target size:` line under Typography.
|
|
25
|
+
- **Nature-specific tick and legend rcParams** (`build_rcparams()`): the Nature preset now applies inward-facing ticks (`xtick.direction: in`, `ytick.direction: in`), minor ticks visible on all axes, mirrored tick marks (`xtick.top: True`, `ytick.right: True`), and `legend.frameon: False` - matching Nature's published figure style guidelines.
|
|
26
|
+
- **`scripts/generate_docs_images.py`**: new script that regenerates all 9 static PNG images used in the documentation (`docs/images/`) from the current codebase in one headless run.
|
|
27
|
+
- **Docs images regenerated**: all 9 images in `docs/images/` rebuilt using the updated codebase - `quickstart_nature.png`, `multi_panel_science.png`, `palette_comparison.png`, `accessibility_colorblind.png`, `accessibility_grayscale.png`, `gallery_nature.png`, `gallery_ieee.png`, `seaborn_scatter_nature.png`, `overlay_bar.png`.
|
|
28
|
+
- **New test coverage**: `TestUseColorCycle` (automatic palette cycle), `TestUseFontSizeTarget` (target_font_pt font size selection), `TestBuildRcparamsLegend` (Nature legend.frameon), and `TestBuildRcparamsTicks` (Nature inward/mirrored tick rcParams).
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- **`examples/03_color_palettes.py`**: added Section 1 demonstrating the automatic default color cycle; renumbered remaining sections 2-6.
|
|
33
|
+
- **`examples/05_validation.py`**: added `is_failure` / `is_warning` convenience property usage.
|
|
34
|
+
- **`examples/09_registry_and_spec.py`**: expanded to cover `target_font_pt`, `is_official`, `assumed_fields`, and `registry.preload()`.
|
|
35
|
+
- **`examples/12_overlays.py`**: added color overlay, grid rendering overlay, scatter + IEEE warning, overlay inspection, and `list_overlays()` with category filter. Imports reorganized to comply with E402 (module-level imports at top); unused loop variable renamed to `_ls` to comply with B007.
|
|
36
|
+
- **Docs**: all docs updated to reflect the automatic palette cycle and `target_font_pt` changes; `colour` spelling standardized to `color` throughout.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## [1.2.2] - 2026-04-27
|
|
41
|
+
|
|
42
|
+
Patch release: docs improvements, README example quality, and CI action bump.
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- **`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.
|
|
47
|
+
- **`examples/output/accessibility_deuteranopia.png`**: new reference output image generated by the `simulate_cvd` section of `04_accessibility_checks.py`.
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
- **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.
|
|
52
|
+
- **README overlay snippet import cleanup**: removed stray `import matplotlib.pyplot as plt` from the minimal overlay example where it was unused.
|
|
53
|
+
- **README validation report output updated**: sample terminal output now reflects a two-column figure width rather than a single-column one.
|
|
54
|
+
- **README `diff` output adds `Avoid: none`**: accessibility block in the `plotstyle diff` sample output now shows the `Avoid` field.
|
|
55
|
+
- **`download-artifact` action bumped to v8** in `.github/workflows/release.yml` (was v4).
|
|
56
|
+
- **Version references bumped to 1.2.2** in `README.md` (citation note) and `docs/installation.md` (version-check snippet).
|
|
57
|
+
|
|
58
|
+
### Fixed
|
|
59
|
+
|
|
60
|
+
- **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.
|
|
61
|
+
- **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.
|
|
62
|
+
- **Typo in `06_export_submission.py` docstring**: `"smit_"` author prefix corrected to `"smith_"`.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
16
66
|
## [1.2.1] - 2026-04-26
|
|
17
67
|
|
|
18
68
|
Patch release: `simulate_cvd` example, warning quality improvements, and docs/example content fixes.
|
|
@@ -146,7 +196,9 @@ First public alpha release.
|
|
|
146
196
|
- **Dynamic versioning**: version derived from git tags via `hatch-vcs` and `importlib.metadata`.
|
|
147
197
|
- **CI/CD pipeline**: GitHub Actions workflows for lint, type-check, test matrix, and automated PyPI release via OIDC Trusted Publishing.
|
|
148
198
|
|
|
149
|
-
[Unreleased]: https://github.com/rahulkaushal04/plotstyle/compare/v1.2.
|
|
199
|
+
[Unreleased]: https://github.com/rahulkaushal04/plotstyle/compare/v1.2.3...HEAD
|
|
200
|
+
[1.2.3]: https://github.com/rahulkaushal04/plotstyle/compare/v1.2.2...v1.2.3
|
|
201
|
+
[1.2.2]: https://github.com/rahulkaushal04/plotstyle/compare/v1.2.1...v1.2.2
|
|
150
202
|
[1.2.1]: https://github.com/rahulkaushal04/plotstyle/compare/v1.2.0...v1.2.1
|
|
151
203
|
[1.2.0]: https://github.com/rahulkaushal04/plotstyle/compare/v1.1.0...v1.2.0
|
|
152
204
|
[1.1.0]: https://github.com/rahulkaushal04/plotstyle/compare/v1.0.0...v1.1.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plotstyle
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.3
|
|
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
|
|
@@ -99,6 +99,14 @@ Description-Content-Type: text/markdown
|
|
|
99
99
|
|
|
100
100
|
**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.
|
|
101
101
|
|
|
102
|
+
<p align="center">
|
|
103
|
+
<img src="https://raw.githubusercontent.com/rahulkaushal04/plotstyle/main/examples/output/before_after.png" width="90%" alt="Left: default Matplotlib output. Right: the same figure styled with plotstyle.use('nature').">
|
|
104
|
+
</p>
|
|
105
|
+
|
|
106
|
+
<p align="center">
|
|
107
|
+
<em>Left: default Matplotlib. Right: <code>plotstyle.use("nature")</code>. Same data, same code.</em>
|
|
108
|
+
</p>
|
|
109
|
+
|
|
102
110
|
---
|
|
103
111
|
|
|
104
112
|
## Table of Contents
|
|
@@ -115,6 +123,8 @@ Description-Content-Type: text/markdown
|
|
|
115
123
|
- [CLI](#cli)
|
|
116
124
|
- [Documentation](#documentation)
|
|
117
125
|
- [Contributing](#contributing)
|
|
126
|
+
- [Code of Conduct](#code-of-conduct)
|
|
127
|
+
- [Security](#security)
|
|
118
128
|
- [Citation](#citation)
|
|
119
129
|
- [License](#license)
|
|
120
130
|
|
|
@@ -280,7 +290,6 @@ Overlays are additive patches that layer on top of a journal preset. They let yo
|
|
|
280
290
|
Pass overlay names in the same list as the journal key:
|
|
281
291
|
|
|
282
292
|
```python
|
|
283
|
-
import matplotlib.pyplot as plt
|
|
284
293
|
import plotstyle
|
|
285
294
|
|
|
286
295
|
# Strip top/right spines for a clean editorial look
|
|
@@ -298,15 +307,19 @@ with plotstyle.use(["nature", "minimal"]) as style:
|
|
|
298
307
|
</p>
|
|
299
308
|
|
|
300
309
|
```python
|
|
310
|
+
import numpy as np
|
|
301
311
|
import matplotlib.pyplot as plt
|
|
302
312
|
import plotstyle
|
|
303
313
|
|
|
314
|
+
x = np.linspace(0, 2 * np.pi, 100)
|
|
315
|
+
|
|
304
316
|
# Larger figure and fonts for Jupyter notebooks
|
|
305
317
|
with plotstyle.use(["nature", "notebook"]) as style:
|
|
306
318
|
fig, ax = plt.subplots() # plt.subplots() picks up the notebook figsize
|
|
307
|
-
ax.plot(
|
|
308
|
-
ax.
|
|
309
|
-
ax.
|
|
319
|
+
ax.plot(x, np.sin(x), label="sin(x)")
|
|
320
|
+
ax.plot(x, np.cos(x), label="cos(x)")
|
|
321
|
+
ax.set_xlabel("Phase (rad)")
|
|
322
|
+
ax.set_ylabel("Amplitude")
|
|
310
323
|
ax.legend()
|
|
311
324
|
style.savefig(fig, "notebook_figure.pdf")
|
|
312
325
|
```
|
|
@@ -316,13 +329,16 @@ with plotstyle.use(["nature", "notebook"]) as style:
|
|
|
316
329
|
</p>
|
|
317
330
|
|
|
318
331
|
```python
|
|
319
|
-
import
|
|
332
|
+
import numpy as np
|
|
320
333
|
import plotstyle
|
|
321
334
|
|
|
335
|
+
x = np.linspace(0, 2 * np.pi, 100)
|
|
336
|
+
|
|
322
337
|
# Swap the colour cycle to a specific palette
|
|
323
338
|
with plotstyle.use(["ieee", "okabe-ito"]) as style:
|
|
324
339
|
fig, ax = style.figure(columns=1)
|
|
325
|
-
|
|
340
|
+
for i in range(4):
|
|
341
|
+
ax.plot(x, np.sin(x + i * 0.5), label=f"Series {i + 1}")
|
|
326
342
|
ax.set_xlabel("x")
|
|
327
343
|
ax.set_ylabel("y")
|
|
328
344
|
ax.legend()
|
|
@@ -409,7 +425,7 @@ import plotstyle
|
|
|
409
425
|
|
|
410
426
|
x = np.linspace(0, 2 * np.pi, 100)
|
|
411
427
|
|
|
412
|
-
# Outside plotstyle.use()
|
|
428
|
+
# Outside plotstyle.use(): some checks will fail
|
|
413
429
|
fig, ax = plt.subplots()
|
|
414
430
|
ax.plot(x, np.sin(x), label="sin(x)")
|
|
415
431
|
ax.set_xlabel("Phase (rad)")
|
|
@@ -418,14 +434,14 @@ ax.legend()
|
|
|
418
434
|
|
|
419
435
|
report = plotstyle.validate(fig, journal="nature")
|
|
420
436
|
print(report) # formatted compliance table
|
|
421
|
-
print(report.passed) # False
|
|
437
|
+
print(report.passed) # False, rcParams not configured
|
|
422
438
|
|
|
423
439
|
for failure in report.failures:
|
|
424
440
|
print(failure.message) # what failed
|
|
425
441
|
print(failure.fix_suggestion) # how to fix it
|
|
426
442
|
plt.close(fig)
|
|
427
443
|
|
|
428
|
-
# Inside plotstyle.use()
|
|
444
|
+
# Inside plotstyle.use(): all checks pass
|
|
429
445
|
with plotstyle.use("nature") as style:
|
|
430
446
|
fig, ax = style.figure(columns=1)
|
|
431
447
|
ax.plot(x, np.sin(x), label="sin(x)")
|
|
@@ -442,15 +458,15 @@ with plotstyle.use("nature") as style:
|
|
|
442
458
|
┌──────────────────────────────────────────────────────┐
|
|
443
459
|
│ PlotStyle Validation Report: Nature │
|
|
444
460
|
├──────────┬───────────────────────────────────────────┤
|
|
445
|
-
│
|
|
446
|
-
│ ✓ PASS │ Figure height
|
|
461
|
+
│ ✗ FAIL │ Figure width 162.6mm does not match Nat...│
|
|
462
|
+
│ ✓ PASS │ Figure height 121.9mm is within the Nat...│
|
|
447
463
|
│ ✗ FAIL │ pdf.fonttype = 3; must be 42 for TrueTy...│
|
|
448
464
|
│ ✗ FAIL │ ps.fonttype = 3; must be 42 for TrueTyp...│
|
|
449
465
|
│ ⚠ WARN │ savefig.dpi = 'figure'; Nature requires...│
|
|
450
466
|
│ ✓ PASS │ All plotted lines and spines meet the N...│
|
|
451
|
-
│ ✗ FAIL │
|
|
467
|
+
│ ✗ FAIL │ 23 text element(s) outside the Nature r...│
|
|
452
468
|
└──────────┴───────────────────────────────────────────┘
|
|
453
|
-
|
|
469
|
+
2/7 checks passed, 1 warning(s), 4 failure(s)
|
|
454
470
|
|
|
455
471
|
passed: False
|
|
456
472
|
|
|
@@ -580,6 +596,7 @@ Export:
|
|
|
580
596
|
Accessibility:
|
|
581
597
|
Colorblind safe: Not required
|
|
582
598
|
Grayscale safe: Not required
|
|
599
|
+
Avoid: none
|
|
583
600
|
```
|
|
584
601
|
|
|
585
602
|
**`plotstyle diff nature science`**
|
|
@@ -653,7 +670,34 @@ Full documentation at **[plotstyle.readthedocs.io](https://plotstyle.readthedocs
|
|
|
653
670
|
- [CLI reference](https://plotstyle.readthedocs.io/en/stable/cli.html)
|
|
654
671
|
- [FAQ](https://plotstyle.readthedocs.io/en/stable/faq.html)
|
|
655
672
|
|
|
656
|
-
Working examples are in the [`examples/`](examples/) directory
|
|
673
|
+
Working examples are in the [`examples/`](https://github.com/rahulkaushal04/plotstyle/tree/main/examples/) directory:
|
|
674
|
+
|
|
675
|
+
| Example | What it covers |
|
|
676
|
+
|---------|----------------|
|
|
677
|
+
| [`01_quickstart.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/01_quickstart.py) | Apply a journal preset, create a figure, and save |
|
|
678
|
+
| [`02_multi_panel_figure.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/02_multi_panel_figure.py) | Multi-panel layouts with automatic panel labels |
|
|
679
|
+
| [`03_color_palettes.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/03_color_palettes.py) | Journal palettes, grayscale-safe markers, `apply_palette` |
|
|
680
|
+
| [`04_accessibility_checks.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/04_accessibility_checks.py) | Colorblind simulation and grayscale print-safety |
|
|
681
|
+
| [`05_validation.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/05_validation.py) | Validate a figure against journal requirements |
|
|
682
|
+
| [`06_export_submission.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/06_export_submission.py) | Export in all required formats for submission |
|
|
683
|
+
| [`07_spec_diff_and_migrate.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/07_spec_diff_and_migrate.py) | Compare journals and migrate a figure between them |
|
|
684
|
+
| [`08_gallery_preview.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/08_gallery_preview.py) | Discover journals and preview their styles |
|
|
685
|
+
| [`09_registry_and_spec.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/09_registry_and_spec.py) | Inspect journal specs from the registry |
|
|
686
|
+
| [`10_context_manager_patterns.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/10_context_manager_patterns.py) | Patterns for managing rcParam lifetime |
|
|
687
|
+
| [`11_seaborn_integration.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/11_seaborn_integration.py) | Keep PlotStyle settings intact with Seaborn |
|
|
688
|
+
| [`12_overlays.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/12_overlays.py) | Overlays: context, color, and plot-type |
|
|
689
|
+
| [`14_print_size_preview.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/14_print_size_preview.py) | Preview a figure at its true physical print size |
|
|
690
|
+
| [`15_matplotlib_native_styles.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/15_matplotlib_native_styles.py) | Use PlotStyle presets with `plt.style` |
|
|
691
|
+
| [`16_latex_and_fonts.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/16_latex_and_fonts.py) | LaTeX modes and font availability checks |
|
|
692
|
+
|
|
693
|
+
Interactive Jupyter notebooks are in [`examples/notebooks/`](https://github.com/rahulkaushal04/plotstyle/tree/main/examples/notebooks/):
|
|
694
|
+
|
|
695
|
+
| Notebook | What it covers |
|
|
696
|
+
|----------|----------------|
|
|
697
|
+
| [`01_quickstart.ipynb`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/notebooks/01_quickstart.ipynb) | Full quickstart: style, figure, palette, validate, save, overlays |
|
|
698
|
+
| [`02_accessibility_and_validation.ipynb`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/notebooks/02_accessibility_and_validation.ipynb) | Colorblind and grayscale previews, validation reports |
|
|
699
|
+
| [`03_journal_comparison_and_migration.ipynb`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/notebooks/03_journal_comparison_and_migration.ipynb) | Diff journals and migrate figures between them |
|
|
700
|
+
| [`04_overlays.ipynb`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/notebooks/04_overlays.ipynb) | Overlays in depth: context, color, plot-type, combining |
|
|
657
701
|
|
|
658
702
|
---
|
|
659
703
|
|
|
@@ -661,21 +705,27 @@ Working examples are in the [`examples/`](examples/) directory.
|
|
|
661
705
|
|
|
662
706
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, adding journal specs, and pull request guidelines.
|
|
663
707
|
|
|
708
|
+
All contributors are expected to follow the [Code of Conduct](CODE_OF_CONDUCT.md).
|
|
709
|
+
|
|
710
|
+
---
|
|
711
|
+
|
|
712
|
+
## Code of Conduct
|
|
713
|
+
|
|
714
|
+
This project follows the [Contributor Covenant](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this standard.
|
|
715
|
+
|
|
716
|
+
---
|
|
717
|
+
|
|
718
|
+
## Security
|
|
719
|
+
|
|
720
|
+
To report a security vulnerability, use [GitHub's private vulnerability reporting](https://github.com/rahulkaushal04/plotstyle/security/advisories/new) rather than opening a public issue. See [SECURITY.md](SECURITY.md) for scope, timeline, and disclosure guidelines.
|
|
721
|
+
|
|
664
722
|
---
|
|
665
723
|
|
|
666
724
|
## Citation
|
|
667
725
|
|
|
668
|
-
If PlotStyle helps your research, a citation or star is appreciated
|
|
726
|
+
If PlotStyle helps your research, a citation or star is appreciated.
|
|
669
727
|
|
|
670
|
-
|
|
671
|
-
@misc{plotstyle,
|
|
672
|
-
author = {Kaushal, Rahul},
|
|
673
|
-
title = {PlotStyle: Publication-ready scientific figure presets for Matplotlib},
|
|
674
|
-
year = {2026},
|
|
675
|
-
url = {https://github.com/rahulkaushal04/plotstyle},
|
|
676
|
-
note = {Version 1.2.1},
|
|
677
|
-
}
|
|
678
|
-
```
|
|
728
|
+
Use the **"Cite this repository"** button on the GitHub sidebar to get a ready-to-use APA or BibTeX entry. It reads from [`CITATION.cff`](CITATION.cff) and is always up to date.
|
|
679
729
|
|
|
680
730
|
---
|
|
681
731
|
|
|
@@ -18,6 +18,14 @@
|
|
|
18
18
|
|
|
19
19
|
**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.
|
|
20
20
|
|
|
21
|
+
<p align="center">
|
|
22
|
+
<img src="https://raw.githubusercontent.com/rahulkaushal04/plotstyle/main/examples/output/before_after.png" width="90%" alt="Left: default Matplotlib output. Right: the same figure styled with plotstyle.use('nature').">
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
<p align="center">
|
|
26
|
+
<em>Left: default Matplotlib. Right: <code>plotstyle.use("nature")</code>. Same data, same code.</em>
|
|
27
|
+
</p>
|
|
28
|
+
|
|
21
29
|
---
|
|
22
30
|
|
|
23
31
|
## Table of Contents
|
|
@@ -34,6 +42,8 @@
|
|
|
34
42
|
- [CLI](#cli)
|
|
35
43
|
- [Documentation](#documentation)
|
|
36
44
|
- [Contributing](#contributing)
|
|
45
|
+
- [Code of Conduct](#code-of-conduct)
|
|
46
|
+
- [Security](#security)
|
|
37
47
|
- [Citation](#citation)
|
|
38
48
|
- [License](#license)
|
|
39
49
|
|
|
@@ -199,7 +209,6 @@ Overlays are additive patches that layer on top of a journal preset. They let yo
|
|
|
199
209
|
Pass overlay names in the same list as the journal key:
|
|
200
210
|
|
|
201
211
|
```python
|
|
202
|
-
import matplotlib.pyplot as plt
|
|
203
212
|
import plotstyle
|
|
204
213
|
|
|
205
214
|
# Strip top/right spines for a clean editorial look
|
|
@@ -217,15 +226,19 @@ with plotstyle.use(["nature", "minimal"]) as style:
|
|
|
217
226
|
</p>
|
|
218
227
|
|
|
219
228
|
```python
|
|
229
|
+
import numpy as np
|
|
220
230
|
import matplotlib.pyplot as plt
|
|
221
231
|
import plotstyle
|
|
222
232
|
|
|
233
|
+
x = np.linspace(0, 2 * np.pi, 100)
|
|
234
|
+
|
|
223
235
|
# Larger figure and fonts for Jupyter notebooks
|
|
224
236
|
with plotstyle.use(["nature", "notebook"]) as style:
|
|
225
237
|
fig, ax = plt.subplots() # plt.subplots() picks up the notebook figsize
|
|
226
|
-
ax.plot(
|
|
227
|
-
ax.
|
|
228
|
-
ax.
|
|
238
|
+
ax.plot(x, np.sin(x), label="sin(x)")
|
|
239
|
+
ax.plot(x, np.cos(x), label="cos(x)")
|
|
240
|
+
ax.set_xlabel("Phase (rad)")
|
|
241
|
+
ax.set_ylabel("Amplitude")
|
|
229
242
|
ax.legend()
|
|
230
243
|
style.savefig(fig, "notebook_figure.pdf")
|
|
231
244
|
```
|
|
@@ -235,13 +248,16 @@ with plotstyle.use(["nature", "notebook"]) as style:
|
|
|
235
248
|
</p>
|
|
236
249
|
|
|
237
250
|
```python
|
|
238
|
-
import
|
|
251
|
+
import numpy as np
|
|
239
252
|
import plotstyle
|
|
240
253
|
|
|
254
|
+
x = np.linspace(0, 2 * np.pi, 100)
|
|
255
|
+
|
|
241
256
|
# Swap the colour cycle to a specific palette
|
|
242
257
|
with plotstyle.use(["ieee", "okabe-ito"]) as style:
|
|
243
258
|
fig, ax = style.figure(columns=1)
|
|
244
|
-
|
|
259
|
+
for i in range(4):
|
|
260
|
+
ax.plot(x, np.sin(x + i * 0.5), label=f"Series {i + 1}")
|
|
245
261
|
ax.set_xlabel("x")
|
|
246
262
|
ax.set_ylabel("y")
|
|
247
263
|
ax.legend()
|
|
@@ -328,7 +344,7 @@ import plotstyle
|
|
|
328
344
|
|
|
329
345
|
x = np.linspace(0, 2 * np.pi, 100)
|
|
330
346
|
|
|
331
|
-
# Outside plotstyle.use()
|
|
347
|
+
# Outside plotstyle.use(): some checks will fail
|
|
332
348
|
fig, ax = plt.subplots()
|
|
333
349
|
ax.plot(x, np.sin(x), label="sin(x)")
|
|
334
350
|
ax.set_xlabel("Phase (rad)")
|
|
@@ -337,14 +353,14 @@ ax.legend()
|
|
|
337
353
|
|
|
338
354
|
report = plotstyle.validate(fig, journal="nature")
|
|
339
355
|
print(report) # formatted compliance table
|
|
340
|
-
print(report.passed) # False
|
|
356
|
+
print(report.passed) # False, rcParams not configured
|
|
341
357
|
|
|
342
358
|
for failure in report.failures:
|
|
343
359
|
print(failure.message) # what failed
|
|
344
360
|
print(failure.fix_suggestion) # how to fix it
|
|
345
361
|
plt.close(fig)
|
|
346
362
|
|
|
347
|
-
# Inside plotstyle.use()
|
|
363
|
+
# Inside plotstyle.use(): all checks pass
|
|
348
364
|
with plotstyle.use("nature") as style:
|
|
349
365
|
fig, ax = style.figure(columns=1)
|
|
350
366
|
ax.plot(x, np.sin(x), label="sin(x)")
|
|
@@ -361,15 +377,15 @@ with plotstyle.use("nature") as style:
|
|
|
361
377
|
┌──────────────────────────────────────────────────────┐
|
|
362
378
|
│ PlotStyle Validation Report: Nature │
|
|
363
379
|
├──────────┬───────────────────────────────────────────┤
|
|
364
|
-
│
|
|
365
|
-
│ ✓ PASS │ Figure height
|
|
380
|
+
│ ✗ FAIL │ Figure width 162.6mm does not match Nat...│
|
|
381
|
+
│ ✓ PASS │ Figure height 121.9mm is within the Nat...│
|
|
366
382
|
│ ✗ FAIL │ pdf.fonttype = 3; must be 42 for TrueTy...│
|
|
367
383
|
│ ✗ FAIL │ ps.fonttype = 3; must be 42 for TrueTyp...│
|
|
368
384
|
│ ⚠ WARN │ savefig.dpi = 'figure'; Nature requires...│
|
|
369
385
|
│ ✓ PASS │ All plotted lines and spines meet the N...│
|
|
370
|
-
│ ✗ FAIL │
|
|
386
|
+
│ ✗ FAIL │ 23 text element(s) outside the Nature r...│
|
|
371
387
|
└──────────┴───────────────────────────────────────────┘
|
|
372
|
-
|
|
388
|
+
2/7 checks passed, 1 warning(s), 4 failure(s)
|
|
373
389
|
|
|
374
390
|
passed: False
|
|
375
391
|
|
|
@@ -499,6 +515,7 @@ Export:
|
|
|
499
515
|
Accessibility:
|
|
500
516
|
Colorblind safe: Not required
|
|
501
517
|
Grayscale safe: Not required
|
|
518
|
+
Avoid: none
|
|
502
519
|
```
|
|
503
520
|
|
|
504
521
|
**`plotstyle diff nature science`**
|
|
@@ -572,7 +589,34 @@ Full documentation at **[plotstyle.readthedocs.io](https://plotstyle.readthedocs
|
|
|
572
589
|
- [CLI reference](https://plotstyle.readthedocs.io/en/stable/cli.html)
|
|
573
590
|
- [FAQ](https://plotstyle.readthedocs.io/en/stable/faq.html)
|
|
574
591
|
|
|
575
|
-
Working examples are in the [`examples/`](examples/) directory
|
|
592
|
+
Working examples are in the [`examples/`](https://github.com/rahulkaushal04/plotstyle/tree/main/examples/) directory:
|
|
593
|
+
|
|
594
|
+
| Example | What it covers |
|
|
595
|
+
|---------|----------------|
|
|
596
|
+
| [`01_quickstart.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/01_quickstart.py) | Apply a journal preset, create a figure, and save |
|
|
597
|
+
| [`02_multi_panel_figure.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/02_multi_panel_figure.py) | Multi-panel layouts with automatic panel labels |
|
|
598
|
+
| [`03_color_palettes.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/03_color_palettes.py) | Journal palettes, grayscale-safe markers, `apply_palette` |
|
|
599
|
+
| [`04_accessibility_checks.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/04_accessibility_checks.py) | Colorblind simulation and grayscale print-safety |
|
|
600
|
+
| [`05_validation.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/05_validation.py) | Validate a figure against journal requirements |
|
|
601
|
+
| [`06_export_submission.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/06_export_submission.py) | Export in all required formats for submission |
|
|
602
|
+
| [`07_spec_diff_and_migrate.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/07_spec_diff_and_migrate.py) | Compare journals and migrate a figure between them |
|
|
603
|
+
| [`08_gallery_preview.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/08_gallery_preview.py) | Discover journals and preview their styles |
|
|
604
|
+
| [`09_registry_and_spec.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/09_registry_and_spec.py) | Inspect journal specs from the registry |
|
|
605
|
+
| [`10_context_manager_patterns.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/10_context_manager_patterns.py) | Patterns for managing rcParam lifetime |
|
|
606
|
+
| [`11_seaborn_integration.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/11_seaborn_integration.py) | Keep PlotStyle settings intact with Seaborn |
|
|
607
|
+
| [`12_overlays.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/12_overlays.py) | Overlays: context, color, and plot-type |
|
|
608
|
+
| [`14_print_size_preview.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/14_print_size_preview.py) | Preview a figure at its true physical print size |
|
|
609
|
+
| [`15_matplotlib_native_styles.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/15_matplotlib_native_styles.py) | Use PlotStyle presets with `plt.style` |
|
|
610
|
+
| [`16_latex_and_fonts.py`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/16_latex_and_fonts.py) | LaTeX modes and font availability checks |
|
|
611
|
+
|
|
612
|
+
Interactive Jupyter notebooks are in [`examples/notebooks/`](https://github.com/rahulkaushal04/plotstyle/tree/main/examples/notebooks/):
|
|
613
|
+
|
|
614
|
+
| Notebook | What it covers |
|
|
615
|
+
|----------|----------------|
|
|
616
|
+
| [`01_quickstart.ipynb`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/notebooks/01_quickstart.ipynb) | Full quickstart: style, figure, palette, validate, save, overlays |
|
|
617
|
+
| [`02_accessibility_and_validation.ipynb`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/notebooks/02_accessibility_and_validation.ipynb) | Colorblind and grayscale previews, validation reports |
|
|
618
|
+
| [`03_journal_comparison_and_migration.ipynb`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/notebooks/03_journal_comparison_and_migration.ipynb) | Diff journals and migrate figures between them |
|
|
619
|
+
| [`04_overlays.ipynb`](https://github.com/rahulkaushal04/plotstyle/blob/main/examples/notebooks/04_overlays.ipynb) | Overlays in depth: context, color, plot-type, combining |
|
|
576
620
|
|
|
577
621
|
---
|
|
578
622
|
|
|
@@ -580,21 +624,27 @@ Working examples are in the [`examples/`](examples/) directory.
|
|
|
580
624
|
|
|
581
625
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, adding journal specs, and pull request guidelines.
|
|
582
626
|
|
|
627
|
+
All contributors are expected to follow the [Code of Conduct](CODE_OF_CONDUCT.md).
|
|
628
|
+
|
|
629
|
+
---
|
|
630
|
+
|
|
631
|
+
## Code of Conduct
|
|
632
|
+
|
|
633
|
+
This project follows the [Contributor Covenant](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this standard.
|
|
634
|
+
|
|
635
|
+
---
|
|
636
|
+
|
|
637
|
+
## Security
|
|
638
|
+
|
|
639
|
+
To report a security vulnerability, use [GitHub's private vulnerability reporting](https://github.com/rahulkaushal04/plotstyle/security/advisories/new) rather than opening a public issue. See [SECURITY.md](SECURITY.md) for scope, timeline, and disclosure guidelines.
|
|
640
|
+
|
|
583
641
|
---
|
|
584
642
|
|
|
585
643
|
## Citation
|
|
586
644
|
|
|
587
|
-
If PlotStyle helps your research, a citation or star is appreciated
|
|
645
|
+
If PlotStyle helps your research, a citation or star is appreciated.
|
|
588
646
|
|
|
589
|
-
|
|
590
|
-
@misc{plotstyle,
|
|
591
|
-
author = {Kaushal, Rahul},
|
|
592
|
-
title = {PlotStyle: Publication-ready scientific figure presets for Matplotlib},
|
|
593
|
-
year = {2026},
|
|
594
|
-
url = {https://github.com/rahulkaushal04/plotstyle},
|
|
595
|
-
note = {Version 1.2.1},
|
|
596
|
-
}
|
|
597
|
-
```
|
|
647
|
+
Use the **"Cite this repository"** button on the GitHub sidebar to get a ready-to-use APA or BibTeX entry. It reads from [`CITATION.cff`](CITATION.cff) and is always up to date.
|
|
598
648
|
|
|
599
649
|
---
|
|
600
650
|
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '1.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 2,
|
|
21
|
+
__version__ = version = '1.2.3'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 2, 3)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -82,6 +82,8 @@ def _cmd_info(journal: str) -> int:
|
|
|
82
82
|
print("Typography:")
|
|
83
83
|
print(f" Font: {fonts} (fallback: {typo.font_fallback})")
|
|
84
84
|
print(f" Size range: {typo.min_font_pt}-{typo.max_font_pt}pt")
|
|
85
|
+
if typo.target_font_pt is not None:
|
|
86
|
+
print(f" Target size: {typo.target_font_pt}pt")
|
|
85
87
|
print(
|
|
86
88
|
f" Panel labels: {typo.panel_label_pt}pt "
|
|
87
89
|
f"{typo.panel_label_weight} {typo.panel_label_case} "
|
|
@@ -30,9 +30,8 @@ def _fig_to_rgb_array(fig: Figure) -> NDArray[np.uint8]:
|
|
|
30
30
|
"""
|
|
31
31
|
fig.canvas.draw()
|
|
32
32
|
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
width, height = fig.canvas.get_width_height()
|
|
33
|
+
# physical=True matches the buffer_rgba() byte count on HiDPI/Retina screens.
|
|
34
|
+
width, height = fig.canvas.get_width_height(physical=True)
|
|
36
35
|
|
|
37
36
|
# buffer_rgba() returns a read-only memoryview; .copy() makes it writeable
|
|
38
37
|
rgba = np.frombuffer(fig.canvas.buffer_rgba(), dtype=np.uint8).reshape(height, width, 4)
|
|
@@ -771,6 +771,14 @@ def use(
|
|
|
771
771
|
if journal_key is not None:
|
|
772
772
|
spec = registry.get(journal_key)
|
|
773
773
|
params = build_rcparams(spec, latex=effective_latex)
|
|
774
|
+
|
|
775
|
+
from cycler import cycler as _cycler
|
|
776
|
+
|
|
777
|
+
from plotstyle.color.palettes import JOURNAL_PALETTE_MAP, load_palette
|
|
778
|
+
|
|
779
|
+
_palette_name = JOURNAL_PALETTE_MAP.get(journal_key)
|
|
780
|
+
if _palette_name:
|
|
781
|
+
params["axes.prop_cycle"] = _cycler("color", load_palette(_palette_name))
|
|
774
782
|
else:
|
|
775
783
|
spec = None
|
|
776
784
|
use_latex = _resolve_latex_mode(effective_latex)
|
|
@@ -174,7 +174,13 @@ def build_rcparams(
|
|
|
174
174
|
font_name = spec.typography.font_fallback
|
|
175
175
|
|
|
176
176
|
figsize = _compute_figure_size(spec)
|
|
177
|
-
|
|
177
|
+
# Use the journal's explicit target when available; fall back to the
|
|
178
|
+
# midpoint heuristic for specs that only publish a compliance range.
|
|
179
|
+
font_size = (
|
|
180
|
+
spec.typography.target_font_pt
|
|
181
|
+
if spec.typography.target_font_pt is not None
|
|
182
|
+
else _compute_base_font_size(spec)
|
|
183
|
+
)
|
|
178
184
|
|
|
179
185
|
params: dict[str, Any] = {
|
|
180
186
|
"pdf.fonttype": _FONTTYPE_TRUETYPE,
|
|
@@ -194,12 +200,25 @@ def build_rcparams(
|
|
|
194
200
|
"xtick.labelsize": font_size,
|
|
195
201
|
"ytick.labelsize": font_size,
|
|
196
202
|
"legend.fontsize": font_size,
|
|
197
|
-
# Clamped to physically reproducible minimums; thinner lines vanish in print.
|
|
198
203
|
"lines.linewidth": max(spec.line.min_weight_pt, 1.0),
|
|
199
204
|
"axes.linewidth": max(spec.line.min_weight_pt, 0.5),
|
|
200
|
-
# "none" keeps text editable in SVG; "path" converts to outlines (more portable).
|
|
201
205
|
"svg.fonttype": "none" if spec.export.editable_text else "path",
|
|
202
206
|
"axes.grid": False,
|
|
207
|
+
"legend.frameon": False,
|
|
208
|
+
"xtick.direction": "in",
|
|
209
|
+
"xtick.major.size": 3.0,
|
|
210
|
+
"xtick.major.width": 0.5,
|
|
211
|
+
"xtick.minor.size": 1.5,
|
|
212
|
+
"xtick.minor.width": 0.5,
|
|
213
|
+
"xtick.minor.visible": True,
|
|
214
|
+
"xtick.top": True,
|
|
215
|
+
"ytick.direction": "in",
|
|
216
|
+
"ytick.major.size": 3.0,
|
|
217
|
+
"ytick.major.width": 0.5,
|
|
218
|
+
"ytick.minor.size": 1.5,
|
|
219
|
+
"ytick.minor.width": 0.5,
|
|
220
|
+
"ytick.minor.visible": True,
|
|
221
|
+
"ytick.right": True,
|
|
203
222
|
}
|
|
204
223
|
)
|
|
205
224
|
|
|
@@ -69,7 +69,7 @@ def _draw_line_panel(ax: Axes) -> None:
|
|
|
69
69
|
ax.plot(x, y, label=f"Series {i + 1}")
|
|
70
70
|
ax.set_xlabel("x")
|
|
71
71
|
ax.set_ylabel("y")
|
|
72
|
-
ax.legend(fontsize="small")
|
|
72
|
+
ax.legend(fontsize="small", loc="upper right")
|
|
73
73
|
ax.set_title("Line Plot", fontsize="small")
|
|
74
74
|
|
|
75
75
|
|
|
@@ -81,7 +81,7 @@ def _draw_scatter_panel(ax: Axes) -> None:
|
|
|
81
81
|
ax.scatter(x[mask], y[mask], label=str(group_label), s=15, alpha=0.8)
|
|
82
82
|
ax.set_xlabel("x")
|
|
83
83
|
ax.set_ylabel("y")
|
|
84
|
-
ax.legend(fontsize="small")
|
|
84
|
+
ax.legend(fontsize="small", loc="lower right")
|
|
85
85
|
ax.set_title("Scatter Plot", fontsize="small")
|
|
86
86
|
|
|
87
87
|
|