natureplot 0.7.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.
- natureplot-0.7.0/.gitignore +10 -0
- natureplot-0.7.0/LICENSE +21 -0
- natureplot-0.7.0/PKG-INFO +118 -0
- natureplot-0.7.0/README.md +100 -0
- natureplot-0.7.0/hatch_build.py +21 -0
- natureplot-0.7.0/pyproject.toml +37 -0
- natureplot-0.7.0/src/natureplot/__init__.py +5 -0
- natureplot-0.7.0/src/natureplot/_assets/catalog.json +450 -0
- natureplot-0.7.0/src/natureplot/_assets/natureplot.global.js +33 -0
- natureplot-0.7.0/src/natureplot/_version.py +2 -0
- natureplot-0.7.0/src/natureplot/chart.py +158 -0
- natureplot-0.7.0/src/natureplot/py.typed +0 -0
- natureplot-0.7.0/tests/test_chart.py +114 -0
natureplot-0.7.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 NaturePlot.js contributors
|
|
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.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: natureplot
|
|
3
|
+
Version: 0.7.0
|
|
4
|
+
Summary: Create interactive nature-inspired SVG charts from Python, with an offline browser renderer.
|
|
5
|
+
Project-URL: JavaScript package, https://www.npmjs.com/package/natureplot
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: charts,html,jupyter,nature,svg,visualization
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# NaturePlot for Python
|
|
20
|
+
|
|
21
|
+
Create interactive nature-inspired SVG charts from Python data. All 50 NaturePlot.js chart types are included: growing calendars, forests, rivers, petals, natural instruments, and more.
|
|
22
|
+
|
|
23
|
+
The Python package embeds the NaturePlot.js browser renderer. It generates HTML for reports, notebooks, and web applications. Charts retain hover readings, keyboard selection, exact data tables, and SVG downloads. No Node.js, CDN, or Python runtime dependencies are needed by users.
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
Choose your Python package manager:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
python -m pip install natureplot
|
|
31
|
+
uv add natureplot
|
|
32
|
+
poetry add natureplot
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Python 3.10 or newer is required.
|
|
36
|
+
|
|
37
|
+
## Create a chart
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from natureplot import Chart
|
|
41
|
+
|
|
42
|
+
chart = Chart(
|
|
43
|
+
"forest",
|
|
44
|
+
data=[
|
|
45
|
+
{"label": "Online", "value": 42},
|
|
46
|
+
{"label": "Retail", "value": 28},
|
|
47
|
+
{"label": "Wholesale", "value": 18},
|
|
48
|
+
],
|
|
49
|
+
title="Orders by sales channel",
|
|
50
|
+
unit="orders",
|
|
51
|
+
theme="meadow",
|
|
52
|
+
)
|
|
53
|
+
chart.write_html("orders.html")
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Open `orders.html` in a browser. The complete JavaScript runtime is embedded, so the chart works offline. Use the **Download SVG** button to save the rendered SVG.
|
|
57
|
+
|
|
58
|
+
## Notebooks
|
|
59
|
+
|
|
60
|
+
Leave `chart` as the final expression in a notebook cell, or use `display(chart)`. The rich HTML representation uses an isolated iframe and requires a notebook frontend that permits JavaScript in trusted output. Each chart includes its runtime and does not modify the notebook's global JavaScript environment.
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from datetime import date
|
|
64
|
+
from natureplot import Chart
|
|
65
|
+
|
|
66
|
+
chart = Chart(
|
|
67
|
+
"garden",
|
|
68
|
+
data=[{"date": date(2026, 9, 1), "value": 8}],
|
|
69
|
+
start_date=date(2026, 9, 1),
|
|
70
|
+
days=30,
|
|
71
|
+
title="September orders",
|
|
72
|
+
)
|
|
73
|
+
chart
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Options and data
|
|
77
|
+
|
|
78
|
+
Options accept both Python `snake_case` and JavaScript `camelCase`: for example, `start_date` or `startDate`, `show_table` or `showTable`. Passing both spellings of one option is an error. Observation dictionary keys use the JavaScript API names, including `observedAt`, `expectedStart`, and `expectedEnd`.
|
|
79
|
+
|
|
80
|
+
Use `None` for missing readings, zero for measured zero, and `datetime.date` for calendar dates. NaN and Infinity are rejected. Integers must be within JavaScript's exact range, ±9,007,199,254,740,991; rescale larger quantities. For pandas, pass `frame.to_dict(orient="records")` with JSON-compatible values and replace missing numeric values with `None` first.
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from natureplot import chart_types
|
|
84
|
+
|
|
85
|
+
for key, metadata in chart_types().items():
|
|
86
|
+
print(key, metadata["category"], metadata["encoding"])
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
General input validation happens in Python. Chart-specific measurement rules, such as valid timeline intervals and maximum category counts, are checked by the shared JavaScript renderer when the page opens. Rendering errors appear as readable alerts in the document.
|
|
90
|
+
|
|
91
|
+
## API
|
|
92
|
+
|
|
93
|
+
- `Chart(chart_type, data, **options)` copies and serializes your data. Later mutations to the original list do not change the chart.
|
|
94
|
+
- `chart.to_dict()` returns a fresh dictionary of JavaScript chart options.
|
|
95
|
+
- `chart.to_html()` returns a complete, self-contained HTML document.
|
|
96
|
+
- `chart.to_html(full_document=False)` returns an embeddable HTML fragment. Scripts must be allowed and executed by the host; inserting it with `innerHTML` alone does not execute its scripts.
|
|
97
|
+
- `chart.to_html(full_document=False, include_js=False)` omits the runtime. Load the matching `natureplot.global.js` before the fragment.
|
|
98
|
+
- `chart.write_html(path)` writes UTF-8 HTML and returns the absolute `Path`.
|
|
99
|
+
- `chart_types()` returns metadata for all 50 built-in charts.
|
|
100
|
+
|
|
101
|
+
Interaction runs in the browser. Python `on_select` callbacks, live kernel synchronization, static PNG/PDF generation, server-side SVG rendering, and JavaScript custom renderer registration are not part of this Python API. Use the JavaScript API for client-side callbacks. Rendering allows inline scripts and styles, so a host's Content Security Policy must permit those or provide an integration of its own.
|
|
102
|
+
|
|
103
|
+
## Build from the monorepo
|
|
104
|
+
|
|
105
|
+
From the repository root:
|
|
106
|
+
|
|
107
|
+
```sh
|
|
108
|
+
npm run prepare:python
|
|
109
|
+
python3 -m venv .venv-packaging
|
|
110
|
+
.venv-packaging/bin/python -m pip install build twine
|
|
111
|
+
.venv-packaging/bin/python -m build python
|
|
112
|
+
.venv-packaging/bin/python -m twine check python/dist/*
|
|
113
|
+
python3 -m unittest discover -s python/tests
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`prepare:python` rebuilds the browser runtime and copies the version, catalog, runtime, and MIT license into this package. Building rejects missing assets, version mismatches, or a mismatched runtime checksum. The source distribution also includes the bundled runtime and can build a wheel without Node.js.
|
|
117
|
+
|
|
118
|
+
See `docs/PUBLISHING.md` in the monorepo for the npm and PyPI publishing steps. This project is MIT licensed.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# NaturePlot for Python
|
|
2
|
+
|
|
3
|
+
Create interactive nature-inspired SVG charts from Python data. All 50 NaturePlot.js chart types are included: growing calendars, forests, rivers, petals, natural instruments, and more.
|
|
4
|
+
|
|
5
|
+
The Python package embeds the NaturePlot.js browser renderer. It generates HTML for reports, notebooks, and web applications. Charts retain hover readings, keyboard selection, exact data tables, and SVG downloads. No Node.js, CDN, or Python runtime dependencies are needed by users.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
Choose your Python package manager:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
python -m pip install natureplot
|
|
13
|
+
uv add natureplot
|
|
14
|
+
poetry add natureplot
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Python 3.10 or newer is required.
|
|
18
|
+
|
|
19
|
+
## Create a chart
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from natureplot import Chart
|
|
23
|
+
|
|
24
|
+
chart = Chart(
|
|
25
|
+
"forest",
|
|
26
|
+
data=[
|
|
27
|
+
{"label": "Online", "value": 42},
|
|
28
|
+
{"label": "Retail", "value": 28},
|
|
29
|
+
{"label": "Wholesale", "value": 18},
|
|
30
|
+
],
|
|
31
|
+
title="Orders by sales channel",
|
|
32
|
+
unit="orders",
|
|
33
|
+
theme="meadow",
|
|
34
|
+
)
|
|
35
|
+
chart.write_html("orders.html")
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Open `orders.html` in a browser. The complete JavaScript runtime is embedded, so the chart works offline. Use the **Download SVG** button to save the rendered SVG.
|
|
39
|
+
|
|
40
|
+
## Notebooks
|
|
41
|
+
|
|
42
|
+
Leave `chart` as the final expression in a notebook cell, or use `display(chart)`. The rich HTML representation uses an isolated iframe and requires a notebook frontend that permits JavaScript in trusted output. Each chart includes its runtime and does not modify the notebook's global JavaScript environment.
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from datetime import date
|
|
46
|
+
from natureplot import Chart
|
|
47
|
+
|
|
48
|
+
chart = Chart(
|
|
49
|
+
"garden",
|
|
50
|
+
data=[{"date": date(2026, 9, 1), "value": 8}],
|
|
51
|
+
start_date=date(2026, 9, 1),
|
|
52
|
+
days=30,
|
|
53
|
+
title="September orders",
|
|
54
|
+
)
|
|
55
|
+
chart
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Options and data
|
|
59
|
+
|
|
60
|
+
Options accept both Python `snake_case` and JavaScript `camelCase`: for example, `start_date` or `startDate`, `show_table` or `showTable`. Passing both spellings of one option is an error. Observation dictionary keys use the JavaScript API names, including `observedAt`, `expectedStart`, and `expectedEnd`.
|
|
61
|
+
|
|
62
|
+
Use `None` for missing readings, zero for measured zero, and `datetime.date` for calendar dates. NaN and Infinity are rejected. Integers must be within JavaScript's exact range, ±9,007,199,254,740,991; rescale larger quantities. For pandas, pass `frame.to_dict(orient="records")` with JSON-compatible values and replace missing numeric values with `None` first.
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from natureplot import chart_types
|
|
66
|
+
|
|
67
|
+
for key, metadata in chart_types().items():
|
|
68
|
+
print(key, metadata["category"], metadata["encoding"])
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
General input validation happens in Python. Chart-specific measurement rules, such as valid timeline intervals and maximum category counts, are checked by the shared JavaScript renderer when the page opens. Rendering errors appear as readable alerts in the document.
|
|
72
|
+
|
|
73
|
+
## API
|
|
74
|
+
|
|
75
|
+
- `Chart(chart_type, data, **options)` copies and serializes your data. Later mutations to the original list do not change the chart.
|
|
76
|
+
- `chart.to_dict()` returns a fresh dictionary of JavaScript chart options.
|
|
77
|
+
- `chart.to_html()` returns a complete, self-contained HTML document.
|
|
78
|
+
- `chart.to_html(full_document=False)` returns an embeddable HTML fragment. Scripts must be allowed and executed by the host; inserting it with `innerHTML` alone does not execute its scripts.
|
|
79
|
+
- `chart.to_html(full_document=False, include_js=False)` omits the runtime. Load the matching `natureplot.global.js` before the fragment.
|
|
80
|
+
- `chart.write_html(path)` writes UTF-8 HTML and returns the absolute `Path`.
|
|
81
|
+
- `chart_types()` returns metadata for all 50 built-in charts.
|
|
82
|
+
|
|
83
|
+
Interaction runs in the browser. Python `on_select` callbacks, live kernel synchronization, static PNG/PDF generation, server-side SVG rendering, and JavaScript custom renderer registration are not part of this Python API. Use the JavaScript API for client-side callbacks. Rendering allows inline scripts and styles, so a host's Content Security Policy must permit those or provide an integration of its own.
|
|
84
|
+
|
|
85
|
+
## Build from the monorepo
|
|
86
|
+
|
|
87
|
+
From the repository root:
|
|
88
|
+
|
|
89
|
+
```sh
|
|
90
|
+
npm run prepare:python
|
|
91
|
+
python3 -m venv .venv-packaging
|
|
92
|
+
.venv-packaging/bin/python -m pip install build twine
|
|
93
|
+
.venv-packaging/bin/python -m build python
|
|
94
|
+
.venv-packaging/bin/python -m twine check python/dist/*
|
|
95
|
+
python3 -m unittest discover -s python/tests
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`prepare:python` rebuilds the browser runtime and copies the version, catalog, runtime, and MIT license into this package. Building rejects missing assets, version mismatches, or a mismatched runtime checksum. The source distribution also includes the bundled runtime and can build a wheel without Node.js.
|
|
99
|
+
|
|
100
|
+
See `docs/PUBLISHING.md` in the monorepo for the npm and PyPI publishing steps. This project is MIT licensed.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Reject incomplete or mismatched source distributions before upload."""
|
|
2
|
+
import hashlib
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CustomBuildHook(BuildHookInterface):
|
|
9
|
+
def initialize(self, version, build_data):
|
|
10
|
+
assets = Path(self.root) / "src/natureplot/_assets"
|
|
11
|
+
try:
|
|
12
|
+
catalog = json.loads((assets / "catalog.json").read_text(encoding="utf-8"))
|
|
13
|
+
bundle = (assets / "natureplot.global.js").read_bytes()
|
|
14
|
+
except FileNotFoundError as error:
|
|
15
|
+
raise RuntimeError("Missing browser assets. Run npm run prepare:python from the repository root.") from error
|
|
16
|
+
if catalog["version"] != self.metadata.version:
|
|
17
|
+
raise RuntimeError("Python and browser versions differ. Run npm run prepare:python.")
|
|
18
|
+
if hashlib.sha256(bundle).hexdigest() != catalog["bundle_sha256"]:
|
|
19
|
+
raise RuntimeError("Browser bundle checksum mismatch. Run npm run prepare:python.")
|
|
20
|
+
if len(catalog["charts"]) != 50:
|
|
21
|
+
raise RuntimeError("The Python distribution must include all 50 charts.")
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.27,<2"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "natureplot"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Create interactive nature-inspired SVG charts from Python, with an offline browser renderer."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
keywords = ["charts", "visualization", "svg", "nature", "jupyter", "html"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Intended Audience :: Science/Research",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Topic :: Scientific/Engineering :: Visualization",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
"JavaScript package" = "https://www.npmjs.com/package/natureplot"
|
|
26
|
+
|
|
27
|
+
[tool.hatch.version]
|
|
28
|
+
path = "src/natureplot/_version.py"
|
|
29
|
+
|
|
30
|
+
[tool.hatch.build.hooks.custom]
|
|
31
|
+
path = "hatch_build.py"
|
|
32
|
+
|
|
33
|
+
[tool.hatch.build.targets.wheel]
|
|
34
|
+
packages = ["src/natureplot"]
|
|
35
|
+
|
|
36
|
+
[tool.hatch.build.targets.sdist]
|
|
37
|
+
include = ["/src", "/tests", "/pyproject.toml", "/hatch_build.py", "/README.md", "/LICENSE"]
|