plotjs 0.0.4__tar.gz → 0.0.6__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.
- {plotjs-0.0.4 → plotjs-0.0.6}/.coverage +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/.github/workflows/doc.yaml +1 -1
- plotjs-0.0.6/.github/workflows/lint.yaml +29 -0
- plotjs-0.0.6/.github/workflows/tests-js.yaml +18 -0
- plotjs-0.0.4/.github/workflows/tests.yaml → plotjs-0.0.6/.github/workflows/tests-python.yaml +4 -5
- {plotjs-0.0.4 → plotjs-0.0.6}/.github/workflows/type.yaml +3 -2
- {plotjs-0.0.4 → plotjs-0.0.6}/.gitignore +3 -2
- {plotjs-0.0.4 → plotjs-0.0.6}/.pre-commit-config.yaml +0 -1
- plotjs-0.0.6/AGENTS.md +225 -0
- {plotjs-0.0.4/plotjs.egg-info → plotjs-0.0.6}/PKG-INFO +3 -3
- {plotjs-0.0.4 → plotjs-0.0.6}/README.md +1 -1
- plotjs-0.0.6/bun.lock +307 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/coverage-badge.svg +1 -1
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/developers/contributing.md +32 -7
- plotjs-0.0.6/docs/developers/overview.md +27 -0
- plotjs-0.0.4/docs/developers/how-it-works.md → plotjs-0.0.6/docs/developers/parsing-matplotlib-svg.md +5 -1
- plotjs-0.0.6/docs/developers/svg-parser-reference.md +123 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/gallery/index.md +18 -2
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/guides/advanced/advanced.py +79 -16
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/guides/advanced/index.md +90 -2
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/guides/css/CSS.py +5 -5
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/guides/css/index.md +6 -6
- plotjs-0.0.6/docs/guides/embed-graphs/index.md +104 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/guides/javascript/index.md +5 -5
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/guides/javascript/javascript.py +3 -3
- plotjs-0.0.6/docs/guides/troubleshooting/index.md +194 -0
- plotjs-0.0.6/docs/iframes/CSS-2.html +1656 -0
- plotjs-0.0.6/docs/iframes/CSS.html +1652 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/iframes/area-natural-disasters.html +299 -217
- plotjs-0.0.6/docs/iframes/bug.html +1071 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/iframes/javascript.html +604 -522
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/iframes/javascript2.html +462 -380
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/iframes/quickstart.html +604 -522
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/iframes/quickstart10.html +466 -384
- plotjs-0.0.6/docs/iframes/quickstart11.html +2489 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/iframes/quickstart2.html +604 -522
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/iframes/quickstart3.html +605 -523
- plotjs-0.0.6/docs/iframes/quickstart4.html +1335 -0
- plotjs-0.0.6/docs/iframes/quickstart5.html +1595 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/iframes/quickstart6.html +305 -223
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/iframes/quickstart7.html +462 -380
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/iframes/quickstart8.html +303 -221
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/iframes/quickstart9.html +919 -837
- plotjs-0.0.6/docs/iframes/random-walk-1.html +39128 -0
- plotjs-0.0.6/docs/img/overview.png +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/index.md +119 -44
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/index.qmd +103 -43
- plotjs-0.0.6/docs/reference/css.md +17 -0
- plotjs-0.0.6/docs/reference/plotjs.md +1 -0
- plotjs-0.0.6/docs/stylesheets/style.css +24 -0
- plotjs-0.0.4/Makefile → plotjs-0.0.6/justfile +16 -3
- {plotjs-0.0.4 → plotjs-0.0.6}/mkdocs.yaml +11 -3
- {plotjs-0.0.4 → plotjs-0.0.6}/overrides/partials/footer.html +1 -1
- plotjs-0.0.6/package.json +13 -0
- plotjs-0.0.6/plotjs/__init__.py +6 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/plotjs/css.py +1 -1
- {plotjs-0.0.4 → plotjs-0.0.6}/plotjs/javascript.py +1 -1
- {plotjs-0.0.4 → plotjs-0.0.6}/plotjs/main.py +157 -77
- plotjs-0.0.6/plotjs/static/plotparser.js +229 -0
- plotjs-0.0.6/plotjs/static/template.html +103 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/plotjs/utils.py +13 -0
- {plotjs-0.0.4 → plotjs-0.0.6/plotjs.egg-info}/PKG-INFO +3 -3
- {plotjs-0.0.4 → plotjs-0.0.6}/plotjs.egg-info/SOURCES.txt +23 -10
- {plotjs-0.0.4 → plotjs-0.0.6}/pyproject.toml +5 -3
- plotjs-0.0.6/tests/test-javascript/ParserSelectors.test.js +51 -0
- plotjs-0.0.6/tests/test-javascript/ParserSetHover.test.js +42 -0
- plotjs-0.0.6/tests/test-python/static/script2.js +1 -0
- plotjs-0.0.6/tests/test-python/static/style-invalid.css +1 -0
- plotjs-0.0.4/tests/test-python/test_css_and_js_utils.py → plotjs-0.0.6/tests/test-python/test_css.py +48 -8
- plotjs-0.0.6/tests/test-python/test_js.py +96 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/tests/test-python/test_main.py +4 -4
- plotjs-0.0.6/tests/test-python/test_other_utils.py +46 -0
- plotjs-0.0.6/tests/test-python/test_plotjs.py +145 -0
- plotjs-0.0.6/uv.lock +3334 -0
- plotjs-0.0.4/.github/workflows/lint.yaml +0 -28
- plotjs-0.0.4/docs/guides/troubleshooting/index.md +0 -28
- plotjs-0.0.4/docs/iframes/CSS-2.html +0 -1574
- plotjs-0.0.4/docs/iframes/CSS.html +0 -1570
- plotjs-0.0.4/docs/iframes/quickstart11.html +0 -2407
- plotjs-0.0.4/docs/iframes/quickstart4.html +0 -1253
- plotjs-0.0.4/docs/iframes/quickstart5.html +0 -1507
- plotjs-0.0.4/docs/reference/css.md +0 -13
- plotjs-0.0.4/docs/reference/magic-plot.md +0 -1
- plotjs-0.0.4/docs/stylesheets/style.css +0 -52
- plotjs-0.0.4/package-lock.json +0 -6317
- plotjs-0.0.4/package.json +0 -11
- plotjs-0.0.4/plotjs/__init__.py +0 -6
- plotjs-0.0.4/plotjs/static/main.js +0 -87
- plotjs-0.0.4/plotjs/static/template.html +0 -236
- plotjs-0.0.4/tests/PlotSVGParser.test.js +0 -83
- plotjs-0.0.4/tests/test-python/test_magic_plot.py +0 -13
- plotjs-0.0.4/vitest.config.js +0 -9
- {plotjs-0.0.4 → plotjs-0.0.6}/.gitattributes +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/.github/workflows/pypi.yaml +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/LICENSE +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/gallery/index.qmd +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/img/how-it-works-1.png +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/img/how-it-works-2.png +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/index_files/figure-commonmark/cell-3-output-1.png +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/reference/datasets.md +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/reference/javascript.md +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/docs/static/style.css +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/plotjs/data/__init__.py +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/plotjs/data/datasets.py +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/plotjs/data/iris.csv +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/plotjs/data/mtcars.csv +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/plotjs/data/titanic.csv +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/plotjs/static/default.css +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/plotjs.egg-info/dependency_links.txt +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/plotjs.egg-info/requires.txt +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/plotjs.egg-info/top_level.txt +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/setup.cfg +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/tests/test-python/__init__.py +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/tests/test-python/static/script.js +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/tests/test-python/static/style.css +0 -0
- {plotjs-0.0.4 → plotjs-0.0.6}/tests/test-python/test_data.py +0 -0
|
Binary file
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Check code formatting
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
check-formatting:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout repository
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Install uv
|
|
18
|
+
uses: astral-sh/setup-uv@v5
|
|
19
|
+
with:
|
|
20
|
+
enable-cache: true
|
|
21
|
+
|
|
22
|
+
- name: Install the project
|
|
23
|
+
run: uv sync --all-groups
|
|
24
|
+
|
|
25
|
+
- name: Run Ruff format check
|
|
26
|
+
run: uv run ruff format --check .
|
|
27
|
+
|
|
28
|
+
- name: Run Ruff linting and auto-fix
|
|
29
|
+
run: uv run ruff check --fix .
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: Tests JavaScript
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: oven-sh/setup-bun@v2
|
|
15
|
+
with:
|
|
16
|
+
bun-version: latest
|
|
17
|
+
- run: bun install
|
|
18
|
+
- run: bun test
|
plotjs-0.0.4/.github/workflows/tests.yaml → plotjs-0.0.6/.github/workflows/tests-python.yaml
RENAMED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
name: Tests
|
|
1
|
+
name: Tests Python
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
pull_request:
|
|
5
5
|
branches: [main]
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
6
8
|
|
|
7
9
|
jobs:
|
|
8
10
|
build:
|
|
@@ -24,8 +26,5 @@ jobs:
|
|
|
24
26
|
- name: Install the project
|
|
25
27
|
run: uv sync --all-groups
|
|
26
28
|
|
|
27
|
-
- name: Install npm dependencies
|
|
28
|
-
run: npm install
|
|
29
|
-
|
|
30
29
|
- name: Run tests
|
|
31
|
-
run:
|
|
30
|
+
run: uv run pytest
|
plotjs-0.0.6/AGENTS.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# PlotJS - LLM Reference Guide
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
PlotJS is a Python package that transforms static matplotlib charts into interactive web visualizations. It exports matplotlib figures as SVG, parses them with JavaScript, and adds browser-based interactivity (tooltips, hover effects, grouping) without requiring chart re-serialization.
|
|
6
|
+
|
|
7
|
+
**Core Philosophy:** Leverage matplotlib's native SVG output + JavaScript DOM manipulation instead of recreating charts in D3/Altair.
|
|
8
|
+
|
|
9
|
+
## Quick Architecture
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Matplotlib Figure → SVG Export (Python) → HTML Template (Jinja2) → Interactive Browser (D3.js)
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Workflow:
|
|
16
|
+
|
|
17
|
+
1. **Python (PlotJS class):** Captures matplotlib figure as SVG string, collects tooltip/styling metadata
|
|
18
|
+
2. **Jinja2 Template:** Injects SVG + CSS + JavaScript parser + configuration into HTML
|
|
19
|
+
3. **Browser (PlotSVGParser):** Parses SVG structure to identify plot elements, attaches hover interactivity
|
|
20
|
+
|
|
21
|
+
## Key Components
|
|
22
|
+
|
|
23
|
+
### Python Module (`/plotjs/`)
|
|
24
|
+
|
|
25
|
+
**`main.py`** - Core `PlotJS` class with method chaining
|
|
26
|
+
|
|
27
|
+
- `__init__(fig, **savefig_kws)` - Converts matplotlib figure to SVG
|
|
28
|
+
- `add_tooltip(labels, groups, hover_nearest, ax)` - Configure hover tooltips
|
|
29
|
+
- `add_css(from_string)` - Add custom CSS styling
|
|
30
|
+
- `add_javascript(from_string)` - Add custom JavaScript
|
|
31
|
+
- `save(file_path)` / `as_html()` - Export to file or return HTML string
|
|
32
|
+
- Internal: `_set_plot_data_json()`, `_set_html()` - Prepare template data
|
|
33
|
+
|
|
34
|
+
**`css.py`** - CSS utilities
|
|
35
|
+
|
|
36
|
+
- `from_dict(css_dict)` - Convert Python dict to CSS
|
|
37
|
+
- `from_file(css_file)` - Load external CSS
|
|
38
|
+
- `is_css_like(s)` - Validate CSS syntax
|
|
39
|
+
|
|
40
|
+
**`javascript.py`** - JavaScript utilities
|
|
41
|
+
|
|
42
|
+
- `from_file(javascript_file)` - Load external JavaScript
|
|
43
|
+
|
|
44
|
+
**`utils.py`** - Internal helpers
|
|
45
|
+
|
|
46
|
+
- `_vector_to_list(vector, name)` - Convert pandas/numpy/lists using Narwhals
|
|
47
|
+
- `_get_and_sanitize_js(file_path, after_pattern)` - Extract JS code
|
|
48
|
+
|
|
49
|
+
**`data/datasets.py`** - Sample datasets (iris, mtcars, titanic) with Narwhals support
|
|
50
|
+
|
|
51
|
+
### Static Assets (`/plotjs/static/`)
|
|
52
|
+
|
|
53
|
+
**`template.html`** - Jinja2 template structure
|
|
54
|
+
|
|
55
|
+
- Injects: `{{ svg }}`, `{{ default_css }}`, `{{ additional_css }}`, `{{ js_parser }}`, `{{ plot_data_json }}`
|
|
56
|
+
- Creates tooltip container and D3-based event handling
|
|
57
|
+
|
|
58
|
+
**`plotparser.js`** - `PlotSVGParser` JavaScript class
|
|
59
|
+
|
|
60
|
+
- `findBars(svg, axes_class)` - Select bar chart elements
|
|
61
|
+
- `findPoints(svg, axes_class, tooltip_groups)` - Select scatter points
|
|
62
|
+
- `findLines(svg, axes_class)` - Select line chart elements
|
|
63
|
+
- `findAreas(svg, axes_class)` - Select filled area elements
|
|
64
|
+
- `nearestElementFromMouse(mouseX, mouseY, elements)` - Hover nearest detection
|
|
65
|
+
- `setHoverEffect(...)` - Attach mouseover handlers, show tooltips
|
|
66
|
+
|
|
67
|
+
**`default.css`** - Base styling for tooltips and hover states
|
|
68
|
+
|
|
69
|
+
## Technical Implementation Details
|
|
70
|
+
|
|
71
|
+
### SVG Parsing Strategy
|
|
72
|
+
|
|
73
|
+
Challenge: Identify plot elements in SVG without metadata.
|
|
74
|
+
|
|
75
|
+
Solution: Pattern-based CSS selectors targeting matplotlib's SVG structure:
|
|
76
|
+
|
|
77
|
+
| Element | SVG Pattern | Selector |
|
|
78
|
+
| -------------- | -------------------------------------- | -------------------------------------------------------- |
|
|
79
|
+
| Scatter Points | `<g id="PathCollection_N"> <use>` | `g#axes_class g[id^="PathCollection"] use` |
|
|
80
|
+
| Lines | `<g id="line2d_N"> <path>` | `g#axes_class g[id^="line2d"] path` (exclude axis lines) |
|
|
81
|
+
| Bars | `<g id="patch_N"> <path>` | `g#axes_class g[id^="patch"] path[clip-path]` |
|
|
82
|
+
| Areas | `<g id="FillBetweenPolyCollection_N">` | `g#axes_class g[id^="FillBetweenPolyCollection"] path` |
|
|
83
|
+
|
|
84
|
+
### Data Flow: Python → JavaScript
|
|
85
|
+
|
|
86
|
+
1. Python collects configuration:
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
plot_data_json = {
|
|
90
|
+
"tooltip_labels": [...],
|
|
91
|
+
"tooltip_groups": [...],
|
|
92
|
+
"tooltip_x_shift": 10,
|
|
93
|
+
"tooltip_y_shift": -10,
|
|
94
|
+
"hover_nearest": False,
|
|
95
|
+
"axes": {"axes_1": {...}, "axes_2": {...}}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
2. Jinja2 injects as JSON in HTML template
|
|
100
|
+
|
|
101
|
+
3. JavaScript accesses via `plot_data["axes"]["axes_1"]["tooltip_labels"]`
|
|
102
|
+
|
|
103
|
+
### Method Chaining
|
|
104
|
+
|
|
105
|
+
All methods return `self` for fluent API:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
PlotJS(fig).add_tooltip(...).add_css(...).save(...)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Multiple Axes Support
|
|
112
|
+
|
|
113
|
+
Each axes processed independently via `ax` parameter:
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
PlotJS(fig).add_tooltip(labels1, ax=ax1).add_tooltip(labels2, ax=ax2).save(...)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Reproducibility
|
|
120
|
+
|
|
121
|
+
Optional `seed` parameter ensures deterministic UUID generation for consistent output.
|
|
122
|
+
|
|
123
|
+
## File Structure
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
plotjs/
|
|
127
|
+
├── __init__.py # Package exports
|
|
128
|
+
├── main.py # Core PlotJS class (330 lines)
|
|
129
|
+
├── css.py # CSS utilities (100 lines)
|
|
130
|
+
├── javascript.py # JavaScript utilities (23 lines)
|
|
131
|
+
├── utils.py # Internal helpers (43 lines)
|
|
132
|
+
├── data/
|
|
133
|
+
│ ├── datasets.py # Sample datasets with Narwhals
|
|
134
|
+
│ └── *.csv # Data files
|
|
135
|
+
└── static/
|
|
136
|
+
├── template.html # Jinja2 HTML template (104 lines)
|
|
137
|
+
├── plotparser.js # SVG parser class (229 lines)
|
|
138
|
+
└── default.css # Default styles (41 lines)
|
|
139
|
+
|
|
140
|
+
tests/
|
|
141
|
+
├── test-python/ # Python unit tests
|
|
142
|
+
└── test-javascript/ # JavaScript unit tests (vitest + jsdom)
|
|
143
|
+
|
|
144
|
+
docs/ # Comprehensive documentation
|
|
145
|
+
├── index.md # Quickstart
|
|
146
|
+
├── guides/ # CSS, JavaScript, advanced usage
|
|
147
|
+
├── developers/ # Architecture, SVG parsing details
|
|
148
|
+
└── reference/ # API reference
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Dependencies
|
|
152
|
+
|
|
153
|
+
**Python:**
|
|
154
|
+
|
|
155
|
+
- matplotlib >= 3.10.0 (SVG export)
|
|
156
|
+
- jinja2 >= 3.0.0 (HTML templating)
|
|
157
|
+
- narwhals >= 2.0.0 (dataframe abstraction)
|
|
158
|
+
|
|
159
|
+
**JavaScript (via CDN):**
|
|
160
|
+
|
|
161
|
+
- d3 v7.9.0 (DOM manipulation via d3-selection)
|
|
162
|
+
|
|
163
|
+
**Python Version:** Requires 3.10+
|
|
164
|
+
|
|
165
|
+
## Critical Patterns & Limitations
|
|
166
|
+
|
|
167
|
+
### Plotting Order Requirement
|
|
168
|
+
|
|
169
|
+
**IMPORTANT:** Element order in matplotlib must match label/group array order.
|
|
170
|
+
|
|
171
|
+
The parser assigns tooltip data by index, not by element identity:
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
# PROBLEM: Mismatched order
|
|
175
|
+
for specie in df["species"].unique(): # Order: setosa, versicolor, virginica
|
|
176
|
+
ax.scatter(df[df["species"]==specie]["x"], df[df["species"]==specie]["y"])
|
|
177
|
+
PlotJS(...).add_tooltip(labels=df["species"]) # Order may differ
|
|
178
|
+
|
|
179
|
+
# SOLUTION: Plot all at once or ensure sorted order
|
|
180
|
+
ax.scatter(df["x"], df["y"], c=df["species"]) # All at once preserves order
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Hover Modes
|
|
184
|
+
|
|
185
|
+
- **Direct hover** (default): Highlights exactly what cursor hovers over
|
|
186
|
+
- **Nearest hover** (`hover_nearest=True`): Highlights closest element to cursor (useful for small points)
|
|
187
|
+
|
|
188
|
+
### Grouping Behavior
|
|
189
|
+
|
|
190
|
+
Elements with same `tooltip_groups` value highlight together and dim others on hover.
|
|
191
|
+
|
|
192
|
+
## Usage Example
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
import matplotlib.pyplot as plt
|
|
196
|
+
from plotjs import PlotJS
|
|
197
|
+
|
|
198
|
+
fig, ax = plt.subplots()
|
|
199
|
+
ax.scatter(x, y)
|
|
200
|
+
|
|
201
|
+
PlotJS(fig) \
|
|
202
|
+
.add_tooltip(
|
|
203
|
+
labels=["Point 1", "Point 2", ...],
|
|
204
|
+
groups=["Group A", "Group A", "Group B", ...],
|
|
205
|
+
hover_nearest=True
|
|
206
|
+
) \
|
|
207
|
+
.add_css(css.from_file("custom.css")) \
|
|
208
|
+
.add_javascript(javascript.from_file("custom.js")) \
|
|
209
|
+
.save("output.html")
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Testing
|
|
213
|
+
|
|
214
|
+
- **Python:** pytest with coverage
|
|
215
|
+
- **JavaScript:** vitest with jsdom (browser simulation)
|
|
216
|
+
|
|
217
|
+
## Documentation
|
|
218
|
+
|
|
219
|
+
See `/docs` for comprehensive guides:
|
|
220
|
+
|
|
221
|
+
- Quickstart and examples
|
|
222
|
+
- CSS/JavaScript customization
|
|
223
|
+
- SVG parsing deep dive
|
|
224
|
+
- Troubleshooting common issues
|
|
225
|
+
- API reference for all classes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plotjs
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.6
|
|
4
4
|
Summary: Turn static matplotlib charts into interactive web visualizations
|
|
5
5
|
Author-email: Joseph Barbier <joseph.barbierdarnal@mail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -11,7 +11,7 @@ Project-URL: Repository, https://github.com/y-sunflower/plotjs
|
|
|
11
11
|
Keywords: matplotlib,interactive,javascript,web,css,d3,mpld3,plotnine
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
14
|
-
Classifier: Development Status ::
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
15
|
Requires-Python: >=3.10
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
@@ -41,7 +41,7 @@ Dynamic: license-file
|
|
|
41
41
|
|
|
42
42
|
## Installation
|
|
43
43
|
|
|
44
|
-
From PyPI:
|
|
44
|
+
From PyPI (recommended):
|
|
45
45
|
|
|
46
46
|
```
|
|
47
47
|
pip install plotjs
|