plotastro 1.0.1__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.
- {plotastro-1.0.1 → plotastro-1.1.0b1}/.gitignore +4 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/CHANGELOG.md +44 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/PKG-INFO +120 -16
- {plotastro-1.0.1 → plotastro-1.1.0b1}/README.md +116 -15
- {plotastro-1.0.1 → plotastro-1.1.0b1}/docs/api.md +14 -0
- plotastro-1.1.0b1/docs/colors.md +190 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/docs/faq.md +9 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/docs/index.md +7 -5
- {plotastro-1.0.1 → plotastro-1.1.0b1}/docs/installation.md +21 -1
- {plotastro-1.0.1 → plotastro-1.1.0b1}/docs/journals.md +33 -2
- {plotastro-1.0.1 → plotastro-1.1.0b1}/docs/quickstart.md +5 -0
- plotastro-1.1.0b1/examples/figures/cmasher.png +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/examples/make_reference_figures.py +27 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/examples/tutorial.ipynb +399 -120
- {plotastro-1.0.1 → plotastro-1.1.0b1}/pyproject.toml +4 -2
- {plotastro-1.0.1 → plotastro-1.1.0b1}/requirements-dev.txt +1 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/src/plotastro/__init__.py +9 -5
- {plotastro-1.0.1 → plotastro-1.1.0b1}/src/plotastro/_authors.py +1 -1
- plotastro-1.1.0b1/src/plotastro/_colors.py +481 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/src/plotastro/_core.py +53 -8
- {plotastro-1.0.1 → plotastro-1.1.0b1}/src/plotastro/styles/aanda.mplstyle +4 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/src/plotastro/styles/apj.mplstyle +4 -0
- plotastro-1.1.0b1/src/plotastro/styles/euclid.mplstyle +123 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/src/plotastro/styles/jcap.mplstyle +4 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/src/plotastro/styles/mnras.mplstyle +4 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/src/plotastro/styles/natastro.mplstyle +4 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/src/plotastro/styles/oja.mplstyle +4 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/src/plotastro/styles/prd.mplstyle +4 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/src/plotastro/styles/rasti.mplstyle +4 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/tests/test_authors.py +10 -0
- plotastro-1.1.0b1/tests/test_colors.py +180 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/tests/test_sizing.py +2 -1
- plotastro-1.1.0b1/tests/test_styles.py +144 -0
- plotastro-1.1.0b1/tools/generate_styles.py +357 -0
- plotastro-1.0.1/docs/colors.md +0 -76
- plotastro-1.0.1/src/plotastro/_colors.py +0 -227
- plotastro-1.0.1/tests/test_colors.py +0 -64
- plotastro-1.0.1/tests/test_styles.py +0 -69
- plotastro-1.0.1/tools/generate_styles.py +0 -202
- {plotastro-1.0.1 → plotastro-1.1.0b1}/.github/workflows/ci.yml +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/.github/workflows/publish.yml +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/.readthedocs.yaml +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/LICENSE +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/docs/authors.md +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/docs/changelog.md +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/docs/conf.py +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/docs/markers.md +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/docs/requirements.txt +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/examples/authors_example.csv +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/examples/figures/cvd_check.png +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/examples/figures/example_column.png +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/examples/figures/example_full.png +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/examples/figures/linestyles.png +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/examples/figures/markers.png +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/examples/figures/palette.png +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/examples/figures/palette_okabe_ito.png +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/examples/figures/redundant_encoding.png +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/requirements.txt +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/src/plotastro/_extras.py +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/tests/conftest.py +0 -0
- {plotastro-1.0.1 → plotastro-1.1.0b1}/tests/test_extras.py +0 -0
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
# Changelog
|
|
2
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
|
+
|
|
3
47
|
## 1.0.1 — 2026-09-01
|
|
4
48
|
|
|
5
49
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: plotastro
|
|
3
|
-
Version: 1.
|
|
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
|
+
[](https://pypi.org/project/plotastro/)
|
|
31
|
+
[](https://pypi.org/project/plotastro/)
|
|
32
|
+
[](https://github.com/BehnoodBandi/plotastro/actions/workflows/ci.yml)
|
|
33
|
+
[](https://plotastro.readthedocs.io)
|
|
34
|
+
[](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
|
|
32
|
-
size, a colour-blind-friendly palette, and
|
|
33
|
-
parts (sizing, panel labels, accessibility
|
|
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
|
|
@@ -88,7 +98,9 @@ The styles share one visual language — Times-like serif fonts at ~9 pt with
|
|
|
88
98
|
~8 pt tick lettering, inward ticks on all four sides with minors, a subtle
|
|
89
99
|
grid, frameless legends — and differ only in figure width (plus the
|
|
90
100
|
sans-serif fonts Nature requires), so your plots stay **consistent between
|
|
91
|
-
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).
|
|
92
104
|
|
|
93
105
|
## Supported journals
|
|
94
106
|
|
|
@@ -105,6 +117,7 @@ papers** no matter where you submit.
|
|
|
105
117
|
| `prd` (`prl`, `revtex`) | Physical Review D | 246.0 pt = 3.40 in | 510.0 pt = 7.06 in |
|
|
106
118
|
| `jcap` | J. Cosmology & Astroparticle Phys. | single-column ≈455 pt = 6.30 in | — |
|
|
107
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) |
|
|
108
121
|
| `thesis` | A4 thesis text width | 426.8 pt = 5.91 in | — |
|
|
109
122
|
| `beamer` | Beamer slide text width | 307.3 pt = 4.25 in | — |
|
|
110
123
|
|
|
@@ -113,8 +126,37 @@ document, put `\the\columnwidth` or `\the\textwidth` in your `.tex` body,
|
|
|
113
126
|
compile, read the value off the page, and pass it directly:
|
|
114
127
|
`pa.figsize(width=345.0)`.
|
|
115
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
|
+
|
|
116
156
|
The only hard dependency is matplotlib; plotastro works with both NumPy 1.x
|
|
117
|
-
and 2.x (CI tests each).
|
|
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?
|
|
118
160
|
`pip install -r requirements-dev.txt`.
|
|
119
161
|
|
|
120
162
|
## Tutorial
|
|
@@ -166,20 +208,71 @@ ax.fill_between(x, lo, hi, color=pa.lighten(pa.COLORS["blue"], 0.7))
|
|
|
166
208
|
pa.darken(pa.COLORS["orange"], 0.3) # the other direction
|
|
167
209
|
```
|
|
168
210
|
|
|
169
|
-
|
|
211
|
+
More palettes ship with the package:
|
|
170
212
|
|
|
171
213
|
- `pa.OKABE_ITO` — [Okabe & Ito (2008)](https://jfly.uni-koeln.de/color/),
|
|
172
214
|
*the* classic CVD-safe recommendation for categorical colours in science;
|
|
173
215
|
- `pa.PETROFF10` — [Petroff (2021)](https://arxiv.org/abs/2107.02270), the
|
|
174
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;
|
|
175
222
|
- `pa.PAIRED` — light/dark pairs for data/model or before/after comparisons:
|
|
176
223
|
`pa.PAIRED["blue"]` → `("#a6cee3", "#1f78b4")`.
|
|
177
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
|
+
|
|
178
238
|
**Colormaps:** the styles default to `viridis` (perceptually uniform,
|
|
179
239
|
CVD-safe). Good picks: `viridis`/`magma`/`cividis` for sequential data,
|
|
180
240
|
`RdBu_r` or `coolwarm` for diverging data (red–*blue*, not red–green). Avoid
|
|
181
|
-
`jet`/`rainbow`.
|
|
182
|
-
|
|
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
|
+

|
|
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()`).
|
|
183
276
|
|
|
184
277
|
### Checking accessibility yourself
|
|
185
278
|
|
|
@@ -271,9 +364,10 @@ your manuscript (custom macros, real kerning):
|
|
|
271
364
|
pa.set_style("mnras", usetex=True) # needs latex + dvipng + ghostscript
|
|
272
365
|
```
|
|
273
366
|
|
|
274
|
-
This loads the `newtx` Times fonts (matching the MNRAS/A&A house font),
|
|
275
|
-
Helvetica for Nature Astronomy
|
|
276
|
-
|
|
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.
|
|
277
371
|
|
|
278
372
|
### Saving figures
|
|
279
373
|
|
|
@@ -355,14 +449,16 @@ complete example.
|
|
|
355
449
|
|
|
356
450
|
| | |
|
|
357
451
|
|---|---|
|
|
358
|
-
| `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`) |
|
|
359
453
|
| `authorlist(csv, journal=)` | LaTeX author/affiliation block from a CSV (CLI: `plotastro-authors`) |
|
|
360
454
|
| `figsize(width, journal=, fraction=, aspect=, ...)` | journal-correct figure dimensions |
|
|
361
455
|
| `subplots(...)` | `plt.subplots` with the size computed for you |
|
|
362
456
|
| `savefig(name, formats=("pdf",))` | save one figure in several formats |
|
|
363
457
|
| `label_panels(axes, ...)` | (a), (b), (c) panel labels |
|
|
364
458
|
| `style_cycler(markers=, linestyles=)` | redundant-encoding property cycle |
|
|
365
|
-
| `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) |
|
|
366
462
|
| `lighten(c, f)`, `darken(c, f)` | matched shades without transparency |
|
|
367
463
|
| `simulate_cvd`, `check_colors`, `check_figure` | colour-vision-deficiency checks |
|
|
368
464
|
| `MARKERS`, `LINESTYLES` | curated marker / dash-pattern sequences |
|
|
@@ -403,7 +499,7 @@ python tools/generate_styles.py # regenerate styles/ after editing the templ
|
|
|
403
499
|
python examples/make_reference_figures.py # regenerate README figures
|
|
404
500
|
```
|
|
405
501
|
|
|
406
|
-
The `.mplstyle` files are generated from
|
|
502
|
+
The `.mplstyle` files are generated from the templates in
|
|
407
503
|
[tools/generate_styles.py](tools/generate_styles.py) — edit that, not the
|
|
408
504
|
files (CI checks they stay in sync). Releases: bump the version in
|
|
409
505
|
`pyproject.toml` and `CHANGELOG.md`, then push a `v*` tag — the
|
|
@@ -418,7 +514,15 @@ files (CI checks they stay in sync). Releases: bump the version in
|
|
|
418
514
|
[Thøger Rivera-Thorsen](https://gist.github.com/thriveth/8560036);
|
|
419
515
|
light colours from Tableau *Color Blind 10*
|
|
420
516
|
- Palettes: [Okabe & Ito](https://jfly.uni-koeln.de/color/),
|
|
421
|
-
[Petroff (2021)](https://arxiv.org/abs/2107.02270),
|
|
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
|
|
422
526
|
- CVD model: Machado, Oliveira & Fernandes (2009), IEEE TVCG 15(6)
|
|
423
527
|
- Figure-size approach after
|
|
424
528
|
[Jack Walton's guide](https://jwalton.info/Embed-Publication-Matplotlib-Latex/)
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
# plotastro
|
|
2
2
|
|
|
3
|
+
[](https://pypi.org/project/plotastro/)
|
|
4
|
+
[](https://pypi.org/project/plotastro/)
|
|
5
|
+
[](https://github.com/BehnoodBandi/plotastro/actions/workflows/ci.yml)
|
|
6
|
+
[](https://plotastro.readthedocs.io)
|
|
7
|
+
[](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
|
|
8
|
-
size, a colour-blind-friendly palette, and
|
|
9
|
-
parts (sizing, panel labels, accessibility
|
|
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
|
|
@@ -64,7 +71,9 @@ The styles share one visual language — Times-like serif fonts at ~9 pt with
|
|
|
64
71
|
~8 pt tick lettering, inward ticks on all four sides with minors, a subtle
|
|
65
72
|
grid, frameless legends — and differ only in figure width (plus the
|
|
66
73
|
sans-serif fonts Nature requires), so your plots stay **consistent between
|
|
67
|
-
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).
|
|
68
77
|
|
|
69
78
|
## Supported journals
|
|
70
79
|
|
|
@@ -81,6 +90,7 @@ papers** no matter where you submit.
|
|
|
81
90
|
| `prd` (`prl`, `revtex`) | Physical Review D | 246.0 pt = 3.40 in | 510.0 pt = 7.06 in |
|
|
82
91
|
| `jcap` | J. Cosmology & Astroparticle Phys. | single-column ≈455 pt = 6.30 in | — |
|
|
83
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) |
|
|
84
94
|
| `thesis` | A4 thesis text width | 426.8 pt = 5.91 in | — |
|
|
85
95
|
| `beamer` | Beamer slide text width | 307.3 pt = 4.25 in | — |
|
|
86
96
|
|
|
@@ -89,8 +99,37 @@ document, put `\the\columnwidth` or `\the\textwidth` in your `.tex` body,
|
|
|
89
99
|
compile, read the value off the page, and pass it directly:
|
|
90
100
|
`pa.figsize(width=345.0)`.
|
|
91
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
|
+
|
|
92
129
|
The only hard dependency is matplotlib; plotastro works with both NumPy 1.x
|
|
93
|
-
and 2.x (CI tests each).
|
|
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?
|
|
94
133
|
`pip install -r requirements-dev.txt`.
|
|
95
134
|
|
|
96
135
|
## Tutorial
|
|
@@ -142,20 +181,71 @@ ax.fill_between(x, lo, hi, color=pa.lighten(pa.COLORS["blue"], 0.7))
|
|
|
142
181
|
pa.darken(pa.COLORS["orange"], 0.3) # the other direction
|
|
143
182
|
```
|
|
144
183
|
|
|
145
|
-
|
|
184
|
+
More palettes ship with the package:
|
|
146
185
|
|
|
147
186
|
- `pa.OKABE_ITO` — [Okabe & Ito (2008)](https://jfly.uni-koeln.de/color/),
|
|
148
187
|
*the* classic CVD-safe recommendation for categorical colours in science;
|
|
149
188
|
- `pa.PETROFF10` — [Petroff (2021)](https://arxiv.org/abs/2107.02270), the
|
|
150
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;
|
|
151
195
|
- `pa.PAIRED` — light/dark pairs for data/model or before/after comparisons:
|
|
152
196
|
`pa.PAIRED["blue"]` → `("#a6cee3", "#1f78b4")`.
|
|
153
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
|
+
|
|
154
211
|
**Colormaps:** the styles default to `viridis` (perceptually uniform,
|
|
155
212
|
CVD-safe). Good picks: `viridis`/`magma`/`cividis` for sequential data,
|
|
156
213
|
`RdBu_r` or `coolwarm` for diverging data (red–*blue*, not red–green). Avoid
|
|
157
|
-
`jet`/`rainbow`.
|
|
158
|
-
|
|
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
|
+

|
|
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()`).
|
|
159
249
|
|
|
160
250
|
### Checking accessibility yourself
|
|
161
251
|
|
|
@@ -247,9 +337,10 @@ your manuscript (custom macros, real kerning):
|
|
|
247
337
|
pa.set_style("mnras", usetex=True) # needs latex + dvipng + ghostscript
|
|
248
338
|
```
|
|
249
339
|
|
|
250
|
-
This loads the `newtx` Times fonts (matching the MNRAS/A&A house font),
|
|
251
|
-
Helvetica for Nature Astronomy
|
|
252
|
-
|
|
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.
|
|
253
344
|
|
|
254
345
|
### Saving figures
|
|
255
346
|
|
|
@@ -331,14 +422,16 @@ complete example.
|
|
|
331
422
|
|
|
332
423
|
| | |
|
|
333
424
|
|---|---|
|
|
334
|
-
| `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`) |
|
|
335
426
|
| `authorlist(csv, journal=)` | LaTeX author/affiliation block from a CSV (CLI: `plotastro-authors`) |
|
|
336
427
|
| `figsize(width, journal=, fraction=, aspect=, ...)` | journal-correct figure dimensions |
|
|
337
428
|
| `subplots(...)` | `plt.subplots` with the size computed for you |
|
|
338
429
|
| `savefig(name, formats=("pdf",))` | save one figure in several formats |
|
|
339
430
|
| `label_panels(axes, ...)` | (a), (b), (c) panel labels |
|
|
340
431
|
| `style_cycler(markers=, linestyles=)` | redundant-encoding property cycle |
|
|
341
|
-
| `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) |
|
|
342
435
|
| `lighten(c, f)`, `darken(c, f)` | matched shades without transparency |
|
|
343
436
|
| `simulate_cvd`, `check_colors`, `check_figure` | colour-vision-deficiency checks |
|
|
344
437
|
| `MARKERS`, `LINESTYLES` | curated marker / dash-pattern sequences |
|
|
@@ -379,7 +472,7 @@ python tools/generate_styles.py # regenerate styles/ after editing the templ
|
|
|
379
472
|
python examples/make_reference_figures.py # regenerate README figures
|
|
380
473
|
```
|
|
381
474
|
|
|
382
|
-
The `.mplstyle` files are generated from
|
|
475
|
+
The `.mplstyle` files are generated from the templates in
|
|
383
476
|
[tools/generate_styles.py](tools/generate_styles.py) — edit that, not the
|
|
384
477
|
files (CI checks they stay in sync). Releases: bump the version in
|
|
385
478
|
`pyproject.toml` and `CHANGELOG.md`, then push a `v*` tag — the
|
|
@@ -394,7 +487,15 @@ files (CI checks they stay in sync). Releases: bump the version in
|
|
|
394
487
|
[Thøger Rivera-Thorsen](https://gist.github.com/thriveth/8560036);
|
|
395
488
|
light colours from Tableau *Color Blind 10*
|
|
396
489
|
- Palettes: [Okabe & Ito](https://jfly.uni-koeln.de/color/),
|
|
397
|
-
[Petroff (2021)](https://arxiv.org/abs/2107.02270),
|
|
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
|
|
398
499
|
- CVD model: Machado, Oliveira & Fernandes (2009), IEEE TVCG 15(6)
|
|
399
500
|
- Figure-size approach after
|
|
400
501
|
[Jack Walton's guide](https://jwalton.info/Embed-Publication-Matplotlib-Latex/)
|
|
@@ -26,6 +26,18 @@ import plotastro as pa
|
|
|
26
26
|
.. autofunction:: plotastro.simulate_cvd
|
|
27
27
|
.. autofunction:: plotastro.check_colors
|
|
28
28
|
.. autofunction:: plotastro.check_figure
|
|
29
|
+
.. autofunction:: plotastro.euclid_colors
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### CMasher (optional)
|
|
33
|
+
|
|
34
|
+
These need the optional `cmasher` package (`pip install cmasher`); see
|
|
35
|
+
{doc}`colors`. `set_style(palette="cmr.<name>", cmap="cmr.<name>")` uses
|
|
36
|
+
them too.
|
|
37
|
+
|
|
38
|
+
```{eval-rst}
|
|
39
|
+
.. autofunction:: plotastro.cmasher_colors
|
|
40
|
+
.. autofunction:: plotastro.cmasher_cmap
|
|
29
41
|
```
|
|
30
42
|
|
|
31
43
|
### Palette constants
|
|
@@ -36,6 +48,8 @@ import plotastro as pa
|
|
|
36
48
|
| `pa.CYCLE` | the same colours as an ordered list |
|
|
37
49
|
| `pa.OKABE_ITO` | Okabe & Ito (2008) 8-colour CVD-safe palette |
|
|
38
50
|
| `pa.PETROFF10` | Petroff (2021) 10-colour CVD-optimised palette |
|
|
51
|
+
| `pa.PETROFF8` | Petroff (2021) 8-colour palette — the Euclid niceplots default |
|
|
52
|
+
| `pa.TOL_VIBRANT` | Paul Tol's *vibrant* 7-colour CVD-safe scheme |
|
|
39
53
|
| `pa.PAIRED` | light/dark pairs: `pa.PAIRED["blue"] -> (light, dark)` |
|
|
40
54
|
|
|
41
55
|
## Markers, line styles and labels
|