anyplotlib 0.1.0__py3-none-any.whl

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 (42) hide show
  1. anyplotlib/__init__.py +53 -0
  2. anyplotlib/_base_plot.py +229 -0
  3. anyplotlib/_electron.py +74 -0
  4. anyplotlib/_repr_utils.py +345 -0
  5. anyplotlib/_utils.py +194 -0
  6. anyplotlib/axes/__init__.py +6 -0
  7. anyplotlib/axes/_axes.py +510 -0
  8. anyplotlib/axes/_inset_axes.py +126 -0
  9. anyplotlib/callbacks.py +328 -0
  10. anyplotlib/embed.py +194 -0
  11. anyplotlib/figure/__init__.py +7 -0
  12. anyplotlib/figure/_figure.py +633 -0
  13. anyplotlib/figure/_gridspec.py +99 -0
  14. anyplotlib/figure/_subplots.py +100 -0
  15. anyplotlib/figure_esm.js +6011 -0
  16. anyplotlib/markers.py +704 -0
  17. anyplotlib/plot1d/__init__.py +6 -0
  18. anyplotlib/plot1d/_plot1d.py +1376 -0
  19. anyplotlib/plot1d/_plotbar.py +436 -0
  20. anyplotlib/plot2d/__init__.py +5 -0
  21. anyplotlib/plot2d/_plot2d.py +726 -0
  22. anyplotlib/plot2d/_plotmesh.py +116 -0
  23. anyplotlib/plot3d/__init__.py +4 -0
  24. anyplotlib/plot3d/_plot3d.py +524 -0
  25. anyplotlib/plotxy/__init__.py +4 -0
  26. anyplotlib/plotxy/_plotxy.py +273 -0
  27. anyplotlib/sphinx_anywidget/__init__.py +177 -0
  28. anyplotlib/sphinx_anywidget/_directive.py +245 -0
  29. anyplotlib/sphinx_anywidget/_repr_utils.py +298 -0
  30. anyplotlib/sphinx_anywidget/_scraper.py +390 -0
  31. anyplotlib/sphinx_anywidget/_wheel_builder.py +84 -0
  32. anyplotlib/sphinx_anywidget/static/anywidget_bridge.js +1099 -0
  33. anyplotlib/sphinx_anywidget/static/anywidget_overlay.css +100 -0
  34. anyplotlib/widgets/__init__.py +18 -0
  35. anyplotlib/widgets/_base.py +218 -0
  36. anyplotlib/widgets/_widgets1d.py +109 -0
  37. anyplotlib/widgets/_widgets2d.py +141 -0
  38. anyplotlib/widgets/_widgets3d.py +50 -0
  39. anyplotlib-0.1.0.dist-info/METADATA +160 -0
  40. anyplotlib-0.1.0.dist-info/RECORD +42 -0
  41. anyplotlib-0.1.0.dist-info/WHEEL +4 -0
  42. anyplotlib-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,160 @@
1
+ Metadata-Version: 2.4
2
+ Name: anyplotlib
3
+ Version: 0.1.0
4
+ Summary: A plotting library using python, javascript and anywidget for performant in browser plotting.
5
+ Project-URL: Homepage, https://cssfrancis.github.io/anyplotlib/
6
+ Project-URL: Repository, https://github.com/CSSFrancis/anyplotlib
7
+ Project-URL: Bug Tracker, https://github.com/CSSFrancis/anyplotlib/issues
8
+ Author-email: Carter Francis <cartsfrancis@gmail.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: anywidget,canvas,interactive,jupyter,plotting,visualization
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Framework :: Jupyter
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Visualization
22
+ Requires-Python: >=3.10
23
+ Requires-Dist: anywidget>=0.9.0
24
+ Requires-Dist: colorcet>=3.0
25
+ Requires-Dist: numpy>=2.0.0
26
+ Requires-Dist: traitlets>=5.0.0
27
+ Provides-Extra: docs
28
+ Requires-Dist: bokeh>=3.0; extra == 'docs'
29
+ Requires-Dist: matplotlib>=3.7; extra == 'docs'
30
+ Requires-Dist: pillow>=10.0; extra == 'docs'
31
+ Requires-Dist: playwright>=1.58.0; extra == 'docs'
32
+ Requires-Dist: plotly>=5.0; extra == 'docs'
33
+ Requires-Dist: pydata-sphinx-theme>=0.16; extra == 'docs'
34
+ Requires-Dist: scipy>=1.15.3; extra == 'docs'
35
+ Requires-Dist: sphinx-design>=0.6; extra == 'docs'
36
+ Requires-Dist: sphinx-gallery>=0.18; extra == 'docs'
37
+ Requires-Dist: sphinx>=8.0; extra == 'docs'
38
+ Provides-Extra: jupyter
39
+ Requires-Dist: jupyterlab>=4.5.5; extra == 'jupyter'
40
+ Description-Content-Type: text/markdown
41
+
42
+ # anyplotlib
43
+
44
+ [![codecov](https://codecov.io/gh/CSSFrancis/anyplotlib/branch/main/graph/badge.svg)](https://codecov.io/gh/CSSFrancis/anyplotlib)
45
+ [![Tests](https://github.com/CSSFrancis/anyplotlib/actions/workflows/tests.yml/badge.svg)](https://github.com/CSSFrancis/anyplotlib/actions/workflows/tests.yml)
46
+
47
+ **anyplotlib** is a fast, interactive plotting library for Jupyter, built on
48
+ [anywidget](https://anywidget.dev/) and a pure-JavaScript canvas renderer.
49
+ It follows matplotlib's object-oriented API — create a `Figure`, call methods
50
+ on `Axes` — so switching is often a one-line change:
51
+
52
+ ```python
53
+ import anyplotlib as apl
54
+
55
+ fig, ax = apl.subplots(1, 1) # same shape as plt.subplots(1, 1)
56
+ ax.imshow(data) # pan, zoom, and inspect — live
57
+ fig # display in a Jupyter cell
58
+ ```
59
+
60
+ If you have used matplotlib's OO interface, you already know most of
61
+ anyplotlib. What you gain is interactivity that stays fast on large data —
62
+ without a kernel round-trip per frame.
63
+
64
+ ## Why another plotting library?
65
+
66
+ Matplotlib is a superb tool for publication-quality static figures, but its
67
+ interactive notebook story (`ipympl`) re-renders the whole figure on the
68
+ Python side for every frame. anyplotlib makes the opposite trade-off:
69
+
70
+ - **All rendering happens in the browser.** Python serialises compact state
71
+ (raw image bytes, base64-encoded float arrays) once; pan/zoom/drag never
72
+ touch the kernel.
73
+ - **Each image, line collection, or marker group is a single canvas object**,
74
+ so blitting works and drag interactions run at full frame rate.
75
+ - **The scope is deliberately limited.** The OO API only (no `plt.plot()`
76
+ global state), a curated set of plot types and marker styles, and raster
77
+ canvas output rather than vector graphics. For print-quality SVG/PDF
78
+ figures, matplotlib remains the right tool.
79
+
80
+ ## Features
81
+
82
+ - **Plot types** — `plot` (1-D lines with markers, linestyles, legends, log y),
83
+ `imshow` (2-D images with colormaps, colorbars, scale bars, overlay masks),
84
+ `pcolormesh` (non-uniform 2-D meshes), `bar` (grouped, horizontal, log,
85
+ value labels), and 3-D `plot_surface` / `scatter3d` / `plot3d`.
86
+ - **Layouts** — `subplots`, matplotlib-compatible `GridSpec` indexing
87
+ (slices, spans, negative indices), `width_ratios`/`height_ratios`,
88
+ `sharex`/`sharey` linked pan-zoom, and floating inset axes with
89
+ minimize/maximize.
90
+ - **Markers** — static overlays (points, circles, ellipses, rectangles,
91
+ polygons, arrows, line segments, text, h/v lines) with matplotlib-style
92
+ kwargs and live `.set()` updates.
93
+ - **Widgets** — draggable overlays (`RectangleWidget`, `CircleWidget`,
94
+ `AnnularWidget`, `CrosshairWidget`, `PolygonWidget`, `VLineWidget`,
95
+ `HLineWidget`, `RangeWidget`, …) that report positions back to Python.
96
+ - **Events** — a two-tier callback system: `pointer_move` fires every drag
97
+ frame for cheap updates; `pointer_settled` / `pointer_up` fire once for
98
+ expensive recomputation. Plus `key_down`, `wheel`, `double_click`, and
99
+ per-line scoped handlers.
100
+ - **Interactive docs** — the bundled `anyplotlib.sphinx_anywidget` extension
101
+ makes any anywidget figure live in Sphinx Gallery pages via Pyodide — no
102
+ kernel or server needed.
103
+ - **Embeddable anywhere** — figures don't require Jupyter. Export
104
+ self-contained HTML (`fig.save_html("plot.html")`), mount the renderer
105
+ directly in an Electron app or web page via the JS `mount()` API, or run a
106
+ live Python backend over any transport with `anyplotlib.embed.FigureBridge`
107
+ (full callback support). See the embedding guide in the docs.
108
+
109
+ ```python
110
+ import numpy as np
111
+ import anyplotlib as apl
112
+
113
+ fig, (ax_img, ax_spec) = apl.subplots(1, 2, figsize=(900, 400))
114
+ img = ax_img.imshow(stack.mean(axis=2), cmap="viridis")
115
+ spec = ax_spec.plot(stack[64, 64], units="eV")
116
+
117
+ cross = img.add_widget("crosshair", cx=64, cy=64)
118
+
119
+ @cross.add_event_handler("pointer_move") # every drag frame — keep it cheap
120
+ def update(event):
121
+ spec.set_data(stack[int(cross.cy), int(cross.cx)])
122
+ ```
123
+
124
+ ## Installation
125
+
126
+ ```bash
127
+ pip install anyplotlib
128
+ ```
129
+
130
+ Works anywhere anywidget does: JupyterLab, Jupyter Notebook, VS Code,
131
+ PyCharm, Google Colab, and marimo. Dependencies are intentionally light:
132
+ `anywidget`, `numpy`, `traitlets`, and `colorcet` (no matplotlib required).
133
+
134
+ ## Documentation
135
+
136
+ Full docs, a live example gallery (interactive in the browser — no install),
137
+ and the event-system guide are at
138
+ **[cssfrancis.github.io/anyplotlib](https://cssfrancis.github.io/anyplotlib/)**.
139
+
140
+ ## Development
141
+
142
+ ```bash
143
+ git clone https://github.com/CSSFrancis/anyplotlib
144
+ cd anyplotlib
145
+ uv sync # install with dev dependencies
146
+ uv run playwright install chromium # browsers for rendering tests
147
+ uv run pytest # full suite (unit + Playwright + visual)
148
+ make html # build the docs locally
149
+ ```
150
+
151
+ The architecture is a single `anywidget.AnyWidget` (`Figure`) that owns all
152
+ traitlets; plot objects are plain Python classes that serialise their state
153
+ dicts to per-panel traits, and `figure_esm.js` renders them. See
154
+ [AGENTS.md](AGENTS.md) for the codebase guide and
155
+ [`anyplotlib/FIGURE_ESM.md`](anyplotlib/FIGURE_ESM.md) for a map of the JS
156
+ renderer.
157
+
158
+ ## License
159
+
160
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,42 @@
1
+ anyplotlib/__init__.py,sha256=_u7ILZ2e7lyQxmpdWiQ6cFqkoo-gMzIdZ4bRT2myvK0,2036
2
+ anyplotlib/_base_plot.py,sha256=iqrsRrm8Slei0n730yp3zLd2EPQeWOyU0jqNuGtUxhU,7740
3
+ anyplotlib/_electron.py,sha256=pCSoUi7jMaucvPd8BsPWtHd1EMZS-SjdDtO9Z1Q9UmU,2245
4
+ anyplotlib/_repr_utils.py,sha256=9oU_v83zffwviO_uhzTUH1uJJrXy530k0TAij61jMfA,12946
5
+ anyplotlib/_utils.py,sha256=RH4N9QhU2RHPxpZXepnKuWpVOM8VrP-7yzcfIWHYkf4,6918
6
+ anyplotlib/callbacks.py,sha256=Pb8eD2Bo-TNLTvE0seig36TFI8JaIdnjxPuHPuflxNY,12285
7
+ anyplotlib/embed.py,sha256=cSDgjRSwqaJb6OvuJ5g3QFlNg0k0EEQH48VtVaR0K_I,7389
8
+ anyplotlib/figure_esm.js,sha256=zljDrA7dsYYWKrCgZSEAj3DuTY5Vi3CV6wUwkjQkwcg,269142
9
+ anyplotlib/markers.py,sha256=VGIN3imVgxMI1vnw0mqOE9q18Aa7qaP_fjEokxF7788,25066
10
+ anyplotlib/axes/__init__.py,sha256=vsMU_WjFcha17Xozxe7v4_oYQ_6qatk8GZlbwKm-cAc,186
11
+ anyplotlib/axes/_axes.py,sha256=7o6gSQWK-85JSaftiDb0x84WFHXM60OLWg0JpFoVW-E,21964
12
+ anyplotlib/axes/_inset_axes.py,sha256=w_7lji2eyiuzGz5vpjMP3I3faPH6MdwSfWLXodq7E4M,4437
13
+ anyplotlib/figure/__init__.py,sha256=9492s6i5zyS47_x4tt9VrP2rFgeajSGuAm6EOH-2V1g,294
14
+ anyplotlib/figure/_figure.py,sha256=H667AK1X32A2vFLlP1sUm97SJ2gkBDa09GeQU5mVnP0,25997
15
+ anyplotlib/figure/_gridspec.py,sha256=LkNepJxzb1ycM3C_uNQlhbq-4LwhGSWt9wIwycT7K5I,3756
16
+ anyplotlib/figure/_subplots.py,sha256=E7kpJ4Y6BA9iXEBLNfSDXJjxf-O-gHQUweHfMd0Nivs,3425
17
+ anyplotlib/plot1d/__init__.py,sha256=xjnzGsO0yjzoE1Rg9yVyFsMgtBzL90jJF7gAFuS0YR0,210
18
+ anyplotlib/plot1d/_plot1d.py,sha256=F64qCQzgSLkj2xWXlMS-2n47GkPBfpcGsdkRx0qMdw0,54308
19
+ anyplotlib/plot1d/_plotbar.py,sha256=2hbj3I86TJr5Zds4a179iNQ9CyQTG8ys9MqY8xBTX_Y,17356
20
+ anyplotlib/plot2d/__init__.py,sha256=g1evLODxN8zPHY4QfS5zEPeuBr_Lu3YIj5bJ1cpBx-M,205
21
+ anyplotlib/plot2d/_plot2d.py,sha256=dl7AHIEiCxNQG5-6zUpPhoS7V8dq5tgrVujPDeItKNI,33442
22
+ anyplotlib/plot2d/_plotmesh.py,sha256=apuGaTApj36sY1fFYr_l3xPie_y5QsiSYG1pAMHsSfg,4533
23
+ anyplotlib/plot3d/__init__.py,sha256=m851XQKGzx5bywIbBK0qntBxzJU7zwxqf6xnOQ8pD1M,138
24
+ anyplotlib/plot3d/_plot3d.py,sha256=dazOH3a8YXtWpEzkhz6f8vEfnX3xJl73UF9NOB6XjVI,21871
25
+ anyplotlib/plotxy/__init__.py,sha256=GsePPwkRzRUxai_vhe1KZpVZgnQIFABFbqw5o3cjU_Q,137
26
+ anyplotlib/plotxy/_plotxy.py,sha256=CP-tj464YhXeELWjJx9XozRAe6KsTnAv3CFSfDIAVKM,13043
27
+ anyplotlib/sphinx_anywidget/__init__.py,sha256=b9BhXg3LoQDYj167Zy5l5d-1sSNIrKIbP4cI_3bFmLA,6559
28
+ anyplotlib/sphinx_anywidget/_directive.py,sha256=_orXovvxqrfHmhu1Wi1DJGx3ITlhi9hdfd0qBaeNYjA,9229
29
+ anyplotlib/sphinx_anywidget/_repr_utils.py,sha256=7Mmcv1gnqiXpRd28i3iiI5Fcmt9iotkJQs8F4Wd3e1w,10144
30
+ anyplotlib/sphinx_anywidget/_scraper.py,sha256=Ku6T63uPvokTMOLalXlenfWCc1gcu1VEI4bvEmjNymo,14660
31
+ anyplotlib/sphinx_anywidget/_wheel_builder.py,sha256=Oi3202dXambMNf5OrObuMic5wkQapHOHzOaWAcsaKyw,2721
32
+ anyplotlib/sphinx_anywidget/static/anywidget_bridge.js,sha256=jPJ7l7JbzoVaFu5ofSbKQ-DGEV-N4n-7NH_9ZarHJrs,47029
33
+ anyplotlib/sphinx_anywidget/static/anywidget_overlay.css,sha256=TlIWo4OUsEZFNROH3UOOpEjrDu8ouulSF-x4qz60ilo,3590
34
+ anyplotlib/widgets/__init__.py,sha256=YUQqQxl2EO_dCMCVWsdZcm9AdzcijHFGOj5zv14V7uQ,633
35
+ anyplotlib/widgets/_base.py,sha256=oWaUFTAmDp1727MGDjK6XUDHxrW5nOhYtrpwXfh5za4,7611
36
+ anyplotlib/widgets/_widgets1d.py,sha256=iFqJd-9qEnB6mXzomUK8xj1dJ5Bpmprkgi7nJ4v1Vb4,3693
37
+ anyplotlib/widgets/_widgets2d.py,sha256=0mjiV5oAgOcWVQsJ63UvdGEgl7-ST-n0BTtX9ogMZWk,4355
38
+ anyplotlib/widgets/_widgets3d.py,sha256=zRd2q5O2KePxU5raCnvO-LatMlpGQjnDMPhG61d40Ks,1638
39
+ anyplotlib-0.1.0.dist-info/METADATA,sha256=55PdoxDikMMFC2rzngYiNI2JRRp2IxUfKF7T6K4WfVk,7068
40
+ anyplotlib-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
41
+ anyplotlib-0.1.0.dist-info/licenses/LICENSE,sha256=NonSXCjWxcYbaMxPnkgFzPpP0bVBTwUDpuDKyKC2uvQ,1071
42
+ anyplotlib-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Carter Francis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.