plotlet 0.3.0__tar.gz → 0.4.0__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.3.0/src/plotlet.egg-info → plotlet-0.4.0}/PKG-INFO +15 -11
- {plotlet-0.3.0 → plotlet-0.4.0}/README.md +12 -9
- {plotlet-0.3.0 → plotlet-0.4.0}/pyproject.toml +3 -2
- plotlet-0.4.0/src/plotlet/artists.py +503 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/builtin_artists.py +230 -16
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/chart.py +207 -52
- plotlet-0.4.0/src/plotlet/colormaps.py +113 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/core.py +175 -91
- plotlet-0.4.0/src/plotlet/dendrogram.py +197 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/layout.py +120 -59
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/layout_diagram.py +5 -3
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/legend.py +19 -11
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/registry.py +16 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/spec.json +13 -4
- {plotlet-0.3.0 → plotlet-0.4.0/src/plotlet.egg-info}/PKG-INFO +15 -11
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet.egg-info/SOURCES.txt +1 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet.egg-info/requires.txt +1 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/tests/test_chart.py +241 -9
- {plotlet-0.3.0 → plotlet-0.4.0}/tests/test_legend.py +20 -17
- {plotlet-0.3.0 → plotlet-0.4.0}/tests/test_subplots.py +83 -63
- {plotlet-0.3.0 → plotlet-0.4.0}/tests/test_units.py +35 -16
- plotlet-0.3.0/src/plotlet/artists.py +0 -314
- plotlet-0.3.0/src/plotlet/colormaps.py +0 -50
- {plotlet-0.3.0 → plotlet-0.4.0}/LICENSE +0 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/setup.cfg +0 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/__init__.py +0 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/_cm_data.py +0 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/_png.py +0 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/_spec.py +0 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/colors.py +0 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/font.py +0 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/fonts/DejaVuSans.ttf +0 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet/scales.py +0 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet.egg-info/dependency_links.txt +0 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/src/plotlet.egg-info/top_level.txt +0 -0
- {plotlet-0.3.0 → plotlet-0.4.0}/tests/test_layout_diagram.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plotlet
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Python library for SVG plots, with multi-panel composition and an extension API for custom plot types.
|
|
5
5
|
Author: gitbamboo42
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/gitbamboo42/plotlet
|
|
@@ -22,6 +22,7 @@ Requires-Python: >=3.10
|
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
|
24
24
|
Requires-Dist: fonttools>=4.0
|
|
25
|
+
Requires-Dist: scipy>=1.10
|
|
25
26
|
Provides-Extra: dev
|
|
26
27
|
Requires-Dist: jupyter; extra == "dev"
|
|
27
28
|
Requires-Dist: nbconvert; extra == "dev"
|
|
@@ -29,13 +30,13 @@ Dynamic: license-file
|
|
|
29
30
|
|
|
30
31
|
# plotlet
|
|
31
32
|
|
|
32
|
-
A
|
|
33
|
+
A Python library for SVG plots — with multi-panel composition, shared-axis layouts, and an extension API for custom plot types.
|
|
33
34
|
|
|
34
|
-
##
|
|
35
|
+
## What it's for
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
plotlet is built for **multi-panel scientific figures with custom plot types** — genome tracks, spike rasters, climate stacks, Manhattan plots, phylogenetic trees. The core ships ~5 standard plots plus multi-panel composition (`|`, `/`, `share_x()`).
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
Custom plot types are a 3-step recipe (`record`, `xdomain`/`ydomain`, `draw`) and live in your own project (or [`cookbook/`](cookbook/)) rather than upstream. See [docs/PHILOSOPHY.md](docs/PHILOSOPHY.md) for the full framing.
|
|
39
40
|
|
|
40
41
|
```python
|
|
41
42
|
import plotlet as pt
|
|
@@ -59,11 +60,11 @@ pip install plotlet
|
|
|
59
60
|
|
|
60
61
|
## Properties
|
|
61
62
|
|
|
62
|
-
- **
|
|
63
|
+
- **Minimal dependencies.** `fonttools` for font handling. numpy / pandas / polars inputs work transparently if you have them.
|
|
63
64
|
- **Static SVG output.** No interactivity, no animation. Same script → byte-identical SVG.
|
|
64
65
|
- **Cross-machine reproducible.** Bundled DejaVu Sans + text-as-paths means rendering is identical on Linux, macOS, Windows, headless CI.
|
|
65
66
|
- **Jupyter-native.** `Chart._repr_html_` auto-renders the last expression in a cell.
|
|
66
|
-
- **
|
|
67
|
+
- **Compact output.** Each plot is ~50 KB SVG, self-contained.
|
|
67
68
|
- **Compositional.** Multi-panel layouts via `|`, `/`, `pt.grid`; share scales with `(a | b).share_x()` or `pt.grid(..., share_x="col")`; layout-level legend with `pt.legend()` covering both discrete swatches and continuous gradients (the colorbar).
|
|
68
69
|
- **AI-readable.** Every figure ships `data-plotlet-*` attributes describing plot type, axes, scales, ranges, and series labels — readable in one XML parse, no glyph-path OCR. Schema: [docs/AI_ATTRS.md](docs/AI_ATTRS.md).
|
|
69
70
|
|
|
@@ -75,7 +76,7 @@ pip install plotlet
|
|
|
75
76
|
|
|
76
77
|
Pass at construction (`pt.chart(data, title=..., grid=True, ...)`) or as chained setters (`c.title(...)`, etc.):
|
|
77
78
|
|
|
78
|
-
`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`, `data_width`, `data_height` (the data region —
|
|
79
|
+
`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`, `data_width`, `data_height` (the data region — the figure canvas grows to fit titles, tick labels, and axis labels). Sizes accept bare pixels (`400`) or unit-suffixed strings (`"4in"`, `"10cm"`, `"100mm"`, `"72pt"`). To fit a composition into a target SVG canvas, chain `.fit(canvas_width=…, canvas_height=…)` after composing — it rescales data regions while keeping fonts, spines, and margins at their absolute pixel sizes.
|
|
79
80
|
|
|
80
81
|
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).
|
|
81
82
|
|
|
@@ -93,11 +94,14 @@ Tick customization: `c.xticks([0, 5, 10], ["A","B","C"], rotation=45, fontsize=1
|
|
|
93
94
|
| `.axhline(y, **opts)` / `.axvline(x, **opts)` | `color`, `linewidth`, `linestyle`, `alpha`, `label`, axes-fraction `xmin`/`xmax` (or `ymin`/`ymax`) |
|
|
94
95
|
| `.axhspan(ymin, ymax, **opts)` / `.axvspan(xmin, xmax, **opts)` | `color`, `alpha`, `label`, axes-fraction `xmin`/`xmax` (or `ymin`/`ymax`) |
|
|
95
96
|
| `.imshow(data, **opts)` | `cmap` (any matplotlib name, default `"viridis"`), `vmin`, `vmax`, `extent=(left, right, bottom, top)` |
|
|
97
|
+
| `.heatmap(df, **opts)` | `cmap`, `vmin`, `vmax`, `norm`, `center`, `xticklabels`, `yticklabels`, `legend` |
|
|
96
98
|
|
|
97
99
|
`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.
|
|
98
100
|
|
|
99
101
|
`.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()`.
|
|
100
102
|
|
|
103
|
+
`.heatmap(df)` is the DataFrame-aware companion to `.imshow`. A pandas DataFrame's `index` becomes the row tick labels and `columns` becomes the column tick labels; row 0 sits at the top. For a plain 2-D array, default labels are integer indices — pass `xticklabels=` / `yticklabels=` to override. Cells render at integer + 0.5 centers on a linear axis, which lines up with scipy's dendrogram leaf positions so a top/left dendrogram pairs cleanly via `share_x` / `share_y`.
|
|
104
|
+
|
|
101
105
|
### Subplots
|
|
102
106
|
|
|
103
107
|
Compose multi-panel layouts with operators on `Chart`:
|
|
@@ -149,7 +153,7 @@ c.write_html("plot.html") # standalone HTML
|
|
|
149
153
|
|
|
150
154
|
## Adding a new plot type
|
|
151
155
|
|
|
152
|
-
plotlet
|
|
156
|
+
plotlet is designed so that adding a new plot type is a 3-step recipe (~50–100 lines) that gets axes, scales, legend, grid, and composability for free. The recommended home is your own project, or [`cookbook/`](cookbook/) as reference. Full guide: [docs/EXTENDING.md](docs/EXTENDING.md).
|
|
153
157
|
|
|
154
158
|
## Testing
|
|
155
159
|
|
|
@@ -163,7 +167,7 @@ python tests/test_subplots.py # subplot baselines + composition invarian
|
|
|
163
167
|
## Non-goals
|
|
164
168
|
|
|
165
169
|
- No interactivity (hover, zoom, click). Static rendering is the point.
|
|
166
|
-
- Not
|
|
170
|
+
- Not aiming for full coverage of standard statistical plots — those needs are well-served elsewhere.
|
|
167
171
|
- Not a 3D plotter, not a dashboard tool.
|
|
168
172
|
- Not a feature catalog — new plot types belong in user projects or `cookbook/`, not in the core.
|
|
169
173
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# plotlet
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A Python library for SVG plots — with multi-panel composition, shared-axis layouts, and an extension API for custom plot types.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## What it's for
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
plotlet is built for **multi-panel scientific figures with custom plot types** — genome tracks, spike rasters, climate stacks, Manhattan plots, phylogenetic trees. The core ships ~5 standard plots plus multi-panel composition (`|`, `/`, `share_x()`).
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Custom plot types are a 3-step recipe (`record`, `xdomain`/`ydomain`, `draw`) and live in your own project (or [`cookbook/`](cookbook/)) rather than upstream. See [docs/PHILOSOPHY.md](docs/PHILOSOPHY.md) for the full framing.
|
|
10
10
|
|
|
11
11
|
```python
|
|
12
12
|
import plotlet as pt
|
|
@@ -30,11 +30,11 @@ pip install plotlet
|
|
|
30
30
|
|
|
31
31
|
## Properties
|
|
32
32
|
|
|
33
|
-
- **
|
|
33
|
+
- **Minimal dependencies.** `fonttools` for font handling. numpy / pandas / polars inputs work transparently if you have them.
|
|
34
34
|
- **Static SVG output.** No interactivity, no animation. Same script → byte-identical SVG.
|
|
35
35
|
- **Cross-machine reproducible.** Bundled DejaVu Sans + text-as-paths means rendering is identical on Linux, macOS, Windows, headless CI.
|
|
36
36
|
- **Jupyter-native.** `Chart._repr_html_` auto-renders the last expression in a cell.
|
|
37
|
-
- **
|
|
37
|
+
- **Compact output.** Each plot is ~50 KB SVG, self-contained.
|
|
38
38
|
- **Compositional.** Multi-panel layouts via `|`, `/`, `pt.grid`; share scales with `(a | b).share_x()` or `pt.grid(..., share_x="col")`; layout-level legend with `pt.legend()` covering both discrete swatches and continuous gradients (the colorbar).
|
|
39
39
|
- **AI-readable.** Every figure ships `data-plotlet-*` attributes describing plot type, axes, scales, ranges, and series labels — readable in one XML parse, no glyph-path OCR. Schema: [docs/AI_ATTRS.md](docs/AI_ATTRS.md).
|
|
40
40
|
|
|
@@ -46,7 +46,7 @@ pip install plotlet
|
|
|
46
46
|
|
|
47
47
|
Pass at construction (`pt.chart(data, title=..., grid=True, ...)`) or as chained setters (`c.title(...)`, etc.):
|
|
48
48
|
|
|
49
|
-
`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`, `data_width`, `data_height` (the data region —
|
|
49
|
+
`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`, `data_width`, `data_height` (the data region — the figure canvas grows to fit titles, tick labels, and axis labels). Sizes accept bare pixels (`400`) or unit-suffixed strings (`"4in"`, `"10cm"`, `"100mm"`, `"72pt"`). To fit a composition into a target SVG canvas, chain `.fit(canvas_width=…, canvas_height=…)` after composing — it rescales data regions while keeping fonts, spines, and margins at their absolute pixel sizes.
|
|
50
50
|
|
|
51
51
|
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).
|
|
52
52
|
|
|
@@ -64,11 +64,14 @@ Tick customization: `c.xticks([0, 5, 10], ["A","B","C"], rotation=45, fontsize=1
|
|
|
64
64
|
| `.axhline(y, **opts)` / `.axvline(x, **opts)` | `color`, `linewidth`, `linestyle`, `alpha`, `label`, axes-fraction `xmin`/`xmax` (or `ymin`/`ymax`) |
|
|
65
65
|
| `.axhspan(ymin, ymax, **opts)` / `.axvspan(xmin, xmax, **opts)` | `color`, `alpha`, `label`, axes-fraction `xmin`/`xmax` (or `ymin`/`ymax`) |
|
|
66
66
|
| `.imshow(data, **opts)` | `cmap` (any matplotlib name, default `"viridis"`), `vmin`, `vmax`, `extent=(left, right, bottom, top)` |
|
|
67
|
+
| `.heatmap(df, **opts)` | `cmap`, `vmin`, `vmax`, `norm`, `center`, `xticklabels`, `yticklabels`, `legend` |
|
|
67
68
|
|
|
68
69
|
`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.
|
|
69
70
|
|
|
70
71
|
`.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()`.
|
|
71
72
|
|
|
73
|
+
`.heatmap(df)` is the DataFrame-aware companion to `.imshow`. A pandas DataFrame's `index` becomes the row tick labels and `columns` becomes the column tick labels; row 0 sits at the top. For a plain 2-D array, default labels are integer indices — pass `xticklabels=` / `yticklabels=` to override. Cells render at integer + 0.5 centers on a linear axis, which lines up with scipy's dendrogram leaf positions so a top/left dendrogram pairs cleanly via `share_x` / `share_y`.
|
|
74
|
+
|
|
72
75
|
### Subplots
|
|
73
76
|
|
|
74
77
|
Compose multi-panel layouts with operators on `Chart`:
|
|
@@ -120,7 +123,7 @@ c.write_html("plot.html") # standalone HTML
|
|
|
120
123
|
|
|
121
124
|
## Adding a new plot type
|
|
122
125
|
|
|
123
|
-
plotlet
|
|
126
|
+
plotlet is designed so that adding a new plot type is a 3-step recipe (~50–100 lines) that gets axes, scales, legend, grid, and composability for free. The recommended home is your own project, or [`cookbook/`](cookbook/) as reference. Full guide: [docs/EXTENDING.md](docs/EXTENDING.md).
|
|
124
127
|
|
|
125
128
|
## Testing
|
|
126
129
|
|
|
@@ -134,7 +137,7 @@ python tests/test_subplots.py # subplot baselines + composition invarian
|
|
|
134
137
|
## Non-goals
|
|
135
138
|
|
|
136
139
|
- No interactivity (hover, zoom, click). Static rendering is the point.
|
|
137
|
-
- Not
|
|
140
|
+
- Not aiming for full coverage of standard statistical plots — those needs are well-served elsewhere.
|
|
138
141
|
- Not a 3D plotter, not a dashboard tool.
|
|
139
142
|
- Not a feature catalog — new plot types belong in user projects or `cookbook/`, not in the core.
|
|
140
143
|
|
|
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "plotlet"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "
|
|
7
|
+
version = "0.4.0"
|
|
8
|
+
description = "Python library for SVG plots, with multi-panel composition and an extension API for custom plot types."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
11
11
|
license-files = ["LICENSE"]
|
|
@@ -36,6 +36,7 @@ classifiers = [
|
|
|
36
36
|
]
|
|
37
37
|
dependencies = [
|
|
38
38
|
"fonttools>=4.0",
|
|
39
|
+
"scipy>=1.10",
|
|
39
40
|
]
|
|
40
41
|
|
|
41
42
|
[project.optional-dependencies]
|