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.
- cplots-0.0.1/PKG-INFO +148 -0
- cplots-0.0.1/README.md +115 -0
- cplots-0.0.1/pyproject.toml +48 -0
- cplots-0.0.1/src/cplots/__init__.py +85 -0
- cplots-0.0.1/src/cplots/backends/__init__.py +4 -0
- cplots-0.0.1/src/cplots/backends/_base.py +36 -0
- cplots-0.0.1/src/cplots/backends/altair.py +296 -0
- cplots-0.0.1/src/cplots/backends/matplotlib.py +233 -0
- cplots-0.0.1/src/cplots/backends/plotly.py +404 -0
- cplots-0.0.1/src/cplots/backends/ultraplot.py +84 -0
- cplots-0.0.1/src/cplots/config.py +29 -0
- cplots-0.0.1/src/cplots/core/__init__.py +43 -0
- cplots-0.0.1/src/cplots/core/base.py +96 -0
- cplots-0.0.1/src/cplots/core/data.py +49 -0
- cplots-0.0.1/src/cplots/core/incremental.py +182 -0
- cplots-0.0.1/src/cplots/core/labels.py +66 -0
- cplots-0.0.1/src/cplots/core/protocols.py +79 -0
- cplots-0.0.1/src/cplots/core/registry.py +86 -0
- cplots-0.0.1/src/cplots/core/spec.py +129 -0
- cplots-0.0.1/src/cplots/core/theme.py +59 -0
- cplots-0.0.1/src/cplots/data/__init__.py +3 -0
- cplots-0.0.1/src/cplots/data/_getdist.py +26 -0
- cplots-0.0.1/src/cplots/data/_pandas.py +29 -0
- cplots-0.0.1/src/cplots/data/_polars.py +29 -0
- cplots-0.0.1/src/cplots/data/_xarray.py +29 -0
- cplots-0.0.1/src/cplots/data/adapters.py +33 -0
- cplots-0.0.1/src/cplots/figure.py +213 -0
- cplots-0.0.1/src/cplots/plots/__init__.py +17 -0
- cplots-0.0.1/src/cplots/plots/background.py +78 -0
- cplots-0.0.1/src/cplots/plots/power_spectrum.py +113 -0
- cplots-0.0.1/src/cplots/plots/triangle.py +85 -0
- cplots-0.0.1/src/cplots/plots/xy.py +97 -0
- cplots-0.0.1/src/cplots/plots/xyz_colored.py +126 -0
- cplots-0.0.1/src/cplots/plots/xyz_colored_grid.py +142 -0
- 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,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
|
+
)
|