rustplotlib 5.0.0__tar.gz → 5.1.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.
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/CLAUDE.md +5 -5
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/Cargo.lock +1 -1
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/Cargo.toml +1 -1
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/PKG-INFO +121 -56
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/README.md +119 -54
- rustplotlib-5.1.0/ROADMAP.md +220 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/pyproject.toml +2 -2
- rustplotlib-5.1.0/python/rustplotlib/animation.py +221 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/backends/__init__.py +6 -0
- rustplotlib-5.1.0/python/rustplotlib/backends/backend_pdf.py +152 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/backends/backend_tk.py +55 -0
- rustplotlib-5.1.0/python/rustplotlib/backends/backend_webagg.py +292 -0
- rustplotlib-5.1.0/python/rustplotlib/collections.py +112 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/colors.py +65 -0
- rustplotlib-5.1.0/python/rustplotlib/dates.py +237 -0
- rustplotlib-5.1.0/python/rustplotlib/gridspec.py +75 -0
- rustplotlib-5.1.0/python/rustplotlib/mpl_toolkits/axes_grid1/__init__.py +5 -0
- rustplotlib-5.1.0/python/rustplotlib/mpl_toolkits/axes_grid1/axes_divider.py +89 -0
- rustplotlib-5.1.0/python/rustplotlib/patheffects.py +111 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/pyplot.py +1621 -99
- rustplotlib-5.1.0/python/rustplotlib/pyplot.pyi +223 -0
- rustplotlib-5.1.0/python/rustplotlib/style/__init__.py +174 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/ticker.py +17 -40
- rustplotlib-5.1.0/python/rustplotlib/transforms.py +166 -0
- rustplotlib-5.1.0/python/rustplotlib/widgets.py +399 -0
- rustplotlib-5.1.0/src/artists/colorbar_artist.rs +201 -0
- rustplotlib-5.1.0/src/artists/fancy_arrow.rs +319 -0
- rustplotlib-5.1.0/src/artists/image.rs +1775 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/line2d.rs +158 -13
- rustplotlib-5.1.0/src/artists/line_collection.rs +113 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/mod.rs +215 -0
- rustplotlib-5.1.0/src/artists/widget.rs +203 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/axes.rs +421 -72
- rustplotlib-5.1.0/src/colors.rs +285 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/figure.rs +731 -38
- rustplotlib-5.1.0/src/lib.rs +85 -0
- rustplotlib-5.1.0/src/mathtext.rs +703 -0
- rustplotlib-5.1.0/src/parse.rs +374 -0
- rustplotlib-5.1.0/src/projections.rs +240 -0
- rustplotlib-5.1.0/src/transforms.rs +245 -0
- rustplotlib-5.1.0/tests/test_advanced_customization.py +118 -0
- rustplotlib-5.1.0/tests/test_axes_figure_api.py +286 -0
- rustplotlib-5.1.0/tests/test_colorbar_annotations.py +148 -0
- rustplotlib-5.1.0/tests/test_colormaps.py +92 -0
- rustplotlib-5.1.0/tests/test_layout.py +137 -0
- rustplotlib-5.1.0/tests/test_markers.py +90 -0
- rustplotlib-5.1.0/tests/test_output_formats.py +88 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_phase8.py +17 -15
- rustplotlib-5.1.0/tests/test_polar.py +160 -0
- rustplotlib-5.1.0/tests/test_regression.py +204 -0
- rustplotlib-5.1.0/tests/test_spine_positioning.py +180 -0
- rustplotlib-5.1.0/tests/test_styles.py +121 -0
- rustplotlib-5.1.0/tests/test_triangulation.py +171 -0
- rustplotlib-5.1.0/tests/test_v5_features.py +744 -0
- rustplotlib-5.1.0/tests/test_widgets.py +259 -0
- rustplotlib-5.0.0/ROADMAP.md +0 -200
- rustplotlib-5.0.0/python/rustplotlib/animation.py +0 -94
- rustplotlib-5.0.0/python/rustplotlib/backends/backend_pdf.py +0 -56
- rustplotlib-5.0.0/python/rustplotlib/collections.py +0 -70
- rustplotlib-5.0.0/python/rustplotlib/dates.py +0 -87
- rustplotlib-5.0.0/python/rustplotlib/gridspec.py +0 -30
- rustplotlib-5.0.0/python/rustplotlib/patheffects.py +0 -36
- rustplotlib-5.0.0/python/rustplotlib/pyplot.pyi +0 -96
- rustplotlib-5.0.0/python/rustplotlib/style/__init__.py +0 -70
- rustplotlib-5.0.0/python/rustplotlib/transforms.py +0 -68
- rustplotlib-5.0.0/python/rustplotlib/widgets.py +0 -75
- rustplotlib-5.0.0/src/artists/image.rs +0 -757
- rustplotlib-5.0.0/src/colors.rs +0 -161
- rustplotlib-5.0.0/src/lib.rs +0 -47
- rustplotlib-5.0.0/src/transforms.rs +0 -104
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/.github/workflows/ci.yml +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/.gitignore +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/CONTRIBUTING.md +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/LICENSE +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/benchmark_results.csv +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/dados/Data/PerfisTemp_rustplotlib.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/docs/superpowers/plans/2026-04-04-jupyter-and-event-foundation.md +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/__init__.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/axes/__init__.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/backends/backend_base.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/backends/backend_inline.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/callback_registry.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/cm.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/cycler.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/events.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/figure.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/font_manager.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/lines.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/mpl_toolkits/__init__.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/mpl_toolkits/mplot3d/__init__.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/patches.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/spines.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/python/rustplotlib/text.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/arrow.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/bar.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/bar3d.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/barh.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/boxplot.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/broken_barh.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/contour.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/contour3d.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/errorbar.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/eventplot.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/fill_between.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/fill_betweenx.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/fill_polygon.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/hexbin.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/hist.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/legend.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/line3d.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/patches.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/pcolormesh.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/pie.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/quiver.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/radar.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/sankey.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/scatter.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/scatter3d.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/stem.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/step.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/streamplot.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/surface3d.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/trisurf3d.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/violin.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/artists/wireframe3d.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/axes3d.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/fonts/DejaVuSans.ttf +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/projection3d.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/svg_renderer.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/text.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/ticker.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/src/window.rs +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_3d.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_backend_tk.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_benchmark.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_colors.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_events.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_figure.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_jupyter_repr.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_new_features.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_new_features2.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_phase6_7.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_phase9_features.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_pyplot.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_spectral_features.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_ticker.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_transforms.py +0 -0
- {rustplotlib-5.0.0 → rustplotlib-5.1.0}/tests/test_v3_features.py +0 -0
|
@@ -11,10 +11,11 @@ Reimplementação completa do matplotlib em Rust puro. Drop-in replacement via P
|
|
|
11
11
|
- 40+ plot types 2D, 7 plot types 3D
|
|
12
12
|
- 70+ colormaps (35 base + 35 reversed)
|
|
13
13
|
- 25 módulos Python compatíveis com API matplotlib
|
|
14
|
-
-
|
|
15
|
-
- Tk backend interativo com toolbar,
|
|
14
|
+
- 550+ testes passando
|
|
15
|
+
- Tk backend interativo com toolbar, zoom/pan funcional, pixel-to-data mapping
|
|
16
16
|
- Jupyter rich display (`_repr_png_`, `_repr_svg_`, `_repr_html_`)
|
|
17
17
|
- Sistema de eventos com `CallbackRegistry` e `mpl_connect`/`mpl_disconnect`
|
|
18
|
+
- Widgets funcionais: Slider, Button, CheckButtons, RadioButtons, TextBox, RangeSlider
|
|
18
19
|
- Backend auto-detection (inline/tk/agg)
|
|
19
20
|
- Output: PNG (tiny-skia), SVG nativo, PDF, GIF, janela interativa
|
|
20
21
|
- Performance: até 16x mais rápido que matplotlib (benchmark real com 12 testes)
|
|
@@ -51,7 +52,7 @@ python/rustplotlib/ # Camada Python
|
|
|
51
52
|
├── dates.py, colors.py, patches.py, ...
|
|
52
53
|
└── mpl_toolkits/mplot3d/ # Suporte 3D
|
|
53
54
|
|
|
54
|
-
tests/ # Testes Python (
|
|
55
|
+
tests/ # Testes Python (326 testes)
|
|
55
56
|
```
|
|
56
57
|
|
|
57
58
|
## Stack Técnica
|
|
@@ -107,8 +108,7 @@ cargo check # Verificar compilação Rust
|
|
|
107
108
|
Próximos itens prioritários (ver ROADMAP.md para lista completa):
|
|
108
109
|
|
|
109
110
|
1. **Backends adicionais** — Qt, GTK, WebAgg, macOS native
|
|
110
|
-
2. **
|
|
111
|
-
3. **Features interativas** — pick events, rotação 3D, blitting
|
|
111
|
+
2. **Features interativas** — pick events, rotação 3D, blitting
|
|
112
112
|
4. **Triangulation plots** — tricontour, tricontourf, tripcolor (atualmente stubs)
|
|
113
113
|
5. **Customização avançada** — spine positioning, TwoSlopeNorm, interpolação bicúbica
|
|
114
114
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rustplotlib
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.1.0
|
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
|
5
5
|
Classifier: Intended Audience :: Science/Research
|
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -9,7 +9,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
9
9
|
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
10
10
|
Requires-Dist: numpy
|
|
11
11
|
License-File: LICENSE
|
|
12
|
-
Summary: Matplotlib drop-in replacement powered by Rust
|
|
12
|
+
Summary: Matplotlib drop-in replacement powered by Rust — 50 plot types, 15 interpolation modes, 81 colormaps, up to 18.7x faster
|
|
13
13
|
Keywords: matplotlib,plotting,visualization,rust,performance
|
|
14
14
|
License: MIT
|
|
15
15
|
Requires-Python: >=3.9
|
|
@@ -37,7 +37,7 @@ No Python runtime dependency for rendering. No wrappers. No subprocess calls. Pu
|
|
|
37
37
|
|---|---|---|---|
|
|
38
38
|
| Rendering engine | C/C++ (AGG) | None (wrap matplotlib or call Python) | **Rust native (tiny-skia)** |
|
|
39
39
|
| External dependencies | NumPy, Pillow, FreeType, etc. | Python + matplotlib required | **Zero** — self-contained |
|
|
40
|
-
| Performance | Baseline | Same or slower (subprocess overhead) | **Up to
|
|
40
|
+
| Performance | Baseline | Same or slower (subprocess overhead) | **Up to 18.7x faster** |
|
|
41
41
|
| Python API | Original | Rust-only or generates .py scripts | **Drop-in replacement** — same API |
|
|
42
42
|
| Approach | Interpreted + C extensions | Wrappers / code generators | **Full reimplementation in Rust** |
|
|
43
43
|
|
|
@@ -195,62 +195,121 @@ plt.show()
|
|
|
195
195
|
### Output Formats
|
|
196
196
|
| Method | Description |
|
|
197
197
|
|---|---|
|
|
198
|
-
| `savefig("file.png")` | Raster PNG (with dpi, transparent
|
|
198
|
+
| `savefig("file.png")` | Raster PNG (with dpi, transparent, bbox_inches='tight') |
|
|
199
199
|
| `savefig("file.svg")` | Native vector SVG (real `<line>`, `<text>`, `<rect>` elements) |
|
|
200
200
|
| `savefig("file.pdf")` | PDF output |
|
|
201
|
-
| `
|
|
202
|
-
| `
|
|
201
|
+
| `savefig("file.eps")` | EPS output |
|
|
202
|
+
| `show()` | Interactive window with backend auto-detection |
|
|
203
|
+
| `PdfPages` | Multi-page PDF with zlib compression |
|
|
204
|
+
| `pickle` | Save/load figures with pickle |
|
|
205
|
+
| `copy_to_clipboard()` | Copy figure as PNG to system clipboard |
|
|
206
|
+
| `to_json()` / `save_json()` | Export figure state as JSON |
|
|
203
207
|
|
|
204
208
|
### Backends & Interactive
|
|
205
209
|
| Feature | Description |
|
|
206
210
|
|---|---|
|
|
207
211
|
| Backend auto-detection | Automatically selects inline (Jupyter), Tk, or Agg backend |
|
|
208
|
-
| Tk backend | Interactive window with
|
|
209
|
-
|
|
|
212
|
+
| Tk backend | Interactive window with toolbar, zoom/pan, coordinate display |
|
|
213
|
+
| WebAgg backend | Browser-based interactive viewer via HTTP server |
|
|
214
|
+
| Navigation toolbar | Home, Back, Forward, Pan, Zoom, Save (Tk + WebAgg) |
|
|
210
215
|
| Event system | `mpl_connect` / `mpl_disconnect` with `CallbackRegistry` |
|
|
211
|
-
|
|
|
212
|
-
| Key events |
|
|
213
|
-
| Draw/Resize/Close events | `DrawEvent`, `ResizeEvent`, `CloseEvent` |
|
|
216
|
+
| Pick events | Artist hit testing backed by Rust (`hit_test_points`, `hit_test_line`) |
|
|
217
|
+
| Mouse/Key/Scroll events | Full event hierarchy: MouseEvent, KeyEvent, PickEvent, DrawEvent, ResizeEvent, CloseEvent |
|
|
214
218
|
| Jupyter rich display | `_repr_png_()`, `_repr_svg_()`, `_repr_html_()` on Figure |
|
|
215
|
-
|
|
|
216
|
-
| `render_to_rgba_buffer()` | Raw RGBA buffer (PyO3) for interactive backends |
|
|
219
|
+
| 3D mouse rotation | Drag to rotate 3D view in Tk backend |
|
|
217
220
|
|
|
218
221
|
### Animation
|
|
219
222
|
| Feature | Description |
|
|
220
223
|
|---|---|
|
|
221
|
-
| `FuncAnimation` | Function-based animation with
|
|
224
|
+
| `FuncAnimation` | Function-based animation with blit support, pause/resume |
|
|
225
|
+
| `ArtistAnimation` | Frame-based animation from artist lists |
|
|
222
226
|
| GIF export | Save animations as GIF (via Pillow) |
|
|
223
|
-
|
|
|
227
|
+
| Live animation | Real-time animation in Tk backend |
|
|
228
|
+
|
|
229
|
+
### Layout Engines
|
|
230
|
+
| Feature | Description |
|
|
231
|
+
|---|---|
|
|
232
|
+
| `tight_layout()` | Dynamic margins from text measurement (Rust) |
|
|
233
|
+
| `constrained_layout=True` | Constraint-based layout engine (Rust) |
|
|
234
|
+
| `GridSpec(nrows, ncols)` | Grid layout with `rowspan`/`colspan` |
|
|
235
|
+
| `SubFigure` | Nested sub-figures with independent layouts |
|
|
236
|
+
| `Figure.add_axes([l,b,w,h])` | Custom axes positioning |
|
|
237
|
+
| `make_axes_locatable` | Axes divider for colorbar positioning |
|
|
238
|
+
|
|
239
|
+
### Widgets (Rust-rendered)
|
|
240
|
+
| Widget | Features |
|
|
241
|
+
|---|---|
|
|
242
|
+
| `Slider` | Track, thumb circle, label, value display, on_changed callbacks |
|
|
243
|
+
| `RangeSlider` | Tuple values, clamp, callbacks |
|
|
244
|
+
| `Button` | Background, border, label, on_clicked callbacks |
|
|
245
|
+
| `CheckButtons` | Toggle, get_status, callbacks |
|
|
246
|
+
| `RadioButtons` | Exclusive selection, value_selected |
|
|
247
|
+
| `TextBox` | on_submit, on_text_change, set_val |
|
|
248
|
+
| `Cursor` | Crosshair following mouse, on_moved callbacks |
|
|
249
|
+
| `MultiCursor` | Cursor spanning multiple axes |
|
|
250
|
+
|
|
251
|
+
### Transform System
|
|
252
|
+
| Component | Description |
|
|
253
|
+
|---|---|
|
|
254
|
+
| `Affine2D` | 2D affine matrix (rotate, scale, translate, compose, invert) — **Rust** |
|
|
255
|
+
| `BlendedTransform` | Separate X/Y transforms — **Rust** |
|
|
256
|
+
| `ax.transData` | Data coordinate transform |
|
|
257
|
+
| `ax.transAxes` | Axes coordinate transform (0-1) |
|
|
258
|
+
| `fig.transFigure` | Figure coordinate transform |
|
|
224
259
|
|
|
225
260
|
### Styles & Themes
|
|
226
261
|
| Feature | Description |
|
|
227
262
|
|---|---|
|
|
228
|
-
| `style.use('dark_background')` |
|
|
263
|
+
| `style.use('dark_background')` | 13 built-in themes (default, dark_background, ggplot, seaborn, bmh, fivethirtyeight, grayscale, Solarize_Light2, tableau-colorblind10, seaborn-whitegrid, seaborn-darkgrid, seaborn-dark, fast) |
|
|
264
|
+
| `style.available` | List all available styles |
|
|
265
|
+
| `style.context('ggplot')` | Context manager for temporary style |
|
|
229
266
|
| `rcParams` | Functional global configuration (30+ supported keys) |
|
|
230
267
|
| `set_facecolor()` | Figure and axes background colors |
|
|
231
268
|
|
|
232
269
|
### Colors
|
|
233
|
-
- **Named:**
|
|
270
|
+
- **Named:** 140+ colors including all CSS/X11 colors (steelblue, coral, tomato, gold, crimson, dodgerblue, forestgreen, etc.)
|
|
234
271
|
- **Shorthand:** `"r"`, `"g"`, `"b"`, `"c"`, `"m"`, `"y"`, `"k"`, `"w"`
|
|
235
272
|
- **Hex:** `"#FF0000"`, `"#f00"`, `"#FF000080"`
|
|
236
273
|
- **RGB/RGBA tuples:** `(1.0, 0.0, 0.0)`, `(1.0, 0.0, 0.0, 0.5)`
|
|
274
|
+
- **Grey/gray variants:** both spellings supported
|
|
237
275
|
|
|
238
276
|
### Linestyles & Markers
|
|
239
277
|
- **Linestyles:** `-` (solid), `--` (dashed), `-.` (dashdot), `:` (dotted)
|
|
240
|
-
- **Markers:** `.` `o` `s` `^` `v` `+` `x` `D` `*`
|
|
241
|
-
- **Format strings:** `"r--o"` = red + dashed + circle markers
|
|
278
|
+
- **Markers:** `.` `o` `s` `^` `v` `<` `>` `+` `x` `D` `d` `*` `p` `h` `H` `8` `|` `_` `P` `X` `1` `2` `3` `4` (24 types)
|
|
279
|
+
- **Format strings:** `"r--o"` = red + dashed + circle markers (parsed in Rust)
|
|
242
280
|
- **markevery:** show marker every N points
|
|
243
281
|
|
|
244
|
-
### Colormaps (
|
|
245
|
-
|
|
282
|
+
### Colormaps (81 base + reversed = ~162 total)
|
|
283
|
+
`viridis` `plasma` `inferno` `magma` `cividis` `twilight` `twilight_shifted` `turbo` `hot` `cool` `coolwarm` `bwr` `seismic` `gray` `jet` `spring` `summer` `autumn` `winter` `copper` `bone` `pink` `binary` `ocean` `terrain` `rainbow` `Blues` `Reds` `Greens` `Oranges` `Purples` `Greys` `YlOrRd` `YlOrBr` `YlGnBu` `YlGn` `OrRd` `BuGn` `BuPu` `GnBu` `PuBu` `PuRd` `RdPu` `PuBuGn` `RdYlBu` `RdBu` `RdGy` `RdYlGn` `PiYG` `PRGn` `BrBG` `PuOr` `Spectral` `Set1` `Set2` `Set3` `Pastel1` `Pastel2` `tab10` `tab20` `tab20b` `tab20c` `Paired` `Accent` `Dark2` `afmhot` `brg` `CMRmap` `Wistia` `cubehelix` `hsv` `gnuplot` `gnuplot2` `gist_earth` `gist_heat` `gist_ncar` `gist_rainbow` `gist_stern` `gist_yarg` `flag` `prism`
|
|
246
284
|
|
|
247
|
-
|
|
285
|
+
All also available reversed with `_r` suffix.
|
|
248
286
|
|
|
249
|
-
|
|
287
|
+
### Image Interpolation (15 modes)
|
|
288
|
+
`nearest` `bilinear` `bicubic` `lanczos` `spline16` `hanning` `hamming` `hermite` `kaiser` `quadric` `catrom` `gaussian` `bessel` `mitchell` `sinc`
|
|
250
289
|
|
|
251
|
-
### Text Rendering
|
|
290
|
+
### Text & Math Rendering
|
|
252
291
|
- Embedded DejaVu Sans font (no system font dependency)
|
|
253
|
-
-
|
|
292
|
+
- **Full TeX math engine in Rust:**
|
|
293
|
+
- Greek letters (24 lowercase + 12 uppercase)
|
|
294
|
+
- Subscript/superscript with Unicode characters
|
|
295
|
+
- Stacked fractions (`\frac{a}{b}`) with horizontal bar
|
|
296
|
+
- Square roots (`\sqrt{x}`) with radical sign
|
|
297
|
+
- Integral/sum/product with limits (`\int_a^b`, `\sum_{i=0}^n`)
|
|
298
|
+
- Accents: `\hat`, `\tilde`, `\vec`, `\dot`, `\ddot`, `\overline`, `\underline`
|
|
299
|
+
- Delimiters: `\left(`, `\right)`, `\langle`, `\rangle`, `\lceil`, `\lfloor`
|
|
300
|
+
- Matrices with bracket rendering
|
|
301
|
+
- 60+ math operators and symbols
|
|
302
|
+
|
|
303
|
+
### Geographic Projections (5 types)
|
|
304
|
+
| Projection | Function |
|
|
305
|
+
|---|---|
|
|
306
|
+
| Hammer | `hammer_project(lon, lat)` |
|
|
307
|
+
| Aitoff | `aitoff_project(lon, lat)` |
|
|
308
|
+
| Mollweide | `mollweide_project(lon, lat)` |
|
|
309
|
+
| Lambert Conformal Conic | `lambert_project(lon, lat, lat1, lat2)` |
|
|
310
|
+
| Stereographic | `stereographic_project(lon, lat, lon0, lat0)` |
|
|
311
|
+
|
|
312
|
+
All with batch versions and `generate_graticule()` for grid lines.
|
|
254
313
|
|
|
255
314
|
### Data Integration
|
|
256
315
|
- **Pandas:** plot directly from DataFrame/Series (optional dependency)
|
|
@@ -265,7 +324,7 @@ All also available as `viridis_r`, `plasma_r`, `hot_r`, etc.
|
|
|
265
324
|
| `rustplotlib.pyplot` | Full implementation (50+ functions) |
|
|
266
325
|
| `rustplotlib.style` | Full implementation (6 themes) |
|
|
267
326
|
| `rustplotlib.animation` | FuncAnimation + GIF export |
|
|
268
|
-
| `rustplotlib.widgets` |
|
|
327
|
+
| `rustplotlib.widgets` | Functional (Slider, Button, CheckButtons, RadioButtons, TextBox, RangeSlider, Cursor) |
|
|
269
328
|
| `rustplotlib.font_manager` | FontProperties |
|
|
270
329
|
| `rustplotlib.ticker` | 12 Formatters + 10 Locators (functional) |
|
|
271
330
|
| `rustplotlib.patches` | Rectangle, Circle, Polygon, FancyBboxPatch, Wedge, FancyArrowPatch |
|
|
@@ -375,25 +434,29 @@ anim.save("wave.gif")
|
|
|
375
434
|
|
|
376
435
|
## Performance Benchmark
|
|
377
436
|
|
|
378
|
-
Benchmarked against matplotlib on Apple Silicon (M-series). Each test runs 10 iterations, averaged:
|
|
437
|
+
Benchmarked against matplotlib on Apple Silicon (M-series, release build). Each test runs 10 iterations, averaged:
|
|
379
438
|
|
|
380
439
|
| Benchmark | matplotlib | rustplotlib | Speedup |
|
|
381
440
|
|---|---|---|---|
|
|
382
|
-
| Line Plot (10k pts) | 0.
|
|
383
|
-
| Scatter (5k pts) | 0.
|
|
384
|
-
| Bar Chart (50 bars) | 0.
|
|
385
|
-
| Histogram (100k pts) | 0.
|
|
386
|
-
| Subplots 2x2 | 0.
|
|
387
|
-
| Heatmap (100x100) | 0.
|
|
388
|
-
| Large Line (100k pts) | 0.
|
|
389
|
-
| Multi-line (20 lines) | 0.
|
|
390
|
-
| Error Bars | 0.
|
|
391
|
-
| Pie Chart | 0.
|
|
392
|
-
| SVG Output | 0.021s | 0.003s | **
|
|
393
|
-
| Full Styled Plot | 0.
|
|
441
|
+
| Line Plot (10k pts) | 0.024s | 0.005s | **4.7x** |
|
|
442
|
+
| Scatter (5k pts) | 0.027s | 0.020s | **1.3x** |
|
|
443
|
+
| Bar Chart (50 bars) | 0.024s | 0.004s | **5.7x** |
|
|
444
|
+
| Histogram (100k pts) | 0.087s | 0.005s | **18.7x** |
|
|
445
|
+
| Subplots 2x2 | 0.038s | 0.010s | **3.9x** |
|
|
446
|
+
| Heatmap (100x100) | 0.019s | 0.005s | **3.7x** |
|
|
447
|
+
| Large Line (100k pts) | 0.109s | 0.110s | **1.0x** |
|
|
448
|
+
| Multi-line (20 lines) | 0.085s | 0.029s | **2.9x** |
|
|
449
|
+
| Error Bars | 0.021s | 0.004s | **5.9x** |
|
|
450
|
+
| Pie Chart | 0.009s | 0.004s | **2.4x** |
|
|
451
|
+
| SVG Output | 0.021s | 0.003s | **7.6x** |
|
|
452
|
+
| Full Styled Plot | 0.018s | 0.005s | **3.9x** |
|
|
453
|
+
| **TOTAL** | **0.481s** | **0.203s** | **2.4x** |
|
|
454
|
+
|
|
455
|
+
> Wins 11 out of 12 benchmarks. Up to **18.7x faster** on histogram rendering.
|
|
394
456
|
|
|
395
457
|
Run the benchmark yourself:
|
|
396
458
|
```bash
|
|
459
|
+
maturin develop --release
|
|
397
460
|
python tests/test_benchmark.py
|
|
398
461
|
```
|
|
399
462
|
|
|
@@ -465,25 +528,27 @@ Contributions are welcome! This is an open-source project under the MIT license.
|
|
|
465
528
|
4. PRs require at least 1 review before merging
|
|
466
529
|
|
|
467
530
|
**Project stats:**
|
|
468
|
-
- **
|
|
469
|
-
- **25 Python modules** —
|
|
470
|
-
- **
|
|
471
|
-
- **
|
|
472
|
-
- **
|
|
473
|
-
- **
|
|
474
|
-
- **
|
|
475
|
-
- **
|
|
476
|
-
- **
|
|
477
|
-
- **
|
|
478
|
-
- **
|
|
531
|
+
- **53 Rust source files** — 30,000+ lines of native code
|
|
532
|
+
- **25+ Python modules** — thin PyO3 wrappers
|
|
533
|
+
- **50 plot types** (43 2D + 7 3D) — 100% of matplotlib plot types
|
|
534
|
+
- **81 colormaps** + reversed = ~162 total (~95% of matplotlib)
|
|
535
|
+
- **550+ tests** passing (including 27 rendering regression tests)
|
|
536
|
+
- **110/110 pyplot functions**, 95/95 Axes methods, 36/36 Figure methods
|
|
537
|
+
- **15 interpolation modes**: nearest, bilinear, bicubic, lanczos, spline16, hanning, hamming, hermite, kaiser, quadric, catrom, gaussian, bessel, mitchell, sinc
|
|
538
|
+
- **5 geographic projections**: Hammer, Aitoff, Mollweide, Lambert, Stereographic
|
|
539
|
+
- **4 backends**: Agg, Tk (interactive), Jupyter inline, WebAgg (browser)
|
|
540
|
+
- **4 output formats**: PNG, SVG, PDF (multi-page), EPS
|
|
541
|
+
- **Full TeX math engine**: Greek, sub/superscript, fractions, sqrt, matrices
|
|
542
|
+
- **Full transform system**: Affine2D, BlendedTransform, transData/transAxes
|
|
543
|
+
- **Full event system**: mouse, keyboard, pick events with Rust hit testing
|
|
544
|
+
- **Widgets**: Slider, Button, CheckButtons, RadioButtons, TextBox (Rust rendering)
|
|
545
|
+
- **Layout engines**: tight layout, constrained layout, GridSpec rowspan/colspan, SubFigure
|
|
479
546
|
- **Zero `unsafe` blocks**
|
|
480
547
|
|
|
481
|
-
**
|
|
482
|
-
- Qt/GTK backends
|
|
483
|
-
-
|
|
484
|
-
-
|
|
485
|
-
- Triangulation plots (tricontour, tripcolor)
|
|
486
|
-
- LaTeX math rendering
|
|
548
|
+
**Remaining (need external dependencies):**
|
|
549
|
+
- Qt/GTK/macOS backends (need PyQt5, PyGObject, PyObjC)
|
|
550
|
+
- Math font rendering (need Computer Modern .ttf files)
|
|
551
|
+
- Basemap coastlines (need Natural Earth shapefiles)
|
|
487
552
|
|
|
488
553
|
---
|
|
489
554
|
|
|
@@ -17,7 +17,7 @@ No Python runtime dependency for rendering. No wrappers. No subprocess calls. Pu
|
|
|
17
17
|
|---|---|---|---|
|
|
18
18
|
| Rendering engine | C/C++ (AGG) | None (wrap matplotlib or call Python) | **Rust native (tiny-skia)** |
|
|
19
19
|
| External dependencies | NumPy, Pillow, FreeType, etc. | Python + matplotlib required | **Zero** — self-contained |
|
|
20
|
-
| Performance | Baseline | Same or slower (subprocess overhead) | **Up to
|
|
20
|
+
| Performance | Baseline | Same or slower (subprocess overhead) | **Up to 18.7x faster** |
|
|
21
21
|
| Python API | Original | Rust-only or generates .py scripts | **Drop-in replacement** — same API |
|
|
22
22
|
| Approach | Interpreted + C extensions | Wrappers / code generators | **Full reimplementation in Rust** |
|
|
23
23
|
|
|
@@ -175,62 +175,121 @@ plt.show()
|
|
|
175
175
|
### Output Formats
|
|
176
176
|
| Method | Description |
|
|
177
177
|
|---|---|
|
|
178
|
-
| `savefig("file.png")` | Raster PNG (with dpi, transparent
|
|
178
|
+
| `savefig("file.png")` | Raster PNG (with dpi, transparent, bbox_inches='tight') |
|
|
179
179
|
| `savefig("file.svg")` | Native vector SVG (real `<line>`, `<text>`, `<rect>` elements) |
|
|
180
180
|
| `savefig("file.pdf")` | PDF output |
|
|
181
|
-
| `
|
|
182
|
-
| `
|
|
181
|
+
| `savefig("file.eps")` | EPS output |
|
|
182
|
+
| `show()` | Interactive window with backend auto-detection |
|
|
183
|
+
| `PdfPages` | Multi-page PDF with zlib compression |
|
|
184
|
+
| `pickle` | Save/load figures with pickle |
|
|
185
|
+
| `copy_to_clipboard()` | Copy figure as PNG to system clipboard |
|
|
186
|
+
| `to_json()` / `save_json()` | Export figure state as JSON |
|
|
183
187
|
|
|
184
188
|
### Backends & Interactive
|
|
185
189
|
| Feature | Description |
|
|
186
190
|
|---|---|
|
|
187
191
|
| Backend auto-detection | Automatically selects inline (Jupyter), Tk, or Agg backend |
|
|
188
|
-
| Tk backend | Interactive window with
|
|
189
|
-
|
|
|
192
|
+
| Tk backend | Interactive window with toolbar, zoom/pan, coordinate display |
|
|
193
|
+
| WebAgg backend | Browser-based interactive viewer via HTTP server |
|
|
194
|
+
| Navigation toolbar | Home, Back, Forward, Pan, Zoom, Save (Tk + WebAgg) |
|
|
190
195
|
| Event system | `mpl_connect` / `mpl_disconnect` with `CallbackRegistry` |
|
|
191
|
-
|
|
|
192
|
-
| Key events |
|
|
193
|
-
| Draw/Resize/Close events | `DrawEvent`, `ResizeEvent`, `CloseEvent` |
|
|
196
|
+
| Pick events | Artist hit testing backed by Rust (`hit_test_points`, `hit_test_line`) |
|
|
197
|
+
| Mouse/Key/Scroll events | Full event hierarchy: MouseEvent, KeyEvent, PickEvent, DrawEvent, ResizeEvent, CloseEvent |
|
|
194
198
|
| Jupyter rich display | `_repr_png_()`, `_repr_svg_()`, `_repr_html_()` on Figure |
|
|
195
|
-
|
|
|
196
|
-
| `render_to_rgba_buffer()` | Raw RGBA buffer (PyO3) for interactive backends |
|
|
199
|
+
| 3D mouse rotation | Drag to rotate 3D view in Tk backend |
|
|
197
200
|
|
|
198
201
|
### Animation
|
|
199
202
|
| Feature | Description |
|
|
200
203
|
|---|---|
|
|
201
|
-
| `FuncAnimation` | Function-based animation with
|
|
204
|
+
| `FuncAnimation` | Function-based animation with blit support, pause/resume |
|
|
205
|
+
| `ArtistAnimation` | Frame-based animation from artist lists |
|
|
202
206
|
| GIF export | Save animations as GIF (via Pillow) |
|
|
203
|
-
|
|
|
207
|
+
| Live animation | Real-time animation in Tk backend |
|
|
208
|
+
|
|
209
|
+
### Layout Engines
|
|
210
|
+
| Feature | Description |
|
|
211
|
+
|---|---|
|
|
212
|
+
| `tight_layout()` | Dynamic margins from text measurement (Rust) |
|
|
213
|
+
| `constrained_layout=True` | Constraint-based layout engine (Rust) |
|
|
214
|
+
| `GridSpec(nrows, ncols)` | Grid layout with `rowspan`/`colspan` |
|
|
215
|
+
| `SubFigure` | Nested sub-figures with independent layouts |
|
|
216
|
+
| `Figure.add_axes([l,b,w,h])` | Custom axes positioning |
|
|
217
|
+
| `make_axes_locatable` | Axes divider for colorbar positioning |
|
|
218
|
+
|
|
219
|
+
### Widgets (Rust-rendered)
|
|
220
|
+
| Widget | Features |
|
|
221
|
+
|---|---|
|
|
222
|
+
| `Slider` | Track, thumb circle, label, value display, on_changed callbacks |
|
|
223
|
+
| `RangeSlider` | Tuple values, clamp, callbacks |
|
|
224
|
+
| `Button` | Background, border, label, on_clicked callbacks |
|
|
225
|
+
| `CheckButtons` | Toggle, get_status, callbacks |
|
|
226
|
+
| `RadioButtons` | Exclusive selection, value_selected |
|
|
227
|
+
| `TextBox` | on_submit, on_text_change, set_val |
|
|
228
|
+
| `Cursor` | Crosshair following mouse, on_moved callbacks |
|
|
229
|
+
| `MultiCursor` | Cursor spanning multiple axes |
|
|
230
|
+
|
|
231
|
+
### Transform System
|
|
232
|
+
| Component | Description |
|
|
233
|
+
|---|---|
|
|
234
|
+
| `Affine2D` | 2D affine matrix (rotate, scale, translate, compose, invert) — **Rust** |
|
|
235
|
+
| `BlendedTransform` | Separate X/Y transforms — **Rust** |
|
|
236
|
+
| `ax.transData` | Data coordinate transform |
|
|
237
|
+
| `ax.transAxes` | Axes coordinate transform (0-1) |
|
|
238
|
+
| `fig.transFigure` | Figure coordinate transform |
|
|
204
239
|
|
|
205
240
|
### Styles & Themes
|
|
206
241
|
| Feature | Description |
|
|
207
242
|
|---|---|
|
|
208
|
-
| `style.use('dark_background')` |
|
|
243
|
+
| `style.use('dark_background')` | 13 built-in themes (default, dark_background, ggplot, seaborn, bmh, fivethirtyeight, grayscale, Solarize_Light2, tableau-colorblind10, seaborn-whitegrid, seaborn-darkgrid, seaborn-dark, fast) |
|
|
244
|
+
| `style.available` | List all available styles |
|
|
245
|
+
| `style.context('ggplot')` | Context manager for temporary style |
|
|
209
246
|
| `rcParams` | Functional global configuration (30+ supported keys) |
|
|
210
247
|
| `set_facecolor()` | Figure and axes background colors |
|
|
211
248
|
|
|
212
249
|
### Colors
|
|
213
|
-
- **Named:**
|
|
250
|
+
- **Named:** 140+ colors including all CSS/X11 colors (steelblue, coral, tomato, gold, crimson, dodgerblue, forestgreen, etc.)
|
|
214
251
|
- **Shorthand:** `"r"`, `"g"`, `"b"`, `"c"`, `"m"`, `"y"`, `"k"`, `"w"`
|
|
215
252
|
- **Hex:** `"#FF0000"`, `"#f00"`, `"#FF000080"`
|
|
216
253
|
- **RGB/RGBA tuples:** `(1.0, 0.0, 0.0)`, `(1.0, 0.0, 0.0, 0.5)`
|
|
254
|
+
- **Grey/gray variants:** both spellings supported
|
|
217
255
|
|
|
218
256
|
### Linestyles & Markers
|
|
219
257
|
- **Linestyles:** `-` (solid), `--` (dashed), `-.` (dashdot), `:` (dotted)
|
|
220
|
-
- **Markers:** `.` `o` `s` `^` `v` `+` `x` `D` `*`
|
|
221
|
-
- **Format strings:** `"r--o"` = red + dashed + circle markers
|
|
258
|
+
- **Markers:** `.` `o` `s` `^` `v` `<` `>` `+` `x` `D` `d` `*` `p` `h` `H` `8` `|` `_` `P` `X` `1` `2` `3` `4` (24 types)
|
|
259
|
+
- **Format strings:** `"r--o"` = red + dashed + circle markers (parsed in Rust)
|
|
222
260
|
- **markevery:** show marker every N points
|
|
223
261
|
|
|
224
|
-
### Colormaps (
|
|
225
|
-
|
|
262
|
+
### Colormaps (81 base + reversed = ~162 total)
|
|
263
|
+
`viridis` `plasma` `inferno` `magma` `cividis` `twilight` `twilight_shifted` `turbo` `hot` `cool` `coolwarm` `bwr` `seismic` `gray` `jet` `spring` `summer` `autumn` `winter` `copper` `bone` `pink` `binary` `ocean` `terrain` `rainbow` `Blues` `Reds` `Greens` `Oranges` `Purples` `Greys` `YlOrRd` `YlOrBr` `YlGnBu` `YlGn` `OrRd` `BuGn` `BuPu` `GnBu` `PuBu` `PuRd` `RdPu` `PuBuGn` `RdYlBu` `RdBu` `RdGy` `RdYlGn` `PiYG` `PRGn` `BrBG` `PuOr` `Spectral` `Set1` `Set2` `Set3` `Pastel1` `Pastel2` `tab10` `tab20` `tab20b` `tab20c` `Paired` `Accent` `Dark2` `afmhot` `brg` `CMRmap` `Wistia` `cubehelix` `hsv` `gnuplot` `gnuplot2` `gist_earth` `gist_heat` `gist_ncar` `gist_rainbow` `gist_stern` `gist_yarg` `flag` `prism`
|
|
226
264
|
|
|
227
|
-
|
|
265
|
+
All also available reversed with `_r` suffix.
|
|
228
266
|
|
|
229
|
-
|
|
267
|
+
### Image Interpolation (15 modes)
|
|
268
|
+
`nearest` `bilinear` `bicubic` `lanczos` `spline16` `hanning` `hamming` `hermite` `kaiser` `quadric` `catrom` `gaussian` `bessel` `mitchell` `sinc`
|
|
230
269
|
|
|
231
|
-
### Text Rendering
|
|
270
|
+
### Text & Math Rendering
|
|
232
271
|
- Embedded DejaVu Sans font (no system font dependency)
|
|
233
|
-
-
|
|
272
|
+
- **Full TeX math engine in Rust:**
|
|
273
|
+
- Greek letters (24 lowercase + 12 uppercase)
|
|
274
|
+
- Subscript/superscript with Unicode characters
|
|
275
|
+
- Stacked fractions (`\frac{a}{b}`) with horizontal bar
|
|
276
|
+
- Square roots (`\sqrt{x}`) with radical sign
|
|
277
|
+
- Integral/sum/product with limits (`\int_a^b`, `\sum_{i=0}^n`)
|
|
278
|
+
- Accents: `\hat`, `\tilde`, `\vec`, `\dot`, `\ddot`, `\overline`, `\underline`
|
|
279
|
+
- Delimiters: `\left(`, `\right)`, `\langle`, `\rangle`, `\lceil`, `\lfloor`
|
|
280
|
+
- Matrices with bracket rendering
|
|
281
|
+
- 60+ math operators and symbols
|
|
282
|
+
|
|
283
|
+
### Geographic Projections (5 types)
|
|
284
|
+
| Projection | Function |
|
|
285
|
+
|---|---|
|
|
286
|
+
| Hammer | `hammer_project(lon, lat)` |
|
|
287
|
+
| Aitoff | `aitoff_project(lon, lat)` |
|
|
288
|
+
| Mollweide | `mollweide_project(lon, lat)` |
|
|
289
|
+
| Lambert Conformal Conic | `lambert_project(lon, lat, lat1, lat2)` |
|
|
290
|
+
| Stereographic | `stereographic_project(lon, lat, lon0, lat0)` |
|
|
291
|
+
|
|
292
|
+
All with batch versions and `generate_graticule()` for grid lines.
|
|
234
293
|
|
|
235
294
|
### Data Integration
|
|
236
295
|
- **Pandas:** plot directly from DataFrame/Series (optional dependency)
|
|
@@ -245,7 +304,7 @@ All also available as `viridis_r`, `plasma_r`, `hot_r`, etc.
|
|
|
245
304
|
| `rustplotlib.pyplot` | Full implementation (50+ functions) |
|
|
246
305
|
| `rustplotlib.style` | Full implementation (6 themes) |
|
|
247
306
|
| `rustplotlib.animation` | FuncAnimation + GIF export |
|
|
248
|
-
| `rustplotlib.widgets` |
|
|
307
|
+
| `rustplotlib.widgets` | Functional (Slider, Button, CheckButtons, RadioButtons, TextBox, RangeSlider, Cursor) |
|
|
249
308
|
| `rustplotlib.font_manager` | FontProperties |
|
|
250
309
|
| `rustplotlib.ticker` | 12 Formatters + 10 Locators (functional) |
|
|
251
310
|
| `rustplotlib.patches` | Rectangle, Circle, Polygon, FancyBboxPatch, Wedge, FancyArrowPatch |
|
|
@@ -355,25 +414,29 @@ anim.save("wave.gif")
|
|
|
355
414
|
|
|
356
415
|
## Performance Benchmark
|
|
357
416
|
|
|
358
|
-
Benchmarked against matplotlib on Apple Silicon (M-series). Each test runs 10 iterations, averaged:
|
|
417
|
+
Benchmarked against matplotlib on Apple Silicon (M-series, release build). Each test runs 10 iterations, averaged:
|
|
359
418
|
|
|
360
419
|
| Benchmark | matplotlib | rustplotlib | Speedup |
|
|
361
420
|
|---|---|---|---|
|
|
362
|
-
| Line Plot (10k pts) | 0.
|
|
363
|
-
| Scatter (5k pts) | 0.
|
|
364
|
-
| Bar Chart (50 bars) | 0.
|
|
365
|
-
| Histogram (100k pts) | 0.
|
|
366
|
-
| Subplots 2x2 | 0.
|
|
367
|
-
| Heatmap (100x100) | 0.
|
|
368
|
-
| Large Line (100k pts) | 0.
|
|
369
|
-
| Multi-line (20 lines) | 0.
|
|
370
|
-
| Error Bars | 0.
|
|
371
|
-
| Pie Chart | 0.
|
|
372
|
-
| SVG Output | 0.021s | 0.003s | **
|
|
373
|
-
| Full Styled Plot | 0.
|
|
421
|
+
| Line Plot (10k pts) | 0.024s | 0.005s | **4.7x** |
|
|
422
|
+
| Scatter (5k pts) | 0.027s | 0.020s | **1.3x** |
|
|
423
|
+
| Bar Chart (50 bars) | 0.024s | 0.004s | **5.7x** |
|
|
424
|
+
| Histogram (100k pts) | 0.087s | 0.005s | **18.7x** |
|
|
425
|
+
| Subplots 2x2 | 0.038s | 0.010s | **3.9x** |
|
|
426
|
+
| Heatmap (100x100) | 0.019s | 0.005s | **3.7x** |
|
|
427
|
+
| Large Line (100k pts) | 0.109s | 0.110s | **1.0x** |
|
|
428
|
+
| Multi-line (20 lines) | 0.085s | 0.029s | **2.9x** |
|
|
429
|
+
| Error Bars | 0.021s | 0.004s | **5.9x** |
|
|
430
|
+
| Pie Chart | 0.009s | 0.004s | **2.4x** |
|
|
431
|
+
| SVG Output | 0.021s | 0.003s | **7.6x** |
|
|
432
|
+
| Full Styled Plot | 0.018s | 0.005s | **3.9x** |
|
|
433
|
+
| **TOTAL** | **0.481s** | **0.203s** | **2.4x** |
|
|
434
|
+
|
|
435
|
+
> Wins 11 out of 12 benchmarks. Up to **18.7x faster** on histogram rendering.
|
|
374
436
|
|
|
375
437
|
Run the benchmark yourself:
|
|
376
438
|
```bash
|
|
439
|
+
maturin develop --release
|
|
377
440
|
python tests/test_benchmark.py
|
|
378
441
|
```
|
|
379
442
|
|
|
@@ -445,25 +508,27 @@ Contributions are welcome! This is an open-source project under the MIT license.
|
|
|
445
508
|
4. PRs require at least 1 review before merging
|
|
446
509
|
|
|
447
510
|
**Project stats:**
|
|
448
|
-
- **
|
|
449
|
-
- **25 Python modules** —
|
|
450
|
-
- **
|
|
451
|
-
- **
|
|
452
|
-
- **
|
|
453
|
-
- **
|
|
454
|
-
- **
|
|
455
|
-
- **
|
|
456
|
-
- **
|
|
457
|
-
- **
|
|
458
|
-
- **
|
|
511
|
+
- **53 Rust source files** — 30,000+ lines of native code
|
|
512
|
+
- **25+ Python modules** — thin PyO3 wrappers
|
|
513
|
+
- **50 plot types** (43 2D + 7 3D) — 100% of matplotlib plot types
|
|
514
|
+
- **81 colormaps** + reversed = ~162 total (~95% of matplotlib)
|
|
515
|
+
- **550+ tests** passing (including 27 rendering regression tests)
|
|
516
|
+
- **110/110 pyplot functions**, 95/95 Axes methods, 36/36 Figure methods
|
|
517
|
+
- **15 interpolation modes**: nearest, bilinear, bicubic, lanczos, spline16, hanning, hamming, hermite, kaiser, quadric, catrom, gaussian, bessel, mitchell, sinc
|
|
518
|
+
- **5 geographic projections**: Hammer, Aitoff, Mollweide, Lambert, Stereographic
|
|
519
|
+
- **4 backends**: Agg, Tk (interactive), Jupyter inline, WebAgg (browser)
|
|
520
|
+
- **4 output formats**: PNG, SVG, PDF (multi-page), EPS
|
|
521
|
+
- **Full TeX math engine**: Greek, sub/superscript, fractions, sqrt, matrices
|
|
522
|
+
- **Full transform system**: Affine2D, BlendedTransform, transData/transAxes
|
|
523
|
+
- **Full event system**: mouse, keyboard, pick events with Rust hit testing
|
|
524
|
+
- **Widgets**: Slider, Button, CheckButtons, RadioButtons, TextBox (Rust rendering)
|
|
525
|
+
- **Layout engines**: tight layout, constrained layout, GridSpec rowspan/colspan, SubFigure
|
|
459
526
|
- **Zero `unsafe` blocks**
|
|
460
527
|
|
|
461
|
-
**
|
|
462
|
-
- Qt/GTK backends
|
|
463
|
-
-
|
|
464
|
-
-
|
|
465
|
-
- Triangulation plots (tricontour, tripcolor)
|
|
466
|
-
- LaTeX math rendering
|
|
528
|
+
**Remaining (need external dependencies):**
|
|
529
|
+
- Qt/GTK/macOS backends (need PyQt5, PyGObject, PyObjC)
|
|
530
|
+
- Math font rendering (need Computer Modern .ttf files)
|
|
531
|
+
- Basemap coastlines (need Natural Earth shapefiles)
|
|
467
532
|
|
|
468
533
|
---
|
|
469
534
|
|