rustplotlib 2.0.0__tar.gz → 3.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 (101) hide show
  1. rustplotlib-3.0.0/CONTRIBUTING.md +195 -0
  2. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/Cargo.lock +1 -1
  3. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/Cargo.toml +1 -1
  4. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/PKG-INFO +58 -17
  5. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/README.md +57 -16
  6. rustplotlib-3.0.0/ROADMAP.md +189 -0
  7. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/pyproject.toml +1 -1
  8. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/patches.py +32 -0
  9. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/pyplot.py +486 -85
  10. rustplotlib-3.0.0/python/rustplotlib/ticker.py +194 -0
  11. rustplotlib-3.0.0/src/artists/arrow.rs +162 -0
  12. rustplotlib-3.0.0/src/artists/bar.rs +397 -0
  13. rustplotlib-3.0.0/src/artists/fill_polygon.rs +108 -0
  14. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/image.rs +210 -109
  15. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/line2d.rs +6 -0
  16. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/mod.rs +9 -0
  17. rustplotlib-3.0.0/src/artists/pcolormesh.rs +193 -0
  18. rustplotlib-3.0.0/src/artists/sankey.rs +193 -0
  19. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/scatter.rs +6 -0
  20. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/axes.rs +365 -19
  21. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/colors.rs +14 -0
  22. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/figure.rs +338 -13
  23. rustplotlib-3.0.0/tests/test_new_features2.py +332 -0
  24. rustplotlib-3.0.0/tests/test_phase9_features.py +455 -0
  25. rustplotlib-3.0.0/tests/test_v3_features.py +312 -0
  26. rustplotlib-2.0.0/ROADMAP.md +0 -171
  27. rustplotlib-2.0.0/python/rustplotlib/ticker.py +0 -23
  28. rustplotlib-2.0.0/src/artists/bar.rs +0 -175
  29. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/.github/workflows/ci.yml +0 -0
  30. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/.gitignore +0 -0
  31. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/LICENSE +0 -0
  32. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/dados/Data/PerfisTemp_rustplotlib.py +0 -0
  33. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/__init__.py +0 -0
  34. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/animation.py +0 -0
  35. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/axes/__init__.py +0 -0
  36. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/backends/__init__.py +0 -0
  37. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/backends/backend_inline.py +0 -0
  38. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/backends/backend_pdf.py +0 -0
  39. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/cm.py +0 -0
  40. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/collections.py +0 -0
  41. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/colors.py +0 -0
  42. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/cycler.py +0 -0
  43. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/dates.py +0 -0
  44. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/figure.py +0 -0
  45. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/font_manager.py +0 -0
  46. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/gridspec.py +0 -0
  47. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/lines.py +0 -0
  48. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/mpl_toolkits/__init__.py +0 -0
  49. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/mpl_toolkits/mplot3d/__init__.py +0 -0
  50. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/patheffects.py +0 -0
  51. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/pyplot.pyi +0 -0
  52. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/spines.py +0 -0
  53. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/style/__init__.py +0 -0
  54. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/text.py +0 -0
  55. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/transforms.py +0 -0
  56. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/python/rustplotlib/widgets.py +0 -0
  57. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/bar3d.rs +0 -0
  58. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/barh.rs +0 -0
  59. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/boxplot.rs +0 -0
  60. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/broken_barh.rs +0 -0
  61. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/contour.rs +0 -0
  62. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/contour3d.rs +0 -0
  63. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/errorbar.rs +0 -0
  64. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/eventplot.rs +0 -0
  65. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/fill_between.rs +0 -0
  66. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/fill_betweenx.rs +0 -0
  67. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/hexbin.rs +0 -0
  68. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/hist.rs +0 -0
  69. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/legend.rs +0 -0
  70. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/line3d.rs +0 -0
  71. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/patches.rs +0 -0
  72. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/pie.rs +0 -0
  73. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/quiver.rs +0 -0
  74. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/radar.rs +0 -0
  75. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/scatter3d.rs +0 -0
  76. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/stem.rs +0 -0
  77. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/step.rs +0 -0
  78. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/streamplot.rs +0 -0
  79. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/surface3d.rs +0 -0
  80. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/trisurf3d.rs +0 -0
  81. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/violin.rs +0 -0
  82. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/artists/wireframe3d.rs +0 -0
  83. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/axes3d.rs +0 -0
  84. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/fonts/DejaVuSans.ttf +0 -0
  85. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/lib.rs +0 -0
  86. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/projection3d.rs +0 -0
  87. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/svg_renderer.rs +0 -0
  88. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/text.rs +0 -0
  89. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/ticker.rs +0 -0
  90. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/transforms.rs +0 -0
  91. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/src/window.rs +0 -0
  92. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/tests/test_3d.py +0 -0
  93. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/tests/test_benchmark.py +0 -0
  94. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/tests/test_colors.py +0 -0
  95. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/tests/test_figure.py +0 -0
  96. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/tests/test_new_features.py +0 -0
  97. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/tests/test_phase6_7.py +0 -0
  98. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/tests/test_phase8.py +0 -0
  99. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/tests/test_pyplot.py +0 -0
  100. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/tests/test_ticker.py +0 -0
  101. {rustplotlib-2.0.0 → rustplotlib-3.0.0}/tests/test_transforms.py +0 -0
@@ -0,0 +1,195 @@
1
+ # Contributing to RustPlotLib
2
+
3
+ Thanks for wanting to help rebuild matplotlib in Rust! This guide will help you get started quickly.
4
+
5
+ ## How to Pick a Task
6
+
7
+ 1. Open [ROADMAP.md](ROADMAP.md) — every unchecked `[ ]` item is up for grabs
8
+ 2. Open a GitHub Issue saying "I'm working on [feature]" to avoid duplicate work
9
+ 3. Features are organized by priority version (v3, v4, v5, v6)
10
+
11
+ **Best first contributions:**
12
+ - Any item in the **v3.0.0** section (formatters, locators, missing plots)
13
+ - Bug fixes and edge cases
14
+ - Improving existing stubs (turning them into real implementations)
15
+
16
+ ## Project Structure
17
+
18
+ ```
19
+ rustplotlib/
20
+ ├── src/ # Rust core (this is where the rendering happens)
21
+ │ ├── lib.rs # PyO3 module registration
22
+ │ ├── figure.rs # Figure + PyO3 bindings (savefig, render, etc.)
23
+ │ ├── axes.rs # Axes (2D plotting area, ~1500 lines)
24
+ │ ├── axes3d.rs # Axes3D (3D plotting)
25
+ │ ├── projection3d.rs # 3D camera + projection math
26
+ │ ├── transforms.rs # Data coords → pixel coords
27
+ │ ├── colors.rs # Color parsing (named, hex, RGB, RGBA)
28
+ │ ├── text.rs # Text rendering (ab_glyph + DejaVu Sans font)
29
+ │ ├── ticker.rs # Auto-tick computation
30
+ │ ├── svg_renderer.rs # Native SVG output
31
+ │ ├── window.rs # Interactive window (winit + softbuffer)
32
+ │ └── artists/ # One file per plot type
33
+ │ ├── mod.rs # Artist trait definition
34
+ │ ├── line2d.rs # plot()
35
+ │ ├── scatter.rs # scatter()
36
+ │ ├── bar.rs # bar()
37
+ │ ├── hist.rs # hist()
38
+ │ ├── image.rs # imshow() + colormaps
39
+ │ ├── contour.rs # contour/contourf
40
+ │ ├── surface3d.rs # plot_surface()
41
+ │ ├── ... (31 total)
42
+ │ └── legend.rs # Legend rendering
43
+
44
+ ├── python/rustplotlib/ # Python API layer
45
+ │ ├── __init__.py # Package exports
46
+ │ ├── pyplot.py # Main API (drop-in replacement for matplotlib.pyplot)
47
+ │ ├── style/__init__.py # Style themes (dark_background, ggplot, etc.)
48
+ │ ├── animation.py # FuncAnimation + GIF export
49
+ │ ├── ticker.py # Formatters and Locators
50
+ │ ├── dates.py # Date handling
51
+ │ ├── ... (23 modules total)
52
+ │ └── mpl_toolkits/mplot3d/ # 3D axes support
53
+
54
+ ├── tests/ # Python tests
55
+ │ ├── test_colors.py
56
+ │ ├── test_figure.py
57
+ │ ├── test_pyplot.py
58
+ │ ├── test_3d.py
59
+ │ ├── test_benchmark.py
60
+ │ └── ... (200+ tests)
61
+
62
+ ├── Cargo.toml # Rust dependencies
63
+ ├── pyproject.toml # Python package config (maturin)
64
+ ├── README.md # Project documentation
65
+ ├── ROADMAP.md # Feature roadmap with checkboxes
66
+ └── CONTRIBUTING.md # This file
67
+ ```
68
+
69
+ ## How to Add a New Plot Type
70
+
71
+ Example: adding `spy()` (sparsity pattern)
72
+
73
+ ### Option A: Pure Python (simple cases)
74
+ If the new plot can be built on top of existing Rust functions:
75
+
76
+ ```python
77
+ # In python/rustplotlib/pyplot.py, add to AxesProxy:
78
+ def spy(self, Z, precision=0, **kwargs):
79
+ import numpy as np
80
+ Z = np.asarray(Z)
81
+ mask = np.abs(Z) > precision
82
+ self.imshow(mask.astype(float), cmap='gray_r', **kwargs)
83
+ self.set_aspect('equal')
84
+ ```
85
+
86
+ ### Option B: Rust Implementation (performance-critical)
87
+ For new rendering that needs to be fast:
88
+
89
+ **1. Create the artist** (`src/artists/my_plot.rs`):
90
+ ```rust
91
+ use crate::artists::Artist;
92
+ use crate::colors::Color;
93
+ use crate::transforms::Transform;
94
+
95
+ pub struct MyPlot {
96
+ pub data: Vec<f64>,
97
+ pub color: Color,
98
+ pub label: Option<String>,
99
+ }
100
+
101
+ impl Artist for MyPlot {
102
+ fn draw(&self, pixmap: &mut tiny_skia::Pixmap, transform: &Transform) {
103
+ // Draw using tiny-skia
104
+ }
105
+ fn data_bounds(&self) -> (f64, f64, f64, f64) {
106
+ // Return (xmin, xmax, ymin, ymax)
107
+ }
108
+ fn legend_label(&self) -> Option<&str> { self.label.as_deref() }
109
+ fn legend_color(&self) -> Color { self.color }
110
+ }
111
+ ```
112
+
113
+ **2. Register in** `src/artists/mod.rs`:
114
+ ```rust
115
+ pub mod my_plot;
116
+ ```
117
+
118
+ **3. Add method to Axes** (`src/axes.rs`):
119
+ ```rust
120
+ pub fn my_plot(&mut self, data: Vec<f64>, color: Option<Color>) {
121
+ let c = color.unwrap_or_else(|| self.next_color());
122
+ self.artists.push(Box::new(my_plot::MyPlot { data, color: c, label: None }));
123
+ }
124
+ ```
125
+
126
+ **4. Add PyO3 binding** (`src/figure.rs`):
127
+ ```rust
128
+ fn axes_my_plot(&mut self, ax_id: usize, data: Vec<f64>, kwargs: &Bound<'_, PyDict>) -> PyResult<()> {
129
+ let ax = self.axes.get_mut(ax_id).ok_or_else(|| ...)?;
130
+ let color = if let Some(c) = kwargs.get_item("color")? { Some(parse_color_value(&c)?) } else { None };
131
+ ax.my_plot(data, color);
132
+ Ok(())
133
+ }
134
+ ```
135
+
136
+ **5. Add Python wrapper** (`python/rustplotlib/pyplot.py`):
137
+ ```python
138
+ # In AxesProxy:
139
+ def my_plot(self, data, **kwargs):
140
+ self._fig.axes_my_plot(self._id, _to_list(data), kwargs)
141
+
142
+ # Module level:
143
+ def my_plot(data, **kwargs):
144
+ _gca().my_plot(data, **kwargs)
145
+ ```
146
+
147
+ **6. Add test** (`tests/test_my_plot.py`):
148
+ ```python
149
+ def test_my_plot():
150
+ import rustplotlib.pyplot as plt
151
+ plt.my_plot([1, 2, 3])
152
+ plt.savefig("/tmp/test_my_plot.png")
153
+ plt.close()
154
+ import os
155
+ assert os.path.exists("/tmp/test_my_plot.png")
156
+ os.remove("/tmp/test_my_plot.png")
157
+ ```
158
+
159
+ ## Development Setup
160
+
161
+ ```bash
162
+ # Clone
163
+ git clone https://github.com/Thi4gon/rustplotlib.git
164
+ cd rustplotlib
165
+
166
+ # Setup (requires Rust and Python 3.9+)
167
+ python -m venv .venv
168
+ source .venv/bin/activate # or .venv\Scripts\activate on Windows
169
+ pip install maturin numpy pytest
170
+
171
+ # Build
172
+ maturin develop
173
+
174
+ # Test
175
+ pytest tests/ -v
176
+
177
+ # Build release (for benchmarks)
178
+ maturin develop --release
179
+ ```
180
+
181
+ ## Code Style
182
+
183
+ - **Rust:** standard rustfmt, no `unsafe`, proper error handling (no `.unwrap()` on user input)
184
+ - **Python:** keep it simple, follow existing patterns in pyplot.py
185
+ - **Tests:** every new feature needs at least one test
186
+ - **Security:** validate all inputs at PyO3 boundary, no path traversal, no panics
187
+
188
+ ## PR Checklist
189
+
190
+ - [ ] All existing tests pass (`pytest tests/ -v`)
191
+ - [ ] New tests added for new features
192
+ - [ ] `maturin develop` compiles without errors
193
+ - [ ] No new warnings in Rust compilation
194
+ - [ ] README.md updated if adding user-facing features
195
+ - [ ] ROADMAP.md checkbox checked for completed items
@@ -1368,7 +1368,7 @@ dependencies = [
1368
1368
 
1369
1369
  [[package]]
1370
1370
  name = "rustplotlib"
1371
- version = "2.0.0"
1371
+ version = "3.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 = "2.0.0"
3
+ version = "3.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: 2.0.0
3
+ Version: 3.0.0
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Science/Research
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -87,15 +87,16 @@ plt.show()
87
87
 
88
88
  ## What's Implemented
89
89
 
90
- ### 2D Plot Types (17 types)
90
+ ### 2D Plot Types (30+ types)
91
91
  | Function | Description |
92
92
  |---|---|
93
- | `plot()` | Line plots with color, linestyle, linewidth, markers, markevery, labels, alpha |
94
- | `scatter()` | Scatter plots with per-point sizes, colors, markers, alpha |
95
- | `bar()` / `barh()` | Vertical and horizontal bar charts (stacked via `bottom` param) |
93
+ | `plot()` | Line plots with color, linestyle, linewidth, markers, markevery, labels, alpha, zorder |
94
+ | `scatter()` | Scatter plots with per-point sizes, colors, markers, alpha, zorder |
95
+ | `bar()` / `barh()` | Vertical and horizontal bar charts (stacked, hatch patterns, zorder) |
96
96
  | `hist()` | Histograms with configurable bins |
97
- | `imshow()` | Image/heatmap display with 35+ colormaps |
97
+ | `imshow()` | Image/heatmap display with 70+ colormaps, bilinear interpolation, annotations |
98
98
  | `fill_between()` / `fill_betweenx()` | Filled area between curves (vertical and horizontal) |
99
+ | `fill()` | Filled polygon from vertex arrays |
99
100
  | `errorbar()` | Error bars with caps (xerr/yerr) |
100
101
  | `step()` | Step plots (pre/post/mid) |
101
102
  | `pie()` | Pie charts with labels |
@@ -106,8 +107,20 @@ plt.show()
106
107
  | `hexbin()` | Hexagonal binning for 2D histograms |
107
108
  | `quiver()` | Vector field arrows |
108
109
  | `streamplot()` | Streamlines for vector fields (Euler integration) |
109
-
110
- ### 3D Plot Types (5 types)
110
+ | `stackplot()` | Stacked area charts |
111
+ | `broken_barh()` | Broken horizontal bar charts |
112
+ | `eventplot()` | Event/raster plots |
113
+ | `pcolormesh()` / `pcolor()` | Pseudocolor plots for irregular grids |
114
+ | `matshow()` | Matrix display with integer ticks |
115
+ | `radar()` | Radar/spider charts |
116
+ | `sankey()` | Sankey flow diagrams |
117
+ | `spy()` | Sparsity pattern visualization |
118
+ | `stairs()` | Step-wise constant function with edges |
119
+ | `ecdf()` | Empirical cumulative distribution |
120
+ | `triplot()` | Triangulation edge drawing |
121
+ | `pcolormesh()` / `pcolor()` already listed above |
122
+
123
+ ### 3D Plot Types (7 types)
111
124
  | Function | Description |
112
125
  |---|---|
113
126
  | `plot()` (3D) | 3D line plots |
@@ -115,6 +128,8 @@ plt.show()
115
128
  | `plot_surface()` | 3D surface plots with colormaps |
116
129
  | `plot_wireframe()` | 3D wireframe plots |
117
130
  | `bar3d()` | 3D bar charts with shading |
131
+ | `plot_trisurf()` | 3D triangulated surface |
132
+ | `contour3D()` | 3D contour lines at Z offset |
118
133
 
119
134
  ### Layout & Figure
120
135
  | Function | Description |
@@ -145,7 +160,9 @@ plt.show()
145
160
  | `axis('off')` | Hide axes completely |
146
161
  | `set_facecolor()` | Axes background color |
147
162
  | `spines['right'].set_visible(False)` | Spine customization |
148
- | `twinx()` | Secondary y-axis |
163
+ | `twinx()` / `twiny()` | Secondary y-axis / x-axis |
164
+ | `zorder` | Drawing order control for all artists |
165
+ | `hatch` | Hatch patterns for bars (`/`, `\\`, `|`, `-`, `+`, `x`, `o`, `.`, `*`) |
149
166
  | `legend()` | Legend with line+marker swatches and positioning |
150
167
  | `grid()` | Grid lines with color, linewidth, linestyle, alpha, which |
151
168
  | `text()` | Positioned text annotations |
@@ -191,9 +208,13 @@ plt.show()
191
208
  - **Format strings:** `"r--o"` = red + dashed + circle markers
192
209
  - **markevery:** show marker every N points
193
210
 
194
- ### Colormaps (35+)
211
+ ### Colormaps (70+)
212
+ 35 base colormaps + all reversed variants (`_r` suffix):
213
+
195
214
  `viridis` `plasma` `inferno` `magma` `cividis` `twilight` `turbo` `hot` `cool` `gray` `jet` `spring` `summer` `autumn` `winter` `copper` `bone` `pink` `binary` `gist_heat` `ocean` `terrain` `Blues` `Reds` `Greens` `YlOrRd` `YlGnBu` `RdYlBu` `RdBu` `PiYG` `PRGn` `BrBG` `Spectral` `Set1` `Set2` `Set3` `Pastel1` `Pastel2` `tab20`
196
215
 
216
+ All also available as `viridis_r`, `plasma_r`, `hot_r`, etc.
217
+
197
218
  ### Text Rendering
198
219
  - Embedded DejaVu Sans font (no system font dependency)
199
220
  - LaTeX-to-Unicode conversion (`$\theta$` -> theta, `$x_1$` -> x1, Greek letters, sub/superscripts, math operators)
@@ -205,21 +226,31 @@ plt.show()
205
226
  - **Dates:** `date2num()`, `num2date()`, date formatters and locators
206
227
  - **Categorical axes:** string-based x values automatically converted
207
228
 
208
- ### Compatibility Modules
229
+ ### Compatibility Modules (23 modules)
209
230
  | Module | Status |
210
231
  |---|---|
211
- | `rustplotlib.pyplot` | Full implementation |
232
+ | `rustplotlib.pyplot` | Full implementation (50+ functions) |
212
233
  | `rustplotlib.style` | Full implementation (6 themes) |
213
234
  | `rustplotlib.animation` | FuncAnimation + GIF export |
214
235
  | `rustplotlib.widgets` | Stubs (Slider, Button, CheckButtons, RadioButtons, TextBox, Cursor) |
215
- | `rustplotlib.font_manager` | FontProperties stub |
216
- | `rustplotlib.ticker` | FormatStrFormatter stub |
236
+ | `rustplotlib.font_manager` | FontProperties |
237
+ | `rustplotlib.ticker` | FormatStrFormatter |
217
238
  | `rustplotlib.patches` | Rectangle, Circle, Polygon, FancyBboxPatch, Wedge |
218
239
  | `rustplotlib.colors` | LinearSegmentedColormap, Normalize, LogNorm |
219
240
  | `rustplotlib.dates` | Date conversion, formatters, locators |
220
241
  | `rustplotlib.gridspec` | GridSpec, SubplotSpec |
221
- | `rustplotlib.backends` | Backend system with `use()` |
242
+ | `rustplotlib.backends` | Backend system, PdfPages |
222
243
  | `rustplotlib.mpl_toolkits.mplot3d` | Axes3D for 3D plotting |
244
+ | `rustplotlib.cm` | Colormap access by name |
245
+ | `rustplotlib.collections` | LineCollection, PathCollection, PatchCollection |
246
+ | `rustplotlib.lines` | Line2D with get/set methods |
247
+ | `rustplotlib.text` | Text, Annotation |
248
+ | `rustplotlib.transforms` | Bbox, Affine2D, BboxTransform |
249
+ | `rustplotlib.patheffects` | Stroke, withStroke, SimplePatchShadow |
250
+ | `rustplotlib.spines` | Spine |
251
+ | `rustplotlib.axes` | Axes class reference |
252
+ | `rustplotlib.figure` | Figure class reference |
253
+ | `rustplotlib.cycler` | cycler compatibility |
223
254
 
224
255
  ---
225
256
 
@@ -389,11 +420,21 @@ Contributions are welcome! This is an open-source project under the MIT license.
389
420
  3. Open a PR against `master`
390
421
  4. PRs require at least 1 review before merging
391
422
 
423
+ **Project stats:**
424
+ - **45+ Rust source files** — 15,000+ lines of native code
425
+ - **23 Python modules** — 4,000+ lines of API
426
+ - **37+ artist types** (30 2D + 7 3D)
427
+ - **70+ colormaps** (35 base + 35 reversed)
428
+ - **228 tests** passing
429
+ - **12 formatters + 10 locators**
430
+ - **RGB/RGBA imshow** support
431
+ - **Zero `unsafe` blocks**
432
+
392
433
  **Priority areas for contribution:**
393
434
  - Turning stub modules into full implementations (widgets, formatters/locators)
394
- - Adding more colormaps with exact matplotlib data
395
435
  - Improving SVG output fidelity
396
- - Jupyter inline display support
436
+ - Interactive 3D (mouse rotation)
437
+ - Qt/GTK backends
397
438
  - More comprehensive test coverage
398
439
 
399
440
  ---
@@ -67,15 +67,16 @@ plt.show()
67
67
 
68
68
  ## What's Implemented
69
69
 
70
- ### 2D Plot Types (17 types)
70
+ ### 2D Plot Types (30+ types)
71
71
  | Function | Description |
72
72
  |---|---|
73
- | `plot()` | Line plots with color, linestyle, linewidth, markers, markevery, labels, alpha |
74
- | `scatter()` | Scatter plots with per-point sizes, colors, markers, alpha |
75
- | `bar()` / `barh()` | Vertical and horizontal bar charts (stacked via `bottom` param) |
73
+ | `plot()` | Line plots with color, linestyle, linewidth, markers, markevery, labels, alpha, zorder |
74
+ | `scatter()` | Scatter plots with per-point sizes, colors, markers, alpha, zorder |
75
+ | `bar()` / `barh()` | Vertical and horizontal bar charts (stacked, hatch patterns, zorder) |
76
76
  | `hist()` | Histograms with configurable bins |
77
- | `imshow()` | Image/heatmap display with 35+ colormaps |
77
+ | `imshow()` | Image/heatmap display with 70+ colormaps, bilinear interpolation, annotations |
78
78
  | `fill_between()` / `fill_betweenx()` | Filled area between curves (vertical and horizontal) |
79
+ | `fill()` | Filled polygon from vertex arrays |
79
80
  | `errorbar()` | Error bars with caps (xerr/yerr) |
80
81
  | `step()` | Step plots (pre/post/mid) |
81
82
  | `pie()` | Pie charts with labels |
@@ -86,8 +87,20 @@ plt.show()
86
87
  | `hexbin()` | Hexagonal binning for 2D histograms |
87
88
  | `quiver()` | Vector field arrows |
88
89
  | `streamplot()` | Streamlines for vector fields (Euler integration) |
89
-
90
- ### 3D Plot Types (5 types)
90
+ | `stackplot()` | Stacked area charts |
91
+ | `broken_barh()` | Broken horizontal bar charts |
92
+ | `eventplot()` | Event/raster plots |
93
+ | `pcolormesh()` / `pcolor()` | Pseudocolor plots for irregular grids |
94
+ | `matshow()` | Matrix display with integer ticks |
95
+ | `radar()` | Radar/spider charts |
96
+ | `sankey()` | Sankey flow diagrams |
97
+ | `spy()` | Sparsity pattern visualization |
98
+ | `stairs()` | Step-wise constant function with edges |
99
+ | `ecdf()` | Empirical cumulative distribution |
100
+ | `triplot()` | Triangulation edge drawing |
101
+ | `pcolormesh()` / `pcolor()` already listed above |
102
+
103
+ ### 3D Plot Types (7 types)
91
104
  | Function | Description |
92
105
  |---|---|
93
106
  | `plot()` (3D) | 3D line plots |
@@ -95,6 +108,8 @@ plt.show()
95
108
  | `plot_surface()` | 3D surface plots with colormaps |
96
109
  | `plot_wireframe()` | 3D wireframe plots |
97
110
  | `bar3d()` | 3D bar charts with shading |
111
+ | `plot_trisurf()` | 3D triangulated surface |
112
+ | `contour3D()` | 3D contour lines at Z offset |
98
113
 
99
114
  ### Layout & Figure
100
115
  | Function | Description |
@@ -125,7 +140,9 @@ plt.show()
125
140
  | `axis('off')` | Hide axes completely |
126
141
  | `set_facecolor()` | Axes background color |
127
142
  | `spines['right'].set_visible(False)` | Spine customization |
128
- | `twinx()` | Secondary y-axis |
143
+ | `twinx()` / `twiny()` | Secondary y-axis / x-axis |
144
+ | `zorder` | Drawing order control for all artists |
145
+ | `hatch` | Hatch patterns for bars (`/`, `\\`, `|`, `-`, `+`, `x`, `o`, `.`, `*`) |
129
146
  | `legend()` | Legend with line+marker swatches and positioning |
130
147
  | `grid()` | Grid lines with color, linewidth, linestyle, alpha, which |
131
148
  | `text()` | Positioned text annotations |
@@ -171,9 +188,13 @@ plt.show()
171
188
  - **Format strings:** `"r--o"` = red + dashed + circle markers
172
189
  - **markevery:** show marker every N points
173
190
 
174
- ### Colormaps (35+)
191
+ ### Colormaps (70+)
192
+ 35 base colormaps + all reversed variants (`_r` suffix):
193
+
175
194
  `viridis` `plasma` `inferno` `magma` `cividis` `twilight` `turbo` `hot` `cool` `gray` `jet` `spring` `summer` `autumn` `winter` `copper` `bone` `pink` `binary` `gist_heat` `ocean` `terrain` `Blues` `Reds` `Greens` `YlOrRd` `YlGnBu` `RdYlBu` `RdBu` `PiYG` `PRGn` `BrBG` `Spectral` `Set1` `Set2` `Set3` `Pastel1` `Pastel2` `tab20`
176
195
 
196
+ All also available as `viridis_r`, `plasma_r`, `hot_r`, etc.
197
+
177
198
  ### Text Rendering
178
199
  - Embedded DejaVu Sans font (no system font dependency)
179
200
  - LaTeX-to-Unicode conversion (`$\theta$` -> theta, `$x_1$` -> x1, Greek letters, sub/superscripts, math operators)
@@ -185,21 +206,31 @@ plt.show()
185
206
  - **Dates:** `date2num()`, `num2date()`, date formatters and locators
186
207
  - **Categorical axes:** string-based x values automatically converted
187
208
 
188
- ### Compatibility Modules
209
+ ### Compatibility Modules (23 modules)
189
210
  | Module | Status |
190
211
  |---|---|
191
- | `rustplotlib.pyplot` | Full implementation |
212
+ | `rustplotlib.pyplot` | Full implementation (50+ functions) |
192
213
  | `rustplotlib.style` | Full implementation (6 themes) |
193
214
  | `rustplotlib.animation` | FuncAnimation + GIF export |
194
215
  | `rustplotlib.widgets` | Stubs (Slider, Button, CheckButtons, RadioButtons, TextBox, Cursor) |
195
- | `rustplotlib.font_manager` | FontProperties stub |
196
- | `rustplotlib.ticker` | FormatStrFormatter stub |
216
+ | `rustplotlib.font_manager` | FontProperties |
217
+ | `rustplotlib.ticker` | FormatStrFormatter |
197
218
  | `rustplotlib.patches` | Rectangle, Circle, Polygon, FancyBboxPatch, Wedge |
198
219
  | `rustplotlib.colors` | LinearSegmentedColormap, Normalize, LogNorm |
199
220
  | `rustplotlib.dates` | Date conversion, formatters, locators |
200
221
  | `rustplotlib.gridspec` | GridSpec, SubplotSpec |
201
- | `rustplotlib.backends` | Backend system with `use()` |
222
+ | `rustplotlib.backends` | Backend system, PdfPages |
202
223
  | `rustplotlib.mpl_toolkits.mplot3d` | Axes3D for 3D plotting |
224
+ | `rustplotlib.cm` | Colormap access by name |
225
+ | `rustplotlib.collections` | LineCollection, PathCollection, PatchCollection |
226
+ | `rustplotlib.lines` | Line2D with get/set methods |
227
+ | `rustplotlib.text` | Text, Annotation |
228
+ | `rustplotlib.transforms` | Bbox, Affine2D, BboxTransform |
229
+ | `rustplotlib.patheffects` | Stroke, withStroke, SimplePatchShadow |
230
+ | `rustplotlib.spines` | Spine |
231
+ | `rustplotlib.axes` | Axes class reference |
232
+ | `rustplotlib.figure` | Figure class reference |
233
+ | `rustplotlib.cycler` | cycler compatibility |
203
234
 
204
235
  ---
205
236
 
@@ -369,11 +400,21 @@ Contributions are welcome! This is an open-source project under the MIT license.
369
400
  3. Open a PR against `master`
370
401
  4. PRs require at least 1 review before merging
371
402
 
403
+ **Project stats:**
404
+ - **45+ Rust source files** — 15,000+ lines of native code
405
+ - **23 Python modules** — 4,000+ lines of API
406
+ - **37+ artist types** (30 2D + 7 3D)
407
+ - **70+ colormaps** (35 base + 35 reversed)
408
+ - **228 tests** passing
409
+ - **12 formatters + 10 locators**
410
+ - **RGB/RGBA imshow** support
411
+ - **Zero `unsafe` blocks**
412
+
372
413
  **Priority areas for contribution:**
373
414
  - Turning stub modules into full implementations (widgets, formatters/locators)
374
- - Adding more colormaps with exact matplotlib data
375
415
  - Improving SVG output fidelity
376
- - Jupyter inline display support
416
+ - Interactive 3D (mouse rotation)
417
+ - Qt/GTK backends
377
418
  - More comprehensive test coverage
378
419
 
379
420
  ---
@@ -0,0 +1,189 @@
1
+ # RustPlotLib Roadmap
2
+
3
+ Goal: Full matplotlib reimplementation in Rust.
4
+
5
+ ---
6
+
7
+ ## DONE — v2.0.0
8
+
9
+ ### 2D Plot Types (26 implemented)
10
+ - [x] plot, scatter, bar, barh, hist, imshow, fill_between, fill_betweenx, fill
11
+ - [x] errorbar, step, pie, boxplot, violinplot, stem
12
+ - [x] contour, contourf, hexbin, quiver, streamplot
13
+ - [x] stackplot, broken_barh, eventplot, pcolormesh/pcolor, matshow, sankey
14
+
15
+ ### 3D Plot Types (7 implemented)
16
+ - [x] plot3D, scatter3D, plot_surface, plot_wireframe, bar3d, plot_trisurf, contour3D
17
+
18
+ ### Drawing Elements (10 implemented)
19
+ - [x] arrow, axhline, axvline, axhspan, axvspan, axline, hlines, vlines, annotate, text
20
+
21
+ ### Rendering
22
+ - [x] PNG raster (tiny-skia), Native SVG (vector), PDF, Interactive window, GIF animation
23
+
24
+ ### Customization
25
+ - [x] Log scale, twinx/twiny, spines, tick_params, zorder, hatch patterns
26
+ - [x] Colorbar, 6 style themes, 70+ colormaps, custom fonts, rcParams (30+ keys)
27
+ - [x] bbox_inches='tight', bilinear interpolation, title loc, multi-group plot
28
+ - [x] Aspect ratio, invert axes, axis off, subplot_mosaic, suptitle, subplots_adjust
29
+
30
+ ### Compatibility Modules (23)
31
+ - [x] pyplot, style, animation, widgets, font_manager, ticker, patches, colors
32
+ - [x] dates, gridspec, backends, mpl_toolkits.mplot3d, cm, collections, lines
33
+ - [x] text, transforms, patheffects, spines, axes, figure, cycler
34
+
35
+ ### Data Integration
36
+ - [x] Pandas, NumPy, NaN handling, dates, categorical axes, imread/imsave
37
+
38
+ ### Security
39
+ - [x] Zero unsafe, path validation, dimension limits, no panics on user input
40
+
41
+ ---
42
+
43
+ ## IN PROGRESS — v3.0.0
44
+
45
+ ### Missing Plot Types
46
+ - [ ] `spy()` — sparsity pattern visualization
47
+ - [ ] `specgram()` — spectrogram
48
+ - [ ] `acorr()` / `xcorr()` — auto/cross correlation
49
+ - [ ] `angle_spectrum()` / `magnitude_spectrum()` / `phase_spectrum()`
50
+ - [ ] `cohere()` — coherence plot
51
+ - [ ] `csd()` / `psd()` — cross/power spectral density
52
+ - [ ] `ecdf()` — empirical cumulative distribution
53
+ - [ ] `stairs()` — step plot with edges
54
+ - [ ] `tricontour()` / `tricontourf()` — contour on triangulation
55
+ - [ ] `tripcolor()` — pseudocolor on triangulation
56
+ - [ ] `triplot()` — plot triangulation edges
57
+
58
+ ### Formatters & Locators (functional, not stubs)
59
+ - [ ] `ScalarFormatter` — default number formatting
60
+ - [ ] `LogFormatter` / `LogFormatterSciNotation`
61
+ - [ ] `EngFormatter` — engineering notation (1k, 1M, 1G)
62
+ - [ ] `PercentFormatter`
63
+ - [ ] `StrMethodFormatter` / `FuncFormatter`
64
+ - [ ] `MaxNLocator` — smart tick placement (partial, have auto_ticks)
65
+ - [ ] `MultipleLocator` — ticks at multiples
66
+ - [ ] `LogLocator` — logarithmic ticks
67
+ - [ ] `FixedLocator` — user-specified positions
68
+ - [ ] `AutoMinorLocator` — automatic minor ticks
69
+ - [ ] `DateFormatter` functional (format ticks as dates)
70
+ - [ ] `DateLocator` functional (place ticks at date intervals)
71
+
72
+ ### Advanced Customization
73
+ - [ ] `FancyArrowPatch` — complex arrow styles (arc, angle, etc.)
74
+ - [ ] `ConnectionPatch` — arrows connecting different axes
75
+ - [ ] Spine positioning (`set_position('center')`, `set_position(('data', 0))`)
76
+ - [ ] Minor ticks rendering (major/minor tick distinction)
77
+ - [ ] Grid major/minor separate styling
78
+ - [ ] `ax.set_xticks(minor=True)` functional
79
+ - [ ] Colorbar as separate Axes (not inline drawing)
80
+ - [ ] `TwoSlopeNorm`, `CenteredNorm`, `BoundaryNorm` functional
81
+
82
+ ### Image Improvements
83
+ - [ ] Bicubic, Lanczos, Spline interpolation
84
+ - [ ] Image origin ('upper' vs 'lower')
85
+ - [ ] Image extent parameter
86
+ - [ ] RGB/RGBA image support in imshow
87
+
88
+ ---
89
+
90
+ ## PLANNED — v4.0.0
91
+
92
+ ### Functional Backends
93
+ - [ ] Qt backend (QApplication, mouse events, toolbar, save dialog)
94
+ - [ ] GTK3/GTK4 backend
95
+ - [ ] Tk backend (tkinter integration)
96
+ - [ ] Jupyter inline backend (rich display protocol, `_repr_png_`)
97
+ - [ ] WebAgg (HTML5 Canvas, browser-based interactive)
98
+ - [ ] macOS native backend (NSView/Metal)
99
+
100
+ ### Functional Widgets
101
+ - [ ] `Slider` with real callback and visual rendering
102
+ - [ ] `RangeSlider`
103
+ - [ ] `Button` with click detection
104
+ - [ ] `CheckButtons` / `RadioButtons`
105
+ - [ ] `TextBox` with keyboard input
106
+ - [ ] `SpanSelector` / `RectangleSelector` / `LassoSelector` functional
107
+ - [ ] `Cursor` with crosshair rendering
108
+
109
+ ### Interactive Features
110
+ - [ ] Mouse events (click, motion, scroll, pick)
111
+ - [ ] Keyboard events
112
+ - [ ] Zoom/pan navigation toolbar
113
+ - [ ] 3D mouse rotation
114
+ - [ ] Blitting for fast animation updates
115
+ - [ ] Interactive data cursors
116
+
117
+ ---
118
+
119
+ ## PLANNED — v5.0.0
120
+
121
+ ### Full LaTeX Math Rendering
122
+ - [ ] TeX layout engine (fractions, roots, integrals, summation)
123
+ - [ ] Subscript/superscript positioning
124
+ - [ ] Math font rendering (Computer Modern, STIX)
125
+ - [ ] `\frac{}{}`, `\sqrt{}`, `\int`, `\sum`, `\prod`
126
+ - [ ] Matrices, arrays, aligned equations
127
+ - [ ] `\mathbf{}`, `\mathit{}`, `\mathrm{}`
128
+
129
+ ### Advanced Layout
130
+ - [ ] Tight layout engine (constraint solver)
131
+ - [ ] Constrained layout
132
+ - [ ] GridSpec with rowspan/colspan
133
+ - [ ] Figure.add_axes() with custom position [left, bottom, width, height]
134
+ - [ ] Axes divider (mpl_toolkits.axes_grid1)
135
+ - [ ] `make_axes_locatable` for colorbar positioning
136
+ - [ ] Nested subplots
137
+
138
+ ### Transform System
139
+ - [ ] Composable transforms (data → axes → figure → display)
140
+ - [ ] `ax.transData`, `ax.transAxes`, `fig.transFigure`
141
+ - [ ] Blended transforms
142
+ - [ ] Custom projections
143
+ - [ ] Affine2D functional (rotate, scale, translate)
144
+ - [ ] `ax.set_transform()` on artists
145
+
146
+ ---
147
+
148
+ ## PLANNED — v6.0.0
149
+
150
+ ### Geographic/Specialized Projections
151
+ - [ ] Polar projection improvements (theta direction, offset)
152
+ - [ ] Hammer, Aitoff, Mollweide projections
153
+ - [ ] Lambert conformal conic
154
+ - [ ] Stereographic projection
155
+ - [ ] Basemap-like coastlines and borders (optional data)
156
+
157
+ ### Serialization
158
+ - [ ] Pickle save/load figures
159
+ - [ ] JSON export/import of figure state
160
+ - [ ] Copy to system clipboard (PNG)
161
+ - [ ] Multi-page PDF (real, not separate files)
162
+
163
+ ### Full Artist Hierarchy
164
+ - [ ] Artist base class with all properties (alpha, clip, zorder, transform, visible, picker, animated, label, url)
165
+ - [ ] `set_clip_path()`, `set_clip_box()`
166
+ - [ ] `contains()` for hit testing
167
+ - [ ] `get_children()`, `findobj()`
168
+ - [ ] `draw()` dispatch through artist tree
169
+ - [ ] `stale` property for incremental redraw
170
+
171
+ ### Remaining API Surface
172
+ - [ ] 100% of `matplotlib.pyplot` functions
173
+ - [ ] 100% of `Axes` methods
174
+ - [ ] 100% of `Figure` methods
175
+ - [ ] Image comparison regression tests vs matplotlib output
176
+ - [ ] Full API documentation with examples
177
+ - [ ] Type stubs (.pyi) for all modules
178
+
179
+ ---
180
+
181
+ ## Contributing
182
+
183
+ Pick any unchecked item, open an issue to discuss, submit a PR with tests.
184
+
185
+ **Highest impact areas:**
186
+ 1. Formatters/Locators (v3.0.0) — makes axes look professional
187
+ 2. Jupyter backend (v4.0.0) — huge for data scientists
188
+ 3. LaTeX rendering (v5.0.0) — needed for scientific papers
189
+ 4. Interactive features (v4.0.0) — needed for exploratory analysis