rustplotlib 4.0.0__tar.gz → 5.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. rustplotlib-5.0.0/CLAUDE.md +119 -0
  2. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/Cargo.lock +1 -1
  3. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/Cargo.toml +1 -1
  4. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/PKG-INFO +51 -23
  5. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/README.md +50 -22
  6. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/ROADMAP.md +58 -48
  7. rustplotlib-5.0.0/benchmark_results.csv +13 -0
  8. rustplotlib-5.0.0/docs/superpowers/plans/2026-04-04-jupyter-and-event-foundation.md +920 -0
  9. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/pyproject.toml +1 -1
  10. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/__init__.py +5 -3
  11. rustplotlib-5.0.0/python/rustplotlib/backends/__init__.py +72 -0
  12. rustplotlib-5.0.0/python/rustplotlib/backends/backend_base.py +164 -0
  13. rustplotlib-5.0.0/python/rustplotlib/backends/backend_inline.py +70 -0
  14. rustplotlib-5.0.0/python/rustplotlib/backends/backend_tk.py +385 -0
  15. rustplotlib-5.0.0/python/rustplotlib/callback_registry.py +37 -0
  16. rustplotlib-5.0.0/python/rustplotlib/events.py +82 -0
  17. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/pyplot.py +39 -22
  18. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/figure.rs +55 -27
  19. rustplotlib-5.0.0/tests/test_backend_tk.py +187 -0
  20. rustplotlib-5.0.0/tests/test_benchmark.py +309 -0
  21. rustplotlib-5.0.0/tests/test_events.py +173 -0
  22. rustplotlib-5.0.0/tests/test_jupyter_repr.py +98 -0
  23. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/tests/test_phase6_7.py +2 -1
  24. rustplotlib-4.0.0/python/rustplotlib/backends/__init__.py +0 -8
  25. rustplotlib-4.0.0/python/rustplotlib/backends/backend_inline.py +0 -24
  26. rustplotlib-4.0.0/tests/test_benchmark.py +0 -123
  27. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/.github/workflows/ci.yml +0 -0
  28. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/.gitignore +0 -0
  29. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/CONTRIBUTING.md +0 -0
  30. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/LICENSE +0 -0
  31. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/dados/Data/PerfisTemp_rustplotlib.py +0 -0
  32. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/animation.py +0 -0
  33. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/axes/__init__.py +0 -0
  34. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/backends/backend_pdf.py +0 -0
  35. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/cm.py +0 -0
  36. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/collections.py +0 -0
  37. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/colors.py +0 -0
  38. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/cycler.py +0 -0
  39. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/dates.py +0 -0
  40. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/figure.py +0 -0
  41. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/font_manager.py +0 -0
  42. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/gridspec.py +0 -0
  43. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/lines.py +0 -0
  44. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/mpl_toolkits/__init__.py +0 -0
  45. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/mpl_toolkits/mplot3d/__init__.py +0 -0
  46. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/patches.py +0 -0
  47. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/patheffects.py +0 -0
  48. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/pyplot.pyi +0 -0
  49. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/spines.py +0 -0
  50. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/style/__init__.py +0 -0
  51. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/text.py +0 -0
  52. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/ticker.py +0 -0
  53. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/transforms.py +0 -0
  54. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/python/rustplotlib/widgets.py +0 -0
  55. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/arrow.rs +0 -0
  56. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/bar.rs +0 -0
  57. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/bar3d.rs +0 -0
  58. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/barh.rs +0 -0
  59. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/boxplot.rs +0 -0
  60. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/broken_barh.rs +0 -0
  61. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/contour.rs +0 -0
  62. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/contour3d.rs +0 -0
  63. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/errorbar.rs +0 -0
  64. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/eventplot.rs +0 -0
  65. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/fill_between.rs +0 -0
  66. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/fill_betweenx.rs +0 -0
  67. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/fill_polygon.rs +0 -0
  68. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/hexbin.rs +0 -0
  69. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/hist.rs +0 -0
  70. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/image.rs +0 -0
  71. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/legend.rs +0 -0
  72. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/line2d.rs +0 -0
  73. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/line3d.rs +0 -0
  74. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/mod.rs +0 -0
  75. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/patches.rs +0 -0
  76. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/pcolormesh.rs +0 -0
  77. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/pie.rs +0 -0
  78. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/quiver.rs +0 -0
  79. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/radar.rs +0 -0
  80. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/sankey.rs +0 -0
  81. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/scatter.rs +0 -0
  82. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/scatter3d.rs +0 -0
  83. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/stem.rs +0 -0
  84. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/step.rs +0 -0
  85. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/streamplot.rs +0 -0
  86. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/surface3d.rs +0 -0
  87. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/trisurf3d.rs +0 -0
  88. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/violin.rs +0 -0
  89. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/artists/wireframe3d.rs +0 -0
  90. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/axes.rs +0 -0
  91. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/axes3d.rs +0 -0
  92. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/colors.rs +0 -0
  93. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/fonts/DejaVuSans.ttf +0 -0
  94. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/lib.rs +0 -0
  95. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/projection3d.rs +0 -0
  96. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/svg_renderer.rs +0 -0
  97. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/text.rs +0 -0
  98. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/ticker.rs +0 -0
  99. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/transforms.rs +0 -0
  100. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/src/window.rs +0 -0
  101. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/tests/test_3d.py +0 -0
  102. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/tests/test_colors.py +0 -0
  103. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/tests/test_figure.py +0 -0
  104. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/tests/test_new_features.py +0 -0
  105. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/tests/test_new_features2.py +0 -0
  106. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/tests/test_phase8.py +0 -0
  107. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/tests/test_phase9_features.py +0 -0
  108. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/tests/test_pyplot.py +0 -0
  109. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/tests/test_spectral_features.py +0 -0
  110. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/tests/test_ticker.py +0 -0
  111. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/tests/test_transforms.py +0 -0
  112. {rustplotlib-4.0.0 → rustplotlib-5.0.0}/tests/test_v3_features.py +0 -0
@@ -0,0 +1,119 @@
1
+ # RustPlotLib — Contexto para Agents
2
+
3
+ Reimplementação completa do matplotlib em Rust puro. Drop-in replacement via PyO3.
4
+
5
+ ## Linguagem
6
+
7
+ - Sempre responder em português (pt-BR)
8
+
9
+ ## Estado Atual — v5.0.0 (Phase 1 + Phase 2)
10
+
11
+ - 40+ plot types 2D, 7 plot types 3D
12
+ - 70+ colormaps (35 base + 35 reversed)
13
+ - 25 módulos Python compatíveis com API matplotlib
14
+ - 298 testes passando
15
+ - Tk backend interativo com toolbar, eventos de mouse/teclado e navegação
16
+ - Jupyter rich display (`_repr_png_`, `_repr_svg_`, `_repr_html_`)
17
+ - Sistema de eventos com `CallbackRegistry` e `mpl_connect`/`mpl_disconnect`
18
+ - Backend auto-detection (inline/tk/agg)
19
+ - Output: PNG (tiny-skia), SVG nativo, PDF, GIF, janela interativa
20
+ - Performance: até 16x mais rápido que matplotlib (benchmark real com 12 testes)
21
+ - Zero blocos `unsafe` em todo o código Rust
22
+
23
+ ## Estrutura do Projeto
24
+
25
+ ```
26
+ src/ # Core Rust
27
+ ├── lib.rs # Registro de módulos PyO3
28
+ ├── figure.rs # Figure + bindings PyO3 (savefig, render)
29
+ ├── axes.rs # Axes 2D (~1500 linhas)
30
+ ├── axes3d.rs # Axes 3D
31
+ ├── projection3d.rs # Câmera + projeção 3D
32
+ ├── transforms.rs # Coordenadas de dados → pixels
33
+ ├── colors.rs # Parse de cores (named, hex, RGB, RGBA)
34
+ ├── text.rs # Renderização de texto (ab_glyph + DejaVu Sans)
35
+ ├── ticker.rs # Cálculo automático de ticks
36
+ ├── svg_renderer.rs # Output SVG nativo
37
+ ├── window.rs # Janela interativa (winit + softbuffer)
38
+ └── artists/ # Um arquivo por tipo de gráfico (35 arquivos)
39
+ ├── mod.rs # Trait Artist
40
+ ├── line2d.rs, scatter.rs, bar.rs, hist.rs, image.rs, ...
41
+ └── legend.rs
42
+
43
+ python/rustplotlib/ # Camada Python
44
+ ├── pyplot.py # API principal (drop-in matplotlib.pyplot)
45
+ ├── style/ # Temas (dark_background, ggplot, seaborn, bmh, fivethirtyeight)
46
+ ├── animation.py # FuncAnimation + GIF
47
+ ├── ticker.py # 12 Formatters + 10 Locators funcionais
48
+ ├── backends/ # backend_base, backend_inline, backend_tk, backend_pdf
49
+ ├── events.py # MouseEvent, KeyEvent, DrawEvent, ResizeEvent, CloseEvent
50
+ ├── callback_registry.py # CallbackRegistry (mpl_connect/mpl_disconnect)
51
+ ├── dates.py, colors.py, patches.py, ...
52
+ └── mpl_toolkits/mplot3d/ # Suporte 3D
53
+
54
+ tests/ # Testes Python (298 testes)
55
+ ```
56
+
57
+ ## Stack Técnica
58
+
59
+ | Componente | Tecnologia |
60
+ |---|---|
61
+ | Renderização 2D | tiny-skia |
62
+ | Fontes | ab_glyph + DejaVu Sans embutida |
63
+ | PNG | crate png |
64
+ | SVG | Renderer customizado |
65
+ | Janela | winit + softbuffer |
66
+ | 3D | Projeção ortográfica customizada |
67
+ | Bindings Python | PyO3 + maturin |
68
+ | NumPy interop | crate numpy (PyO3) |
69
+
70
+ ## Como Adicionar Features
71
+
72
+ ### Novo tipo de gráfico (caminho completo):
73
+ 1. `src/artists/novo_plot.rs` — implementar trait Artist (draw, data_bounds, legend_label, legend_color)
74
+ 2. `src/artists/mod.rs` — registrar módulo
75
+ 3. `src/axes.rs` — adicionar método no Axes
76
+ 4. `src/figure.rs` — adicionar binding PyO3
77
+ 5. `python/rustplotlib/pyplot.py` — wrapper Python (AxesProxy + função module-level)
78
+ 6. `tests/test_*.py` — testes
79
+ 7. `ROADMAP.md` — marcar checkbox `[x]`
80
+ 8. `README.md` — atualizar tabela de features
81
+
82
+ ### Feature simples (só Python):
83
+ Se pode ser construída em cima das funções Rust existentes, implementar direto em `pyplot.py`.
84
+
85
+ ## Comandos de Desenvolvimento
86
+
87
+ ```bash
88
+ cd /Users/thi4gon/Documents/workspace/matplot
89
+ source .venv/bin/activate
90
+ maturin develop # Build debug
91
+ maturin develop --release # Build release (benchmarks)
92
+ pytest tests/ -v # Rodar todos os testes
93
+ cargo check # Verificar compilação Rust
94
+ ```
95
+
96
+ ## Regras de Código
97
+
98
+ - **Zero `unsafe`** — sem exceção
99
+ - **Sem `.unwrap()` em input do usuário** — usar proper error handling
100
+ - **Validar inputs na fronteira PyO3** — path traversal, dimensões, tipos
101
+ - **Todo feature novo precisa de teste**
102
+ - **Manter compatibilidade com API do matplotlib** — mesmos nomes de funções e parâmetros
103
+ - **Atualizar ROADMAP.md e README.md** ao completar features
104
+
105
+ ## Roadmap Ativo (próximo: v5.1.0)
106
+
107
+ Próximos itens prioritários (ver ROADMAP.md para lista completa):
108
+
109
+ 1. **Backends adicionais** — Qt, GTK, WebAgg, macOS native
110
+ 2. **Widgets funcionais** — Slider, Button, CheckButtons com renderização real
111
+ 3. **Features interativas** — pick events, rotação 3D, blitting
112
+ 4. **Triangulation plots** — tricontour, tricontourf, tripcolor (atualmente stubs)
113
+ 5. **Customização avançada** — spine positioning, TwoSlopeNorm, interpolação bicúbica
114
+
115
+ ## Git
116
+
117
+ - Branch principal: `master`
118
+ - Repo: `https://github.com/Thi4gon/rustplotlib`
119
+ - Commits seguem conventional commits: `feat:`, `fix:`, `docs:`, `release:`
@@ -1368,7 +1368,7 @@ dependencies = [
1368
1368
 
1369
1369
  [[package]]
1370
1370
  name = "rustplotlib"
1371
- version = "4.0.0"
1371
+ version = "5.0.0"
1372
1372
  dependencies = [
1373
1373
  "ab_glyph",
1374
1374
  "numpy",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rustplotlib"
3
- version = "4.0.0"
3
+ version = "5.0.0"
4
4
  edition = "2021"
5
5
  readme = "README.md"
6
6
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rustplotlib
3
- Version: 4.0.0
3
+ Version: 5.0.0
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Science/Research
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -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 30x faster** |
40
+ | Performance | Baseline | Same or slower (subprocess overhead) | **Up to 16x 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
 
@@ -198,9 +198,23 @@ plt.show()
198
198
  | `savefig("file.png")` | Raster PNG (with dpi, transparent options) |
199
199
  | `savefig("file.svg")` | Native vector SVG (real `<line>`, `<text>`, `<rect>` elements) |
200
200
  | `savefig("file.pdf")` | PDF output |
201
- | `show()` | Interactive window display |
201
+ | `show()` | Interactive window with backend auto-detection (Tk/inline/agg) |
202
202
  | `PdfPages` | Multi-page PDF export |
203
203
 
204
+ ### Backends & Interactive
205
+ | Feature | Description |
206
+ |---|---|
207
+ | Backend auto-detection | Automatically selects inline (Jupyter), Tk, or Agg backend |
208
+ | Tk backend | Interactive window with `PhotoImage` rendering (640x480) |
209
+ | Navigation toolbar | Home, Back, Forward, Pan, Zoom, Save + status bar (7 widgets) |
210
+ | Event system | `mpl_connect` / `mpl_disconnect` with `CallbackRegistry` |
211
+ | Mouse events | `MouseEvent` with button, x/y data, key modifiers |
212
+ | Key events | `KeyEvent` for keyboard interaction |
213
+ | Draw/Resize/Close events | `DrawEvent`, `ResizeEvent`, `CloseEvent` |
214
+ | Jupyter rich display | `_repr_png_()`, `_repr_svg_()`, `_repr_html_()` on Figure |
215
+ | `render_to_svg_string()` | SVG output as string (PyO3) for Jupyter inline |
216
+ | `render_to_rgba_buffer()` | Raw RGBA buffer (PyO3) for interactive backends |
217
+
204
218
  ### Animation
205
219
  | Feature | Description |
206
220
  |---|---|
@@ -245,7 +259,7 @@ All also available as `viridis_r`, `plasma_r`, `hot_r`, etc.
245
259
  - **Dates:** `date2num()`, `num2date()`, date formatters and locators
246
260
  - **Categorical axes:** string-based x values automatically converted
247
261
 
248
- ### Compatibility Modules (23 modules)
262
+ ### Compatibility Modules (25 modules)
249
263
  | Module | Status |
250
264
  |---|---|
251
265
  | `rustplotlib.pyplot` | Full implementation (50+ functions) |
@@ -253,12 +267,14 @@ All also available as `viridis_r`, `plasma_r`, `hot_r`, etc.
253
267
  | `rustplotlib.animation` | FuncAnimation + GIF export |
254
268
  | `rustplotlib.widgets` | Stubs (Slider, Button, CheckButtons, RadioButtons, TextBox, Cursor) |
255
269
  | `rustplotlib.font_manager` | FontProperties |
256
- | `rustplotlib.ticker` | FormatStrFormatter |
257
- | `rustplotlib.patches` | Rectangle, Circle, Polygon, FancyBboxPatch, Wedge |
258
- | `rustplotlib.colors` | LinearSegmentedColormap, Normalize, LogNorm |
259
- | `rustplotlib.dates` | Date conversion, formatters, locators |
270
+ | `rustplotlib.ticker` | 12 Formatters + 10 Locators (functional) |
271
+ | `rustplotlib.patches` | Rectangle, Circle, Polygon, FancyBboxPatch, Wedge, FancyArrowPatch |
272
+ | `rustplotlib.colors` | LinearSegmentedColormap, Normalize, LogNorm, BoundaryNorm |
273
+ | `rustplotlib.dates` | Date conversion, DateFormatter, DateLocator, Auto/Day/Month/Year/Hour/MinuteLocator |
260
274
  | `rustplotlib.gridspec` | GridSpec, SubplotSpec |
261
- | `rustplotlib.backends` | Backend system, PdfPages |
275
+ | `rustplotlib.backends` | Backend system with auto-detection (inline/tk/agg), PdfPages |
276
+ | `rustplotlib.backends.backend_base` | FigureCanvasBase, FigureManagerBase, NavigationToolbar2 |
277
+ | `rustplotlib.backends.backend_tk` | Tk interactive window with toolbar and events |
262
278
  | `rustplotlib.mpl_toolkits.mplot3d` | Axes3D for 3D plotting |
263
279
  | `rustplotlib.cm` | Colormap access by name |
264
280
  | `rustplotlib.collections` | LineCollection, PathCollection, PatchCollection |
@@ -268,7 +284,9 @@ All also available as `viridis_r`, `plasma_r`, `hot_r`, etc.
268
284
  | `rustplotlib.patheffects` | Stroke, withStroke, SimplePatchShadow |
269
285
  | `rustplotlib.spines` | Spine |
270
286
  | `rustplotlib.axes` | Axes class reference |
271
- | `rustplotlib.figure` | Figure class reference |
287
+ | `rustplotlib.figure` | Figure class with Jupyter rich display (`_repr_png_`, `_repr_svg_`, `_repr_html_`) |
288
+ | `rustplotlib.events` | MouseEvent, KeyEvent, DrawEvent, ResizeEvent, CloseEvent |
289
+ | `rustplotlib.callback_registry` | CallbackRegistry for mpl_connect/mpl_disconnect |
272
290
  | `rustplotlib.cycler` | cycler compatibility |
273
291
 
274
292
  ---
@@ -361,11 +379,18 @@ Benchmarked against matplotlib on Apple Silicon (M-series). Each test runs 10 it
361
379
 
362
380
  | Benchmark | matplotlib | rustplotlib | Speedup |
363
381
  |---|---|---|---|
364
- | Line Plot (10k points) | 0.064s | 0.002s | **30.8x** |
365
- | Scatter (5k points) | 0.029s | 0.017s | **1.7x** |
366
- | Bar Chart (50 bars) | 0.023s | 0.002s | **9.6x** |
367
- | Histogram (100k points) | 0.081s | 0.003s | **27.9x** |
368
- | Subplots 2x2 | 0.041s | 0.002s | **26.7x** |
382
+ | Line Plot (10k pts) | 0.028s | 0.005s | **5.3x** |
383
+ | Scatter (5k pts) | 0.028s | 0.021s | **1.4x** |
384
+ | Bar Chart (50 bars) | 0.026s | 0.005s | **5.0x** |
385
+ | Histogram (100k pts) | 0.090s | 0.006s | **16.1x** |
386
+ | Subplots 2x2 | 0.046s | 0.011s | **4.2x** |
387
+ | Heatmap (100x100) | 0.021s | 0.006s | **3.4x** |
388
+ | Large Line (100k pts) | 0.110s | 0.109s | **1.0x** |
389
+ | Multi-line (20 lines) | 0.090s | 0.037s | **2.4x** |
390
+ | Error Bars | 0.022s | 0.004s | **6.4x** |
391
+ | Pie Chart | 0.012s | 0.005s | **2.7x** |
392
+ | SVG Output | 0.021s | 0.003s | **6.9x** |
393
+ | Full Styled Plot | 0.019s | 0.006s | **3.4x** |
369
394
 
370
395
  Run the benchmark yourself:
371
396
  ```bash
@@ -440,22 +465,25 @@ Contributions are welcome! This is an open-source project under the MIT license.
440
465
  4. PRs require at least 1 review before merging
441
466
 
442
467
  **Project stats:**
443
- - **45+ Rust source files** — 16,000+ lines of native code
444
- - **23 Python modules** — 5,000+ lines of API
468
+ - **45+ Rust source files** — 23,000+ lines of native code
469
+ - **25 Python modules** — 4,900+ lines of API
445
470
  - **47+ plot functions** (40 2D + 7 3D)
446
471
  - **70+ colormaps** (35 base + 35 reversed)
447
- - **262 tests** passing
448
- - **12 formatters + 10 locators** (functional)
472
+ - **298 tests** passing
473
+ - **22 formatters + locators** (functional)
474
+ - **Tk interactive backend** with navigation toolbar and event system
475
+ - **Jupyter rich display** (`_repr_png_`, `_repr_svg_`, `_repr_html_`)
476
+ - **Event system** with `mpl_connect` / `mpl_disconnect`
449
477
  - **RGB/RGBA imshow**, bilinear interpolation, heatmap annotations
450
478
  - **Signal processing**: specgram, psd, acorr, xcorr, coherence
451
479
  - **Zero `unsafe` blocks**
452
480
 
453
481
  **Priority areas for contribution:**
454
- - Turning stub modules into full implementations (widgets, formatters/locators)
455
- - Improving SVG output fidelity
456
- - Interactive 3D (mouse rotation)
457
482
  - Qt/GTK backends
458
- - More comprehensive test coverage
483
+ - Functional widgets (Slider, Button, CheckButtons with real rendering)
484
+ - 3D mouse rotation
485
+ - Triangulation plots (tricontour, tripcolor)
486
+ - LaTeX math rendering
459
487
 
460
488
  ---
461
489
 
@@ -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 30x faster** |
20
+ | Performance | Baseline | Same or slower (subprocess overhead) | **Up to 16x 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
 
@@ -178,9 +178,23 @@ plt.show()
178
178
  | `savefig("file.png")` | Raster PNG (with dpi, transparent options) |
179
179
  | `savefig("file.svg")` | Native vector SVG (real `<line>`, `<text>`, `<rect>` elements) |
180
180
  | `savefig("file.pdf")` | PDF output |
181
- | `show()` | Interactive window display |
181
+ | `show()` | Interactive window with backend auto-detection (Tk/inline/agg) |
182
182
  | `PdfPages` | Multi-page PDF export |
183
183
 
184
+ ### Backends & Interactive
185
+ | Feature | Description |
186
+ |---|---|
187
+ | Backend auto-detection | Automatically selects inline (Jupyter), Tk, or Agg backend |
188
+ | Tk backend | Interactive window with `PhotoImage` rendering (640x480) |
189
+ | Navigation toolbar | Home, Back, Forward, Pan, Zoom, Save + status bar (7 widgets) |
190
+ | Event system | `mpl_connect` / `mpl_disconnect` with `CallbackRegistry` |
191
+ | Mouse events | `MouseEvent` with button, x/y data, key modifiers |
192
+ | Key events | `KeyEvent` for keyboard interaction |
193
+ | Draw/Resize/Close events | `DrawEvent`, `ResizeEvent`, `CloseEvent` |
194
+ | Jupyter rich display | `_repr_png_()`, `_repr_svg_()`, `_repr_html_()` on Figure |
195
+ | `render_to_svg_string()` | SVG output as string (PyO3) for Jupyter inline |
196
+ | `render_to_rgba_buffer()` | Raw RGBA buffer (PyO3) for interactive backends |
197
+
184
198
  ### Animation
185
199
  | Feature | Description |
186
200
  |---|---|
@@ -225,7 +239,7 @@ All also available as `viridis_r`, `plasma_r`, `hot_r`, etc.
225
239
  - **Dates:** `date2num()`, `num2date()`, date formatters and locators
226
240
  - **Categorical axes:** string-based x values automatically converted
227
241
 
228
- ### Compatibility Modules (23 modules)
242
+ ### Compatibility Modules (25 modules)
229
243
  | Module | Status |
230
244
  |---|---|
231
245
  | `rustplotlib.pyplot` | Full implementation (50+ functions) |
@@ -233,12 +247,14 @@ All also available as `viridis_r`, `plasma_r`, `hot_r`, etc.
233
247
  | `rustplotlib.animation` | FuncAnimation + GIF export |
234
248
  | `rustplotlib.widgets` | Stubs (Slider, Button, CheckButtons, RadioButtons, TextBox, Cursor) |
235
249
  | `rustplotlib.font_manager` | FontProperties |
236
- | `rustplotlib.ticker` | FormatStrFormatter |
237
- | `rustplotlib.patches` | Rectangle, Circle, Polygon, FancyBboxPatch, Wedge |
238
- | `rustplotlib.colors` | LinearSegmentedColormap, Normalize, LogNorm |
239
- | `rustplotlib.dates` | Date conversion, formatters, locators |
250
+ | `rustplotlib.ticker` | 12 Formatters + 10 Locators (functional) |
251
+ | `rustplotlib.patches` | Rectangle, Circle, Polygon, FancyBboxPatch, Wedge, FancyArrowPatch |
252
+ | `rustplotlib.colors` | LinearSegmentedColormap, Normalize, LogNorm, BoundaryNorm |
253
+ | `rustplotlib.dates` | Date conversion, DateFormatter, DateLocator, Auto/Day/Month/Year/Hour/MinuteLocator |
240
254
  | `rustplotlib.gridspec` | GridSpec, SubplotSpec |
241
- | `rustplotlib.backends` | Backend system, PdfPages |
255
+ | `rustplotlib.backends` | Backend system with auto-detection (inline/tk/agg), PdfPages |
256
+ | `rustplotlib.backends.backend_base` | FigureCanvasBase, FigureManagerBase, NavigationToolbar2 |
257
+ | `rustplotlib.backends.backend_tk` | Tk interactive window with toolbar and events |
242
258
  | `rustplotlib.mpl_toolkits.mplot3d` | Axes3D for 3D plotting |
243
259
  | `rustplotlib.cm` | Colormap access by name |
244
260
  | `rustplotlib.collections` | LineCollection, PathCollection, PatchCollection |
@@ -248,7 +264,9 @@ All also available as `viridis_r`, `plasma_r`, `hot_r`, etc.
248
264
  | `rustplotlib.patheffects` | Stroke, withStroke, SimplePatchShadow |
249
265
  | `rustplotlib.spines` | Spine |
250
266
  | `rustplotlib.axes` | Axes class reference |
251
- | `rustplotlib.figure` | Figure class reference |
267
+ | `rustplotlib.figure` | Figure class with Jupyter rich display (`_repr_png_`, `_repr_svg_`, `_repr_html_`) |
268
+ | `rustplotlib.events` | MouseEvent, KeyEvent, DrawEvent, ResizeEvent, CloseEvent |
269
+ | `rustplotlib.callback_registry` | CallbackRegistry for mpl_connect/mpl_disconnect |
252
270
  | `rustplotlib.cycler` | cycler compatibility |
253
271
 
254
272
  ---
@@ -341,11 +359,18 @@ Benchmarked against matplotlib on Apple Silicon (M-series). Each test runs 10 it
341
359
 
342
360
  | Benchmark | matplotlib | rustplotlib | Speedup |
343
361
  |---|---|---|---|
344
- | Line Plot (10k points) | 0.064s | 0.002s | **30.8x** |
345
- | Scatter (5k points) | 0.029s | 0.017s | **1.7x** |
346
- | Bar Chart (50 bars) | 0.023s | 0.002s | **9.6x** |
347
- | Histogram (100k points) | 0.081s | 0.003s | **27.9x** |
348
- | Subplots 2x2 | 0.041s | 0.002s | **26.7x** |
362
+ | Line Plot (10k pts) | 0.028s | 0.005s | **5.3x** |
363
+ | Scatter (5k pts) | 0.028s | 0.021s | **1.4x** |
364
+ | Bar Chart (50 bars) | 0.026s | 0.005s | **5.0x** |
365
+ | Histogram (100k pts) | 0.090s | 0.006s | **16.1x** |
366
+ | Subplots 2x2 | 0.046s | 0.011s | **4.2x** |
367
+ | Heatmap (100x100) | 0.021s | 0.006s | **3.4x** |
368
+ | Large Line (100k pts) | 0.110s | 0.109s | **1.0x** |
369
+ | Multi-line (20 lines) | 0.090s | 0.037s | **2.4x** |
370
+ | Error Bars | 0.022s | 0.004s | **6.4x** |
371
+ | Pie Chart | 0.012s | 0.005s | **2.7x** |
372
+ | SVG Output | 0.021s | 0.003s | **6.9x** |
373
+ | Full Styled Plot | 0.019s | 0.006s | **3.4x** |
349
374
 
350
375
  Run the benchmark yourself:
351
376
  ```bash
@@ -420,22 +445,25 @@ Contributions are welcome! This is an open-source project under the MIT license.
420
445
  4. PRs require at least 1 review before merging
421
446
 
422
447
  **Project stats:**
423
- - **45+ Rust source files** — 16,000+ lines of native code
424
- - **23 Python modules** — 5,000+ lines of API
448
+ - **45+ Rust source files** — 23,000+ lines of native code
449
+ - **25 Python modules** — 4,900+ lines of API
425
450
  - **47+ plot functions** (40 2D + 7 3D)
426
451
  - **70+ colormaps** (35 base + 35 reversed)
427
- - **262 tests** passing
428
- - **12 formatters + 10 locators** (functional)
452
+ - **298 tests** passing
453
+ - **22 formatters + locators** (functional)
454
+ - **Tk interactive backend** with navigation toolbar and event system
455
+ - **Jupyter rich display** (`_repr_png_`, `_repr_svg_`, `_repr_html_`)
456
+ - **Event system** with `mpl_connect` / `mpl_disconnect`
429
457
  - **RGB/RGBA imshow**, bilinear interpolation, heatmap annotations
430
458
  - **Signal processing**: specgram, psd, acorr, xcorr, coherence
431
459
  - **Zero `unsafe` blocks**
432
460
 
433
461
  **Priority areas for contribution:**
434
- - Turning stub modules into full implementations (widgets, formatters/locators)
435
- - Improving SVG output fidelity
436
- - Interactive 3D (mouse rotation)
437
462
  - Qt/GTK backends
438
- - More comprehensive test coverage
463
+ - Functional widgets (Slider, Button, CheckButtons with real rendering)
464
+ - 3D mouse rotation
465
+ - Triangulation plots (tricontour, tripcolor)
466
+ - LaTeX math rendering
439
467
 
440
468
  ---
441
469
 
@@ -4,7 +4,7 @@ Goal: Full matplotlib reimplementation in Rust.
4
4
 
5
5
  ---
6
6
 
7
- ## DONE — v3.0.0
7
+ ## DONE — v4.0.0
8
8
 
9
9
  ### 2D Plot Types (40+ implemented)
10
10
  - [x] plot, scatter, bar, barh, hist, imshow (RGB/RGBA + bilinear), fill_between, fill_betweenx, fill
@@ -30,8 +30,16 @@ Goal: Full matplotlib reimplementation in Rust.
30
30
  - [x] 6 style themes, 70+ colormaps (+ reversed), custom fonts, rcParams (30+ keys)
31
31
  - [x] Bilinear interpolation, title loc, multi-group plot, image extent, RGB/RGBA imshow
32
32
  - [x] Aspect ratio, invert axes, axis off, subplot_mosaic, suptitle, subplots_adjust
33
- - [x] Minor ticks, label colors, get_xlim/get_ylim (functional), axes clear
34
- - [x] 12 formatters + 10 locators (functional)
33
+ - [x] Minor ticks rendering + `set_xticks(minor=True)` functional
34
+ - [x] Label colors, get_xlim/get_ylim (functional), axes clear
35
+ - [x] Image origin ('upper' / 'lower')
36
+
37
+ ### Formatters & Locators (22 implemented)
38
+ - [x] ScalarFormatter, LogFormatter, LogFormatterSciNotation, LogFormatterMathtext
39
+ - [x] EngFormatter, PercentFormatter, StrMethodFormatter, FuncFormatter, FormatStrFormatter
40
+ - [x] MaxNLocator, AutoLocator, MultipleLocator, LogLocator, FixedLocator, AutoMinorLocator
41
+ - [x] DateFormatter, AutoDateFormatter, DateLocator, AutoDateLocator
42
+ - [x] DayLocator, MonthLocator, YearLocator, HourLocator, MinuteLocator
35
43
 
36
44
  ### Compatibility Modules (23)
37
45
  - [x] pyplot (50+ functions), style, animation, widgets, font_manager, ticker, patches, colors
@@ -46,55 +54,59 @@ Goal: Full matplotlib reimplementation in Rust.
46
54
 
47
55
  ---
48
56
 
49
- ## IN PROGRESS v4.0.0
57
+ ## DONEv5.0.0 (Phase 1 + Phase 2)
58
+
59
+ ### Backend System
60
+ - [x] `backend_base.py` — `FigureCanvasBase`, `FigureManagerBase`, `NavigationToolbar2`
61
+ - [x] `backends/__init__.py` — auto-detection (inline/tk/agg), registry, `show_figure()`
62
+ - [x] `switch_backend()` / `set_backend()` functional
63
+
64
+ ### Tk Interactive Backend
65
+ - [x] `backend_tk.py` — `FigureCanvasTk`, `FigureManagerTk`, `NavigationToolbarTk`
66
+ - [x] Tkinter window with PhotoImage rendering
67
+ - [x] Mouse events (click, release, motion, scroll)
68
+ - [x] Keyboard events
69
+ - [x] Navigation toolbar (Home, Back, Fwd, Pan, Zoom, Save)
70
+ - [x] Coordinate display on mouse motion
71
+ - [x] `show()` and `FigureProxy.show()` delegate to backend system
72
+
73
+ ### Jupyter Rich Display
74
+ - [x] `render_to_svg_string()` exposed via PyO3
75
+ - [x] `render_to_rgba_buffer()` exposed via PyO3
76
+ - [x] `_repr_png_`, `_repr_svg_`, `_repr_html_` on FigureProxy
77
+ - [x] `backend_inline.py` rewritten with SVG support and configurable `figure_format`
78
+
79
+ ### Event System
80
+ - [x] Event classes: `Event`, `LocationEvent`, `MouseEvent`, `KeyEvent`, `PickEvent`, `DrawEvent`, `ResizeEvent`, `CloseEvent`
81
+ - [x] `CallbackRegistry` with `connect(signal, func)`, `disconnect(cid)`, `process(signal, *args)`
82
+ - [x] `CanvasProxy.mpl_connect()` / `mpl_disconnect()` functional
83
+ - [x] `events` and `callback_registry` modules registered in package
84
+
85
+ ### Compatibility Modules (25 total)
86
+ - [x] Added: events, callback_registry (+ backends expanded with backend_base, backend_tk, backend_inline)
87
+
88
+ ---
89
+
90
+ ## PLANNED — v5.1.0
50
91
 
51
92
  ### Remaining Plot Types
52
- - [ ] `csd()` / `psd()` — cross/power spectral density
53
- - [ ] `ecdf()` — empirical cumulative distribution
54
- - [ ] `stairs()` — step plot with edges
55
- - [ ] `tricontour()` / `tricontourf()` — contour on triangulation
56
- - [ ] `tripcolor()` — pseudocolor on triangulation
57
- - [ ] `triplot()` — plot triangulation edges
58
-
59
- ### Formatters & Locators (functional, not stubs)
60
- - [ ] `ScalarFormatter` — default number formatting
61
- - [ ] `LogFormatter` / `LogFormatterSciNotation`
62
- - [ ] `EngFormatter` — engineering notation (1k, 1M, 1G)
63
- - [ ] `PercentFormatter`
64
- - [ ] `StrMethodFormatter` / `FuncFormatter`
65
- - [ ] `MaxNLocator` — smart tick placement (partial, have auto_ticks)
66
- - [ ] `MultipleLocator` — ticks at multiples
67
- - [ ] `LogLocator` — logarithmic ticks
68
- - [ ] `FixedLocator` — user-specified positions
69
- - [ ] `AutoMinorLocator` — automatic minor ticks
70
- - [ ] `DateFormatter` functional (format ticks as dates)
71
- - [ ] `DateLocator` functional (place ticks at date intervals)
93
+ - [ ] `tricontour()` / `tricontourf()` — contour on triangulation (currently stubs)
94
+ - [ ] `tripcolor()` — pseudocolor on triangulation (currently stub)
72
95
 
73
96
  ### Advanced Customization
74
- - [ ] `FancyArrowPatch` — complex arrow styles (arc, angle, etc.)
75
- - [ ] `ConnectionPatch` — arrows connecting different axes
97
+ - [ ] `FancyArrowPatch` — complex arrow styles (arc, angle, etc.) — currently basic stub
98
+ - [ ] `ConnectionPatch` — arrows connecting different axes — currently basic stub
76
99
  - [ ] Spine positioning (`set_position('center')`, `set_position(('data', 0))`)
77
- - [ ] Minor ticks rendering (major/minor tick distinction)
78
100
  - [ ] Grid major/minor separate styling
79
- - [ ] `ax.set_xticks(minor=True)` functional
80
101
  - [ ] Colorbar as separate Axes (not inline drawing)
81
- - [ ] `TwoSlopeNorm`, `CenteredNorm`, `BoundaryNorm` functional
102
+ - [ ] `TwoSlopeNorm`, `CenteredNorm` functional
82
103
 
83
104
  ### Image Improvements
84
105
  - [ ] Bicubic, Lanczos, Spline interpolation
85
- - [ ] Image origin ('upper' vs 'lower')
86
- - [ ] Image extent parameter
87
- - [ ] RGB/RGBA image support in imshow
88
106
 
89
- ---
90
-
91
- ## PLANNED — v4.0.0
92
-
93
- ### Functional Backends
107
+ ### Additional Backends
94
108
  - [ ] Qt backend (QApplication, mouse events, toolbar, save dialog)
95
109
  - [ ] GTK3/GTK4 backend
96
- - [ ] Tk backend (tkinter integration)
97
- - [ ] Jupyter inline backend (rich display protocol, `_repr_png_`)
98
110
  - [ ] WebAgg (HTML5 Canvas, browser-based interactive)
99
111
  - [ ] macOS native backend (NSView/Metal)
100
112
 
@@ -108,16 +120,14 @@ Goal: Full matplotlib reimplementation in Rust.
108
120
  - [ ] `Cursor` with crosshair rendering
109
121
 
110
122
  ### Interactive Features
111
- - [ ] Mouse events (click, motion, scroll, pick)
112
- - [ ] Keyboard events
113
- - [ ] Zoom/pan navigation toolbar
123
+ - [ ] Pick events (artist hit testing)
114
124
  - [ ] 3D mouse rotation
115
125
  - [ ] Blitting for fast animation updates
116
126
  - [ ] Interactive data cursors
117
127
 
118
128
  ---
119
129
 
120
- ## PLANNED — v5.0.0
130
+ ## PLANNED — v6.0.0
121
131
 
122
132
  ### Full LaTeX Math Rendering
123
133
  - [ ] TeX layout engine (fractions, roots, integrals, summation)
@@ -146,7 +156,7 @@ Goal: Full matplotlib reimplementation in Rust.
146
156
 
147
157
  ---
148
158
 
149
- ## PLANNED — v6.0.0
159
+ ## PLANNED — v7.0.0
150
160
 
151
161
  ### Geographic/Specialized Projections
152
162
  - [ ] Polar projection improvements (theta direction, offset)
@@ -184,7 +194,7 @@ Goal: Full matplotlib reimplementation in Rust.
184
194
  Pick any unchecked item, open an issue to discuss, submit a PR with tests.
185
195
 
186
196
  **Highest impact areas:**
187
- 1. Formatters/Locators (v3.0.0) — makes axes look professional
188
- 2. Jupyter backend (v4.0.0) — huge for data scientists
189
- 3. LaTeX rendering (v5.0.0) — needed for scientific papers
190
- 4. Interactive features (v4.0.0) — needed for exploratory analysis
197
+ 1. Qt/GTK backends (v5.1.0) — needed for desktop applications
198
+ 2. Functional widgets (v5.1.0) — Slider, Button, CheckButtons with real rendering
199
+ 3. LaTeX rendering (v6.0.0) — needed for scientific papers
200
+ 4. Triangulation plots (v5.1.0) — tricontour, tripcolor
@@ -0,0 +1,13 @@
1
+ benchmark,matplotlib_s,rustplotlib_s,speedup
2
+ Line Plot (10k pts),0.028050,0.005270,5.32
3
+ Scatter (5k pts),0.028230,0.020534,1.37
4
+ Bar Chart (50 bars),0.025549,0.005095,5.01
5
+ Histogram (100k pts),0.090139,0.005606,16.08
6
+ Subplots 2x2,0.046219,0.010970,4.21
7
+ Heatmap (100x100),0.020790,0.006080,3.42
8
+ Large Line (100k pts),0.109854,0.109353,1.00
9
+ Multi-line (20 lines),0.090231,0.037224,2.42
10
+ Error Bars,0.022393,0.003487,6.42
11
+ Pie Chart,0.012209,0.004486,2.72
12
+ SVG Output,0.020507,0.002972,6.90
13
+ Full Styled Plot,0.018751,0.005461,3.43