plotastro 1.0.0__tar.gz → 1.1.0b1__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.
Files changed (62) hide show
  1. plotastro-1.1.0b1/.gitignore +15 -0
  2. plotastro-1.1.0b1/.readthedocs.yaml +17 -0
  3. plotastro-1.1.0b1/CHANGELOG.md +101 -0
  4. {plotastro-1.0.0 → plotastro-1.1.0b1}/PKG-INFO +123 -18
  5. {plotastro-1.0.0 → plotastro-1.1.0b1}/README.md +119 -17
  6. plotastro-1.1.0b1/docs/api.md +94 -0
  7. plotastro-1.1.0b1/docs/authors.md +78 -0
  8. plotastro-1.1.0b1/docs/changelog.md +2 -0
  9. plotastro-1.1.0b1/docs/colors.md +190 -0
  10. plotastro-1.1.0b1/docs/conf.py +72 -0
  11. plotastro-1.1.0b1/docs/faq.md +55 -0
  12. plotastro-1.1.0b1/docs/index.md +93 -0
  13. plotastro-1.1.0b1/docs/installation.md +61 -0
  14. plotastro-1.1.0b1/docs/journals.md +82 -0
  15. plotastro-1.1.0b1/docs/markers.md +73 -0
  16. plotastro-1.1.0b1/docs/quickstart.md +104 -0
  17. plotastro-1.1.0b1/docs/requirements.txt +5 -0
  18. plotastro-1.1.0b1/examples/figures/cmasher.png +0 -0
  19. {plotastro-1.0.0 → plotastro-1.1.0b1}/examples/make_reference_figures.py +27 -0
  20. {plotastro-1.0.0 → plotastro-1.1.0b1}/examples/tutorial.ipynb +399 -120
  21. {plotastro-1.0.0 → plotastro-1.1.0b1}/pyproject.toml +4 -2
  22. {plotastro-1.0.0 → plotastro-1.1.0b1}/requirements-dev.txt +1 -0
  23. {plotastro-1.0.0 → plotastro-1.1.0b1}/src/plotastro/__init__.py +9 -5
  24. {plotastro-1.0.0 → plotastro-1.1.0b1}/src/plotastro/_authors.py +1 -1
  25. plotastro-1.1.0b1/src/plotastro/_colors.py +481 -0
  26. {plotastro-1.0.0 → plotastro-1.1.0b1}/src/plotastro/_core.py +53 -8
  27. {plotastro-1.0.0 → plotastro-1.1.0b1}/src/plotastro/styles/aanda.mplstyle +4 -0
  28. {plotastro-1.0.0 → plotastro-1.1.0b1}/src/plotastro/styles/apj.mplstyle +4 -0
  29. plotastro-1.1.0b1/src/plotastro/styles/euclid.mplstyle +123 -0
  30. {plotastro-1.0.0 → plotastro-1.1.0b1}/src/plotastro/styles/jcap.mplstyle +4 -0
  31. {plotastro-1.0.0 → plotastro-1.1.0b1}/src/plotastro/styles/mnras.mplstyle +4 -0
  32. {plotastro-1.0.0 → plotastro-1.1.0b1}/src/plotastro/styles/natastro.mplstyle +4 -0
  33. {plotastro-1.0.0 → plotastro-1.1.0b1}/src/plotastro/styles/oja.mplstyle +4 -0
  34. {plotastro-1.0.0 → plotastro-1.1.0b1}/src/plotastro/styles/prd.mplstyle +4 -0
  35. {plotastro-1.0.0 → plotastro-1.1.0b1}/src/plotastro/styles/rasti.mplstyle +4 -0
  36. {plotastro-1.0.0 → plotastro-1.1.0b1}/tests/test_authors.py +10 -0
  37. plotastro-1.1.0b1/tests/test_colors.py +180 -0
  38. {plotastro-1.0.0 → plotastro-1.1.0b1}/tests/test_sizing.py +2 -1
  39. plotastro-1.1.0b1/tests/test_styles.py +144 -0
  40. plotastro-1.1.0b1/tools/generate_styles.py +357 -0
  41. plotastro-1.0.0/.gitignore +0 -8
  42. plotastro-1.0.0/CHANGELOG.md +0 -48
  43. plotastro-1.0.0/src/plotastro/_colors.py +0 -227
  44. plotastro-1.0.0/tests/test_colors.py +0 -64
  45. plotastro-1.0.0/tests/test_styles.py +0 -69
  46. plotastro-1.0.0/tools/generate_styles.py +0 -202
  47. {plotastro-1.0.0 → plotastro-1.1.0b1}/.github/workflows/ci.yml +0 -0
  48. {plotastro-1.0.0 → plotastro-1.1.0b1}/.github/workflows/publish.yml +0 -0
  49. {plotastro-1.0.0 → plotastro-1.1.0b1}/LICENSE +0 -0
  50. {plotastro-1.0.0 → plotastro-1.1.0b1}/examples/authors_example.csv +0 -0
  51. {plotastro-1.0.0 → plotastro-1.1.0b1}/examples/figures/cvd_check.png +0 -0
  52. {plotastro-1.0.0 → plotastro-1.1.0b1}/examples/figures/example_column.png +0 -0
  53. {plotastro-1.0.0 → plotastro-1.1.0b1}/examples/figures/example_full.png +0 -0
  54. {plotastro-1.0.0 → plotastro-1.1.0b1}/examples/figures/linestyles.png +0 -0
  55. {plotastro-1.0.0 → plotastro-1.1.0b1}/examples/figures/markers.png +0 -0
  56. {plotastro-1.0.0 → plotastro-1.1.0b1}/examples/figures/palette.png +0 -0
  57. {plotastro-1.0.0 → plotastro-1.1.0b1}/examples/figures/palette_okabe_ito.png +0 -0
  58. {plotastro-1.0.0 → plotastro-1.1.0b1}/examples/figures/redundant_encoding.png +0 -0
  59. {plotastro-1.0.0 → plotastro-1.1.0b1}/requirements.txt +0 -0
  60. {plotastro-1.0.0 → plotastro-1.1.0b1}/src/plotastro/_extras.py +0 -0
  61. {plotastro-1.0.0 → plotastro-1.1.0b1}/tests/conftest.py +0 -0
  62. {plotastro-1.0.0 → plotastro-1.1.0b1}/tests/test_extras.py +0 -0
@@ -0,0 +1,15 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .ipynb_checkpoints/
4
+ dist/
5
+ build/
6
+ *.egg-info/
7
+ .pytest_cache/
8
+ .venv/
9
+ docs/_build/
10
+ docs/_figures/
11
+ docs/tutorial.ipynb
12
+ .vscode/
13
+ .gitignore
14
+ .DS_Store
15
+ .gitignore
@@ -0,0 +1,17 @@
1
+ # Read the Docs configuration — https://docs.readthedocs.io/en/stable/config-file/v2.html
2
+ version: 2
3
+
4
+ build:
5
+ os: ubuntu-24.04
6
+ tools:
7
+ python: "3.12"
8
+
9
+ sphinx:
10
+ configuration: docs/conf.py
11
+ fail_on_warning: false
12
+
13
+ python:
14
+ install:
15
+ - method: pip
16
+ path: .
17
+ - requirements: docs/requirements.txt
@@ -0,0 +1,101 @@
1
+ # Changelog
2
+
3
+ ## 1.1.0b1 — 2026-10-06 (beta)
4
+
5
+ A pre-release: `pip install plotastro` still gives the stable 1.0.1. To try
6
+ this beta, use `pip install --pre plotastro` (or `pip install
7
+ "plotastro==1.1.0b1"`).
8
+
9
+ ### Added
10
+ - `euclid` style (alias `ec`) for Euclid Consortium papers, adapted from
11
+ the Euclid Consortium Editorial Board's
12
+ [niceplots](https://gitlab.euclid-sgs.uk/ECEB/niceplots) (GPL-3.0,
13
+ Euclid-internal): sans-serif 10 pt text with Computer Modern maths, no
14
+ grid or minor ticks, framed legends, Petroff-8 colours, and niceplots'
15
+ 4 × 3 in figure convention (LaTeX scales the figure into the A&A
16
+ column). The settings are re-expressed in plotastro's own template;
17
+ nothing is copied from niceplots.
18
+ - Palettes `PETROFF8` and `TOL_VIBRANT`, and `euclid_colors(scheme, n=)`
19
+ giving niceplots' five colour schemes under their niceplots names.
20
+ - `set_style(..., palette=...)` swaps the colour cycle for any named
21
+ palette or list of colours.
22
+ - Optional [CMasher](https://cmasher.readthedocs.io) support, for discrete
23
+ colours and colormaps: `cmasher_colors(cmap, n=8, cmap_range=(0.15, 0.85))`
24
+ samples colours from a CMasher map, `cmasher_cmap(cmap, cmap_range=, n=)`
25
+ returns the map (optionally cut, or split into `n` levels), and
26
+ `set_style` accepts `palette="cmr.<name>"`. CMasher is **not** a
27
+ dependency: install it with `pip install "plotastro[cmasher]"` (or
28
+ `pip install cmasher`). plotastro imports it only when one of these is
29
+ used, and without it they raise an `ImportError` saying how to install it.
30
+ - `set_style(..., cmap=...)` sets the default colormap: any matplotlib
31
+ name, or `"cmr.<name>"` for CMasher.
32
+
33
+ ### Changed
34
+ - `figsize()` / `subplots()`: the default `aspect` now comes from the
35
+ journal (golden ratio everywhere except `euclid`, which uses 4:3).
36
+ - `authorlist(..., journal="euclid")` uses the A&A format (Euclid's
37
+ `aaEC` class).
38
+
39
+ ### Fixed
40
+ - Switching styles in one session no longer carries settings over.
41
+ matplotlib only overwrites the rcParams a style names, and the styles
42
+ named different ones: after `euclid`, for example, `set_style("mnras")`
43
+ or `plt.style.use("mnras")` kept Euclid's tick padding. Every style now
44
+ sets the same rcParams, using matplotlib's defaults where they apply,
45
+ and a test checks this.
46
+
47
+ ## 1.0.1 — 2026-09-01
48
+
49
+ ### Added
50
+ - Documentation site (Sphinx + Furo on Read the Docs) with the rendered
51
+ tutorial notebook and a full API reference:
52
+ <https://plotastro.readthedocs.io>.
53
+
54
+ No changes to the package code itself.
55
+
56
+ ## 1.0.0 — 2026-09-01
57
+
58
+ First release as an installable package, `plotastro`.
59
+
60
+ ### Added
61
+ - `pip install plotastro`; importing it registers all styles with
62
+ matplotlib, so `plt.style.use("mnras")` works everywhere.
63
+ - Journal styles: **MNRAS**, **RASTI**, **A&A**, **ApJ/ApJL (AASTeX)**,
64
+ **Open Journal of Astrophysics**, **PRD/PRL (REVTeX)**, **JCAP**, and
65
+ **Nature Astronomy** (sans-serif variant), plus `thesis`/`beamer`
66
+ width presets. All generated from one template
67
+ (`tools/generate_styles.py`) so they stay consistent.
68
+ - Helpers: `set_style`, `figsize`, `subplots`, `savefig`,
69
+ `style_cycler`, `lighten`/`darken`, `label_panels` (journal-style
70
+ (a)/(b)/(c) panel labels), reference charts
71
+ (`show_colors`/`show_markers`/`show_linestyles`).
72
+ - Colour-vision-deficiency checking: `simulate_cvd`, `check_colors`,
73
+ and `check_figure` (Machado et al. 2009 model; no extra dependencies).
74
+ - Palettes: the default colour-blind-friendly cycle (`COLORS`), Okabe &
75
+ Ito (`OKABE_ITO`), Petroff-10 (`PETROFF10`) and light/dark pairs
76
+ (`PAIRED`).
77
+ - Author-list generator: `authorlist("authors.csv", journal=...)` and the
78
+ `plotastro-authors` command-line tool turn a CSV of names/affiliations/
79
+ ORCIDs/emails into the journal's LaTeX author block (MNRAS, A&A,
80
+ AASTeX, REVTeX, JCAP and generic formats), with automatic affiliation
81
+ numbering and sharing. Reads real collaboration lists as-is
82
+ (`Authorname`/`Firstname`+`Lastname` columns, one row per affiliation,
83
+ embedded LaTeX accents, extra columns ignored).
84
+ - Zero-learning-curve mode: importing plotastro registers every style
85
+ with matplotlib, so `plt.style.use("mnras")` + ordinary matplotlib is
86
+ the entire integration (`pa.use(...)` is an alias of `set_style`).
87
+ - `requirements.txt` / `requirements-dev.txt` for pip users; NumPy 1.x
88
+ and 2.x both supported and tested in CI.
89
+ - Tests (pytest), CI and PyPI-publishing GitHub Actions workflows,
90
+ executed tutorial notebook, MIT license.
91
+
92
+ ### Changed
93
+ - Styles no longer require LaTeX: portable STIX mathtext by default,
94
+ with `set_style(..., usetex=True)` to opt in (newtx fonts).
95
+ - Submission-safe saving defaults: PDF, tight bbox, 450 dpi,
96
+ TrueType font embedding (`pdf.fonttype 42`).
97
+
98
+ ### Migration from the original repo
99
+ - `MNRAS_Style.mplstyle` → `plt.style.use("mnras")` (after `import plotastro`).
100
+ - `myfigsize.set_size(...)` → `plotastro.set_size(...)` still works, but
101
+ prefer `plotastro.figsize(...)` / `plotastro.subplots(...)`.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: plotastro
3
- Version: 1.0.0
3
+ Version: 1.1.0b1
4
4
  Summary: Publication-quality matplotlib styles and helpers for astronomy journals (MNRAS, A&A, ApJ, OJA, PRD, JCAP, Nature Astronomy)
5
5
  Project-URL: Homepage, https://github.com/BehnoodBandi/plotastro
6
6
  Project-URL: Issues, https://github.com/BehnoodBandi/plotastro/issues
@@ -17,20 +17,30 @@ Classifier: Topic :: Scientific/Engineering :: Astronomy
17
17
  Classifier: Topic :: Scientific/Engineering :: Visualization
18
18
  Requires-Python: >=3.9
19
19
  Requires-Dist: matplotlib>=3.5
20
+ Provides-Extra: cmasher
21
+ Requires-Dist: cmasher>=1.7; extra == 'cmasher'
20
22
  Provides-Extra: dev
23
+ Requires-Dist: cmasher>=1.7; extra == 'dev'
21
24
  Requires-Dist: numpy; extra == 'dev'
22
25
  Requires-Dist: pytest; extra == 'dev'
23
26
  Description-Content-Type: text/markdown
24
27
 
25
28
  # plotastro
26
29
 
30
+ [![PyPI](https://img.shields.io/pypi/v/plotastro.svg)](https://pypi.org/project/plotastro/)
31
+ [![Python versions](https://img.shields.io/pypi/pyversions/plotastro.svg)](https://pypi.org/project/plotastro/)
32
+ [![CI](https://github.com/BehnoodBandi/plotastro/actions/workflows/ci.yml/badge.svg)](https://github.com/BehnoodBandi/plotastro/actions/workflows/ci.yml)
33
+ [![Docs](https://readthedocs.org/projects/plotastro/badge/?version=latest)](https://plotastro.readthedocs.io)
34
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
35
+
27
36
  **Publication-quality matplotlib figures for astronomy journals.**
28
37
 
29
38
  One `pip install` gives you journal-matched styles for **MNRAS**, **RASTI**,
30
39
  **A&A**, **ApJ/ApJL**, the **Open Journal of Astrophysics**, **PRD/PRL**,
31
- **JCAP** and **Nature Astronomy** — figures at exactly the right physical
32
- size, a colour-blind-friendly palette, and helpers that make the tedious
33
- parts (sizing, panel labels, accessibility checks, saving) one-liners.
40
+ **JCAP**, **Nature Astronomy** and **Euclid Consortium** papers — figures
41
+ at exactly the right physical size, a colour-blind-friendly palette, and
42
+ helpers that make the tedious parts (sizing, panel labels, accessibility
43
+ checks, saving) one-liners.
34
44
 
35
45
  ```bash
36
46
  pip install plotastro
@@ -66,7 +76,8 @@ pa.savefig("myplot") # -> myplot.pdf, ready for \includegraphics
66
76
  |---|---|
67
77
  | ![single-column example](examples/figures/example_column.png) | ![full-width example](examples/figures/example_full.png) |
68
78
 
69
- **Start with the [tutorial notebook](examples/tutorial.ipynb)** — it walks
79
+ **Full documentation: [plotastro.readthedocs.io](https://plotastro.readthedocs.io)** —
80
+ or start with the [tutorial notebook](examples/tutorial.ipynb), which walks
70
81
  through every feature with runnable examples.
71
82
 
72
83
  ## Why this exists
@@ -87,7 +98,9 @@ The styles share one visual language — Times-like serif fonts at ~9 pt with
87
98
  ~8 pt tick lettering, inward ticks on all four sides with minors, a subtle
88
99
  grid, frameless legends — and differ only in figure width (plus the
89
100
  sans-serif fonts Nature requires), so your plots stay **consistent between
90
- papers** no matter where you submit.
101
+ papers** no matter where you submit. The one exception is `euclid`, which
102
+ deliberately matches the Euclid Consortium's own niceplots look instead
103
+ (see below).
91
104
 
92
105
  ## Supported journals
93
106
 
@@ -104,6 +117,7 @@ papers** no matter where you submit.
104
117
  | `prd` (`prl`, `revtex`) | Physical Review D | 246.0 pt = 3.40 in | 510.0 pt = 7.06 in |
105
118
  | `jcap` | J. Cosmology & Astroparticle Phys. | single-column ≈455 pt = 6.30 in | — |
106
119
  | `natastro` (`nature`) | Nature Astronomy (sans-serif!) | 253.2 pt = 3.50 in (89 mm) | 520.7 pt = 7.20 in (183 mm) |
120
+ | `euclid` (`ec`) | Euclid Consortium papers (A&A; niceplots look, sans-serif) | drawn 4.00 in = 289.1 pt, LaTeX scales it to 88 mm | 8.00 in = 578.2 pt (2 × column) |
107
121
  | `thesis` | A4 thesis text width | 426.8 pt = 5.91 in | — |
108
122
  | `beamer` | Beamer slide text width | 307.3 pt = 4.25 in | — |
109
123
 
@@ -112,8 +126,37 @@ document, put `\the\columnwidth` or `\the\textwidth` in your `.tex` body,
112
126
  compile, read the value off the page, and pass it directly:
113
127
  `pa.figsize(width=345.0)`.
114
128
 
129
+ ### Euclid Consortium papers
130
+
131
+ `pa.set_style("euclid")` reproduces the look of
132
+ [niceplots](https://gitlab.euclid-sgs.uk/ECEB/niceplots), the Euclid
133
+ Consortium Editorial Board's matplotlib style for Euclid papers
134
+ (Euclid-internal, GPL-3.0; set up by Lukas Hergt, with tweaks by Laila
135
+ Linke). The style and its colour schemes are **adapted from that
136
+ repository**: the settings are re-expressed in plotastro's own template and
137
+ nothing is copied from it. How it differs from the other styles:
138
+
139
+ - sans-serif text at 10 pt with Computer Modern maths, no grid, no minor
140
+ ticks, framed legends, and `axes.xmargin = 0`;
141
+ - the default cycle is Petroff's 8-colour palette (`pa.PETROFF8`);
142
+ niceplots' other schemes are available under their niceplots names —
143
+ `pa.set_style("euclid", palette="categorical3")` or
144
+ `pa.euclid_colors("sequential", n=6)` (see *The colour palette* below);
145
+ - **sizing follows niceplots rather than the exact-size approach**: figures
146
+ are drawn 4 × 3 in (two-column: 8 × 6 in) and LaTeX scales them into the
147
+ 88 mm A&A column, so the 10 pt lettering prints at ≈ 8.7 pt. Include them
148
+ with `\includegraphics[width=\columnwidth]{fig.pdf}`. For a figure at
149
+ its exact printed size with the Euclid look, size it for A&A instead:
150
+ `pa.subplots(journal="aanda")`.
151
+
152
+ `pa.set_style("euclid", usetex=True)` gives niceplots' LaTeX rendering
153
+ (Computer Modern Sans text). Euclid papers use A&A's `aaEC` class, so
154
+ `pa.authorlist(..., journal="euclid")` produces the A&A author block.
155
+
115
156
  The only hard dependency is matplotlib; plotastro works with both NumPy 1.x
116
- and 2.x (CI tests each). Running the examples from a clone?
157
+ and 2.x (CI tests each). [CMasher](https://cmasher.readthedocs.io) colours
158
+ and colormaps are an optional extra (`pip install "plotastro[cmasher]"`; see
159
+ below). Running the examples from a clone?
117
160
  `pip install -r requirements-dev.txt`.
118
161
 
119
162
  ## Tutorial
@@ -165,20 +208,71 @@ ax.fill_between(x, lo, hi, color=pa.lighten(pa.COLORS["blue"], 0.7))
165
208
  pa.darken(pa.COLORS["orange"], 0.3) # the other direction
166
209
  ```
167
210
 
168
- Three more palettes ship with the package:
211
+ More palettes ship with the package:
169
212
 
170
213
  - `pa.OKABE_ITO` — [Okabe & Ito (2008)](https://jfly.uni-koeln.de/color/),
171
214
  *the* classic CVD-safe recommendation for categorical colours in science;
172
215
  - `pa.PETROFF10` — [Petroff (2021)](https://arxiv.org/abs/2107.02270), the
173
216
  CVD-optimised 10-colour cycle used across particle physics;
217
+ - `pa.PETROFF8` — Petroff's 8-colour sibling, the default cycle of the
218
+ Euclid Consortium's [niceplots](https://gitlab.euclid-sgs.uk/ECEB/niceplots)
219
+ (and of the `euclid` style here);
220
+ - `pa.TOL_VIBRANT` — [Paul Tol's](https://personal.sron.nl/~pault/) *vibrant*
221
+ qualitative scheme, 7 CVD-safe colours;
174
222
  - `pa.PAIRED` — light/dark pairs for data/model or before/after comparisons:
175
223
  `pa.PAIRED["blue"]` → `("#a6cee3", "#1f78b4")`.
176
224
 
225
+ Any of them can become the active cycle when you activate a style —
226
+ `pa.set_style("mnras", palette="okabe_ito")` — or pass your own list of
227
+ colours. The colour schemes of the Euclid Consortium's niceplots are also
228
+ available under their niceplots names (adapted from that repository):
229
+ `pa.euclid_colors()` takes `"categorical1"` (Petroff-8), `"categorical2"`
230
+ (Okabe & Ito), `"categorical3"` (black + Tol vibrant), `"sequential"` (`n`
231
+ colours from `copper`) or `"diverging"` (`n` colours from `coolwarm`):
232
+
233
+ ```python
234
+ pa.set_style("euclid", palette="diverging") # by name
235
+ ax.set_prop_cycle(color=pa.euclid_colors("sequential", n=6)) # per axes
236
+ ```
237
+
177
238
  **Colormaps:** the styles default to `viridis` (perceptually uniform,
178
239
  CVD-safe). Good picks: `viridis`/`magma`/`cividis` for sequential data,
179
240
  `RdBu_r` or `coolwarm` for diverging data (red–*blue*, not red–green). Avoid
180
- `jet`/`rainbow`. For more astro-friendly maps see
181
- [cmasher](https://cmasher.readthedocs.io) and [cmocean](https://matplotlib.org/cmocean/).
241
+ `jet`/`rainbow`. Change the default with `pa.set_style("mnras", cmap="cividis")`.
242
+ For many more maps, use CMasher (next section) or
243
+ [cmocean](https://matplotlib.org/cmocean/).
244
+
245
+ ### CMasher colours and colormaps (optional)
246
+
247
+ ![CMasher colours and colormaps](examples/figures/cmasher.png)
248
+
249
+ [CMasher](https://cmasher.readthedocs.io) (van der Velden 2020,
250
+ [JOSS 5, 2004](https://doi.org/10.21105/joss.02004)) is a collection of
251
+ perceptually uniform scientific colormaps (sequential, diverging and
252
+ cyclic), most of them colour-vision-deficiency friendly. plotastro can use
253
+ it for both discrete colours and colormaps, but it is **not a dependency**.
254
+ Install it only if you want it (`pip install cmasher`, or
255
+ `pip install "plotastro[cmasher]"`); plotastro imports it only when you ask
256
+ for a CMasher colour. Names start with `cmr.`, as in CMasher itself:
257
+
258
+ ```python
259
+ pa.set_style("mnras", palette="cmr.rainforest") # 8-colour cycle from a CMasher map
260
+ pa.set_style("mnras", cmap="cmr.ocean") # default colormap for imshow etc.
261
+
262
+ ax.set_prop_cycle(color=pa.cmasher_colors("torch", n=5)) # n discrete colours
263
+ ax.imshow(img, cmap=pa.cmasher_cmap("rainforest")) # the colormap
264
+ ax.contourf(x, y, z, levels=6, cmap=pa.cmasher_cmap("iceburn", n=6)) # 6 levels
265
+ ```
266
+
267
+ Discrete colours are sampled from `cmap_range=(0.15, 0.85)` by default.
268
+ This follows CMasher's advice, since most of its sequential maps run from
269
+ black to white and those ends vanish on the page. For lines that must be
270
+ easy to tell apart, CMasher suggests `apple`, `chroma`, `neon`,
271
+ `rainforest` or `torch`; for steps of one quantity, a single-hue map such
272
+ as `flamingo`, `freeze`, `gothic`, `jungle` or `ocean`. To span the whole
273
+ map with a fixed number of lines, sample exactly that many:
274
+ `pa.cmasher_colors("rainforest", n=len(models))`. Please cite CMasher if
275
+ you use it (`cmasher.get_bibtex()`).
182
276
 
183
277
  ### Checking accessibility yourself
184
278
 
@@ -270,9 +364,10 @@ your manuscript (custom macros, real kerning):
270
364
  pa.set_style("mnras", usetex=True) # needs latex + dvipng + ghostscript
271
365
  ```
272
366
 
273
- This loads the `newtx` Times fonts (matching the MNRAS/A&A house font), or
274
- Helvetica for Nature Astronomy. Develop with `usetex=False`, flip it on for
275
- the final version — LaTeX rendering is slow.
367
+ This loads the `newtx` Times fonts (matching the MNRAS/A&A house font),
368
+ Helvetica for Nature Astronomy, or plain Computer Modern Sans for the Euclid
369
+ style (as niceplots does). Develop with `usetex=False`, flip it on for the
370
+ final version — LaTeX rendering is slow.
276
371
 
277
372
  ### Saving figures
278
373
 
@@ -354,14 +449,16 @@ complete example.
354
449
 
355
450
  | | |
356
451
  |---|---|
357
- | `set_style(journal, usetex=, grid=, **rc)` | activate a journal's style (alias: `use`) |
452
+ | `set_style(journal, usetex=, grid=, palette=, cmap=, **rc)` | activate a journal's style (alias: `use`) |
358
453
  | `authorlist(csv, journal=)` | LaTeX author/affiliation block from a CSV (CLI: `plotastro-authors`) |
359
454
  | `figsize(width, journal=, fraction=, aspect=, ...)` | journal-correct figure dimensions |
360
455
  | `subplots(...)` | `plt.subplots` with the size computed for you |
361
456
  | `savefig(name, formats=("pdf",))` | save one figure in several formats |
362
457
  | `label_panels(axes, ...)` | (a), (b), (c) panel labels |
363
458
  | `style_cycler(markers=, linestyles=)` | redundant-encoding property cycle |
364
- | `COLORS`, `CYCLE`, `OKABE_ITO`, `PETROFF10`, `PAIRED` | palettes |
459
+ | `COLORS`, `CYCLE`, `OKABE_ITO`, `PETROFF8`, `PETROFF10`, `TOL_VIBRANT`, `PAIRED` | palettes |
460
+ | `euclid_colors(scheme, n=)` | the Euclid niceplots colour schemes, by name |
461
+ | `cmasher_colors(cmap, n=, cmap_range=)`, `cmasher_cmap(cmap, cmap_range=, n=)` | CMasher colours / colormaps (optional `cmasher` package) |
365
462
  | `lighten(c, f)`, `darken(c, f)` | matched shades without transparency |
366
463
  | `simulate_cvd`, `check_colors`, `check_figure` | colour-vision-deficiency checks |
367
464
  | `MARKERS`, `LINESTYLES` | curated marker / dash-pattern sequences |
@@ -402,7 +499,7 @@ python tools/generate_styles.py # regenerate styles/ after editing the templ
402
499
  python examples/make_reference_figures.py # regenerate README figures
403
500
  ```
404
501
 
405
- The `.mplstyle` files are generated from a single template in
502
+ The `.mplstyle` files are generated from the templates in
406
503
  [tools/generate_styles.py](tools/generate_styles.py) — edit that, not the
407
504
  files (CI checks they stay in sync). Releases: bump the version in
408
505
  `pyproject.toml` and `CHANGELOG.md`, then push a `v*` tag — the
@@ -412,12 +509,20 @@ files (CI checks they stay in sync). Releases: bump the version in
412
509
  ## Credits
413
510
 
414
511
  - Original MNRAS style this grew from:
415
- [M. Knabenhans' mplstyle_for_MNRAS](https://github.com/mischakn/mplstyle_for_MNRAS)
512
+ [M. Knabenhans' mplstyle_for_MNRAS](https://github.com/miknab/mplstyle_for_MNRAS)
416
513
  - Colour-blind-friendly Set1 ordering:
417
514
  [Thøger Rivera-Thorsen](https://gist.github.com/thriveth/8560036);
418
515
  light colours from Tableau *Color Blind 10*
419
516
  - Palettes: [Okabe & Ito](https://jfly.uni-koeln.de/color/),
420
- [Petroff (2021)](https://arxiv.org/abs/2107.02270), ColorBrewer *Paired*
517
+ [Petroff (2021)](https://arxiv.org/abs/2107.02270),
518
+ [Paul Tol](https://personal.sron.nl/~pault/), ColorBrewer *Paired*
519
+ - Optional colormaps: [CMasher](https://cmasher.readthedocs.io)
520
+ (E. van der Velden 2020, JOSS 5, 2004; BSD-3-Clause), used as an optional
521
+ dependency, not bundled
522
+ - Euclid style and colour schemes adapted from the Euclid Consortium
523
+ Editorial Board's [niceplots](https://gitlab.euclid-sgs.uk/ECEB/niceplots)
524
+ (Lukas Hergt and Laila Linke; GPL-3.0, Euclid-internal) — settings
525
+ re-expressed in plotastro's own template, nothing copied
421
526
  - CVD model: Machado, Oliveira & Fernandes (2009), IEEE TVCG 15(6)
422
527
  - Figure-size approach after
423
528
  [Jack Walton's guide](https://jwalton.info/Embed-Publication-Matplotlib-Latex/)
@@ -1,12 +1,19 @@
1
1
  # plotastro
2
2
 
3
+ [![PyPI](https://img.shields.io/pypi/v/plotastro.svg)](https://pypi.org/project/plotastro/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/plotastro.svg)](https://pypi.org/project/plotastro/)
5
+ [![CI](https://github.com/BehnoodBandi/plotastro/actions/workflows/ci.yml/badge.svg)](https://github.com/BehnoodBandi/plotastro/actions/workflows/ci.yml)
6
+ [![Docs](https://readthedocs.org/projects/plotastro/badge/?version=latest)](https://plotastro.readthedocs.io)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
8
+
3
9
  **Publication-quality matplotlib figures for astronomy journals.**
4
10
 
5
11
  One `pip install` gives you journal-matched styles for **MNRAS**, **RASTI**,
6
12
  **A&A**, **ApJ/ApJL**, the **Open Journal of Astrophysics**, **PRD/PRL**,
7
- **JCAP** and **Nature Astronomy** — figures at exactly the right physical
8
- size, a colour-blind-friendly palette, and helpers that make the tedious
9
- parts (sizing, panel labels, accessibility checks, saving) one-liners.
13
+ **JCAP**, **Nature Astronomy** and **Euclid Consortium** papers — figures
14
+ at exactly the right physical size, a colour-blind-friendly palette, and
15
+ helpers that make the tedious parts (sizing, panel labels, accessibility
16
+ checks, saving) one-liners.
10
17
 
11
18
  ```bash
12
19
  pip install plotastro
@@ -42,7 +49,8 @@ pa.savefig("myplot") # -> myplot.pdf, ready for \includegraphics
42
49
  |---|---|
43
50
  | ![single-column example](examples/figures/example_column.png) | ![full-width example](examples/figures/example_full.png) |
44
51
 
45
- **Start with the [tutorial notebook](examples/tutorial.ipynb)** — it walks
52
+ **Full documentation: [plotastro.readthedocs.io](https://plotastro.readthedocs.io)** —
53
+ or start with the [tutorial notebook](examples/tutorial.ipynb), which walks
46
54
  through every feature with runnable examples.
47
55
 
48
56
  ## Why this exists
@@ -63,7 +71,9 @@ The styles share one visual language — Times-like serif fonts at ~9 pt with
63
71
  ~8 pt tick lettering, inward ticks on all four sides with minors, a subtle
64
72
  grid, frameless legends — and differ only in figure width (plus the
65
73
  sans-serif fonts Nature requires), so your plots stay **consistent between
66
- papers** no matter where you submit.
74
+ papers** no matter where you submit. The one exception is `euclid`, which
75
+ deliberately matches the Euclid Consortium's own niceplots look instead
76
+ (see below).
67
77
 
68
78
  ## Supported journals
69
79
 
@@ -80,6 +90,7 @@ papers** no matter where you submit.
80
90
  | `prd` (`prl`, `revtex`) | Physical Review D | 246.0 pt = 3.40 in | 510.0 pt = 7.06 in |
81
91
  | `jcap` | J. Cosmology & Astroparticle Phys. | single-column ≈455 pt = 6.30 in | — |
82
92
  | `natastro` (`nature`) | Nature Astronomy (sans-serif!) | 253.2 pt = 3.50 in (89 mm) | 520.7 pt = 7.20 in (183 mm) |
93
+ | `euclid` (`ec`) | Euclid Consortium papers (A&A; niceplots look, sans-serif) | drawn 4.00 in = 289.1 pt, LaTeX scales it to 88 mm | 8.00 in = 578.2 pt (2 × column) |
83
94
  | `thesis` | A4 thesis text width | 426.8 pt = 5.91 in | — |
84
95
  | `beamer` | Beamer slide text width | 307.3 pt = 4.25 in | — |
85
96
 
@@ -88,8 +99,37 @@ document, put `\the\columnwidth` or `\the\textwidth` in your `.tex` body,
88
99
  compile, read the value off the page, and pass it directly:
89
100
  `pa.figsize(width=345.0)`.
90
101
 
102
+ ### Euclid Consortium papers
103
+
104
+ `pa.set_style("euclid")` reproduces the look of
105
+ [niceplots](https://gitlab.euclid-sgs.uk/ECEB/niceplots), the Euclid
106
+ Consortium Editorial Board's matplotlib style for Euclid papers
107
+ (Euclid-internal, GPL-3.0; set up by Lukas Hergt, with tweaks by Laila
108
+ Linke). The style and its colour schemes are **adapted from that
109
+ repository**: the settings are re-expressed in plotastro's own template and
110
+ nothing is copied from it. How it differs from the other styles:
111
+
112
+ - sans-serif text at 10 pt with Computer Modern maths, no grid, no minor
113
+ ticks, framed legends, and `axes.xmargin = 0`;
114
+ - the default cycle is Petroff's 8-colour palette (`pa.PETROFF8`);
115
+ niceplots' other schemes are available under their niceplots names —
116
+ `pa.set_style("euclid", palette="categorical3")` or
117
+ `pa.euclid_colors("sequential", n=6)` (see *The colour palette* below);
118
+ - **sizing follows niceplots rather than the exact-size approach**: figures
119
+ are drawn 4 × 3 in (two-column: 8 × 6 in) and LaTeX scales them into the
120
+ 88 mm A&A column, so the 10 pt lettering prints at ≈ 8.7 pt. Include them
121
+ with `\includegraphics[width=\columnwidth]{fig.pdf}`. For a figure at
122
+ its exact printed size with the Euclid look, size it for A&A instead:
123
+ `pa.subplots(journal="aanda")`.
124
+
125
+ `pa.set_style("euclid", usetex=True)` gives niceplots' LaTeX rendering
126
+ (Computer Modern Sans text). Euclid papers use A&A's `aaEC` class, so
127
+ `pa.authorlist(..., journal="euclid")` produces the A&A author block.
128
+
91
129
  The only hard dependency is matplotlib; plotastro works with both NumPy 1.x
92
- and 2.x (CI tests each). Running the examples from a clone?
130
+ and 2.x (CI tests each). [CMasher](https://cmasher.readthedocs.io) colours
131
+ and colormaps are an optional extra (`pip install "plotastro[cmasher]"`; see
132
+ below). Running the examples from a clone?
93
133
  `pip install -r requirements-dev.txt`.
94
134
 
95
135
  ## Tutorial
@@ -141,20 +181,71 @@ ax.fill_between(x, lo, hi, color=pa.lighten(pa.COLORS["blue"], 0.7))
141
181
  pa.darken(pa.COLORS["orange"], 0.3) # the other direction
142
182
  ```
143
183
 
144
- Three more palettes ship with the package:
184
+ More palettes ship with the package:
145
185
 
146
186
  - `pa.OKABE_ITO` — [Okabe & Ito (2008)](https://jfly.uni-koeln.de/color/),
147
187
  *the* classic CVD-safe recommendation for categorical colours in science;
148
188
  - `pa.PETROFF10` — [Petroff (2021)](https://arxiv.org/abs/2107.02270), the
149
189
  CVD-optimised 10-colour cycle used across particle physics;
190
+ - `pa.PETROFF8` — Petroff's 8-colour sibling, the default cycle of the
191
+ Euclid Consortium's [niceplots](https://gitlab.euclid-sgs.uk/ECEB/niceplots)
192
+ (and of the `euclid` style here);
193
+ - `pa.TOL_VIBRANT` — [Paul Tol's](https://personal.sron.nl/~pault/) *vibrant*
194
+ qualitative scheme, 7 CVD-safe colours;
150
195
  - `pa.PAIRED` — light/dark pairs for data/model or before/after comparisons:
151
196
  `pa.PAIRED["blue"]` → `("#a6cee3", "#1f78b4")`.
152
197
 
198
+ Any of them can become the active cycle when you activate a style —
199
+ `pa.set_style("mnras", palette="okabe_ito")` — or pass your own list of
200
+ colours. The colour schemes of the Euclid Consortium's niceplots are also
201
+ available under their niceplots names (adapted from that repository):
202
+ `pa.euclid_colors()` takes `"categorical1"` (Petroff-8), `"categorical2"`
203
+ (Okabe & Ito), `"categorical3"` (black + Tol vibrant), `"sequential"` (`n`
204
+ colours from `copper`) or `"diverging"` (`n` colours from `coolwarm`):
205
+
206
+ ```python
207
+ pa.set_style("euclid", palette="diverging") # by name
208
+ ax.set_prop_cycle(color=pa.euclid_colors("sequential", n=6)) # per axes
209
+ ```
210
+
153
211
  **Colormaps:** the styles default to `viridis` (perceptually uniform,
154
212
  CVD-safe). Good picks: `viridis`/`magma`/`cividis` for sequential data,
155
213
  `RdBu_r` or `coolwarm` for diverging data (red–*blue*, not red–green). Avoid
156
- `jet`/`rainbow`. For more astro-friendly maps see
157
- [cmasher](https://cmasher.readthedocs.io) and [cmocean](https://matplotlib.org/cmocean/).
214
+ `jet`/`rainbow`. Change the default with `pa.set_style("mnras", cmap="cividis")`.
215
+ For many more maps, use CMasher (next section) or
216
+ [cmocean](https://matplotlib.org/cmocean/).
217
+
218
+ ### CMasher colours and colormaps (optional)
219
+
220
+ ![CMasher colours and colormaps](examples/figures/cmasher.png)
221
+
222
+ [CMasher](https://cmasher.readthedocs.io) (van der Velden 2020,
223
+ [JOSS 5, 2004](https://doi.org/10.21105/joss.02004)) is a collection of
224
+ perceptually uniform scientific colormaps (sequential, diverging and
225
+ cyclic), most of them colour-vision-deficiency friendly. plotastro can use
226
+ it for both discrete colours and colormaps, but it is **not a dependency**.
227
+ Install it only if you want it (`pip install cmasher`, or
228
+ `pip install "plotastro[cmasher]"`); plotastro imports it only when you ask
229
+ for a CMasher colour. Names start with `cmr.`, as in CMasher itself:
230
+
231
+ ```python
232
+ pa.set_style("mnras", palette="cmr.rainforest") # 8-colour cycle from a CMasher map
233
+ pa.set_style("mnras", cmap="cmr.ocean") # default colormap for imshow etc.
234
+
235
+ ax.set_prop_cycle(color=pa.cmasher_colors("torch", n=5)) # n discrete colours
236
+ ax.imshow(img, cmap=pa.cmasher_cmap("rainforest")) # the colormap
237
+ ax.contourf(x, y, z, levels=6, cmap=pa.cmasher_cmap("iceburn", n=6)) # 6 levels
238
+ ```
239
+
240
+ Discrete colours are sampled from `cmap_range=(0.15, 0.85)` by default.
241
+ This follows CMasher's advice, since most of its sequential maps run from
242
+ black to white and those ends vanish on the page. For lines that must be
243
+ easy to tell apart, CMasher suggests `apple`, `chroma`, `neon`,
244
+ `rainforest` or `torch`; for steps of one quantity, a single-hue map such
245
+ as `flamingo`, `freeze`, `gothic`, `jungle` or `ocean`. To span the whole
246
+ map with a fixed number of lines, sample exactly that many:
247
+ `pa.cmasher_colors("rainforest", n=len(models))`. Please cite CMasher if
248
+ you use it (`cmasher.get_bibtex()`).
158
249
 
159
250
  ### Checking accessibility yourself
160
251
 
@@ -246,9 +337,10 @@ your manuscript (custom macros, real kerning):
246
337
  pa.set_style("mnras", usetex=True) # needs latex + dvipng + ghostscript
247
338
  ```
248
339
 
249
- This loads the `newtx` Times fonts (matching the MNRAS/A&A house font), or
250
- Helvetica for Nature Astronomy. Develop with `usetex=False`, flip it on for
251
- the final version — LaTeX rendering is slow.
340
+ This loads the `newtx` Times fonts (matching the MNRAS/A&A house font),
341
+ Helvetica for Nature Astronomy, or plain Computer Modern Sans for the Euclid
342
+ style (as niceplots does). Develop with `usetex=False`, flip it on for the
343
+ final version — LaTeX rendering is slow.
252
344
 
253
345
  ### Saving figures
254
346
 
@@ -330,14 +422,16 @@ complete example.
330
422
 
331
423
  | | |
332
424
  |---|---|
333
- | `set_style(journal, usetex=, grid=, **rc)` | activate a journal's style (alias: `use`) |
425
+ | `set_style(journal, usetex=, grid=, palette=, cmap=, **rc)` | activate a journal's style (alias: `use`) |
334
426
  | `authorlist(csv, journal=)` | LaTeX author/affiliation block from a CSV (CLI: `plotastro-authors`) |
335
427
  | `figsize(width, journal=, fraction=, aspect=, ...)` | journal-correct figure dimensions |
336
428
  | `subplots(...)` | `plt.subplots` with the size computed for you |
337
429
  | `savefig(name, formats=("pdf",))` | save one figure in several formats |
338
430
  | `label_panels(axes, ...)` | (a), (b), (c) panel labels |
339
431
  | `style_cycler(markers=, linestyles=)` | redundant-encoding property cycle |
340
- | `COLORS`, `CYCLE`, `OKABE_ITO`, `PETROFF10`, `PAIRED` | palettes |
432
+ | `COLORS`, `CYCLE`, `OKABE_ITO`, `PETROFF8`, `PETROFF10`, `TOL_VIBRANT`, `PAIRED` | palettes |
433
+ | `euclid_colors(scheme, n=)` | the Euclid niceplots colour schemes, by name |
434
+ | `cmasher_colors(cmap, n=, cmap_range=)`, `cmasher_cmap(cmap, cmap_range=, n=)` | CMasher colours / colormaps (optional `cmasher` package) |
341
435
  | `lighten(c, f)`, `darken(c, f)` | matched shades without transparency |
342
436
  | `simulate_cvd`, `check_colors`, `check_figure` | colour-vision-deficiency checks |
343
437
  | `MARKERS`, `LINESTYLES` | curated marker / dash-pattern sequences |
@@ -378,7 +472,7 @@ python tools/generate_styles.py # regenerate styles/ after editing the templ
378
472
  python examples/make_reference_figures.py # regenerate README figures
379
473
  ```
380
474
 
381
- The `.mplstyle` files are generated from a single template in
475
+ The `.mplstyle` files are generated from the templates in
382
476
  [tools/generate_styles.py](tools/generate_styles.py) — edit that, not the
383
477
  files (CI checks they stay in sync). Releases: bump the version in
384
478
  `pyproject.toml` and `CHANGELOG.md`, then push a `v*` tag — the
@@ -388,12 +482,20 @@ files (CI checks they stay in sync). Releases: bump the version in
388
482
  ## Credits
389
483
 
390
484
  - Original MNRAS style this grew from:
391
- [M. Knabenhans' mplstyle_for_MNRAS](https://github.com/mischakn/mplstyle_for_MNRAS)
485
+ [M. Knabenhans' mplstyle_for_MNRAS](https://github.com/miknab/mplstyle_for_MNRAS)
392
486
  - Colour-blind-friendly Set1 ordering:
393
487
  [Thøger Rivera-Thorsen](https://gist.github.com/thriveth/8560036);
394
488
  light colours from Tableau *Color Blind 10*
395
489
  - Palettes: [Okabe & Ito](https://jfly.uni-koeln.de/color/),
396
- [Petroff (2021)](https://arxiv.org/abs/2107.02270), ColorBrewer *Paired*
490
+ [Petroff (2021)](https://arxiv.org/abs/2107.02270),
491
+ [Paul Tol](https://personal.sron.nl/~pault/), ColorBrewer *Paired*
492
+ - Optional colormaps: [CMasher](https://cmasher.readthedocs.io)
493
+ (E. van der Velden 2020, JOSS 5, 2004; BSD-3-Clause), used as an optional
494
+ dependency, not bundled
495
+ - Euclid style and colour schemes adapted from the Euclid Consortium
496
+ Editorial Board's [niceplots](https://gitlab.euclid-sgs.uk/ECEB/niceplots)
497
+ (Lukas Hergt and Laila Linke; GPL-3.0, Euclid-internal) — settings
498
+ re-expressed in plotastro's own template, nothing copied
397
499
  - CVD model: Machado, Oliveira & Fernandes (2009), IEEE TVCG 15(6)
398
500
  - Figure-size approach after
399
501
  [Jack Walton's guide](https://jwalton.info/Embed-Publication-Matplotlib-Latex/)