rsplotlib 0.1.5.post1__tar.gz → 0.1.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/Cargo.lock +1 -1
  2. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/Cargo.toml +1 -1
  3. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/PKG-INFO +2 -4
  4. rsplotlib-0.1.6/README.md +755 -0
  5. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/README_zh.md +1 -3
  6. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/pyproject.toml +1 -1
  7. rsplotlib-0.1.5.post1/README.md +0 -6
  8. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/.github/ci.yml +0 -0
  9. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/.github/release.yml +0 -0
  10. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/.gitignore +0 -0
  11. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/LICENSE +0 -0
  12. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/build_wheel.sh +0 -0
  13. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/python/rsplotlib/__init__.py +0 -0
  14. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/python/rsplotlib/_figure_defaults.py +0 -0
  15. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/python/rsplotlib/_font_resolver.py +0 -0
  16. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/python/rsplotlib/_rcparams.py +0 -0
  17. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/python/rsplotlib/api.py +0 -0
  18. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/python/rsplotlib/gridspec.py +0 -0
  19. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/python/rsplotlib/pylab.py +0 -0
  20. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/python/rsplotlib/pyplot.py +0 -0
  21. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/python/rsplotlib/style.py +0 -0
  22. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/python/rsplotlib/ticker.py +0 -0
  23. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/rust-toolchain.toml +0 -0
  24. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/axes.rs +0 -0
  25. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/axes_bounds.rs +0 -0
  26. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/axes_grid.rs +0 -0
  27. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/axes_legend.rs +0 -0
  28. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/axes_mesh.rs +0 -0
  29. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/axes_render_elements.rs +0 -0
  30. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/axes_title.rs +0 -0
  31. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/axis.rs +0 -0
  32. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/colormap.rs +0 -0
  33. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/colors.rs +0 -0
  34. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/elements.rs +0 -0
  35. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/figure.rs +0 -0
  36. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/lib.rs +0 -0
  37. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/marker.rs +0 -0
  38. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/pyfuncs.rs +0 -0
  39. {rsplotlib-0.1.5.post1 → rsplotlib-0.1.6}/src/text_utils.rs +0 -0
@@ -339,7 +339,7 @@ dependencies = [
339
339
 
340
340
  [[package]]
341
341
  name = "rsplotlib"
342
- version = "0.1.5"
342
+ version = "0.1.6"
343
343
  dependencies = [
344
344
  "plotters",
345
345
  "png",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rsplotlib"
3
- version = "0.1.5"
3
+ version = "0.1.6"
4
4
  edition = "2024"
5
5
  readme = "README.md"
6
6
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rsplotlib
3
- Version: 0.1.5.post1
3
+ Version: 0.1.6
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: Programming Language :: Python :: 3 :: Only
@@ -768,10 +768,8 @@ MIT License — 详见 [LICENSE](LICENSE) 文件。
768
768
  ## 相关链接
769
769
 
770
770
  - **GitHub**: https://github.com/YJ-Niu/rsplotlib
771
- - **PyPI**: (待发布)
772
- - **文档**: (待完善)
773
771
 
774
772
  ---
775
773
 
776
- _最后更新:2026-06-17 · 版本 v0.1.5_
774
+ _最后更新:2026-06-17 · 版本 v0.1.6_
777
775
 
@@ -0,0 +1,755 @@
1
+ # rsplotlib
2
+
3
+ > A high-performance Python plotting library powered by Rust, with a Matplotlib-compatible API
4
+
5
+ [![Python](https://img.shields.io/badge/Python-3.8%2B-blue)](https://www.python.org/)
6
+ [![Rust](https://img.shields.io/badge/Rust-2021-orange)](https://www.rust-lang.org/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+ [![PyO3](https://img.shields.io/badge/PyO3-0.29-2c2d72)](https://pyo3.rs/)
9
+ [![plotters](https://img.shields.io/badge/plotters-0.3-7d5cff)](https://github.com/plotters-rs/plotters)
10
+
11
+ ---
12
+
13
+ ## Table of Contents
14
+
15
+ - [Introduction](#introduction)
16
+ - [Core Features](#core-features)
17
+ - [Installation](#installation)
18
+ - [Quick Start](#quick-start)
19
+ - [Feature Reference](#feature-reference)
20
+ - [API Reference](#api-reference)
21
+ - [Performance Advantages](#performance-advantages)
22
+ - [Project Structure](#project-structure)
23
+ - [Development & Contributing](#development--contributing)
24
+ - [Font Configuration](#font-configuration)
25
+ - [License](#license)
26
+ - [Acknowledgments](#acknowledgments)
27
+
28
+ ---
29
+
30
+ ## Introduction
31
+
32
+ **rsplotlib** is a cross-language Python plotting library whose core rendering engine is written entirely in Rust, providing a Matplotlib-compatible Python API through PyO3. The project aims to maximize compatibility with existing Matplotlib code while leveraging Rust's memory safety and zero-cost abstractions to deliver significant performance improvements.
33
+
34
+ ### Design Philosophy
35
+
36
+ - **API First**: Maintain a highly compatible interface with Matplotlib for low migration cost
37
+ - **Performance Matters**: Offload performance-critical paths (rendering, batch operations) to Rust
38
+ - **Zero Extra Dependencies**: No native Matplotlib installation required - just a Python interpreter
39
+ - **Cross-Platform Consistency**: Identical rendering quality on macOS, Linux, and Windows
40
+
41
+ ---
42
+
43
+ ## Core Features
44
+
45
+ ### Rich Chart Types
46
+
47
+ - **Basic Charts**: Line plots, scatter plots, bar charts, horizontal bar charts
48
+ - **Statistical Charts**: Histograms, box plots, pie charts, error bars, stem plots, step plots
49
+ - **Advanced Charts**: Stacked area plots, heatmap/image display, fill-between regions
50
+
51
+ ### Annotation & Reference Elements
52
+
53
+ - **Reference Lines**: Horizontal (`axhline`), vertical (`axvline`)
54
+ - **Span Highlighting**: Horizontal span (`axhspan`), vertical span (`axvspan`)
55
+ - **Arbitrary-Slope Reference Lines**: `axline` - draw a line through any two points, extending across the plot
56
+ - **Batch Lines**: `hlines` / `vlines` - Rust-level batch implementation, no Python `for` loops
57
+ - **Text Annotations**: `text`, `title`, arrowed `annotate` (with `arrowprops` support)
58
+
59
+ ### Coordinates & Layout
60
+
61
+ - Multi-subplot support: `subplots()`, `subplot()`, grid layouts
62
+ - Twin axes: `twinx()` / `twiny()`
63
+ - Log-scale axes: `semilogx()`, `semilogy()`, `loglog()`
64
+ - Grid display, legends, axis limits, tick customization
65
+
66
+ ### Output & Resolution
67
+
68
+ - **PNG**: Bitmap output with DPI control
69
+ - **SVG**: Scalable vector output for lossless scaling
70
+ - **Custom DPI**: `savefig(filename, dpi=300)` supports arbitrary resolution
71
+ - **DPI in PNG Metadata**: DPI written directly into PNG metadata for publication use
72
+
73
+ ### Scatter Plot Enhancements
74
+
75
+ - **Per-Point Colors**: `ax.scatter(x, y, c=['red', 'blue', 'green'])`
76
+ - **Per-Point Sizes**: `ax.scatter(x, y, s=[10, 20, 30, 40])`
77
+ - **Independent Color + Size**: Implemented at Rust level - zero Python loop overhead
78
+
79
+ ### Style Management
80
+
81
+ - **`plt.style` Module**: Matplotlib-compatible style interface
82
+ - **`plt.style.use()`**: Apply preset styles
83
+ - **`plt.style.available`**: Query available styles
84
+ - **`plt.rcParams`**: Global parameter configuration (font family, size, etc.)
85
+
86
+ ### Fonts & Internationalization
87
+
88
+ - **Cross-Platform Font Resolution**: Automatically finds available system fonts
89
+ - **CJK Support**: Built-in detection for Chinese/Japanese/Korean fonts
90
+ - **Custom Font Registration**: `register_sans_serif_font(path)` - register any font file
91
+
92
+ ---
93
+
94
+ ## Installation
95
+
96
+ ### Prerequisites
97
+
98
+ | Dependency | Version | Notes |
99
+ | ---------- | ------- | --------------------------------------- |
100
+ | Python | 3.8+ | CPython implementation |
101
+ | Rust | 1.70+ | Required only when building from source |
102
+ | maturin | 1.13+ | Rust-Python package build tool |
103
+
104
+ ### Method 1: Build from source with maturin (recommended for developers)
105
+
106
+ ```bash
107
+ # 1. Clone the repository
108
+ git clone https://github.com/YJ-Niu/rsplotlib.git
109
+ cd rsplotlib
110
+
111
+ # 2. Build and install (compiles Rust, installs to current Python env)
112
+ pip install maturin
113
+ maturin develop --release
114
+ ```
115
+
116
+ ### Method 2: Build a wheel package
117
+
118
+ ```bash
119
+ # Use the project build script
120
+ ./build_wheel.sh
121
+
122
+ # Install the generated wheel
123
+ pip install target/wheels/rsplotlib-*.whl
124
+ ```
125
+
126
+ ### Method 3: Rust extension only (for debugging)
127
+
128
+ ```bash
129
+ # Compile the Rust cdylib
130
+ cargo build --release
131
+
132
+ # Copy the compiled artifact to the correct Python extension module name
133
+ # macOS:
134
+ cp target/release/librsplotlib.dylib python/rsplotlib/rsplotlib.cpython-39-darwin.so
135
+
136
+ # Linux:
137
+ # cp target/release/librsplotlib.so python/rsplotlib/rsplotlib.cpython-39-x86_64-linux-gnu.so
138
+
139
+ # Use from the source directory
140
+ export PYTHONPATH="$PWD/python:$PYTHONPATH"
141
+ ```
142
+
143
+ ### Verify Installation
144
+
145
+ ```python
146
+ >>> import rsplotlib.pyplot as plt
147
+ >>> fig, ax = plt.subplots()
148
+ >>> ax.plot([1, 2, 3], [1, 4, 9])
149
+ >>> fig.savefig('test.png')
150
+ # If test.png is generated, installation succeeded
151
+ ```
152
+
153
+ ---
154
+
155
+ ## Quick Start
156
+
157
+ ### Basic Usage: Line Plot
158
+
159
+ ```python
160
+ from rsplotlib import pyplot as plt
161
+ from rsplotlib.pylab import mpl
162
+
163
+ # Optional: Configure CJK fonts
164
+ mpl.rcParams['font.sans-serif'] = ['PingFang SC', 'Microsoft YaHei', 'Arial']
165
+
166
+ # Create Figure and Axes
167
+ fig, ax = plt.subplots(figsize=(8, 6))
168
+
169
+ # Plot data
170
+ x = [0, 1, 2, 3, 4, 5]
171
+ y1 = [1, 2, 4, 8, 16, 32]
172
+ y2 = [32, 16, 8, 4, 2, 1]
173
+
174
+ ax.plot(x, y1, label='Exponential Growth', lw=2.0)
175
+ ax.plot(x, y2, label='Exponential Decay', lw=2.0, linestyle='--')
176
+
177
+ # Decorate the chart
178
+ ax.set_title('Basic Line Plot Example')
179
+ ax.set_xlabel('Time')
180
+ ax.set_ylabel('Value')
181
+ ax.legend()
182
+ ax.grid(True)
183
+
184
+ # Save as high-resolution PNG
185
+ fig.savefig('line_plot.png', dpi=300)
186
+ ```
187
+
188
+ ### Scatter Plot: Per-Point Colors and Sizes
189
+
190
+ ```python
191
+ import random
192
+ from rsplotlib import pyplot as plt
193
+
194
+ # Generate random data
195
+ random.seed(42)
196
+ n = 50
197
+ x = [random.gauss(0, 1) for _ in range(n)]
198
+ y = [random.gauss(0, 1) for _ in range(n)]
199
+
200
+ # Per-point colors and sizes (Rust-level processing, zero Python loops)
201
+ colors = ['red' if xi > 0 else 'blue' for xi in x]
202
+ sizes = [max(10, abs(xi * yi * 50)) for xi, yi in zip(x, y)]
203
+
204
+ fig, ax = plt.subplots()
205
+ ax.scatter(x, y, c=colors, s=sizes, alpha=0.7)
206
+ ax.set_title('Scatter: Independent Colors/Sizes')
207
+ fig.savefig('scatter.png')
208
+ ```
209
+
210
+ ### Span Highlighting & Reference Lines
211
+
212
+ ```python
213
+ from rsplotlib import pyplot as plt
214
+
215
+ fig, ax = plt.subplots()
216
+ x = list(range(-5, 6))
217
+ y = [xi**2 for xi in x]
218
+
219
+ # Plot data
220
+ ax.plot(x, y, 'b-', lw=2, label='y = x^2')
221
+
222
+ # Vertical span highlight
223
+ ax.axvspan(-1, 1, color='yellow', alpha=0.3, label='Minimum Region')
224
+
225
+ # Horizontal span highlight
226
+ ax.axhspan(0, 5, color='lightgreen', alpha=0.2)
227
+
228
+ # Horizontal/vertical reference lines
229
+ ax.axhline(y=0, color='gray', linestyle=':', linewidth=1)
230
+ ax.axvline(x=0, color='gray', linestyle=':', linewidth=1)
231
+
232
+ # Arbitrary-slope reference line (through the whole chart)
233
+ ax.axline((0, 0), (1, 1), color='red', linestyle='--', linewidth=1.5)
234
+
235
+ ax.legend()
236
+ fig.savefig('reference_lines.png')
237
+ ```
238
+
239
+ ### Arrowed Annotations
240
+
241
+ ```python
242
+ from rsplotlib import pyplot as plt
243
+
244
+ fig, ax = plt.subplots()
245
+
246
+ # Plot curve
247
+ x = list(range(-10, 11))
248
+ y = [xi**3 - 3*xi for xi in x]
249
+ ax.plot(x, y, 'b-', lw=2)
250
+
251
+ # Add arrowed annotations
252
+ ax.annotate('Local Maximum', xy=(-1, 2), xytext=(-8, 500),
253
+ fontsize=11, color='red',
254
+ arrowprops={'arrowstyle': '->', 'arrowsize': 1.0})
255
+
256
+ ax.annotate('Local Minimum', xy=(1, -2), xytext=(3, -500),
257
+ fontsize=11, color='blue',
258
+ arrowprops={'arrowstyle': '->', 'arrowsize': 1.0})
259
+
260
+ ax.annotate('Origin', xy=(0, 0), xytext=(5, 200),
261
+ fontsize=11, color='darkgreen')
262
+
263
+ ax.set_title('ax.annotate: Text with Arrow Annotations')
264
+ fig.savefig('annotations.png')
265
+ ```
266
+
267
+ ### Batch Horizontal/Vertical Lines (Rust-level implementation)
268
+
269
+ ```python
270
+ from rsplotlib import pyplot as plt
271
+
272
+ fig, ax = plt.subplots()
273
+ ax.plot([0, 10], [0, 10], 'k-', lw=1)
274
+
275
+ # Draw horizontal lines in batch (Rust-level loop, zero Python overhead)
276
+ ax.hlines([2, 4, 6, 8], color='steelblue', linestyle='--', linewidth=1)
277
+
278
+ # Draw vertical lines in batch
279
+ ax.vlines([2, 4, 6, 8], color='darkorange', linestyle=':', linewidth=1)
280
+
281
+ ax.set_title('hlines / vlines: Batch Reference Lines (Rust-level)')
282
+ fig.savefig('hlines_vlines.png')
283
+ ```
284
+
285
+ ### Multiple Subplots
286
+
287
+ ```python
288
+ from rsplotlib import pyplot as plt
289
+
290
+ # 2x2 grid
291
+ fig, axes = plt.subplots(2, 2)
292
+
293
+ # axes is a flat list
294
+ axes[0].plot([1, 2, 3], [1, 4, 9])
295
+ axes[0].set_title('Subplot 1')
296
+
297
+ axes[1].bar(['A', 'B', 'C'], [3, 7, 2])
298
+ axes[1].set_title('Subplot 2')
299
+
300
+ axes[2].scatter([1,2,3,4], [4,3,2,1], c=['red','green','blue','orange'])
301
+ axes[2].set_title('Subplot 3')
302
+
303
+ axes[3].hist([0.5, 1.2, 1.8, 2.1, 2.5, 3.0, 3.2, 3.8, 4.1, 4.5], bins=5)
304
+ axes[3].set_title('Subplot 4')
305
+
306
+ fig.savefig('subplots.png', dpi=200)
307
+ ```
308
+
309
+ ### Module-Level Interface (Without Explicit Axes)
310
+
311
+ ```python
312
+ from rsplotlib import pyplot as plt
313
+
314
+ # Use plt.* directly
315
+ plt.figure()
316
+ plt.plot([1, 2, 3], [1, 2, 3], 'r-')
317
+ plt.axhline(y=2, color='gray', linestyle='--')
318
+ plt.axvspan(1, 2, color='yellow', alpha=0.3)
319
+ plt.title('Module-Level Interface')
320
+ plt.savefig('module_level.png')
321
+ ```
322
+
323
+ ---
324
+
325
+ ## Feature Reference
326
+
327
+ ### Plotting Functions
328
+
329
+ | Function | Description | Module-Level | Axes Method |
330
+ | ---------------- | ----------------------------------------- | ------------ | ----------- |
331
+ | `plot()` | Line plot | Yes | Yes |
332
+ | `scatter()` | Scatter plot (supports color/size arrays) | Yes | Yes |
333
+ | `bar()` | Bar chart | Yes | Yes |
334
+ | `barh()` | Horizontal bar chart | Yes | Yes |
335
+ | `hist()` | Histogram | Yes | Yes |
336
+ | `pie()` | Pie chart | Yes | Yes |
337
+ | `boxplot()` | Box plot | Yes | Yes |
338
+ | `fill_between()` | Fill between lines | Yes | Yes |
339
+ | `errorbar()` | Error bar plot | Yes | Yes |
340
+ | `stem()` | Stem plot | Yes | Yes |
341
+ | `step()` | Step plot | Yes | Yes |
342
+ | `imshow()` | Image/heatmap | Yes | Yes |
343
+ | `stackplot()` | Stacked area plot | Yes | Yes |
344
+ | `semilogx()` | X-axis log-scale line plot | Yes | Yes |
345
+ | `semilogy()` | Y-axis log-scale line plot | Yes | Yes |
346
+ | `loglog()` | Log-log scale line plot | Yes | Yes |
347
+
348
+ ### Annotation Elements
349
+
350
+ | Function | Description | Module-Level | Axes Method |
351
+ | ------------ | ----------------------------------- | ------------ | ----------- |
352
+ | `axhline()` | Horizontal reference line | Yes | Yes |
353
+ | `axvline()` | Vertical reference line | Yes | Yes |
354
+ | `axhspan()` | Horizontal span highlight | Yes | Yes |
355
+ | `axvspan()` | Vertical span highlight | Yes | Yes |
356
+ | `axline()` | Arbitrary-slope reference line | Yes | Yes |
357
+ | `hlines()` | Batch horizontal lines (Rust-level) | Yes | Yes |
358
+ | `vlines()` | Batch vertical lines (Rust-level) | Yes | Yes |
359
+ | `text()` | Text annotation | Yes | Yes |
360
+ | `annotate()` | Arrowed text annotation | Yes | Yes |
361
+
362
+ ### Chart Configuration
363
+
364
+ | Function | Description |
365
+ | -------------------------------------- | --------------------------------- |
366
+ | `title()` / `ax.set_title()` | Set chart title |
367
+ | `xlabel()` / `ax.set_xlabel()` | Set X-axis label |
368
+ | `ylabel()` / `ax.set_ylabel()` | Set Y-axis label |
369
+ | `grid()` | Show/hide grid lines |
370
+ | `legend()` | Show legend |
371
+ | `xlim()` / `ylim()` | Set axis limits |
372
+ | `xticks()` / `yticks()` | Set tick positions and labels |
373
+ | `xscale()` / `yscale()` | Set axis scale (`linear` / `log`) |
374
+ | `margins()` | Set auto-scaling margins |
375
+ | `box()` | Set axes border display |
376
+ | `minorticks_on()` / `minorticks_off()` | Minor tick display control |
377
+
378
+ ### Subplots & Layout
379
+
380
+ | Function | Description |
381
+ | ------------------------------ | --------------------------- |
382
+ | `subplots(nrows, ncols)` | Create a subplot grid |
383
+ | `subplot(nrows, ncols, index)` | Create a single subplot |
384
+ | `twinx()` / `twiny()` | Create twin axes |
385
+ | `tight_layout()` | Auto-adjust layout |
386
+ | `fig.set_size(w, h)` | Set figure pixel dimensions |
387
+
388
+ ### Figure Control
389
+
390
+ | Function | Description |
391
+ | ----------------------------- | ------------------------------------------ |
392
+ | `figure()` | Create a new Figure object |
393
+ | `savefig(filename, dpi=None)` | Save to file, with custom DPI support |
394
+ | `show()` | Display figure (saves to default location) |
395
+ | `gca()` | Get current Axes |
396
+ | `gcf()` | Get current Figure |
397
+ | `cla()` | Clear current Axes |
398
+ | `clf()` | Clear current Figure |
399
+ | `close()` | Close current Figure |
400
+
401
+ ---
402
+
403
+ ## API Reference
404
+
405
+ ### Figure.savefig
406
+
407
+ Save the figure to a file.
408
+
409
+ ```python
410
+ fig.savefig(filename, dpi=None)
411
+ ```
412
+
413
+ **Parameters:**
414
+
415
+ - `filename` (str): Output file path. Supports `.png` and `.svg` extensions
416
+ - `dpi` (float, optional): Resolution (dots per inch). Defaults to Figure's DPI at creation time
417
+
418
+ **Example:**
419
+
420
+ ```python
421
+ fig.savefig('plot.png') # Default DPI
422
+ fig.savefig('plot_hd.png', dpi=150) # Screen resolution
423
+ fig.savefig('plot_print.png', dpi=300) # Print resolution
424
+ fig.savefig('plot.svg') # Vector graphics
425
+ ```
426
+
427
+ ### Axes.scatter - Enhanced Version
428
+
429
+ Scatter plot with support for per-point independent colors and sizes.
430
+
431
+ ```python
432
+ ax.scatter(x, y, s=20.0, c=None, marker='o', label=None, alpha=1.0, **kwargs)
433
+ ```
434
+
435
+ **Parameters:**
436
+
437
+ - `x`, `y` (list/array): Point coordinate data
438
+ - `s` (float or list/array): A single float value for all points, or an array for per-point sizes
439
+ - `c` (str or list[str]): A single color string, or an array of color strings
440
+ - `marker` (str): Marker shape. Supports `'o'`, `'s'`, `'^'`, `'v'`, `'D'`, `'*'`, `'+'`, `'x'`, `'<'`, `'>'`
441
+ - `label` (str): Legend label
442
+ - `alpha` (float): Transparency (0.0-1.0)
443
+ - `**kwargs`: Extra parameters. Supports `color` (as alias for `c`)
444
+
445
+ **Example:**
446
+
447
+ ```python
448
+ # Single-color scatter
449
+ ax.scatter(x, y, c='red', s=50)
450
+
451
+ # Per-point independent colors
452
+ ax.scatter(x, y, c=['red', 'green', 'blue', ...], s=50)
453
+
454
+ # Per-point independent sizes
455
+ ax.scatter(x, y, s=[10, 20, 30, ...], c='blue')
456
+
457
+ # Simultaneously independent colors + sizes (Rust-level batch processing)
458
+ ax.scatter(x, y, c=colors, s=sizes, marker='D', alpha=0.8)
459
+ ```
460
+
461
+ ### Axes.axhspan / axvspan
462
+
463
+ Span highlighting fill.
464
+
465
+ ```python
466
+ ax.axhspan(ymin, ymax, color=None, alpha=0.3)
467
+ ax.axvspan(xmin, xmax, color=None, alpha=0.3)
468
+ ```
469
+
470
+ **Parameters:**
471
+
472
+ - `ymin`, `ymax` (float): Y-axis bounds for horizontal span (data coordinates)
473
+ - `xmin`, `xmax` (float): X-axis bounds for vertical span (data coordinates)
474
+ - `color` (str): Fill color, defaults to light gray-blue
475
+ - `alpha` (float): Transparency, default 0.3
476
+
477
+ ### Axes.axline
478
+
479
+ Draw an arbitrary-slope reference line through two points, across the full chart.
480
+
481
+ ```python
482
+ ax.axline(xy1, xy2, color=None, linestyle=None, linewidth=None)
483
+ ```
484
+
485
+ **Parameters:**
486
+
487
+ - `xy1` (tuple): Starting coordinates `(x1, y1)`
488
+ - `xy2` (tuple): Ending coordinates `(x2, y2)`
489
+ - `color` (str): Line color
490
+ - `linestyle` (str): Line style. `'-'` (solid), `'--'` (dashed), `':'` (dotted), `'-.'` (dash-dot)
491
+ - `linewidth` (float): Line width
492
+
493
+ ### Axes.annotate
494
+
495
+ Add arrowed text annotations.
496
+
497
+ ```python
498
+ ax.annotate(text, xy, xytext=None, fontsize=12.0, color='black',
499
+ arrowprops=None, arrowstyle=None, arrowsize=1.0)
500
+ ```
501
+
502
+ **Parameters:**
503
+
504
+ - `text` (str): Annotation text
505
+ - `xy` (tuple): Coordinates of the point being annotated `(x, y)`
506
+ - `xytext` (tuple, optional): Position to place the text. If provided, an arrow is automatically drawn from this position to `xy`
507
+ - `fontsize` (float): Font size, default 12.0
508
+ - `color` (str): Text and arrow color, default `'black'`
509
+ - `arrowprops` (dict, optional): Arrow properties dictionary. Supports:
510
+ - `arrowstyle`: Arrow style (e.g., `'->'`, `'-|>'`)
511
+ - `arrowsize`: Arrow relative size
512
+ - `arrowstyle` (str, optional): Arrow style independent of `arrowprops`
513
+ - `arrowsize` (float, optional): Arrow size independent of `arrowprops`
514
+
515
+ ### hlines / vlines (Rust-level batch implementation)
516
+
517
+ Draw multiple horizontal or vertical lines. All internal looping is done at the Rust level, avoiding Python loop overhead.
518
+
519
+ ```python
520
+ ax.hlines(y, color=None, linestyle=None, linewidth=None)
521
+ ax.vlines(x, color=None, linestyle=None, linewidth=None)
522
+ ```
523
+
524
+ **Parameters:**
525
+
526
+ - `y` / `x` (list/array): Position list
527
+
528
+ ---
529
+
530
+ ## Performance Advantages
531
+
532
+ rsplotlib achieves performance optimization through a layered-down architecture strategy.
533
+
534
+ ### Architecture Layers
535
+
536
+ ```
537
+ +----------------------------------------------------+
538
+ | Python Layer (API Compatibility Layer) |
539
+ | * pyplot.py (Matplotlib-compatible API) |
540
+ | * api.py (Parameter normalization / |
541
+ | alias mapping) |
542
+ | * _patch_* (Method patching / dynamic |
543
+ | dispatch) |
544
+ +----------------------------------------------------+
545
+ | Rust Layer (High-Performance Core) |
546
+ | * lib.rs (Module registration / font |
547
+ | system) |
548
+ | * figure.rs (Figure objects / render |
549
+ | scheduling) |
550
+ | * axes.rs (Axes objects / data parsing) |
551
+ | * elements.rs (Plot element data structures) |
552
+ | * axes_render_elements.rs (plotters render) |
553
+ | * pyfuncs.rs (Module-level function |
554
+ | exposure) |
555
+ +----------------------------------------------------+
556
+ ```
557
+
558
+ ### Performance-Critical Paths Offloaded to Rust
559
+
560
+ | Feature | Traditional Implementation | rsplotlib Implementation |
561
+ | --------------------------- | ---------------------------------------------- | ------------------------------------- |
562
+ | `scatter(c=colors)` | Python iterates over every point | Rust `ScatterMulti` unified rendering |
563
+ | `scatter(s=sizes)` | Python iterates over every point | Rust unified size array processing |
564
+ | `hlines([y1, y2, y3, ...])` | Python `for` loop calling `axhline` repeatedly | Single Rust call, batch processing |
565
+ | `vlines([x1, x2, x3, ...])` | Python `for` loop calling `axvline` repeatedly | Single Rust call, batch processing |
566
+ | `savefig(dpi=300)` | No DPI support / Python scaling | Rust writes PNG DPI metadata directly |
567
+
568
+ ### Why a Rust + Python Hybrid Architecture?
569
+
570
+ 1. **Development Speed**: Rapid iteration on API design and parameter validation at the Python layer
571
+ 2. **Execution Performance**: Rust handles rendering, looping, and memory-intensive computations
572
+ 3. **Memory Safety**: Rust guarantees no data races at compile time
573
+ 4. **Zero Extra Dependencies**: No native Matplotlib installation required
574
+
575
+ ---
576
+
577
+ ## Project Structure
578
+
579
+ ```
580
+ rsplotlib/
581
+ +-- python/ # Python wrapper layer
582
+ | +-- rsplotlib/
583
+ | +-- __init__.py # Package entry & exports
584
+ | +-- api.py # Module-level API function definitions
585
+ | +-- pyplot.py # Matplotlib-compatible pyplot interface
586
+ | | # (with docstrings for IDE hover)
587
+ | +-- pylab.py # pylab-style interface, provides mpl.rcParams
588
+ | +-- style.py # plt.style style management
589
+ | +-- _rcparams.py # rcParams configuration management
590
+ | +-- _font_resolver.py # System font path resolution
591
+ | +-- _figure_defaults.py # Figure default configuration
592
+ | +-- gridspec.py # Grid layout management
593
+ | +-- ticker.py # Tick locator (AutoLocator, MaxNLocator)
594
+ |
595
+ +-- src/ # Rust core implementation
596
+ | +-- lib.rs # Library entry point, Python module registration
597
+ | +-- figure.rs # Figure class (savefig, DPI management)
598
+ | +-- axes.rs # Axes class (all plotting methods)
599
+ | +-- axes_render_elements.rs # Element rendering engine (plotters-based)
600
+ | +-- axes_bounds.rs # Coordinate boundary calculations
601
+ | +-- axes_title.rs # Title rendering
602
+ | +-- axes_legend.rs # Legend rendering
603
+ | +-- axes_grid.rs # Grid line rendering
604
+ | +-- axes_mesh.rs # Axis tick marks
605
+ | +-- axis.rs # Axis data structure
606
+ | +-- elements.rs # Plot element enum (Line, Scatter, Bar, ...)
607
+ | +-- pyfuncs.rs # Module-level functions exposed to Python
608
+ | +-- colors.rs # Color parsing (named, RGB, HSL)
609
+ | +-- colormap.rs # Color mapping
610
+ | +-- marker.rs # Marker shape rendering
611
+ | +-- text_utils.rs # Text utility functions
612
+ |
613
+ +-- Cargo.toml # Rust dependencies (PyO3, plotters, png)
614
+ +-- pyproject.toml # Python package configuration (maturin)
615
+ +-- build_wheel.sh # Wheel package build script
616
+ +-- README.md # English documentation (this file)
617
+ +-- README_zh.md # Chinese documentation
618
+ ```
619
+
620
+ ---
621
+
622
+ ## Development & Contributing
623
+
624
+ ### Local Development Environment
625
+
626
+ ```bash
627
+ # 1. Install Rust
628
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
629
+
630
+ # 2. Install maturin
631
+ pip install maturin
632
+
633
+ # 3. Development-mode build (compiles Rust, installs to current Python env)
634
+ maturin develop --release
635
+
636
+ # 4. Run interactive tests
637
+ python3 -c "
638
+ from rsplotlib import pyplot as plt
639
+ fig, ax = plt.subplots()
640
+ ax.plot([1,2,3], [1,4,9])
641
+ fig.savefig('/tmp/test.png')
642
+ print('OK')
643
+ "
644
+ ```
645
+
646
+ ### Development Workflow
647
+
648
+ 1. **Understand Requirements**: Analyze which Matplotlib functionality needs implementation
649
+ 2. **Implement at Rust Layer**: Add core logic in `src/`
650
+ - Add new plot elements: Modify `elements.rs`
651
+ - Add plotting methods: Modify `axes.rs`
652
+ - Add rendering logic: Modify `axes_render_elements.rs`
653
+ - Expose module-level functions: Modify `pyfuncs.rs`
654
+ - Register: Modify `lib.rs`
655
+ 3. **Wrap at Python Layer**: Add API in `python/rsplotlib/`
656
+ - Add docstrings (for IDE hover display)
657
+ - Handle parameter aliases (e.g., `lw` -> `linewidth`)
658
+ - Route array parameters to Rust batch methods
659
+ 4. **Compile & Test**: `maturin develop --release`
660
+ 5. **Verify Results**: Generate images for visual inspection
661
+
662
+ ### Adding Documentation to the Python Layer (for IDE Hover)
663
+
664
+ Functions in the Python wrapper include detailed docstrings so that when users hover over them in IDEs (VS Code, PyCharm, etc.), they automatically see descriptions and parameter lists.
665
+
666
+ ```python
667
+ def axhspan(ymin, ymax, **kwargs):
668
+ """Draw a horizontal span (colored region).
669
+
670
+ Usage:
671
+ plt.axhspan(0, 1, color='yellow', alpha=0.3)
672
+
673
+ Args:
674
+ ymin: Lower y-axis bound
675
+ ymax: Upper y-axis bound
676
+ color: Fill color (defaults to blue-gray)
677
+ alpha: Transparency (0.0-1.0, default 0.3)
678
+ """
679
+ ...
680
+ ```
681
+
682
+ ### Contributing Guidelines
683
+
684
+ PRs are welcome! Please include:
685
+
686
+ - A clear description of the feature or bug fix
687
+ - Generated example images, when applicable
688
+ - Make sure to update both `README.md` and `README_zh.md`
689
+
690
+ ### Known Limitations
691
+
692
+ - 3D plotting is not supported in the current version
693
+ - Animated/interactive charts are not supported
694
+ - `contour` / `violinplot` / `hexbin` are placeholder implementations
695
+
696
+ ---
697
+
698
+ ## Font Configuration
699
+
700
+ rsplotlib supports custom fonts via `mpl.rcParams`, as well as direct font file registration.
701
+
702
+ ### Auto-Detected System Fonts
703
+
704
+ | Platform | Common Fonts |
705
+ | ----------- | -------------------------------------------------------------------------- |
706
+ | **macOS** | Arial, Helvetica, PingFang SC, STHeiti, Hiragino Sans GB, Arial Unicode MS |
707
+ | **Linux** | DejaVu Sans, Liberation Sans, Noto Sans CJK SC, WenQuanYi Micro Hei |
708
+ | **Windows** | Microsoft YaHei, SimHei, SimSun, Arial |
709
+
710
+ ### Custom Font Configuration
711
+
712
+ ```python
713
+ from rsplotlib.pylab import mpl
714
+ from rsplotlib import pyplot as plt
715
+
716
+ # Set sans-serif font family (priority order)
717
+ mpl.rcParams['font.sans-serif'] = ['PingFang SC', 'Microsoft YaHei', 'DejaVu Sans']
718
+
719
+ # Set default font size
720
+ mpl.rcParams['font.size'] = 12
721
+ ```
722
+
723
+ ### Direct Font File Registration
724
+
725
+ ```python
726
+ from rsplotlib import rsplotlib as _rs
727
+
728
+ # Register any .ttf/.otf/.ttc file as sans-serif
729
+ _rs.register_sans_serif_font('/path/to/your/custom-font.ttf')
730
+ ```
731
+
732
+ ---
733
+
734
+ ## License
735
+
736
+ MIT License - See the [LICENSE](LICENSE) file for details.
737
+
738
+ ---
739
+
740
+ ## Acknowledgments
741
+
742
+ - [**PyO3**](https://github.com/PyO3/pyo3) - Rust <-> Python bindings library, version 0.29
743
+ - [**plotters**](https://github.com/plotters-rs/plotters) - Rust plotting library, provides underlying rendering capability
744
+ - [**Matplotlib**](https://matplotlib.org/) - Python plotting ecosystem standard, provides API design reference
745
+ - [**maturin**](https://github.com/PyO3/maturin) - Rust Python package build and publication tool
746
+
747
+ ---
748
+
749
+ ## Related Links
750
+
751
+ - **GitHub**: https://github.com/YJ-Niu/rsplotlib
752
+
753
+ ---
754
+
755
+ _Last updated: 2026-06-17 / Version v0.1.6_
@@ -742,9 +742,7 @@ MIT License — 详见 [LICENSE](LICENSE) 文件。
742
742
  ## 相关链接
743
743
 
744
744
  - **GitHub**: https://github.com/YJ-Niu/rsplotlib
745
- - **PyPI**: (待发布)
746
- - **文档**: (待完善)
747
745
 
748
746
  ---
749
747
 
750
- _最后更新:2026-06-17 · 版本 v0.1.5_
748
+ _最后更新:2026-06-17 · 版本 v0.1.6_
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "rsplotlib"
7
- version = "0.1.5.post1"
7
+ version = "0.1.6"
8
8
  description = "A high-performance matplotlib-compatible plotting library powered by Rust"
9
9
  readme = "README_zh.md"
10
10
  license = { text = "MIT" }
@@ -1,6 +0,0 @@
1
- # rsplotlib
2
-
3
- > A high-performance Python plotting library powered by Rust, with a Matplotlib-compatible API
4
-
5
- [![Python](https://img.shields.io/badge/Python-3.8%2B-blue)](https://www.python.org/)
6
- [![Rust](https://img.shields.io/badge/Rust-2021-orange)](https://www.rust-lang.org/)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes