plotlet 0.4.0__tar.gz → 0.6.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.
Files changed (156) hide show
  1. plotlet-0.6.0/PKG-INFO +95 -0
  2. plotlet-0.6.0/README.md +58 -0
  3. {plotlet-0.4.0 → plotlet-0.6.0}/pyproject.toml +21 -5
  4. plotlet-0.6.0/src/plotlet/__init__.py +71 -0
  5. plotlet-0.6.0/src/plotlet/_coord_registry.py +50 -0
  6. plotlet-0.6.0/src/plotlet/_datasets/anscombe.csv +45 -0
  7. plotlet-0.6.0/src/plotlet/_datasets/flights.csv +145 -0
  8. plotlet-0.6.0/src/plotlet/_datasets/penguins.csv +345 -0
  9. plotlet-0.6.0/src/plotlet/_datasets/tips.csv +245 -0
  10. plotlet-0.6.0/src/plotlet/_ir.py +452 -0
  11. plotlet-0.6.0/src/plotlet/_journal.py +377 -0
  12. plotlet-0.6.0/src/plotlet/_json_layer.py +144 -0
  13. plotlet-0.6.0/src/plotlet/_regions.py +143 -0
  14. plotlet-0.6.0/src/plotlet/_spec.py +147 -0
  15. plotlet-0.6.0/src/plotlet/_splits.py +105 -0
  16. plotlet-0.6.0/src/plotlet/_tree.py +113 -0
  17. plotlet-0.6.0/src/plotlet/artists/__init__.py +53 -0
  18. plotlet-0.6.0/src/plotlet/artists/_marching.py +140 -0
  19. plotlet-0.6.0/src/plotlet/artists/_shared.py +204 -0
  20. plotlet-0.6.0/src/plotlet/artists/bar.py +421 -0
  21. plotlet-0.6.0/src/plotlet/artists/boxplot.py +264 -0
  22. plotlet-0.6.0/src/plotlet/artists/contour.py +165 -0
  23. plotlet-0.6.0/src/plotlet/artists/dendrogram.py +249 -0
  24. plotlet-0.6.0/src/plotlet/artists/density_1d.py +127 -0
  25. plotlet-0.6.0/src/plotlet/artists/ecdf.py +111 -0
  26. plotlet-0.6.0/src/plotlet/artists/errorbar.py +263 -0
  27. plotlet-0.6.0/src/plotlet/artists/fills.py +218 -0
  28. plotlet-0.6.0/src/plotlet/artists/freqpoly.py +137 -0
  29. plotlet-0.6.0/src/plotlet/artists/heatmap.py +704 -0
  30. plotlet-0.6.0/src/plotlet/artists/hexbin.py +148 -0
  31. plotlet-0.6.0/src/plotlet/artists/hist.py +367 -0
  32. plotlet-0.6.0/src/plotlet/artists/hist2d.py +180 -0
  33. plotlet-0.6.0/src/plotlet/artists/imshow.py +237 -0
  34. plotlet-0.6.0/src/plotlet/artists/kde_2d.py +230 -0
  35. plotlet-0.6.0/src/plotlet/artists/line.py +275 -0
  36. plotlet-0.6.0/src/plotlet/artists/pointplot.py +140 -0
  37. plotlet-0.6.0/src/plotlet/artists/qq.py +129 -0
  38. plotlet-0.6.0/src/plotlet/artists/references.py +367 -0
  39. plotlet-0.6.0/src/plotlet/artists/regression.py +446 -0
  40. plotlet-0.6.0/src/plotlet/artists/ridge.py +142 -0
  41. plotlet-0.6.0/src/plotlet/artists/rug.py +102 -0
  42. plotlet-0.6.0/src/plotlet/artists/scatter.py +434 -0
  43. plotlet-0.6.0/src/plotlet/artists/shapes.py +185 -0
  44. plotlet-0.6.0/src/plotlet/artists/strip.py +169 -0
  45. plotlet-0.6.0/src/plotlet/artists/swarm.py +178 -0
  46. plotlet-0.6.0/src/plotlet/artists/text.py +297 -0
  47. plotlet-0.6.0/src/plotlet/artists/violin.py +241 -0
  48. plotlet-0.6.0/src/plotlet/chart.py +1195 -0
  49. plotlet-0.6.0/src/plotlet/cluster.py +440 -0
  50. plotlet-0.6.0/src/plotlet/datasets.py +107 -0
  51. plotlet-0.6.0/src/plotlet/draw/__init__.py +41 -0
  52. plotlet-0.6.0/src/plotlet/draw/_css_colors.py +159 -0
  53. plotlet-0.6.0/src/plotlet/draw/_png.py +78 -0
  54. plotlet-0.6.0/src/plotlet/draw/colormaps.py +219 -0
  55. plotlet-0.6.0/src/plotlet/draw/colors.py +172 -0
  56. plotlet-0.6.0/src/plotlet/draw/font.py +352 -0
  57. plotlet-0.6.0/src/plotlet/draw/fonts/Arimo-Bold.ttf +0 -0
  58. plotlet-0.6.0/src/plotlet/draw/fonts/Arimo-BoldItalic.ttf +0 -0
  59. plotlet-0.6.0/src/plotlet/draw/fonts/Arimo-Italic.ttf +0 -0
  60. plotlet-0.6.0/src/plotlet/draw/fonts/Arimo-Regular.ttf +0 -0
  61. plotlet-0.6.0/src/plotlet/draw/fonts/DejaVuSans-Bold.ttf +0 -0
  62. plotlet-0.6.0/src/plotlet/draw/fonts/DejaVuSans-BoldOblique.ttf +0 -0
  63. plotlet-0.6.0/src/plotlet/draw/fonts/DejaVuSans-Oblique.ttf +0 -0
  64. plotlet-0.6.0/src/plotlet/draw/fonts/LICENSE-Arimo.txt +93 -0
  65. plotlet-0.6.0/src/plotlet/draw/fonts/LICENSE-DejaVuSans.txt +99 -0
  66. plotlet-0.6.0/src/plotlet/draw/format.py +34 -0
  67. plotlet-0.6.0/src/plotlet/draw/linestyles.py +27 -0
  68. plotlet-0.6.0/src/plotlet/draw/primitives.py +687 -0
  69. plotlet-0.6.0/src/plotlet/extensions/annotation_strip.py +675 -0
  70. plotlet-0.6.0/src/plotlet/extensions/chord_links.py +209 -0
  71. plotlet-0.6.0/src/plotlet/extensions/chord_ribbon.py +318 -0
  72. plotlet-0.6.0/src/plotlet/extensions/curved_tree.py +244 -0
  73. plotlet-0.6.0/src/plotlet/extensions/numeric_bar.py +109 -0
  74. plotlet-0.6.0/src/plotlet/facet.py +245 -0
  75. plotlet-0.6.0/src/plotlet/formatters.py +164 -0
  76. plotlet-0.6.0/src/plotlet/layout_diagram.py +316 -0
  77. plotlet-0.6.0/src/plotlet/legend.py +120 -0
  78. plotlet-0.6.0/src/plotlet/lint.py +130 -0
  79. plotlet-0.6.0/src/plotlet/registry.py +324 -0
  80. plotlet-0.6.0/src/plotlet/render/__init__.py +77 -0
  81. plotlet-0.6.0/src/plotlet/render/_attachments.py +296 -0
  82. plotlet-0.6.0/src/plotlet/render/_chrome.py +953 -0
  83. plotlet-0.6.0/src/plotlet/render/_chrome_circular.py +360 -0
  84. plotlet-0.6.0/src/plotlet/render/_layout_engine.py +1427 -0
  85. plotlet-0.6.0/src/plotlet/render/_legend.py +645 -0
  86. plotlet-0.6.0/src/plotlet/render/_nodes.py +521 -0
  87. plotlet-0.6.0/src/plotlet/render/_validate.py +289 -0
  88. plotlet-0.6.0/src/plotlet/render/coordinates.py +697 -0
  89. plotlet-0.6.0/src/plotlet/render/core.py +2100 -0
  90. plotlet-0.6.0/src/plotlet/render/resolved.py +717 -0
  91. plotlet-0.6.0/src/plotlet/scales.py +576 -0
  92. plotlet-0.6.0/src/plotlet/sectors.py +330 -0
  93. plotlet-0.6.0/src/plotlet/spec.json +135 -0
  94. plotlet-0.6.0/src/plotlet/themes/dark.json +24 -0
  95. plotlet-0.6.0/src/plotlet/themes/minimal.json +26 -0
  96. plotlet-0.6.0/src/plotlet/themes/void.json +15 -0
  97. plotlet-0.6.0/src/plotlet/themes.py +99 -0
  98. plotlet-0.6.0/src/plotlet/utils.py +626 -0
  99. plotlet-0.6.0/src/plotlet.egg-info/PKG-INFO +95 -0
  100. plotlet-0.6.0/src/plotlet.egg-info/SOURCES.txt +129 -0
  101. plotlet-0.6.0/src/plotlet.egg-info/requires.txt +14 -0
  102. plotlet-0.6.0/tests/test_attachments.py +287 -0
  103. plotlet-0.6.0/tests/test_chart.py +3594 -0
  104. plotlet-0.6.0/tests/test_circular_coordinate.py +581 -0
  105. plotlet-0.6.0/tests/test_cluster.py +67 -0
  106. plotlet-0.6.0/tests/test_colors.py +247 -0
  107. plotlet-0.6.0/tests/test_datasets.py +53 -0
  108. plotlet-0.6.0/tests/test_extensions.py +40 -0
  109. plotlet-0.6.0/tests/test_fonts.py +310 -0
  110. plotlet-0.6.0/tests/test_formatters.py +64 -0
  111. plotlet-0.6.0/tests/test_help.py +25 -0
  112. plotlet-0.6.0/tests/test_import_boundary.py +149 -0
  113. plotlet-0.6.0/tests/test_io.py +61 -0
  114. plotlet-0.6.0/tests/test_ir.py +265 -0
  115. plotlet-0.6.0/tests/test_ir_resolved.py +289 -0
  116. plotlet-0.6.0/tests/test_ir_validate.py +318 -0
  117. plotlet-0.6.0/tests/test_journal_roundtrip.py +127 -0
  118. {plotlet-0.4.0 → plotlet-0.6.0}/tests/test_layout_diagram.py +17 -15
  119. plotlet-0.6.0/tests/test_legend.py +288 -0
  120. plotlet-0.6.0/tests/test_lint.py +23 -0
  121. plotlet-0.6.0/tests/test_record_signatures.py +75 -0
  122. plotlet-0.6.0/tests/test_sectors.py +393 -0
  123. plotlet-0.6.0/tests/test_subplots.py +564 -0
  124. plotlet-0.6.0/tests/test_themes.py +89 -0
  125. {plotlet-0.4.0 → plotlet-0.6.0}/tests/test_units.py +32 -29
  126. plotlet-0.4.0/PKG-INFO +0 -176
  127. plotlet-0.4.0/README.md +0 -146
  128. plotlet-0.4.0/src/plotlet/__init__.py +0 -33
  129. plotlet-0.4.0/src/plotlet/_png.py +0 -38
  130. plotlet-0.4.0/src/plotlet/_spec.py +0 -23
  131. plotlet-0.4.0/src/plotlet/artists.py +0 -503
  132. plotlet-0.4.0/src/plotlet/builtin_artists.py +0 -570
  133. plotlet-0.4.0/src/plotlet/chart.py +0 -718
  134. plotlet-0.4.0/src/plotlet/colormaps.py +0 -113
  135. plotlet-0.4.0/src/plotlet/colors.py +0 -20
  136. plotlet-0.4.0/src/plotlet/core.py +0 -1055
  137. plotlet-0.4.0/src/plotlet/dendrogram.py +0 -197
  138. plotlet-0.4.0/src/plotlet/font.py +0 -63
  139. plotlet-0.4.0/src/plotlet/layout.py +0 -896
  140. plotlet-0.4.0/src/plotlet/layout_diagram.py +0 -237
  141. plotlet-0.4.0/src/plotlet/legend.py +0 -367
  142. plotlet-0.4.0/src/plotlet/registry.py +0 -97
  143. plotlet-0.4.0/src/plotlet/scales.py +0 -123
  144. plotlet-0.4.0/src/plotlet/spec.json +0 -100
  145. plotlet-0.4.0/src/plotlet.egg-info/PKG-INFO +0 -176
  146. plotlet-0.4.0/src/plotlet.egg-info/SOURCES.txt +0 -32
  147. plotlet-0.4.0/src/plotlet.egg-info/requires.txt +0 -6
  148. plotlet-0.4.0/tests/test_chart.py +0 -564
  149. plotlet-0.4.0/tests/test_legend.py +0 -146
  150. plotlet-0.4.0/tests/test_subplots.py +0 -385
  151. {plotlet-0.4.0 → plotlet-0.6.0}/LICENSE +0 -0
  152. {plotlet-0.4.0 → plotlet-0.6.0}/setup.cfg +0 -0
  153. {plotlet-0.4.0/src/plotlet → plotlet-0.6.0/src/plotlet/draw}/_cm_data.py +0 -0
  154. {plotlet-0.4.0/src/plotlet → plotlet-0.6.0/src/plotlet/draw}/fonts/DejaVuSans.ttf +0 -0
  155. {plotlet-0.4.0 → plotlet-0.6.0}/src/plotlet.egg-info/dependency_links.txt +0 -0
  156. {plotlet-0.4.0 → plotlet-0.6.0}/src/plotlet.egg-info/top_level.txt +0 -0
plotlet-0.6.0/PKG-INFO ADDED
@@ -0,0 +1,95 @@
1
+ Metadata-Version: 2.4
2
+ Name: plotlet
3
+ Version: 0.6.0
4
+ Summary: Python library for reproducible, multi-panel scientific figures, with byte-identical output across machines and an extension API for custom plot types.
5
+ Author: gitbamboo42
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/gitbamboo42/plotlet
8
+ Project-URL: Repository, https://github.com/gitbamboo42/plotlet
9
+ Project-URL: Issues, https://github.com/gitbamboo42/plotlet/issues
10
+ Keywords: plot,svg,scientific,visualization,jupyter,reproducible
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Scientific/Engineering :: Visualization
21
+ Classifier: Topic :: Multimedia :: Graphics
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: fonttools>=4.0
26
+ Requires-Dist: scipy>=1.10
27
+ Requires-Dist: resvg_py>=0.3
28
+ Provides-Extra: dev
29
+ Requires-Dist: jupyter; extra == "dev"
30
+ Requires-Dist: nbconvert; extra == "dev"
31
+ Provides-Extra: test
32
+ Requires-Dist: pytest>=7; extra == "test"
33
+ Requires-Dist: pandas; extra == "test"
34
+ Provides-Extra: pdf
35
+ Requires-Dist: cairosvg; extra == "pdf"
36
+ Dynamic: license-file
37
+
38
+ # plotlet
39
+
40
+ plotlet is a Python library for reproducible, multi-panel scientific figures. Byte-identical output across machines, a standard plotting vocabulary, and a first-class extension story for custom plot types.
41
+
42
+ ## Documentation
43
+
44
+ Hands-on tour with executable examples:
45
+
46
+ - [notebooks/00_introduction.ipynb](notebooks/00_introduction.ipynb) — long-form data, aesthetic inheritance, layering, composition (more topic notebooks in [`notebooks/`](notebooks/))
47
+
48
+ Reference docs in [`docs/`](docs/):
49
+
50
+ - [API reference](docs/API.md) — mark methods, frame options, scales, tick overrides
51
+ - [Philosophy](docs/PHILOSOPHY.md) — what's in core, what's not, and why
52
+ - [Subplots](docs/SUBPLOTS.md) — multi-panel composition, shared scales
53
+ - [Coordinates](docs/COORDINATES.md) — Circular, custom non-Cartesian projections
54
+ - [Extending](docs/EXTENDING.md) — write your own plot type
55
+ - [Themes](docs/THEMES.md) — visual presets
56
+ - [AI attributes](docs/AI_ATTRS.md) — `data-plotlet-*` schema for automation
57
+
58
+ Reference plot types beyond the standard vocabulary ship in the separate [`plotlet-extensions`](https://github.com/gitbamboo42/plotlet-extensions) package (single-file artists — sankey, alluvial, raincloud, upset_plot, …; `pip install plotlet-extensions`, then `import plotlet.extensions.<name>`) and in the [`plotlet-cookbook`](https://github.com/gitbamboo42/plotlet-cookbook) repo (multi-file, domain-specific projects). A few extensions the core tests depend on still ship in core under [`src/plotlet/extensions/`](src/plotlet/extensions/).
59
+
60
+ ## For AI assistants
61
+
62
+ Compact, vendor-neutral onboarding docs live in [`skills/`](skills/):
63
+
64
+ - [`skills/users.md`](skills/users.md) — for AI tools generating plotlet code on a user's behalf.
65
+ - [`skills/developers.md`](skills/developers.md) — for AI (or human) contributors working on plotlet itself. Symlink as `CLAUDE.md` / `.cursorrules` / `AGENTS.md` as your tool expects.
66
+
67
+ ## Dependencies
68
+
69
+ plotlet supports Python 3.10+.
70
+
71
+ Required: `fonttools`, `scipy` (regression, qq, CI error bands, clustering/dendrogram), `resvg_py` (PNG rendering — prebuilt wheels, no system libraries). numpy / pandas / polars inputs work transparently.
72
+
73
+ Optional: `cairosvg` for PDF export (`pip install plotlet[pdf]`).
74
+
75
+ ## Installation
76
+
77
+ ```bash
78
+ pip install plotlet
79
+ ```
80
+
81
+ ## Testing
82
+
83
+ ```bash
84
+ pip install -e ".[test]"
85
+ pytest tests/ # check vs. committed baselines
86
+ pytest tests/ --update # regenerate (review the diff!)
87
+ ```
88
+
89
+ ## Development
90
+
91
+ Development takes place on GitHub. Please submit bugs to the issue tracker with a reproducible example.
92
+
93
+ ## License
94
+
95
+ MIT
@@ -0,0 +1,58 @@
1
+ # plotlet
2
+
3
+ plotlet is a Python library for reproducible, multi-panel scientific figures. Byte-identical output across machines, a standard plotting vocabulary, and a first-class extension story for custom plot types.
4
+
5
+ ## Documentation
6
+
7
+ Hands-on tour with executable examples:
8
+
9
+ - [notebooks/00_introduction.ipynb](notebooks/00_introduction.ipynb) — long-form data, aesthetic inheritance, layering, composition (more topic notebooks in [`notebooks/`](notebooks/))
10
+
11
+ Reference docs in [`docs/`](docs/):
12
+
13
+ - [API reference](docs/API.md) — mark methods, frame options, scales, tick overrides
14
+ - [Philosophy](docs/PHILOSOPHY.md) — what's in core, what's not, and why
15
+ - [Subplots](docs/SUBPLOTS.md) — multi-panel composition, shared scales
16
+ - [Coordinates](docs/COORDINATES.md) — Circular, custom non-Cartesian projections
17
+ - [Extending](docs/EXTENDING.md) — write your own plot type
18
+ - [Themes](docs/THEMES.md) — visual presets
19
+ - [AI attributes](docs/AI_ATTRS.md) — `data-plotlet-*` schema for automation
20
+
21
+ Reference plot types beyond the standard vocabulary ship in the separate [`plotlet-extensions`](https://github.com/gitbamboo42/plotlet-extensions) package (single-file artists — sankey, alluvial, raincloud, upset_plot, …; `pip install plotlet-extensions`, then `import plotlet.extensions.<name>`) and in the [`plotlet-cookbook`](https://github.com/gitbamboo42/plotlet-cookbook) repo (multi-file, domain-specific projects). A few extensions the core tests depend on still ship in core under [`src/plotlet/extensions/`](src/plotlet/extensions/).
22
+
23
+ ## For AI assistants
24
+
25
+ Compact, vendor-neutral onboarding docs live in [`skills/`](skills/):
26
+
27
+ - [`skills/users.md`](skills/users.md) — for AI tools generating plotlet code on a user's behalf.
28
+ - [`skills/developers.md`](skills/developers.md) — for AI (or human) contributors working on plotlet itself. Symlink as `CLAUDE.md` / `.cursorrules` / `AGENTS.md` as your tool expects.
29
+
30
+ ## Dependencies
31
+
32
+ plotlet supports Python 3.10+.
33
+
34
+ Required: `fonttools`, `scipy` (regression, qq, CI error bands, clustering/dendrogram), `resvg_py` (PNG rendering — prebuilt wheels, no system libraries). numpy / pandas / polars inputs work transparently.
35
+
36
+ Optional: `cairosvg` for PDF export (`pip install plotlet[pdf]`).
37
+
38
+ ## Installation
39
+
40
+ ```bash
41
+ pip install plotlet
42
+ ```
43
+
44
+ ## Testing
45
+
46
+ ```bash
47
+ pip install -e ".[test]"
48
+ pytest tests/ # check vs. committed baselines
49
+ pytest tests/ --update # regenerate (review the diff!)
50
+ ```
51
+
52
+ ## Development
53
+
54
+ Development takes place on GitHub. Please submit bugs to the issue tracker with a reproducible example.
55
+
56
+ ## License
57
+
58
+ MIT
@@ -1,11 +1,11 @@
1
1
  [build-system]
2
- requires = ["setuptools>=64", "wheel"]
2
+ requires = ["setuptools>=77", "wheel"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "plotlet"
7
- version = "0.4.0"
8
- description = "Python library for SVG plots, with multi-panel composition and an extension API for custom plot types."
7
+ version = "0.6.0"
8
+ description = "Python library for reproducible, multi-panel scientific figures, with byte-identical output across machines and an extension API for custom plot types."
9
9
  readme = "README.md"
10
10
  license = "MIT"
11
11
  license-files = ["LICENSE"]
@@ -16,7 +16,6 @@ authors = [
16
16
  keywords = [
17
17
  "plot",
18
18
  "svg",
19
- "matplotlib",
20
19
  "scientific",
21
20
  "visualization",
22
21
  "jupyter",
@@ -31,12 +30,14 @@ classifiers = [
31
30
  "Programming Language :: Python :: 3.10",
32
31
  "Programming Language :: Python :: 3.11",
33
32
  "Programming Language :: Python :: 3.12",
33
+ "Programming Language :: Python :: 3.13",
34
34
  "Topic :: Scientific/Engineering :: Visualization",
35
35
  "Topic :: Multimedia :: Graphics",
36
36
  ]
37
37
  dependencies = [
38
38
  "fonttools>=4.0",
39
39
  "scipy>=1.10",
40
+ "resvg_py>=0.3",
40
41
  ]
41
42
 
42
43
  [project.optional-dependencies]
@@ -44,6 +45,17 @@ dev = [
44
45
  "jupyter",
45
46
  "nbconvert",
46
47
  ]
48
+ test = [
49
+ "pytest>=7",
50
+ "pandas",
51
+ ]
52
+ pdf = [
53
+ "cairosvg",
54
+ ]
55
+
56
+ [tool.pytest.ini_options]
57
+ testpaths = ["tests"]
58
+ addopts = "-ra"
47
59
 
48
60
  [project.urls]
49
61
  Homepage = "https://github.com/gitbamboo42/plotlet"
@@ -52,6 +64,10 @@ Issues = "https://github.com/gitbamboo42/plotlet/issues"
52
64
 
53
65
  [tool.setuptools.packages.find]
54
66
  where = ["src"]
67
+ namespaces = true
55
68
 
56
69
  [tool.setuptools.package-data]
57
- plotlet = ["spec.json", "fonts/*.ttf"]
70
+ # draw/fonts/*.txt are the font licenses — DejaVu (Bitstream Vera–derived)
71
+ # and Arimo (SIL OFL 1.1) both require the license text to accompany
72
+ # redistribution, so they must ship in the wheel next to the TTFs.
73
+ plotlet = ["spec.json", "themes/*.json", "draw/fonts/*.ttf", "draw/fonts/*.txt", "_datasets/*.csv"]
@@ -0,0 +1,71 @@
1
+ """plotlet — pure-Python deferred-rendering SVG plot library.
2
+
3
+ import plotlet as pt
4
+ c = pt.chart(df, title="...", xlabel="x", ylabel="y", legend=True, gridlines=True)
5
+ c.line(x="time", y="value", color="series")
6
+ c # auto-renders in Jupyter
7
+
8
+ Chart methods chain for incremental composition:
9
+
10
+ df = {"x": [1, 2, 3], "y": [1, 4, 9]}
11
+ c = pt.chart()
12
+ c.line(df, x="x", y="y", label="squares")
13
+ c.title("Hello").legend().gridlines(True)
14
+ c
15
+ """
16
+ from ._spec import SPEC
17
+ from .draw import TAB10, palette, list_palettes
18
+ from .draw import colormap, list_colormaps, register_colormap
19
+ from . import artists # noqa: F401 — registers built-in artists on import
20
+ from .chart import Chart, Layout, chart, grid
21
+ from .legend import legend
22
+ from .registry import ArtistSpec, add_artist, artist_table, declare_coord_support
23
+ from .sectors import Sectors
24
+ from .layout_diagram import layout_diagram
25
+ from .themes import load_theme, list_themes, register_theme
26
+ from .facet import facet, FacetGrid
27
+ from .datasets import load_dataset, list_datasets
28
+ from .cluster import linkage, linkage_split, SplitTree
29
+ from .formatters import (register_formatter, list_formatters,
30
+ superscript, subscript)
31
+ from ._coord_registry import register_coord_codec
32
+ from ._journal import (to_journal, from_journal, to_json, from_json,
33
+ JournalNode, Journal)
34
+ from ._ir import to_ir, from_ir, resolve_ir, FigureIR, IRNode
35
+ from . import draw, utils
36
+
37
+
38
+ def __getattr__(name):
39
+ # The one render-half class in the top-level namespace stays a lazy
40
+ # import so that `import plotlet` loads only the recording half —
41
+ # the render half loads on first render (or first touch of this
42
+ # name). Enforced by tests/test_import_boundary.py.
43
+ if name == "CircularCoordinate":
44
+ from .render.coordinates import CircularCoordinate
45
+ return CircularCoordinate
46
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
47
+
48
+ __all__ = ["chart", "Chart", "Layout", "SPEC", "TAB10",
49
+ "palette", "list_palettes",
50
+ "colormap", "list_colormaps", "register_colormap",
51
+ "grid", "legend",
52
+ "ArtistSpec", "add_artist", "artist_table", "declare_coord_support",
53
+ "CircularCoordinate", "Sectors",
54
+ "layout_diagram",
55
+ "load_theme", "list_themes", "register_theme",
56
+ "facet", "FacetGrid",
57
+ "load_dataset", "list_datasets",
58
+ "linkage", "linkage_split", "SplitTree",
59
+ "register_formatter", "list_formatters",
60
+ "superscript", "subscript",
61
+ "to_json", "from_json", "register_coord_codec",
62
+ "to_journal", "from_journal", "JournalNode", "Journal",
63
+ "to_ir", "from_ir", "FigureIR", "IRNode", "resolve_ir",
64
+ "draw", "utils"]
65
+
66
+ # Single source of truth: pyproject.toml. importlib.metadata reads it at
67
+ # runtime from the installed package metadata (works for `pip install` and
68
+ # `pip install -e .` alike). Migrating to setuptools_scm later doesn't
69
+ # touch this code — it just changes how pyproject.toml's version is set.
70
+ from importlib.metadata import version as _pkg_version
71
+ __version__ = _pkg_version("plotlet")
@@ -0,0 +1,50 @@
1
+ """Coord codec registry — a neutral home for the `class_name → class` map
2
+ that both `serialize.py` and `_journal.py` need for round-tripping coord
3
+ objects like `CircularCoordinate`.
4
+
5
+ Lives here rather than in either consumer so that removing one of them
6
+ later (e.g. retiring the JSON tree serializer once the journal covers
7
+ the same ground) doesn't leave the registry orphaned. The public API
8
+ `plotlet.register_coord_codec` re-exports from this module directly.
9
+ """
10
+ from __future__ import annotations
11
+
12
+
13
+ # Populated by `register_coord_codec`; coord classes register themselves
14
+ # at their definition site (or serialize.py registers built-ins on module
15
+ # import, for the ones that ship with plotlet).
16
+ _COORD_REGISTRY: dict[str, type] = {}
17
+
18
+
19
+ def register_coord_codec(cls: type) -> type:
20
+ """Register `cls` as a serializable coord. The class must define
21
+ `_to_dict(self) -> dict` and `_from_dict(cls, dict) -> cls`. Returns
22
+ `cls` so this can be used as a decorator."""
23
+ if not hasattr(cls, "_to_dict") or not hasattr(cls, "_from_dict"):
24
+ raise TypeError(
25
+ f"register_coord_codec: {cls.__name__} must define "
26
+ f"`_to_dict` and `_from_dict`."
27
+ )
28
+ _COORD_REGISTRY[cls.__name__] = cls
29
+ return cls
30
+
31
+
32
+ def resolve_coord(name: str) -> type:
33
+ """Look up a coord class by registered name, importing the built-in
34
+ coord module on first miss — built-ins register at their definition
35
+ site, and nothing else guarantees that module has been imported when
36
+ a `{"$coord": ...}` envelope arrives from JSON in a fresh process."""
37
+ try:
38
+ return _COORD_REGISTRY[name]
39
+ except KeyError:
40
+ pass
41
+ from .render import coordinates # noqa: F401 — registers built-ins
42
+ try:
43
+ return _COORD_REGISTRY[name]
44
+ except KeyError:
45
+ raise KeyError(
46
+ f"unknown coordinate {name!r}. Registered coords: "
47
+ f"{sorted(_COORD_REGISTRY)}. Custom coord classes must be "
48
+ f"imported (and registered via `register_coord_codec`) before "
49
+ f"a figure referencing them is decoded."
50
+ ) from None
@@ -0,0 +1,45 @@
1
+ dataset,x,y
2
+ I,10.0,8.04
3
+ I,8.0,6.95
4
+ I,13.0,7.58
5
+ I,9.0,8.81
6
+ I,11.0,8.33
7
+ I,14.0,9.96
8
+ I,6.0,7.24
9
+ I,4.0,4.26
10
+ I,12.0,10.84
11
+ I,7.0,4.82
12
+ I,5.0,5.68
13
+ II,10.0,9.14
14
+ II,8.0,8.14
15
+ II,13.0,8.74
16
+ II,9.0,8.77
17
+ II,11.0,9.26
18
+ II,14.0,8.1
19
+ II,6.0,6.13
20
+ II,4.0,3.1
21
+ II,12.0,9.13
22
+ II,7.0,7.26
23
+ II,5.0,4.74
24
+ III,10.0,7.46
25
+ III,8.0,6.77
26
+ III,13.0,12.74
27
+ III,9.0,7.11
28
+ III,11.0,7.81
29
+ III,14.0,8.84
30
+ III,6.0,6.08
31
+ III,4.0,5.39
32
+ III,12.0,8.15
33
+ III,7.0,6.42
34
+ III,5.0,5.73
35
+ IV,8.0,6.58
36
+ IV,8.0,5.76
37
+ IV,8.0,7.71
38
+ IV,8.0,8.84
39
+ IV,8.0,8.47
40
+ IV,8.0,7.04
41
+ IV,8.0,5.25
42
+ IV,19.0,12.5
43
+ IV,8.0,5.56
44
+ IV,8.0,7.91
45
+ IV,8.0,6.89
@@ -0,0 +1,145 @@
1
+ year,month,passengers
2
+ 1949,January,112
3
+ 1949,February,118
4
+ 1949,March,132
5
+ 1949,April,129
6
+ 1949,May,121
7
+ 1949,June,135
8
+ 1949,July,148
9
+ 1949,August,148
10
+ 1949,September,136
11
+ 1949,October,119
12
+ 1949,November,104
13
+ 1949,December,118
14
+ 1950,January,115
15
+ 1950,February,126
16
+ 1950,March,141
17
+ 1950,April,135
18
+ 1950,May,125
19
+ 1950,June,149
20
+ 1950,July,170
21
+ 1950,August,170
22
+ 1950,September,158
23
+ 1950,October,133
24
+ 1950,November,114
25
+ 1950,December,140
26
+ 1951,January,145
27
+ 1951,February,150
28
+ 1951,March,178
29
+ 1951,April,163
30
+ 1951,May,172
31
+ 1951,June,178
32
+ 1951,July,199
33
+ 1951,August,199
34
+ 1951,September,184
35
+ 1951,October,162
36
+ 1951,November,146
37
+ 1951,December,166
38
+ 1952,January,171
39
+ 1952,February,180
40
+ 1952,March,193
41
+ 1952,April,181
42
+ 1952,May,183
43
+ 1952,June,218
44
+ 1952,July,230
45
+ 1952,August,242
46
+ 1952,September,209
47
+ 1952,October,191
48
+ 1952,November,172
49
+ 1952,December,194
50
+ 1953,January,196
51
+ 1953,February,196
52
+ 1953,March,236
53
+ 1953,April,235
54
+ 1953,May,229
55
+ 1953,June,243
56
+ 1953,July,264
57
+ 1953,August,272
58
+ 1953,September,237
59
+ 1953,October,211
60
+ 1953,November,180
61
+ 1953,December,201
62
+ 1954,January,204
63
+ 1954,February,188
64
+ 1954,March,235
65
+ 1954,April,227
66
+ 1954,May,234
67
+ 1954,June,264
68
+ 1954,July,302
69
+ 1954,August,293
70
+ 1954,September,259
71
+ 1954,October,229
72
+ 1954,November,203
73
+ 1954,December,229
74
+ 1955,January,242
75
+ 1955,February,233
76
+ 1955,March,267
77
+ 1955,April,269
78
+ 1955,May,270
79
+ 1955,June,315
80
+ 1955,July,364
81
+ 1955,August,347
82
+ 1955,September,312
83
+ 1955,October,274
84
+ 1955,November,237
85
+ 1955,December,278
86
+ 1956,January,284
87
+ 1956,February,277
88
+ 1956,March,317
89
+ 1956,April,313
90
+ 1956,May,318
91
+ 1956,June,374
92
+ 1956,July,413
93
+ 1956,August,405
94
+ 1956,September,355
95
+ 1956,October,306
96
+ 1956,November,271
97
+ 1956,December,306
98
+ 1957,January,315
99
+ 1957,February,301
100
+ 1957,March,356
101
+ 1957,April,348
102
+ 1957,May,355
103
+ 1957,June,422
104
+ 1957,July,465
105
+ 1957,August,467
106
+ 1957,September,404
107
+ 1957,October,347
108
+ 1957,November,305
109
+ 1957,December,336
110
+ 1958,January,340
111
+ 1958,February,318
112
+ 1958,March,362
113
+ 1958,April,348
114
+ 1958,May,363
115
+ 1958,June,435
116
+ 1958,July,491
117
+ 1958,August,505
118
+ 1958,September,404
119
+ 1958,October,359
120
+ 1958,November,310
121
+ 1958,December,337
122
+ 1959,January,360
123
+ 1959,February,342
124
+ 1959,March,406
125
+ 1959,April,396
126
+ 1959,May,420
127
+ 1959,June,472
128
+ 1959,July,548
129
+ 1959,August,559
130
+ 1959,September,463
131
+ 1959,October,407
132
+ 1959,November,362
133
+ 1959,December,405
134
+ 1960,January,417
135
+ 1960,February,391
136
+ 1960,March,419
137
+ 1960,April,461
138
+ 1960,May,472
139
+ 1960,June,535
140
+ 1960,July,622
141
+ 1960,August,606
142
+ 1960,September,508
143
+ 1960,October,461
144
+ 1960,November,390
145
+ 1960,December,432