cplots 0.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 (35) hide show
  1. cplots-0.0.1/PKG-INFO +148 -0
  2. cplots-0.0.1/README.md +115 -0
  3. cplots-0.0.1/pyproject.toml +48 -0
  4. cplots-0.0.1/src/cplots/__init__.py +85 -0
  5. cplots-0.0.1/src/cplots/backends/__init__.py +4 -0
  6. cplots-0.0.1/src/cplots/backends/_base.py +36 -0
  7. cplots-0.0.1/src/cplots/backends/altair.py +296 -0
  8. cplots-0.0.1/src/cplots/backends/matplotlib.py +233 -0
  9. cplots-0.0.1/src/cplots/backends/plotly.py +404 -0
  10. cplots-0.0.1/src/cplots/backends/ultraplot.py +84 -0
  11. cplots-0.0.1/src/cplots/config.py +29 -0
  12. cplots-0.0.1/src/cplots/core/__init__.py +43 -0
  13. cplots-0.0.1/src/cplots/core/base.py +96 -0
  14. cplots-0.0.1/src/cplots/core/data.py +49 -0
  15. cplots-0.0.1/src/cplots/core/incremental.py +182 -0
  16. cplots-0.0.1/src/cplots/core/labels.py +66 -0
  17. cplots-0.0.1/src/cplots/core/protocols.py +79 -0
  18. cplots-0.0.1/src/cplots/core/registry.py +86 -0
  19. cplots-0.0.1/src/cplots/core/spec.py +129 -0
  20. cplots-0.0.1/src/cplots/core/theme.py +59 -0
  21. cplots-0.0.1/src/cplots/data/__init__.py +3 -0
  22. cplots-0.0.1/src/cplots/data/_getdist.py +26 -0
  23. cplots-0.0.1/src/cplots/data/_pandas.py +29 -0
  24. cplots-0.0.1/src/cplots/data/_polars.py +29 -0
  25. cplots-0.0.1/src/cplots/data/_xarray.py +29 -0
  26. cplots-0.0.1/src/cplots/data/adapters.py +33 -0
  27. cplots-0.0.1/src/cplots/figure.py +213 -0
  28. cplots-0.0.1/src/cplots/plots/__init__.py +17 -0
  29. cplots-0.0.1/src/cplots/plots/background.py +78 -0
  30. cplots-0.0.1/src/cplots/plots/power_spectrum.py +113 -0
  31. cplots-0.0.1/src/cplots/plots/triangle.py +85 -0
  32. cplots-0.0.1/src/cplots/plots/xy.py +97 -0
  33. cplots-0.0.1/src/cplots/plots/xyz_colored.py +126 -0
  34. cplots-0.0.1/src/cplots/plots/xyz_colored_grid.py +142 -0
  35. cplots-0.0.1/src/cplots/py.typed +0 -0
cplots-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,148 @@
1
+ Metadata-Version: 2.3
2
+ Name: cplots
3
+ Version: 0.0.1
4
+ Summary: C-Plots: A unified plotting library for Cosmology.
5
+ Author: Rodrigo Calderon
6
+ Author-email: Rodrigo Calderon <calderon.cosmoly@gmail.com>
7
+ Requires-Dist: cplots[matplotlib,plotly,altair,getdist,pandas,polars] ; extra == 'all'
8
+ Requires-Dist: altair>=5.0 ; extra == 'altair'
9
+ Requires-Dist: pytest>=8.0 ; extra == 'dev'
10
+ Requires-Dist: mypy>=1.10 ; extra == 'dev'
11
+ Requires-Dist: ruff>=0.4 ; extra == 'dev'
12
+ Requires-Dist: mkdocs-material>=9.5 ; extra == 'docs'
13
+ Requires-Dist: mkdocstrings[python]>=0.25 ; extra == 'docs'
14
+ Requires-Dist: mkdocs-marimo>=0.2.1 ; extra == 'docs'
15
+ Requires-Dist: getdist>=1.4 ; extra == 'getdist'
16
+ Requires-Dist: matplotlib>=3.7 ; extra == 'matplotlib'
17
+ Requires-Dist: pandas>=1.5 ; extra == 'pandas'
18
+ Requires-Dist: plotly>=5.0 ; extra == 'plotly'
19
+ Requires-Dist: polars>=0.20 ; extra == 'polars'
20
+ Requires-Dist: ultraplot>=0.1 ; extra == 'ultraplot'
21
+ Requires-Python: >=3.10
22
+ Provides-Extra: all
23
+ Provides-Extra: altair
24
+ Provides-Extra: dev
25
+ Provides-Extra: docs
26
+ Provides-Extra: getdist
27
+ Provides-Extra: matplotlib
28
+ Provides-Extra: pandas
29
+ Provides-Extra: plotly
30
+ Provides-Extra: polars
31
+ Provides-Extra: ultraplot
32
+ Description-Content-Type: text/markdown
33
+
34
+ <p align="center">
35
+ <img src="docs/assets/logo-wordmark.svg" width="65%" alt="cplots">
36
+ </p>
37
+
38
+ <p align="center">
39
+ <strong>A backend-agnostic cosmological plotting library.</strong><br>
40
+ Write your analysis once; render with <code>matplotlib</code>, <code>plotly</code>, or <code>altair</code> — no lock-in.
41
+ </p>
42
+
43
+ <p align="center">
44
+ <a href="https://pypi.org/project/cplots/"><img src="https://img.shields.io/pypi/v/cplots.svg?color=blue" alt="PyPI version"></a>
45
+ <a href="https://pypi.org/project/cplots/"><img src="https://img.shields.io/pypi/pyversions/cplots.svg" alt="Python versions"></a>
46
+ <a href="https://rcalderonb6.github.io/cplots/"><img src="https://img.shields.io/badge/docs-rcalderonb6.github.io%2Fcplots-blue" alt="Docs"></a>
47
+ <a href="https://github.com/rcalderonb6/cplots/actions/workflows/docs.yml"><img src="https://github.com/rcalderonb6/cplots/actions/workflows/docs.yml/badge.svg" alt="Deploy docs"></a>
48
+ </p>
49
+
50
+ ---
51
+
52
+ ## How it works
53
+
54
+ Every plot flows through three clean layers:
55
+
56
+ ```
57
+ Raw arrays / DataFrames / xarray Datasets
58
+
59
+ PlotData immutable input containers
60
+
61
+ PlotSpec backend-agnostic IR — the decoupling boundary
62
+
63
+ Backend matplotlib · plotly · altair
64
+ ```
65
+
66
+ Plot subclasses never import backends. Backends never import plot subclasses.
67
+ Swap the backend at call time, via a context manager, or globally — the plot code stays unchanged.
68
+
69
+ ---
70
+
71
+ ## Features
72
+
73
+ - **Six plot types** — `XYPlot`, `PKSpectrum`, `ClSpectrum`, `BackgroundEvolution`, `TrianglePlot`, `XYZColored`
74
+ - **Three backends** — publication PNG via **matplotlib**, interactive HTML via **plotly**, Vega-Lite JSON via **altair**
75
+ - **Multi-panel figures** — compose plots into grids with colspan/rowspan, shared axes, and custom ratios
76
+ - **LaTeX labels** — pass raw LaTeX strings through to plotly's MathJax renderer
77
+ - **Pluggable adapters** — accepts NumPy arrays, pandas DataFrames, xarray Datasets, and GetDist `MCSamples`
78
+ - **Zero lock-in** — third-party backends and adapters register via `pyproject.toml` entry points
79
+
80
+ ---
81
+
82
+ ## Quick example
83
+
84
+ ```python
85
+ import numpy as np
86
+ import cplots
87
+
88
+ k = np.logspace(-3, 0, 200)
89
+ pk = k ** -1.5
90
+
91
+ # Display with default backend (matplotlib)
92
+ cplots.PKSpectrum(k, pk, label="z=0").show()
93
+
94
+ # Interactive HTML with LaTeX labels
95
+ cplots.PKSpectrum(
96
+ k, pk,
97
+ x_label=r"$k\;[h\,\mathrm{Mpc}^{-1}]$",
98
+ y_label=r"$P(k)\;[h^{-3}\,\mathrm{Mpc}^3]$",
99
+ latex_labels=True,
100
+ ).save("pk.html", backend="plotly")
101
+
102
+ # Multi-panel figure
103
+ z = np.linspace(0, 3)
104
+ Hz = 67.34 * np.sqrt(0.3 * (1 + z)**3 + 0.7)
105
+
106
+ fig = cplots.Figure.grid([
107
+ [cplots.PKSpectrum(k, pk), cplots.BackgroundEvolution(z, {"H": Hz})],
108
+ ])
109
+ fig.show()
110
+ ```
111
+
112
+ ### Switching backends
113
+
114
+ ```python
115
+ # Per call
116
+ plot.show(backend="plotly")
117
+
118
+ # Context manager
119
+ with cplots.backend("altair"):
120
+ plot.show()
121
+
122
+ # Global default
123
+ cplots.set_backend("plotly")
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Installation
129
+
130
+ ```bash
131
+ pip install cplots[matplotlib] # matplotlib only
132
+ pip install cplots[matplotlib,plotly] # two backends
133
+ pip install cplots[all] # all backends + getdist
134
+ ```
135
+
136
+ **Development install:**
137
+
138
+ ```bash
139
+ git clone https://github.com/rcalderonb6/cplots
140
+ pip install -e ".[matplotlib,dev]"
141
+ ```
142
+
143
+ ---
144
+
145
+ ## Documentation
146
+
147
+ Full documentation, including the API reference, user guide, and interactive examples, is available at
148
+ [rcalderonb6.github.io/cplots](https://rcalderonb6.github.io/cplots/).
cplots-0.0.1/README.md ADDED
@@ -0,0 +1,115 @@
1
+ <p align="center">
2
+ <img src="docs/assets/logo-wordmark.svg" width="65%" alt="cplots">
3
+ </p>
4
+
5
+ <p align="center">
6
+ <strong>A backend-agnostic cosmological plotting library.</strong><br>
7
+ Write your analysis once; render with <code>matplotlib</code>, <code>plotly</code>, or <code>altair</code> — no lock-in.
8
+ </p>
9
+
10
+ <p align="center">
11
+ <a href="https://pypi.org/project/cplots/"><img src="https://img.shields.io/pypi/v/cplots.svg?color=blue" alt="PyPI version"></a>
12
+ <a href="https://pypi.org/project/cplots/"><img src="https://img.shields.io/pypi/pyversions/cplots.svg" alt="Python versions"></a>
13
+ <a href="https://rcalderonb6.github.io/cplots/"><img src="https://img.shields.io/badge/docs-rcalderonb6.github.io%2Fcplots-blue" alt="Docs"></a>
14
+ <a href="https://github.com/rcalderonb6/cplots/actions/workflows/docs.yml"><img src="https://github.com/rcalderonb6/cplots/actions/workflows/docs.yml/badge.svg" alt="Deploy docs"></a>
15
+ </p>
16
+
17
+ ---
18
+
19
+ ## How it works
20
+
21
+ Every plot flows through three clean layers:
22
+
23
+ ```
24
+ Raw arrays / DataFrames / xarray Datasets
25
+
26
+ PlotData immutable input containers
27
+
28
+ PlotSpec backend-agnostic IR — the decoupling boundary
29
+
30
+ Backend matplotlib · plotly · altair
31
+ ```
32
+
33
+ Plot subclasses never import backends. Backends never import plot subclasses.
34
+ Swap the backend at call time, via a context manager, or globally — the plot code stays unchanged.
35
+
36
+ ---
37
+
38
+ ## Features
39
+
40
+ - **Six plot types** — `XYPlot`, `PKSpectrum`, `ClSpectrum`, `BackgroundEvolution`, `TrianglePlot`, `XYZColored`
41
+ - **Three backends** — publication PNG via **matplotlib**, interactive HTML via **plotly**, Vega-Lite JSON via **altair**
42
+ - **Multi-panel figures** — compose plots into grids with colspan/rowspan, shared axes, and custom ratios
43
+ - **LaTeX labels** — pass raw LaTeX strings through to plotly's MathJax renderer
44
+ - **Pluggable adapters** — accepts NumPy arrays, pandas DataFrames, xarray Datasets, and GetDist `MCSamples`
45
+ - **Zero lock-in** — third-party backends and adapters register via `pyproject.toml` entry points
46
+
47
+ ---
48
+
49
+ ## Quick example
50
+
51
+ ```python
52
+ import numpy as np
53
+ import cplots
54
+
55
+ k = np.logspace(-3, 0, 200)
56
+ pk = k ** -1.5
57
+
58
+ # Display with default backend (matplotlib)
59
+ cplots.PKSpectrum(k, pk, label="z=0").show()
60
+
61
+ # Interactive HTML with LaTeX labels
62
+ cplots.PKSpectrum(
63
+ k, pk,
64
+ x_label=r"$k\;[h\,\mathrm{Mpc}^{-1}]$",
65
+ y_label=r"$P(k)\;[h^{-3}\,\mathrm{Mpc}^3]$",
66
+ latex_labels=True,
67
+ ).save("pk.html", backend="plotly")
68
+
69
+ # Multi-panel figure
70
+ z = np.linspace(0, 3)
71
+ Hz = 67.34 * np.sqrt(0.3 * (1 + z)**3 + 0.7)
72
+
73
+ fig = cplots.Figure.grid([
74
+ [cplots.PKSpectrum(k, pk), cplots.BackgroundEvolution(z, {"H": Hz})],
75
+ ])
76
+ fig.show()
77
+ ```
78
+
79
+ ### Switching backends
80
+
81
+ ```python
82
+ # Per call
83
+ plot.show(backend="plotly")
84
+
85
+ # Context manager
86
+ with cplots.backend("altair"):
87
+ plot.show()
88
+
89
+ # Global default
90
+ cplots.set_backend("plotly")
91
+ ```
92
+
93
+ ---
94
+
95
+ ## Installation
96
+
97
+ ```bash
98
+ pip install cplots[matplotlib] # matplotlib only
99
+ pip install cplots[matplotlib,plotly] # two backends
100
+ pip install cplots[all] # all backends + getdist
101
+ ```
102
+
103
+ **Development install:**
104
+
105
+ ```bash
106
+ git clone https://github.com/rcalderonb6/cplots
107
+ pip install -e ".[matplotlib,dev]"
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Documentation
113
+
114
+ Full documentation, including the API reference, user guide, and interactive examples, is available at
115
+ [rcalderonb6.github.io/cplots](https://rcalderonb6.github.io/cplots/).
@@ -0,0 +1,48 @@
1
+ [project]
2
+ name = "cplots"
3
+ version = "0.0.1"
4
+ description = "C-Plots: A unified plotting library for Cosmology."
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "Rodrigo Calderon", email = "calderon.cosmoly@gmail.com" }
8
+ ]
9
+ requires-python = ">=3.10"
10
+ dependencies = []
11
+
12
+ [project.optional-dependencies]
13
+ matplotlib = ["matplotlib>=3.7"]
14
+ plotly = ["plotly>=5.0"]
15
+ altair = ["altair>=5.0"]
16
+ ultraplot = ["ultraplot>=0.1"]
17
+ getdist = ["getdist>=1.4"]
18
+ pandas = ["pandas>=1.5"]
19
+ polars = ["polars>=0.20"]
20
+ dev = ["pytest>=8.0", "mypy>=1.10", "ruff>=0.4"]
21
+ docs = ["mkdocs-material>=9.5", "mkdocstrings[python]>=0.25","mkdocs-marimo>=0.2.1"]
22
+ all = ["cplots[matplotlib,plotly,altair,getdist,pandas,polars]"]
23
+
24
+ [project.entry-points."cplots.backends"]
25
+ matplotlib = "cplots.backends.matplotlib:MatplotlibBackend"
26
+ plotly = "cplots.backends.plotly:PlotlyBackend"
27
+ altair = "cplots.backends.altair:AltairBackend"
28
+ ultraplot = "cplots.backends.ultraplot:UltraplotBackend"
29
+
30
+ [build-system]
31
+ requires = ["uv_build>=0.9.9,<0.10.0"]
32
+ build-backend = "uv_build"
33
+
34
+ [tool.ruff]
35
+ target-version = "py310"
36
+ line-length = 100
37
+ exclude = ["notebooks/"]
38
+
39
+ [tool.ruff.lint]
40
+ select = ["E", "F", "I", "UP"]
41
+
42
+ [tool.mypy]
43
+ python_version = "3.10"
44
+ strict = true
45
+
46
+ [tool.pytest.ini_options]
47
+ testpaths = ["tests"]
48
+
@@ -0,0 +1,85 @@
1
+ """cplots: a backend-agnostic cosmological plotting library.
2
+
3
+ Three-layer architecture:
4
+ PlotData (immutable input) → PlotSpec IR → Backend (renders native figure)
5
+
6
+ Backends (matplotlib, plotly, altair) are selected per call, via context
7
+ manager, or globally. Third-party backends register via entry points.
8
+
9
+ Example:
10
+ >>> import numpy as np
11
+ >>> import cplots
12
+ >>> k = np.logspace(-3, 0, 200)
13
+ >>> pk = k ** -1.5
14
+ >>> cplots.PKSpectrum(k, pk, label="P(k)").show()
15
+ """
16
+
17
+ # Trigger backend registration by importing the backends package.
18
+ import cplots.backends # noqa: E402, F401
19
+ from cplots.config import backend, resolve_backend, set_backend
20
+ from cplots.core.base import Plot
21
+ from cplots.core.data import (
22
+ BackgroundData,
23
+ ClData,
24
+ PKData,
25
+ PlotData,
26
+ TriangleData,
27
+ XYData,
28
+ XYZData,
29
+ )
30
+ from cplots.core.incremental import (
31
+ build_incrementally,
32
+ incremental,
33
+ labeled_prefixes,
34
+ sequence_prefixes,
35
+ )
36
+ from cplots.core.protocols import BackendProtocol
37
+ from cplots.core.registry import get_backend, register_backend
38
+ from cplots.core.spec import FigureSpec, PanelSpec, PlotSpec, Trace
39
+ from cplots.core.theme import DARK, PUBLICATION, ThemeSpec
40
+ from cplots.data.adapters import to_plot_data
41
+ from cplots.figure import Figure
42
+ from cplots.plots.background import BackgroundEvolution
43
+ from cplots.plots.power_spectrum import ClSpectrum, PKSpectrum, PowerSpectrumBase
44
+ from cplots.plots.triangle import TrianglePlot
45
+ from cplots.plots.xy import XYPlot
46
+ from cplots.plots.xyz_colored import XYZColored
47
+ from cplots.plots.xyz_colored_grid import XYZColoredGrid
48
+
49
+ __all__ = [
50
+ "DARK",
51
+ "Figure",
52
+ "FigureSpec",
53
+ "PanelSpec",
54
+ "PUBLICATION",
55
+ "BackendProtocol",
56
+ "BackgroundData",
57
+ "BackgroundEvolution",
58
+ "ClData",
59
+ "ClSpectrum",
60
+ "PKData",
61
+ "PKSpectrum",
62
+ "Plot",
63
+ "PlotData",
64
+ "PlotSpec",
65
+ "PowerSpectrumBase",
66
+ "ThemeSpec",
67
+ "Trace",
68
+ "TriangleData",
69
+ "TrianglePlot",
70
+ "XYData",
71
+ "XYPlot",
72
+ "XYZColored",
73
+ "XYZColoredGrid",
74
+ "XYZData",
75
+ "backend",
76
+ "build_incrementally",
77
+ "get_backend",
78
+ "incremental",
79
+ "labeled_prefixes",
80
+ "register_backend",
81
+ "resolve_backend",
82
+ "sequence_prefixes",
83
+ "set_backend",
84
+ "to_plot_data",
85
+ ]
@@ -0,0 +1,4 @@
1
+ from cplots.backends._base import BaseBackend
2
+ from cplots.backends.matplotlib import MatplotlibBackend
3
+
4
+ __all__ = ["BaseBackend", "MatplotlibBackend"]
@@ -0,0 +1,36 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+
6
+ class BaseBackend:
7
+ """Optional base class for backends that want automatic registration.
8
+
9
+ Subclass with the ``name`` keyword to self-register on class creation::
10
+
11
+ class MyBackend(BaseBackend, name="mybackend"):
12
+ def render(self, spec): ...
13
+ ...
14
+
15
+ The ``name`` keyword triggers :func:`~cplots.core.registry.register_backend`
16
+ at class-definition time so no manual registration call is required.
17
+ """
18
+
19
+ def __init_subclass__(cls, name: str | None = None, **kw: Any) -> None:
20
+ super().__init_subclass__(**kw)
21
+ if name is not None:
22
+ from cplots.core.registry import register_backend
23
+
24
+ register_backend(name, cls())
25
+
26
+ def render_figure(self, spec: Any) -> Any:
27
+ """Render a multi-panel FigureSpec.
28
+
29
+ Raises:
30
+ NotImplementedError: Subclasses that support multi-panel layouts
31
+ must override this method.
32
+ """
33
+ raise NotImplementedError(
34
+ f"{type(self).__name__} does not implement render_figure(). "
35
+ "Multi-panel layouts require a backend that supports FigureSpec."
36
+ )