plotastro 1.0.0__tar.gz → 1.0.1__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 (54) hide show
  1. {plotastro-1.0.0 → plotastro-1.0.1}/.gitignore +3 -0
  2. plotastro-1.0.1/.readthedocs.yaml +17 -0
  3. {plotastro-1.0.0 → plotastro-1.0.1}/CHANGELOG.md +9 -0
  4. {plotastro-1.0.0 → plotastro-1.0.1}/PKG-INFO +4 -3
  5. {plotastro-1.0.0 → plotastro-1.0.1}/README.md +3 -2
  6. plotastro-1.0.1/docs/api.md +80 -0
  7. plotastro-1.0.1/docs/authors.md +78 -0
  8. plotastro-1.0.1/docs/changelog.md +2 -0
  9. plotastro-1.0.1/docs/colors.md +76 -0
  10. plotastro-1.0.1/docs/conf.py +72 -0
  11. plotastro-1.0.1/docs/faq.md +46 -0
  12. plotastro-1.0.1/docs/index.md +91 -0
  13. plotastro-1.0.1/docs/installation.md +41 -0
  14. plotastro-1.0.1/docs/journals.md +51 -0
  15. plotastro-1.0.1/docs/markers.md +73 -0
  16. plotastro-1.0.1/docs/quickstart.md +99 -0
  17. plotastro-1.0.1/docs/requirements.txt +5 -0
  18. {plotastro-1.0.0 → plotastro-1.0.1}/pyproject.toml +1 -1
  19. {plotastro-1.0.0 → plotastro-1.0.1}/.github/workflows/ci.yml +0 -0
  20. {plotastro-1.0.0 → plotastro-1.0.1}/.github/workflows/publish.yml +0 -0
  21. {plotastro-1.0.0 → plotastro-1.0.1}/LICENSE +0 -0
  22. {plotastro-1.0.0 → plotastro-1.0.1}/examples/authors_example.csv +0 -0
  23. {plotastro-1.0.0 → plotastro-1.0.1}/examples/figures/cvd_check.png +0 -0
  24. {plotastro-1.0.0 → plotastro-1.0.1}/examples/figures/example_column.png +0 -0
  25. {plotastro-1.0.0 → plotastro-1.0.1}/examples/figures/example_full.png +0 -0
  26. {plotastro-1.0.0 → plotastro-1.0.1}/examples/figures/linestyles.png +0 -0
  27. {plotastro-1.0.0 → plotastro-1.0.1}/examples/figures/markers.png +0 -0
  28. {plotastro-1.0.0 → plotastro-1.0.1}/examples/figures/palette.png +0 -0
  29. {plotastro-1.0.0 → plotastro-1.0.1}/examples/figures/palette_okabe_ito.png +0 -0
  30. {plotastro-1.0.0 → plotastro-1.0.1}/examples/figures/redundant_encoding.png +0 -0
  31. {plotastro-1.0.0 → plotastro-1.0.1}/examples/make_reference_figures.py +0 -0
  32. {plotastro-1.0.0 → plotastro-1.0.1}/examples/tutorial.ipynb +0 -0
  33. {plotastro-1.0.0 → plotastro-1.0.1}/requirements-dev.txt +0 -0
  34. {plotastro-1.0.0 → plotastro-1.0.1}/requirements.txt +0 -0
  35. {plotastro-1.0.0 → plotastro-1.0.1}/src/plotastro/__init__.py +0 -0
  36. {plotastro-1.0.0 → plotastro-1.0.1}/src/plotastro/_authors.py +0 -0
  37. {plotastro-1.0.0 → plotastro-1.0.1}/src/plotastro/_colors.py +0 -0
  38. {plotastro-1.0.0 → plotastro-1.0.1}/src/plotastro/_core.py +0 -0
  39. {plotastro-1.0.0 → plotastro-1.0.1}/src/plotastro/_extras.py +0 -0
  40. {plotastro-1.0.0 → plotastro-1.0.1}/src/plotastro/styles/aanda.mplstyle +0 -0
  41. {plotastro-1.0.0 → plotastro-1.0.1}/src/plotastro/styles/apj.mplstyle +0 -0
  42. {plotastro-1.0.0 → plotastro-1.0.1}/src/plotastro/styles/jcap.mplstyle +0 -0
  43. {plotastro-1.0.0 → plotastro-1.0.1}/src/plotastro/styles/mnras.mplstyle +0 -0
  44. {plotastro-1.0.0 → plotastro-1.0.1}/src/plotastro/styles/natastro.mplstyle +0 -0
  45. {plotastro-1.0.0 → plotastro-1.0.1}/src/plotastro/styles/oja.mplstyle +0 -0
  46. {plotastro-1.0.0 → plotastro-1.0.1}/src/plotastro/styles/prd.mplstyle +0 -0
  47. {plotastro-1.0.0 → plotastro-1.0.1}/src/plotastro/styles/rasti.mplstyle +0 -0
  48. {plotastro-1.0.0 → plotastro-1.0.1}/tests/conftest.py +0 -0
  49. {plotastro-1.0.0 → plotastro-1.0.1}/tests/test_authors.py +0 -0
  50. {plotastro-1.0.0 → plotastro-1.0.1}/tests/test_colors.py +0 -0
  51. {plotastro-1.0.0 → plotastro-1.0.1}/tests/test_extras.py +0 -0
  52. {plotastro-1.0.0 → plotastro-1.0.1}/tests/test_sizing.py +0 -0
  53. {plotastro-1.0.0 → plotastro-1.0.1}/tests/test_styles.py +0 -0
  54. {plotastro-1.0.0 → plotastro-1.0.1}/tools/generate_styles.py +0 -0
@@ -6,3 +6,6 @@ build/
6
6
  *.egg-info/
7
7
  .pytest_cache/
8
8
  .venv/
9
+ docs/_build/
10
+ docs/_figures/
11
+ docs/tutorial.ipynb
@@ -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
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.1 — 2026-09-01
4
+
5
+ ### Added
6
+ - Documentation site (Sphinx + Furo on Read the Docs) with the rendered
7
+ tutorial notebook and a full API reference:
8
+ <https://plotastro.readthedocs.io>.
9
+
10
+ No changes to the package code itself.
11
+
3
12
  ## 1.0.0 — 2026-09-01
4
13
 
5
14
  First release as an installable package, `plotastro`.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: plotastro
3
- Version: 1.0.0
3
+ Version: 1.0.1
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
@@ -66,7 +66,8 @@ pa.savefig("myplot") # -> myplot.pdf, ready for \includegraphics
66
66
  |---|---|
67
67
  | ![single-column example](examples/figures/example_column.png) | ![full-width example](examples/figures/example_full.png) |
68
68
 
69
- **Start with the [tutorial notebook](examples/tutorial.ipynb)** — it walks
69
+ **Full documentation: [plotastro.readthedocs.io](https://plotastro.readthedocs.io)** —
70
+ or start with the [tutorial notebook](examples/tutorial.ipynb), which walks
70
71
  through every feature with runnable examples.
71
72
 
72
73
  ## Why this exists
@@ -412,7 +413,7 @@ files (CI checks they stay in sync). Releases: bump the version in
412
413
  ## Credits
413
414
 
414
415
  - Original MNRAS style this grew from:
415
- [M. Knabenhans' mplstyle_for_MNRAS](https://github.com/mischakn/mplstyle_for_MNRAS)
416
+ [M. Knabenhans' mplstyle_for_MNRAS](https://github.com/miknab/mplstyle_for_MNRAS)
416
417
  - Colour-blind-friendly Set1 ordering:
417
418
  [Thøger Rivera-Thorsen](https://gist.github.com/thriveth/8560036);
418
419
  light colours from Tableau *Color Blind 10*
@@ -42,7 +42,8 @@ pa.savefig("myplot") # -> myplot.pdf, ready for \includegraphics
42
42
  |---|---|
43
43
  | ![single-column example](examples/figures/example_column.png) | ![full-width example](examples/figures/example_full.png) |
44
44
 
45
- **Start with the [tutorial notebook](examples/tutorial.ipynb)** — it walks
45
+ **Full documentation: [plotastro.readthedocs.io](https://plotastro.readthedocs.io)** —
46
+ or start with the [tutorial notebook](examples/tutorial.ipynb), which walks
46
47
  through every feature with runnable examples.
47
48
 
48
49
  ## Why this exists
@@ -388,7 +389,7 @@ files (CI checks they stay in sync). Releases: bump the version in
388
389
  ## Credits
389
390
 
390
391
  - Original MNRAS style this grew from:
391
- [M. Knabenhans' mplstyle_for_MNRAS](https://github.com/mischakn/mplstyle_for_MNRAS)
392
+ [M. Knabenhans' mplstyle_for_MNRAS](https://github.com/miknab/mplstyle_for_MNRAS)
392
393
  - Colour-blind-friendly Set1 ordering:
393
394
  [Thøger Rivera-Thorsen](https://gist.github.com/thriveth/8560036);
394
395
  light colours from Tableau *Color Blind 10*
@@ -0,0 +1,80 @@
1
+ # API reference
2
+
3
+ Everything is available at the top level:
4
+
5
+ ```python
6
+ import plotastro as pa
7
+ ```
8
+
9
+ ## Styles and sizing
10
+
11
+ ```{eval-rst}
12
+ .. autofunction:: plotastro.set_style
13
+ .. autofunction:: plotastro.figsize
14
+ .. autofunction:: plotastro.subplots
15
+ .. autofunction:: plotastro.savefig
16
+ .. autofunction:: plotastro.current_journal
17
+ ```
18
+
19
+ `pa.use(...)` is an alias of {func}`plotastro.set_style`.
20
+
21
+ ## Colours
22
+
23
+ ```{eval-rst}
24
+ .. autofunction:: plotastro.lighten
25
+ .. autofunction:: plotastro.darken
26
+ .. autofunction:: plotastro.simulate_cvd
27
+ .. autofunction:: plotastro.check_colors
28
+ .. autofunction:: plotastro.check_figure
29
+ ```
30
+
31
+ ### Palette constants
32
+
33
+ | name | contents |
34
+ |---|---|
35
+ | `pa.COLORS` | the default 12-colour colour-blind-friendly cycle, by name |
36
+ | `pa.CYCLE` | the same colours as an ordered list |
37
+ | `pa.OKABE_ITO` | Okabe & Ito (2008) 8-colour CVD-safe palette |
38
+ | `pa.PETROFF10` | Petroff (2021) 10-colour CVD-optimised palette |
39
+ | `pa.PAIRED` | light/dark pairs: `pa.PAIRED["blue"] -> (light, dark)` |
40
+
41
+ ## Markers, line styles and labels
42
+
43
+ ```{eval-rst}
44
+ .. autofunction:: plotastro.style_cycler
45
+ .. autofunction:: plotastro.label_panels
46
+ ```
47
+
48
+ | name | contents |
49
+ |---|---|
50
+ | `pa.MARKERS` | marker sequence that stays distinguishable at 4 pt |
51
+ | `pa.LINESTYLES` | named dash patterns beyond matplotlib's built-ins |
52
+
53
+ ## Reference charts
54
+
55
+ ```{eval-rst}
56
+ .. autofunction:: plotastro.show_colors
57
+ .. autofunction:: plotastro.show_markers
58
+ .. autofunction:: plotastro.show_linestyles
59
+ ```
60
+
61
+ ## Author lists
62
+
63
+ ```{eval-rst}
64
+ .. autofunction:: plotastro.authorlist
65
+ ```
66
+
67
+ The `plotastro-authors` command-line tool wraps this function; run
68
+ `plotastro-authors --help` for its options.
69
+
70
+ ## Journal data and legacy
71
+
72
+ ```{eval-rst}
73
+ .. autofunction:: plotastro.set_size
74
+ ```
75
+
76
+ | name | contents |
77
+ |---|---|
78
+ | `pa.JOURNALS` | per-journal column/full widths (LaTeX points) and metadata |
79
+ | `pa.GOLDEN` | the golden ratio (default figure aspect), ≈ 0.618 |
80
+ | `pa.STYLE_DIR` | path to the bundled `.mplstyle` files |
@@ -0,0 +1,78 @@
1
+ # Author lists from a CSV
2
+
3
+ Assembling the author/affiliation block by hand is error-prone on long
4
+ collaborations. Feed plotastro the author CSV your collaboration already
5
+ maintains — it works with real-world lists exactly as they are:
6
+
7
+ ```text
8
+ Lastname,Firstname,Authorname,Email,JoinedAsBuilder,Affiliation,ORCID,
9
+ Bandi,Behnood,Behnood Bandi, b.bandi@sussex.ac.uk, False,"Astronomy Centre, University of Sussex, Falmer, Brighton BN1 9QH, UK",0000-0001-5838-3903,
10
+ Rocher,Antoine,Antoine Rocher,antoine.rocher@epfl.ch,False,"EPFL, \'{E}cole polytechnique f\'{e}d\'{e}rale de Lausanne, Chemin des Maillettes, 51, 1290 Versoix, Switzerland",0000-0003-4349-6424,
11
+ Verdier,Aur\'{e}lien,Aur\'{e}lien Verdier,aurelien.verdier@epfl.ch,False,"EPFL, \'{E}cole polytechnique f\'{e}d\'{e}rale de Lausanne, Chemin des Maillettes, 51, 1290 Versoix, Switzerland",,
12
+ Richard,Johan,Johan Richard,johan.richard@univ-lyon1.fr,False,"CRAL, Centre de Recherche Astrophysique de Lyon, Universit\'{e} de Lyon, 9 avenue Charles Andr\'{e}, 69230 Saint-Genis-Laval, France",0000-0001-5492-1049,
13
+ Loveday,Jon ,Jon Loveday, j.loveday@sussex.ac.uk, False,"Astronomy Centre, University of Sussex, Falmer, Brighton BN1 9QH, UK",0000-0001-5290-8940,
14
+ Brown,Michael,Michael Brown,michael.brown@monash.edu,False,"Monash, School of Physics and Astronomy, Monash University, Wellington Road, Clayton, VIC 3800, Australia",0000-0002-1207-9137,
15
+ ```
16
+
17
+ ## What the reader understands
18
+
19
+ - **Names**: `Authorname` is preferred (alias `name`); if absent, the name
20
+ is built from `Firstname` + `Lastname`.
21
+ - **Affiliations**: `Affiliation`/`affiliations` — several separated by
22
+ `;`, or one row per affiliation (repeated author rows are merged).
23
+ Numbered in order of first appearance and shared between authors
24
+ automatically.
25
+ - **Optional**: `ORCID` (used where the format supports it) and `Email` —
26
+ the first author with an email becomes the corresponding author.
27
+ - **Everything else is ignored** (`JoinedAsBuilder`, ...), stray spaces
28
+ are stripped, and LaTeX already in the file (accents like `\'{e}`)
29
+ passes through untouched.
30
+
31
+ ## Generating the LaTeX
32
+
33
+ ```python
34
+ import plotastro as pa
35
+ print(pa.authorlist("authors.csv", journal="mnras"))
36
+ ```
37
+
38
+ ```latex
39
+ \author[B. Bandi et al.]{
40
+ Behnood Bandi,$^{1}$\thanks{E-mail: b.bandi@sussex.ac.uk}
41
+ Antoine Rocher,$^{2}$
42
+ Aur\'{e}lien Verdier,$^{2}$
43
+ Johan Richard,$^{3}$
44
+ Jon Loveday$^{1}$
45
+ and Michael Brown$^{4}$
46
+ \\
47
+ % List of institutions
48
+ $^{1}$Astronomy Centre, University of Sussex, Falmer, Brighton BN1 9QH, UK\\
49
+ $^{2}$EPFL, \'{E}cole polytechnique f\'{e}d\'{e}rale de Lausanne, Chemin des Maillettes, 51, 1290 Versoix, Switzerland\\
50
+ $^{3}$CRAL, Centre de Recherche Astrophysique de Lyon, Universit\'{e} de Lyon, 9 avenue Charles Andr\'{e}, 69230 Saint-Genis-Laval, France\\
51
+ $^{4}$Monash, School of Physics and Astronomy, Monash University, Wellington Road, Clayton, VIC 3800, Australia
52
+ }
53
+ ```
54
+
55
+ The same CSV works for every journal the package knows:
56
+
57
+ | `journal=` | output format |
58
+ |---|---|
59
+ | `mnras`, `rasti` | MNRAS `\author[...]{...}` block with superscripts |
60
+ | `aanda` | A&A `\inst{...}` + `\institute{...}` |
61
+ | `apj`, `oja` | AASTeX `\author[orcid]{...}` + `\affiliation`, `\correspondingauthor` |
62
+ | `prd` | REVTeX `\author` + `\email` + `\affiliation` |
63
+ | `jcap` | jcappub lettered `\affiliation[a]` + `\emailAdd` |
64
+ | `generic` | plain numbered-superscript block |
65
+
66
+ ## Command line
67
+
68
+ A CLI ships with the package, so co-authors who don't use Python can run
69
+ it too:
70
+
71
+ ```bash
72
+ plotastro-authors authors.csv --journal aanda
73
+ plotastro-authors authors.csv -j apj -o authors.tex
74
+ ```
75
+
76
+ The output is a starting point that compiles with the journal's template —
77
+ always diff it against the class file's expectations before submission
78
+ (each output starts with a reminder comment).
@@ -0,0 +1,2 @@
1
+ ```{include} ../CHANGELOG.md
2
+ ```
@@ -0,0 +1,76 @@
1
+ # Colours
2
+
3
+ ## The default palette
4
+
5
+ ```{image} _figures/palette.png
6
+ :alt: The default colour-blind-friendly cycle
7
+ :width: 85%
8
+ ```
9
+
10
+ The default cycle has 12 colours, all accessible by name via
11
+ `plotastro.COLORS` (e.g. `pa.COLORS["blue"]`), or as matplotlib's
12
+ `"C0"`…`"C11"` shorthands:
13
+
14
+ - **C0–C8** are a colour-blind-safe re-ordering of the
15
+ [ColorBrewer](https://colorbrewer2.org) *Set1* qualitative palette
16
+ (popularised by [Thøger Rivera-Thorsen's CBcycle](https://gist.github.com/thriveth/8560036)).
17
+ Consecutive colours differ in **lightness as well as hue**, so adjacent
18
+ lines stay distinguishable under the common deficiencies (deuteranopia,
19
+ protanopia) *and* in greyscale print; the notorious red–green pair is
20
+ pushed far apart in the cycle (green is C2, red is C7), so plots with a
21
+ handful of lines never rely on it.
22
+ - **C9–C11** are light companions (from Tableau's *Color Blind 10*): use
23
+ them for uncertainty bands, reference curves, or de-emphasised data
24
+ underneath a saturated line of the same hue.
25
+
26
+ ## Matched shades without transparency
27
+
28
+ Better for print and EPS than `alpha=` (no colour shifts where elements
29
+ overlap):
30
+
31
+ ```python
32
+ ax.plot(x, y, color=pa.COLORS["blue"])
33
+ ax.fill_between(x, lo, hi, color=pa.lighten(pa.COLORS["blue"], 0.7))
34
+ pa.darken(pa.COLORS["orange"], 0.3) # the other direction
35
+ ```
36
+
37
+ ## More palettes
38
+
39
+ - `pa.OKABE_ITO` — [Okabe & Ito (2008)](https://jfly.uni-koeln.de/color/),
40
+ *the* classic CVD-safe recommendation for categorical colours in science;
41
+ - `pa.PETROFF10` — [Petroff (2021)](https://arxiv.org/abs/2107.02270), the
42
+ CVD-optimised 10-colour cycle used across particle physics;
43
+ - `pa.PAIRED` — light/dark pairs for data/model or before/after
44
+ comparisons: `pa.PAIRED["blue"]` → `("#a6cee3", "#1f78b4")`.
45
+
46
+ ## Checking accessibility yourself
47
+
48
+ ```{image} _figures/cvd_check.png
49
+ :alt: The default palette under simulated colour-vision deficiencies
50
+ :width: 85%
51
+ ```
52
+
53
+ Don't take the palette's word for it — simulate it (Machado et al. 2009
54
+ model, no extra dependencies):
55
+
56
+ ```python
57
+ pa.check_colors() # any palette under deuteranopia/protanopia/greyscale
58
+ pa.check_colors(pa.PAIRED) # works on your own colour lists/dicts too
59
+ pa.check_figure(fig) # simulate a whole rendered figure — the
60
+ # final check before submission
61
+ pa.simulate_cvd("#e41a1c", "deuteranopia") # the raw transform
62
+ ```
63
+
64
+ If two lines merge in any panel, add markers or dash patterns (see
65
+ {doc}`markers`), or pick colours further apart in the cycle. MNRAS
66
+ recommends [Color Oracle](https://colororacle.org) and ColorBrewer for
67
+ exactly this; with plotastro it's built in.
68
+
69
+ ## Colormaps
70
+
71
+ The styles default to `viridis` (perceptually uniform, CVD-safe). Good
72
+ picks: `viridis`/`magma`/`cividis` for sequential data, `RdBu_r` or
73
+ `coolwarm` for diverging data (red–*blue*, not red–green). Avoid
74
+ `jet`/`rainbow`. For more astro-friendly maps see
75
+ [cmasher](https://cmasher.readthedocs.io) and
76
+ [cmocean](https://matplotlib.org/cmocean/).
@@ -0,0 +1,72 @@
1
+ """Sphinx configuration for plotastro's documentation (Read the Docs)."""
2
+
3
+ import json
4
+ import re
5
+ import shutil
6
+ from importlib.metadata import PackageNotFoundError, version as get_version
7
+ from pathlib import Path
8
+
9
+ project = "plotastro"
10
+ author = "Behnood Bandi"
11
+ copyright = "2026, Behnood Bandi"
12
+
13
+ try:
14
+ release = get_version("plotastro")
15
+ except PackageNotFoundError:
16
+ release = "1.0.0"
17
+ version = ".".join(release.split(".")[:2])
18
+
19
+ extensions = [
20
+ "myst_nb", # markdown pages + rendered notebooks
21
+ "sphinx.ext.autodoc",
22
+ "sphinx.ext.napoleon", # numpy-style docstrings
23
+ "sphinx.ext.viewcode",
24
+ "sphinx.ext.intersphinx",
25
+ "sphinx_copybutton",
26
+ ]
27
+
28
+ myst_enable_extensions = ["colon_fence", "deflist"]
29
+ myst_heading_anchors = 3
30
+
31
+ # The tutorial notebook is committed already-executed; never re-run it here.
32
+ nb_execution_mode = "off"
33
+
34
+ exclude_patterns = ["_build", "jupyter_execute", "Thumbs.db", ".DS_Store"]
35
+
36
+ # Pull the notebook and the reference figures into the docs source tree so
37
+ # the build is self-contained (works identically locally and on RTD).
38
+ _docs = Path(__file__).resolve().parent
39
+ _repo = _docs.parent
40
+ shutil.copytree(_repo / "examples" / "figures", _docs / "_figures",
41
+ dirs_exist_ok=True)
42
+
43
+ # The notebook's hand-written table of contents uses Jupyter-style anchors
44
+ # that don't exist in Sphinx (and Furo shows its own sidebar TOC), so strip
45
+ # those lines from the copy rendered here.
46
+ _nb = json.loads((_repo / "examples" / "tutorial.ipynb").read_text())
47
+ for _cell in _nb["cells"]:
48
+ if _cell["cell_type"] == "markdown":
49
+ _src = _cell["source"]
50
+ _lines = _src.splitlines(True) if isinstance(_src, str) else _src
51
+ _cell["source"] = [l for l in _lines
52
+ if not re.match(r"^\d+\.\s+\[.+\]\(#.+\)\s*$", l)]
53
+ (_docs / "tutorial.ipynb").write_text(json.dumps(_nb))
54
+
55
+ autodoc_member_order = "bysource"
56
+ autodoc_typehints = "none"
57
+ napoleon_google_docstring = False
58
+ napoleon_numpy_docstring = True
59
+
60
+ intersphinx_mapping = {
61
+ "python": ("https://docs.python.org/3", None),
62
+ "matplotlib": ("https://matplotlib.org/stable", None),
63
+ "numpy": ("https://numpy.org/doc/stable", None),
64
+ }
65
+
66
+ html_theme = "furo"
67
+ html_title = f"plotastro {release}"
68
+ html_theme_options = {
69
+ "source_repository": "https://github.com/BehnoodBandi/plotastro",
70
+ "source_branch": "master",
71
+ "source_directory": "docs/",
72
+ }
@@ -0,0 +1,46 @@
1
+ # Tweaks and FAQ
2
+
3
+ **How do I turn the grid off?**
4
+ `pa.set_style("mnras", grid=False)`, or per-axes `ax.grid(False)`.
5
+
6
+ **How do I override any other setting?**
7
+ `pa.set_style("mnras", **{"font.size": 10})`, or set
8
+ `plt.rcParams[...]` after `set_style` — the styles are ordinary
9
+ matplotlib rcParams underneath.
10
+
11
+ **I get a "Times New Roman not found" warning.**
12
+ The font list falls back through Times → Nimbus Roman → STIX → DejaVu
13
+ automatically; install `mscorefonts`/STIX to silence it, or ignore it.
14
+
15
+ **My labels are getting cut off.**
16
+ They shouldn't be — the styles enable `constrained_layout`. If you manage
17
+ layout manually (e.g. `fig.subplots_adjust`), disable it first with
18
+ `plt.rcParams["figure.constrained_layout.use"] = False`.
19
+
20
+ **What about astronomical images?**
21
+ Use `origin="lower"` in `imshow` (or uncomment `image.origin: lower` in
22
+ the style file), and `ax.grid(False)`.
23
+
24
+ **Figures look huge/small on my screen.**
25
+ That's just `figure.dpi: 150` for display; the size that lands on disk
26
+ is exact.
27
+
28
+ **Can I use the styles without any plotastro code?**
29
+ Yes — after `import plotastro` once, `plt.style.use("mnras")` works in any
30
+ code; or copy the `.mplstyle` files from `src/plotastro/styles/` into
31
+ `matplotlib.get_configdir()/stylelib/` and skip the package entirely.
32
+
33
+ **I used the original mplstyle_for_MNRAS repo — what changed?**
34
+ `plotastro.set_size(...)` reproduces the original `myfigsize.set_size()`
35
+ (including the `mnras`/`mnras_full` width names), and the old
36
+ `MNRAS_Style.mplstyle` is now `plt.style.use("mnras")`.
37
+
38
+ **A journal wants EPS and my transparency disappeared.**
39
+ EPS has no transparency support. Replace `alpha=` with
40
+ `pa.lighten(colour, amount)` shades — opaque, prints identically, and
41
+ looks the same on screen.
42
+
43
+ **Which colormap should I use?**
44
+ `viridis` (the default), `magma` or `cividis` for sequential data;
45
+ `RdBu_r`/`coolwarm` for diverging data. Avoid `jet` and `rainbow` — they
46
+ are not perceptually uniform and are hostile to colour-blind readers.
@@ -0,0 +1,91 @@
1
+ # plotastro
2
+
3
+ **Publication-quality matplotlib figures for astronomy journals.**
4
+
5
+ One `pip install` gives you journal-matched styles for **MNRAS**, **RASTI**,
6
+ **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, author lists, saving)
10
+ one-liners.
11
+
12
+ ```bash
13
+ pip install plotastro
14
+ ```
15
+
16
+ **Simplest usage — no new API to learn.** Importing plotastro registers the
17
+ styles with matplotlib itself; after one `plt.style.use` line you write
18
+ ordinary matplotlib, and the default figure size is already the journal's
19
+ column width:
20
+
21
+ ```python
22
+ import matplotlib.pyplot as plt
23
+ import plotastro # just to register the styles
24
+
25
+ plt.style.use("mnras") # or "aanda", "apj", "oja", "prd", ...
26
+ fig, ax = plt.subplots() # plain matplotlib from here on
27
+ ```
28
+
29
+ **With the helpers** (optional, but they make the tedious parts one-liners):
30
+
31
+ ```python
32
+ import plotastro as pa
33
+
34
+ pa.set_style("mnras")
35
+ fig, ax = pa.subplots() # one-column figure, golden-ratio height
36
+ ax.plot(x, y, label="model")
37
+ ax.set_xlabel("$x$")
38
+ ax.legend()
39
+ pa.savefig("myplot") # -> myplot.pdf, ready for \includegraphics
40
+ ```
41
+
42
+ ```{image} _figures/example_column.png
43
+ :alt: A single-column example figure
44
+ :width: 55%
45
+ ```
46
+
47
+ ## Why plotastro exists
48
+
49
+ Two problems ruin most paper figures:
50
+
51
+ 1. **Wrong physical size.** If you hand LaTeX a 6-inch figure and it
52
+ squeezes it into an 84 mm column, every label shrinks by ~50 % and
53
+ becomes unreadable. The fix: build the figure at its final printed
54
+ width, then include it with a plain `\includegraphics{fig.pdf}` —
55
+ no `[width=...]`.
56
+ 2. **Inaccessible colours.** ~5 % of male readers have a colour-vision
57
+ deficiency, and MNRAS's author guidelines explicitly ask for
58
+ colour-blind-friendly figures. The default matplotlib cycle is not;
59
+ the one here is — and {func}`plotastro.check_figure` lets you verify it.
60
+
61
+ The styles share one visual language — Times-like serif fonts at ~9 pt with
62
+ ~8 pt tick lettering, inward ticks on all four sides with minors, a subtle
63
+ grid, frameless legends — and differ only in figure width (plus the
64
+ sans-serif fonts Nature requires), so your plots stay **consistent between
65
+ papers** no matter where you submit.
66
+
67
+ ## Where to go next
68
+
69
+ - {doc}`installation` — install options and requirements
70
+ - {doc}`quickstart` — the five-minute version
71
+ - {doc}`tutorial` — the full hands-on notebook, rendered
72
+ - {doc}`journals` — supported journals and their figure widths
73
+ - {doc}`colors` — the palettes and colour-blindness checking
74
+ - {doc}`markers` — markers, line styles, cyclers and panel labels
75
+ - {doc}`authors` — LaTeX author lists from your collaboration's CSV
76
+ - {doc}`api` — every public function
77
+
78
+ ```{toctree}
79
+ :hidden:
80
+
81
+ installation
82
+ quickstart
83
+ tutorial
84
+ journals
85
+ colors
86
+ markers
87
+ authors
88
+ api
89
+ faq
90
+ changelog
91
+ ```
@@ -0,0 +1,41 @@
1
+ # Installation
2
+
3
+ ## From PyPI
4
+
5
+ ```bash
6
+ pip install plotastro
7
+ ```
8
+
9
+ The only hard dependency is matplotlib (≥ 3.5). plotastro works with both
10
+ NumPy 1.x and 2.x — CI tests each — and with Python 3.9+. No LaTeX
11
+ installation is required (LaTeX text rendering is optional, see
12
+ {doc}`quickstart`).
13
+
14
+ ## From a clone
15
+
16
+ ```bash
17
+ git clone https://github.com/BehnoodBandi/plotastro
18
+ cd plotastro
19
+ pip install -e ".[dev]" # editable install + test dependencies
20
+ pytest # optional: run the test suite
21
+ ```
22
+
23
+ To run the examples and notebook from a clone:
24
+
25
+ ```bash
26
+ pip install -r requirements-dev.txt
27
+ ```
28
+
29
+ ## Styles only, no package
30
+
31
+ If you just want the `.mplstyle` files, copy them from
32
+ `src/plotastro/styles/` into your matplotlib configuration directory:
33
+
34
+ ```python
35
+ import matplotlib
36
+ print(matplotlib.get_configdir()) # copy the files into <this>/stylelib/
37
+ ```
38
+
39
+ After that, `plt.style.use("mnras")` works in any script without plotastro
40
+ installed. (With the package installed, this step is unnecessary —
41
+ importing plotastro registers the styles automatically.)
@@ -0,0 +1,51 @@
1
+ # Supported journals
2
+
3
+ {func}`plotastro.set_style`, {func}`plotastro.figsize` and
4
+ `plt.style.use(...)` accept these keys (aliases in parentheses):
5
+
6
+ | key | journal | one column | full width |
7
+ |---|---|---|---|
8
+ | `mnras` | Monthly Notices of the RAS | 240.0 pt = 3.32 in | 504.0 pt = 6.97 in |
9
+ | `rasti` | RAS Techniques & Instruments | 240.0 pt = 3.32 in | 504.0 pt = 6.97 in |
10
+ | `aanda` (`a&a`, `aa`) | Astronomy & Astrophysics | 250.4 pt = 3.46 in (88 mm) | 512.2 pt = 7.09 in (180 mm) |
11
+ | `apj` (`apjl`, `aastex`) | The Astrophysical Journal | 242.3 pt = 3.35 in | 513.1 pt = 7.10 in |
12
+ | `oja` | Open Journal of Astrophysics | ≈245.3 pt = 3.39 in | ≈508 pt = 7.03 in |
13
+ | `prd` (`prl`, `revtex`) | Physical Review D | 246.0 pt = 3.40 in | 510.0 pt = 7.06 in |
14
+ | `jcap` | J. Cosmology & Astroparticle Phys. | single-column ≈455 pt = 6.30 in | — |
15
+ | `natastro` (`nature`) | Nature Astronomy (sans-serif!) | 253.2 pt = 3.50 in (89 mm) | 520.7 pt = 7.20 in (183 mm) |
16
+ | `thesis` | A4 thesis text width | 426.8 pt = 5.91 in | — |
17
+ | `beamer` | Beamer slide text width | 307.3 pt = 4.25 in | — |
18
+
19
+ Widths come from each journal's LaTeX class or author guide. All styles
20
+ share the same fonts, colours, tick and legend settings; only the figure
21
+ width differs — except Nature Astronomy, which switches to the sans-serif
22
+ fonts and smaller (5–7 pt) lettering Nature's figure guide requires.
23
+
24
+ ## Custom documents
25
+
26
+ For your own document (custom class, thesis template, ...), put
27
+ `\the\columnwidth` or `\the\textwidth` anywhere in the `.tex` body, compile,
28
+ read the value off the page, and pass it directly:
29
+
30
+ ```python
31
+ pa.figsize(width=345.0) # width in LaTeX points (1 pt = 1/72.27 in)
32
+ ```
33
+
34
+ ## Per-journal submission notes
35
+
36
+ | journal | accepted figure formats | notes |
37
+ |---|---|---|
38
+ | MNRAS / RASTI | EPS preferred, PDF/TIFF fine | ≥ 400 dpi raster, ~8 pt lettering, colour-blind friendly required |
39
+ | A&A | PDF/EPS | figures 88 mm (column) or 170–180 mm (page) wide |
40
+ | ApJ / AAS | PDF/EPS/PNG | vector strongly preferred |
41
+ | OJA | PDF (arXiv-ready) | whatever compiles on arXiv works |
42
+ | PRD / JCAP | PDF/EPS | vector preferred |
43
+ | Nature Astronomy | PDF/EPS/AI | sans-serif fonts, 5–7 pt lettering |
44
+
45
+ Official guidelines:
46
+ [MNRAS](https://academic.oup.com/mnras/pages/general_instructions) ·
47
+ [A&A](https://www.aanda.org/for-authors) ·
48
+ [AAS Journals](https://journals.aas.org/graphics-guide/) ·
49
+ [OJA](https://astro.theoj.org/site/instructions) ·
50
+ [APS](https://journals.aps.org/authors) ·
51
+ [Nature](https://www.nature.com/nature/for-authors/formatting-guide)
@@ -0,0 +1,73 @@
1
+ # Markers, line styles and panel labels
2
+
3
+ ## Markers
4
+
5
+ ```{image} _figures/markers.png
6
+ :alt: The marker reference chart
7
+ :width: 85%
8
+ ```
9
+
10
+ `plotastro.MARKERS = ["o", "s", "^", "D", "v", "p", "*", "X"]` — filled
11
+ shapes that survive shrinking to 4 pt. Conventions worth knowing:
12
+
13
+ | marker | typical use in astro figures |
14
+ |---|---|
15
+ | `"o"` `"s"` `"D"` | primary data series |
16
+ | `"^"` / `"v"` | **lower / upper limits** (readers expect this) |
17
+ | `"*"` `"p"` | highlight special objects (the Sun, a best-fit point) |
18
+ | `"x"` `"+"` | thin crosses — dense scatter plots, since they don't occlude |
19
+ | `"."` | huge point clouds (use `ms=1`–`2`, or better, rasterized hexbin) |
20
+
21
+ Useful tricks: `markevery=7` thins markers on dense curves; `mfc="none"`
22
+ (hollow markers) keeps overlapping datasets readable; `ms=` and `mew=`
23
+ control size and edge width.
24
+
25
+ ## Line styles
26
+
27
+ ```{image} _figures/linestyles.png
28
+ :alt: The named line-style reference chart
29
+ :width: 85%
30
+ ```
31
+
32
+ Beyond matplotlib's `"-"`, `"--"`, `":"`, `"-."`, the dict
33
+ `plotastro.LINESTYLES` provides named dash tuples of the form
34
+ `(offset, (on, off, ...))` in points:
35
+
36
+ ```python
37
+ ax.plot(x, y, ls=pa.LINESTYLES["long dash"]) # (0, (9, 3))
38
+ ax.plot(x, y, ls=(0, (4, 1, 1, 1))) # or roll your own
39
+ ```
40
+
41
+ Guidelines: keep to ≤ 4 distinct dash patterns per panel (more becomes
42
+ noise); use solid for data / the headline result and dashes/dots for models
43
+ and references; MNRAS explicitly warns against triple-dot-dashed lines.
44
+
45
+ ## Redundant encoding — the cycler
46
+
47
+ Colour should never be the *only* difference between curves.
48
+ {func}`plotastro.style_cycler` advances colour, marker and/or line style
49
+ **in step**, so every series is unique in two or three channels at once
50
+ (and survives greyscale printing):
51
+
52
+ ```{image} _figures/redundant_encoding.png
53
+ :alt: Lines distinguished by colour, marker and dash pattern simultaneously
54
+ :width: 55%
55
+ ```
56
+
57
+ ```python
58
+ ax.set_prop_cycle(pa.style_cycler(markers=True)) # one axes
59
+ ax.set_prop_cycle(pa.style_cycler(linestyles=True, markers=True))
60
+ plt.rc("axes", prop_cycle=pa.style_cycler(markers=True)) # everywhere
61
+ ```
62
+
63
+ ## Panel labels
64
+
65
+ Journals want multi-panel figures labelled (a), (b), (c)… —
66
+ {func}`plotastro.label_panels` does it in one line, in reading order:
67
+
68
+ ```python
69
+ fig, axes = pa.subplots(2, 2, width="full")
70
+ pa.label_panels(axes) # (a) (b) (c) (d)
71
+ pa.label_panels(axes, loc="outside", fmt="{}", fontweight="bold") # Nature style
72
+ pa.label_panels(axes, uppercase=True, loc="lower right") # (A) ... bottom-right
73
+ ```
@@ -0,0 +1,99 @@
1
+ # Quickstart
2
+
3
+ ## Two ways to use plotastro
4
+
5
+ **Plain matplotlib** — importing plotastro registers the styles with
6
+ matplotlib, so this is the entire integration:
7
+
8
+ ```python
9
+ import matplotlib.pyplot as plt
10
+ import plotastro
11
+
12
+ plt.style.use("mnras")
13
+ fig, ax = plt.subplots() # already MNRAS column-sized
14
+ ```
15
+
16
+ **With the helpers** — journal-aware sizing and saving:
17
+
18
+ ```python
19
+ import plotastro as pa
20
+
21
+ pa.set_style("mnras") # pa.use(...) is an alias
22
+ fig, ax = pa.subplots()
23
+ ax.plot(x, y, label="model")
24
+ ax.set_xlabel("$x$")
25
+ ax.legend()
26
+ pa.savefig("myplot") # -> myplot.pdf
27
+ ```
28
+
29
+ Then in LaTeX, include the figure **without any scaling** — that is the
30
+ whole point (the fonts come out exactly as designed):
31
+
32
+ ```latex
33
+ \begin{figure}
34
+ \includegraphics{myplot.pdf} % no [width=...] needed!
35
+ \caption{...}
36
+ \end{figure}
37
+ ```
38
+
39
+ ## Figure sizing
40
+
41
+ {func}`plotastro.figsize` knows the column and full text widths of each
42
+ journal (see {doc}`journals`):
43
+
44
+ ```python
45
+ pa.figsize("column") # one column, golden-ratio height
46
+ pa.figsize("full") # full text width
47
+ pa.figsize("column", fraction=0.5) # half a column
48
+ pa.figsize("column", aspect=1) # square panel (aspect = height/width)
49
+ pa.figsize("column", journal="aanda") # size for a specific journal
50
+ pa.figsize(345.0) # any width in LaTeX points
51
+ ```
52
+
53
+ {func}`plotastro.subplots` takes the same arguments *plus* everything
54
+ `plt.subplots` accepts, and scales the height with the grid so each panel
55
+ keeps its aspect:
56
+
57
+ ```python
58
+ fig, ax = pa.subplots() # 1 panel, one column
59
+ fig, axes = pa.subplots(2, 2, width="full") # 2x2 grid, full width
60
+ fig, axes = pa.subplots(1, 2, width="full", aspect=0.75, sharey=True)
61
+ ```
62
+
63
+ ## Overriding the style
64
+
65
+ ```python
66
+ pa.set_style("mnras", grid=False) # no grid
67
+ pa.set_style("mnras", **{"font.size": 10}) # any rcParam
68
+ ```
69
+
70
+ ## LaTeX text rendering
71
+
72
+ By default the styles use matplotlib's built-in *mathtext* with STIX fonts —
73
+ Times-compatible maths that works everywhere, with no LaTeX required. For
74
+ pixel-perfect agreement with your manuscript:
75
+
76
+ ```python
77
+ pa.set_style("mnras", usetex=True) # needs latex + dvipng + ghostscript
78
+ ```
79
+
80
+ This loads the `newtx` Times fonts (matching the MNRAS/A&A house font), or
81
+ Helvetica for Nature Astronomy. Develop with `usetex=False`, flip it on for
82
+ the final version — LaTeX rendering is slow.
83
+
84
+ ## Saving figures
85
+
86
+ The styles bake in submission-friendly defaults: **PDF** output, 450 dpi for
87
+ rasterised elements, tight bounding box, and TrueType font embedding
88
+ (`pdf.fonttype: 42`, so no Type-3 font rejections from submission systems).
89
+
90
+ ```python
91
+ pa.savefig("figure1") # figure1.pdf
92
+ pa.savefig("figure1", formats=("pdf", "png")) # + a PNG for slides
93
+ pa.savefig("figure1", fig=fig, dpi=600) # extra options pass through
94
+ ```
95
+
96
+ If a journal insists on EPS, note EPS has **no transparency** — replace
97
+ `alpha=` with {func}`plotastro.lighten` shades (a good habit anyway).
98
+
99
+ For the full walk-through with plots, see the {doc}`tutorial`.
@@ -0,0 +1,5 @@
1
+ # Documentation build requirements (Read the Docs installs these).
2
+ sphinx>=7,<9
3
+ furo
4
+ myst-nb>=1.1
5
+ sphinx-copybutton
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "plotastro"
7
- version = "1.0.0"
7
+ version = "1.0.1"
8
8
  description = "Publication-quality matplotlib styles and helpers for astronomy journals (MNRAS, A&A, ApJ, OJA, PRD, JCAP, Nature Astronomy)"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
File without changes
File without changes
File without changes