plotlet 0.1.0__tar.gz → 0.1.3__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.
- {plotlet-0.1.0/src/plotlet.egg-info → plotlet-0.1.3}/PKG-INFO +48 -9
- {plotlet-0.1.0 → plotlet-0.1.3}/README.md +47 -8
- {plotlet-0.1.0 → plotlet-0.1.3}/pyproject.toml +1 -1
- {plotlet-0.1.0 → plotlet-0.1.3}/src/plotlet/__init__.py +8 -2
- plotlet-0.1.3/src/plotlet/_cm_data.py +189 -0
- plotlet-0.1.3/src/plotlet/_png.py +38 -0
- {plotlet-0.1.0 → plotlet-0.1.3}/src/plotlet/_spec.py +2 -0
- plotlet-0.1.3/src/plotlet/artists.py +314 -0
- plotlet-0.1.3/src/plotlet/builtin_artists.py +254 -0
- plotlet-0.1.3/src/plotlet/chart.py +337 -0
- plotlet-0.1.3/src/plotlet/colormaps.py +50 -0
- plotlet-0.1.3/src/plotlet/core.py +581 -0
- plotlet-0.1.3/src/plotlet/layout.py +530 -0
- plotlet-0.1.3/src/plotlet/legend.py +349 -0
- plotlet-0.1.3/src/plotlet/registry.py +74 -0
- {plotlet-0.1.0 → plotlet-0.1.3}/src/plotlet/scales.py +14 -7
- {plotlet-0.1.0 → plotlet-0.1.3}/src/plotlet/spec.json +20 -4
- {plotlet-0.1.0 → plotlet-0.1.3/src/plotlet.egg-info}/PKG-INFO +48 -9
- {plotlet-0.1.0 → plotlet-0.1.3}/src/plotlet.egg-info/SOURCES.txt +10 -1
- plotlet-0.1.3/tests/test_chart.py +279 -0
- plotlet-0.1.3/tests/test_legend.py +131 -0
- plotlet-0.1.3/tests/test_subplots.py +306 -0
- plotlet-0.1.0/src/plotlet/artists.py +0 -154
- plotlet-0.1.0/src/plotlet/chart.py +0 -150
- plotlet-0.1.0/src/plotlet/core.py +0 -336
- plotlet-0.1.0/tests/test_chart.py +0 -109
- {plotlet-0.1.0 → plotlet-0.1.3}/LICENSE +0 -0
- {plotlet-0.1.0 → plotlet-0.1.3}/setup.cfg +0 -0
- {plotlet-0.1.0 → plotlet-0.1.3}/src/plotlet/colors.py +0 -0
- {plotlet-0.1.0 → plotlet-0.1.3}/src/plotlet/font.py +0 -0
- {plotlet-0.1.0 → plotlet-0.1.3}/src/plotlet/fonts/DejaVuSans.ttf +0 -0
- {plotlet-0.1.0 → plotlet-0.1.3}/src/plotlet.egg-info/dependency_links.txt +0 -0
- {plotlet-0.1.0 → plotlet-0.1.3}/src/plotlet.egg-info/requires.txt +0 -0
- {plotlet-0.1.0 → plotlet-0.1.3}/src/plotlet.egg-info/top_level.txt +0 -0
- {plotlet-0.1.0 → plotlet-0.1.3}/tests/test_old.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plotlet
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Small, hackable Python library that emits matplotlib-style SVG plots.
|
|
5
5
|
Author: gitbamboo42
|
|
6
6
|
License-Expression: MIT
|
|
@@ -33,7 +33,7 @@ A small, hackable Python library that emits matplotlib-style SVG plots.
|
|
|
33
33
|
|
|
34
34
|
## Why
|
|
35
35
|
|
|
36
|
-
matplotlib is the right tool when you want the kitchen sink. plotlet's niche is **custom plot types** — genome tracks, Manhattan plots, phylogenetic trees, anything matplotlib's extension API makes painful. The whole library
|
|
36
|
+
matplotlib is the right tool when you want the kitchen sink. plotlet's niche is **custom plot types** — genome tracks, Manhattan plots, phylogenetic trees, anything matplotlib's extension API makes painful. The whole library has a deliberately tiny, exposed core: adding a new plot type is a 3-step recipe, not an architecture project.
|
|
37
37
|
|
|
38
38
|
It's a **scaffold, not a feature catalog**: the core ships ~5 standard plots and the infrastructure for extending. Custom plot types live in your own project (or [`cookbook/`](cookbook/)), not upstream. See [docs/PHILOSOPHY.md](docs/PHILOSOPHY.md) for the full framing.
|
|
39
39
|
|
|
@@ -53,12 +53,8 @@ c # auto-renders in Jupyter
|
|
|
53
53
|
|
|
54
54
|
## Install
|
|
55
55
|
|
|
56
|
-
Not on PyPI yet — clone and install editable:
|
|
57
|
-
|
|
58
56
|
```bash
|
|
59
|
-
|
|
60
|
-
cd plotlet
|
|
61
|
-
pip install -e .
|
|
57
|
+
pip install plotlet
|
|
62
58
|
```
|
|
63
59
|
|
|
64
60
|
## Properties
|
|
@@ -68,6 +64,7 @@ pip install -e .
|
|
|
68
64
|
- **Cross-machine reproducible.** Bundled DejaVu Sans + text-as-paths means rendering is identical on Linux, macOS, Windows, headless CI.
|
|
69
65
|
- **Jupyter-native.** `Figure._repr_html_` auto-renders the last expression in a cell.
|
|
70
66
|
- **Tiny output.** Each plot is ~50 KB SVG, self-contained.
|
|
67
|
+
- **Compositional.** Multi-panel layouts via `|`, `/`, `pt.grid`; share scales with `share_x=` / `share_y=`; layout-level legend with `pt.legend()` covering both discrete swatches and continuous gradients (the colorbar).
|
|
71
68
|
|
|
72
69
|
## API
|
|
73
70
|
|
|
@@ -77,7 +74,11 @@ pip install -e .
|
|
|
77
74
|
|
|
78
75
|
Pass at construction (`pt.chart(data, title=..., grid=True, ...)`) or as chained setters (`c.title(...)`, etc.):
|
|
79
76
|
|
|
80
|
-
`title`, `xlabel`, `ylabel`, `xlim=(a, b)`, `ylim=(a, b)`, `xscale="log"|"
|
|
77
|
+
`title`, `xlabel`, `ylabel`, `xlim=(a, b)`, `ylim=(a, b)`, `xscale="linear"|"log"|"category"` (chained: `c.xscale("category", order=[...], padding=0)`), `yscale=...`, `grid=True/False`, `legend=True/False`, `width`, `height`
|
|
78
|
+
|
|
79
|
+
String-valued data on either axis (`scatter(["a","b","c"], ...)`, `bar`, …) auto-switches to a categorical scale, alphabetical by default. `padding=0` makes category bands contiguous (heatmap-track look).
|
|
80
|
+
|
|
81
|
+
Tick customization: `c.xticks([0, 5, 10], ["A","B","C"], rotation=45, fontsize=12, direction="out", marks=False)`. Pass `[]` to hide. `yticks(...)` works the same way.
|
|
81
82
|
|
|
82
83
|
### Mark methods
|
|
83
84
|
|
|
@@ -88,8 +89,45 @@ Pass at construction (`pt.chart(data, title=..., grid=True, ...)`) or as chained
|
|
|
88
89
|
| `.bar(x=, y=, **opts)` | `color`, `label`, `alpha` |
|
|
89
90
|
| `.hist(x=, **opts)` | `bins`, `color`, `alpha`, `label` |
|
|
90
91
|
| `.fill_between(x=, y1=, y2=, **opts)` | `color`, `alpha`, `label` |
|
|
92
|
+
| `.axhline(y, **opts)` / `.axvline(x, **opts)` | `color`, `linewidth`, `linestyle`, `alpha`, `label`, axes-fraction `xmin`/`xmax` (or `ymin`/`ymax`) |
|
|
93
|
+
| `.axhspan(ymin, ymax, **opts)` / `.axvspan(xmin, xmax, **opts)` | `color`, `alpha`, `label`, axes-fraction `xmin`/`xmax` (or `ymin`/`ymax`) |
|
|
94
|
+
| `.imshow(data, **opts)` | `cmap` (any matplotlib name, default `"viridis"`), `vmin`, `vmax`, `extent=(left, right, bottom, top)` |
|
|
95
|
+
|
|
96
|
+
`hue=<col>` (on `.line` / `.scatter`) splits into one call per unique value with auto-labels and tab10 colors. Reference lines and spans default to black; spans use `alpha=0.2`. They're drawn outside the data color cycle and don't participate in autoscaling — they're decorations on the frame, not data.
|
|
97
|
+
|
|
98
|
+
`.imshow(data)` renders a 2-D array as a colored grid. Small grids (`nrows × ncols ≤ 10000`) emit one `<rect>` per cell and stay vector-clean at any zoom; larger grids encode as a single base64 PNG and quantize to 256 levels. Image row 0 is rendered at the top of its rectangle; the y axis stays Cartesian (small at bottom). All ~180 matplotlib colormaps are vendored — see `pt.list_colormaps()`.
|
|
99
|
+
|
|
100
|
+
### Subplots
|
|
101
|
+
|
|
102
|
+
Compose multi-panel layouts with operators on `Chart`:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
a | b # side-by-side
|
|
106
|
+
a / b # stacked
|
|
107
|
+
a | b | c # left-fold flatten — one row of three, not nested
|
|
108
|
+
|
|
109
|
+
pt.grid([[a, b], # 2-D grid; cells may be `None`
|
|
110
|
+
[c, d]])
|
|
111
|
+
|
|
112
|
+
# Share x or y across panels — collapses the gap between them
|
|
113
|
+
# and forces both onto the source's scale.
|
|
114
|
+
top = pt.chart()
|
|
115
|
+
main = pt.chart(share_x=top)
|
|
116
|
+
top / main # vertically stacked, x-axis joined
|
|
117
|
+
|
|
118
|
+
# Layout-level legend (covers colorbar and discrete swatches in
|
|
119
|
+
# one constructor — geometry follows from the source's color mapping).
|
|
120
|
+
hm = pt.chart(); hm.imshow(matrix, cmap="viridis")
|
|
121
|
+
hm | pt.legend(hm) # heatmap + colorbar (gradient strip)
|
|
122
|
+
|
|
123
|
+
# Multi-source: groups by chart, using each chart's title as
|
|
124
|
+
# section header. `names={chart: "Override"}` renames a header,
|
|
125
|
+
# `names={chart: None}` hides it, `group_by_chart=False` flattens.
|
|
126
|
+
(hm | top) | pt.legend() # auto-collects from siblings
|
|
127
|
+
parent = a | b; parent.legend() # sugar for parent | pt.legend()
|
|
128
|
+
```
|
|
91
129
|
|
|
92
|
-
`
|
|
130
|
+
A composed chart owns its children; render the parent (`(a | b).show()` or `.to_svg()` / `.save_svg(...)`). Calling `.show()` on a child raises. See [`docs/SUBPLOTS.md`](docs/SUBPLOTS.md) for the design rationale.
|
|
93
131
|
|
|
94
132
|
### Render / save
|
|
95
133
|
|
|
@@ -117,6 +155,7 @@ plotlet's central hackability claim: a custom plot type is a 3-step recipe (~50
|
|
|
117
155
|
python tests/test_chart.py # check vs. committed baselines
|
|
118
156
|
python tests/test_chart.py --update # regenerate (review the diff!)
|
|
119
157
|
python tests/test_chart.py --gallery # build tests/baseline_images/chart/index.html
|
|
158
|
+
python tests/test_subplots.py # subplot baselines + composition invariants
|
|
120
159
|
```
|
|
121
160
|
|
|
122
161
|
## Non-goals
|
|
@@ -4,7 +4,7 @@ A small, hackable Python library that emits matplotlib-style SVG plots.
|
|
|
4
4
|
|
|
5
5
|
## Why
|
|
6
6
|
|
|
7
|
-
matplotlib is the right tool when you want the kitchen sink. plotlet's niche is **custom plot types** — genome tracks, Manhattan plots, phylogenetic trees, anything matplotlib's extension API makes painful. The whole library
|
|
7
|
+
matplotlib is the right tool when you want the kitchen sink. plotlet's niche is **custom plot types** — genome tracks, Manhattan plots, phylogenetic trees, anything matplotlib's extension API makes painful. The whole library has a deliberately tiny, exposed core: adding a new plot type is a 3-step recipe, not an architecture project.
|
|
8
8
|
|
|
9
9
|
It's a **scaffold, not a feature catalog**: the core ships ~5 standard plots and the infrastructure for extending. Custom plot types live in your own project (or [`cookbook/`](cookbook/)), not upstream. See [docs/PHILOSOPHY.md](docs/PHILOSOPHY.md) for the full framing.
|
|
10
10
|
|
|
@@ -24,12 +24,8 @@ c # auto-renders in Jupyter
|
|
|
24
24
|
|
|
25
25
|
## Install
|
|
26
26
|
|
|
27
|
-
Not on PyPI yet — clone and install editable:
|
|
28
|
-
|
|
29
27
|
```bash
|
|
30
|
-
|
|
31
|
-
cd plotlet
|
|
32
|
-
pip install -e .
|
|
28
|
+
pip install plotlet
|
|
33
29
|
```
|
|
34
30
|
|
|
35
31
|
## Properties
|
|
@@ -39,6 +35,7 @@ pip install -e .
|
|
|
39
35
|
- **Cross-machine reproducible.** Bundled DejaVu Sans + text-as-paths means rendering is identical on Linux, macOS, Windows, headless CI.
|
|
40
36
|
- **Jupyter-native.** `Figure._repr_html_` auto-renders the last expression in a cell.
|
|
41
37
|
- **Tiny output.** Each plot is ~50 KB SVG, self-contained.
|
|
38
|
+
- **Compositional.** Multi-panel layouts via `|`, `/`, `pt.grid`; share scales with `share_x=` / `share_y=`; layout-level legend with `pt.legend()` covering both discrete swatches and continuous gradients (the colorbar).
|
|
42
39
|
|
|
43
40
|
## API
|
|
44
41
|
|
|
@@ -48,7 +45,11 @@ pip install -e .
|
|
|
48
45
|
|
|
49
46
|
Pass at construction (`pt.chart(data, title=..., grid=True, ...)`) or as chained setters (`c.title(...)`, etc.):
|
|
50
47
|
|
|
51
|
-
`title`, `xlabel`, `ylabel`, `xlim=(a, b)`, `ylim=(a, b)`, `xscale="log"|"
|
|
48
|
+
`title`, `xlabel`, `ylabel`, `xlim=(a, b)`, `ylim=(a, b)`, `xscale="linear"|"log"|"category"` (chained: `c.xscale("category", order=[...], padding=0)`), `yscale=...`, `grid=True/False`, `legend=True/False`, `width`, `height`
|
|
49
|
+
|
|
50
|
+
String-valued data on either axis (`scatter(["a","b","c"], ...)`, `bar`, …) auto-switches to a categorical scale, alphabetical by default. `padding=0` makes category bands contiguous (heatmap-track look).
|
|
51
|
+
|
|
52
|
+
Tick customization: `c.xticks([0, 5, 10], ["A","B","C"], rotation=45, fontsize=12, direction="out", marks=False)`. Pass `[]` to hide. `yticks(...)` works the same way.
|
|
52
53
|
|
|
53
54
|
### Mark methods
|
|
54
55
|
|
|
@@ -59,8 +60,45 @@ Pass at construction (`pt.chart(data, title=..., grid=True, ...)`) or as chained
|
|
|
59
60
|
| `.bar(x=, y=, **opts)` | `color`, `label`, `alpha` |
|
|
60
61
|
| `.hist(x=, **opts)` | `bins`, `color`, `alpha`, `label` |
|
|
61
62
|
| `.fill_between(x=, y1=, y2=, **opts)` | `color`, `alpha`, `label` |
|
|
63
|
+
| `.axhline(y, **opts)` / `.axvline(x, **opts)` | `color`, `linewidth`, `linestyle`, `alpha`, `label`, axes-fraction `xmin`/`xmax` (or `ymin`/`ymax`) |
|
|
64
|
+
| `.axhspan(ymin, ymax, **opts)` / `.axvspan(xmin, xmax, **opts)` | `color`, `alpha`, `label`, axes-fraction `xmin`/`xmax` (or `ymin`/`ymax`) |
|
|
65
|
+
| `.imshow(data, **opts)` | `cmap` (any matplotlib name, default `"viridis"`), `vmin`, `vmax`, `extent=(left, right, bottom, top)` |
|
|
66
|
+
|
|
67
|
+
`hue=<col>` (on `.line` / `.scatter`) splits into one call per unique value with auto-labels and tab10 colors. Reference lines and spans default to black; spans use `alpha=0.2`. They're drawn outside the data color cycle and don't participate in autoscaling — they're decorations on the frame, not data.
|
|
68
|
+
|
|
69
|
+
`.imshow(data)` renders a 2-D array as a colored grid. Small grids (`nrows × ncols ≤ 10000`) emit one `<rect>` per cell and stay vector-clean at any zoom; larger grids encode as a single base64 PNG and quantize to 256 levels. Image row 0 is rendered at the top of its rectangle; the y axis stays Cartesian (small at bottom). All ~180 matplotlib colormaps are vendored — see `pt.list_colormaps()`.
|
|
70
|
+
|
|
71
|
+
### Subplots
|
|
72
|
+
|
|
73
|
+
Compose multi-panel layouts with operators on `Chart`:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
a | b # side-by-side
|
|
77
|
+
a / b # stacked
|
|
78
|
+
a | b | c # left-fold flatten — one row of three, not nested
|
|
79
|
+
|
|
80
|
+
pt.grid([[a, b], # 2-D grid; cells may be `None`
|
|
81
|
+
[c, d]])
|
|
82
|
+
|
|
83
|
+
# Share x or y across panels — collapses the gap between them
|
|
84
|
+
# and forces both onto the source's scale.
|
|
85
|
+
top = pt.chart()
|
|
86
|
+
main = pt.chart(share_x=top)
|
|
87
|
+
top / main # vertically stacked, x-axis joined
|
|
88
|
+
|
|
89
|
+
# Layout-level legend (covers colorbar and discrete swatches in
|
|
90
|
+
# one constructor — geometry follows from the source's color mapping).
|
|
91
|
+
hm = pt.chart(); hm.imshow(matrix, cmap="viridis")
|
|
92
|
+
hm | pt.legend(hm) # heatmap + colorbar (gradient strip)
|
|
93
|
+
|
|
94
|
+
# Multi-source: groups by chart, using each chart's title as
|
|
95
|
+
# section header. `names={chart: "Override"}` renames a header,
|
|
96
|
+
# `names={chart: None}` hides it, `group_by_chart=False` flattens.
|
|
97
|
+
(hm | top) | pt.legend() # auto-collects from siblings
|
|
98
|
+
parent = a | b; parent.legend() # sugar for parent | pt.legend()
|
|
99
|
+
```
|
|
62
100
|
|
|
63
|
-
`
|
|
101
|
+
A composed chart owns its children; render the parent (`(a | b).show()` or `.to_svg()` / `.save_svg(...)`). Calling `.show()` on a child raises. See [`docs/SUBPLOTS.md`](docs/SUBPLOTS.md) for the design rationale.
|
|
64
102
|
|
|
65
103
|
### Render / save
|
|
66
104
|
|
|
@@ -88,6 +126,7 @@ plotlet's central hackability claim: a custom plot type is a 3-step recipe (~50
|
|
|
88
126
|
python tests/test_chart.py # check vs. committed baselines
|
|
89
127
|
python tests/test_chart.py --update # regenerate (review the diff!)
|
|
90
128
|
python tests/test_chart.py --gallery # build tests/baseline_images/chart/index.html
|
|
129
|
+
python tests/test_subplots.py # subplot baselines + composition invariants
|
|
91
130
|
```
|
|
92
131
|
|
|
93
132
|
## Non-goals
|
|
@@ -16,8 +16,14 @@ Chained API (legacy, still supported):
|
|
|
16
16
|
"""
|
|
17
17
|
from ._spec import SPEC
|
|
18
18
|
from .colors import TAB10, colors
|
|
19
|
+
from .colormaps import colormap, list_colormaps
|
|
19
20
|
from .core import Figure, figure
|
|
20
21
|
from .chart import Chart, chart
|
|
22
|
+
from .layout import grid
|
|
23
|
+
from .legend import legend
|
|
24
|
+
from .registry import ArtistSpec, add_artist
|
|
21
25
|
|
|
22
|
-
__all__ = ["chart", "Chart", "figure", "Figure", "SPEC", "TAB10", "colors"
|
|
23
|
-
|
|
26
|
+
__all__ = ["chart", "Chart", "figure", "Figure", "SPEC", "TAB10", "colors",
|
|
27
|
+
"colormap", "list_colormaps", "grid", "legend",
|
|
28
|
+
"ArtistSpec", "add_artist"]
|
|
29
|
+
__version__ = "0.1.3"
|