Commit 805057a
FIX: Toolbar savefig respects rcparams (#615)
* Feature: Respect savefig rcParams in Download button
Fixes #138, #234, #339
The Download button now respects ALL matplotlib savefig.* rcParams
instead of always saving as PNG with hardcoded settings.
Implementation:
- Override Toolbar.save_figure() to call canvas._send_save_buffer()
- Add Canvas._send_save_buffer() that calls figure.savefig() without
hardcoded parameters (respects all rcParams)
- Send buffer + format metadata to frontend via ipywidgets comm
- Update frontend handle_save() to accept buffers from backend
- Support multiple formats with correct MIME types:
PNG, PDF, SVG, EPS, JPEG, TIFF, PS, TIF
- Set correct file extensions based on format
- Maintain backward compatibility with canvas.toDataURL() fallback
Respects these rcParams:
- savefig.format (png, pdf, svg, jpg, eps, etc.)
- savefig.dpi (resolution)
- savefig.transparent (transparent backgrounds)
- savefig.facecolor (custom background colors)
- All other savefig.* parameters
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Test: Add comprehensive tests for rcParams support
Manual test notebook (tests/manual_test_rcparams_save.ipynb):
- Tests all savefig.* rcParams (format, transparent, facecolor, dpi)
- Tests multiple formats: PNG, PDF, SVG, JPEG
- Includes verification checklist
- Documents expected behavior for each test case
Python unit tests (tests/test_download.py):
- Test _send_save_buffer respects savefig.format (PNG, PDF, SVG)
- Test download() method calls _send_save_buffer
- Test Toolbar.save_figure() calls _send_save_buffer
- Test respects savefig.dpi and savefig.transparent rcParams
- Test warns on unsupported format (e.g., webp)
- Add 'tests' to pytest testpaths in pyproject.toml
Addresses issues #138, #234, #339
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Feature: Add fig.canvas.download() for programmatic downloads
- Add public download() method to Canvas class
- Allows triggering downloads from Python code without clicking button
- Respects all savefig rcParams like the toolbar button
- Includes comprehensive docstring with examples
- Add test file demonstrating programmatic usage
Use cases:
- Batch downloading multiple figures
- Automated workflows
- Custom save logic in notebooks
Example:
fig, ax = plt.subplots()
ax.plot([1, 2, 3])
fig.canvas.download() # Triggers browser download
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Fix: Check format before savefig for matplotlib 3.5 compatibility
matplotlib 3.5 may reject invalid formats before we can check them,
so we need to validate the format from rcParams BEFORE calling savefig()
to ensure our warning is properly emitted.
Fixes test_send_save_buffer_warns_on_unsupported_format on matplotlib 3.5.
* Support all matplotlib formats in Download button
Remove artificial format restrictions - if matplotlib can generate it,
we support downloading it. Use known MIME types where available, or
fall back to application/octet-stream for unknown formats. The filename
extension ensures proper OS handling regardless.
This enables formats like PGF (LaTeX graphics), SVG compressed (svgz),
and raw RGBA formats to download correctly.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Refactor: Use pytest parametrize for format tests
Use pytest.mark.parametrize to reduce code duplication in format tests.
Remove PGF test as LaTeX backend is not available in CI environment.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* remove junk file
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>1 parent 5a81b50 commit 805057a
File tree
5 files changed
+514
-3
lines changed- ipympl
- src
- tests
5 files changed
+514
-3
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
128 | 128 | | |
129 | 129 | | |
130 | 130 | | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
131 | 135 | | |
132 | 136 | | |
133 | 137 | | |
| |||
327 | 331 | | |
328 | 332 | | |
329 | 333 | | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
330 | 380 | | |
331 | 381 | | |
332 | 382 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
120 | 120 | | |
121 | 121 | | |
122 | 122 | | |
| 123 | + | |
123 | 124 | | |
124 | 125 | | |
125 | 126 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
148 | 148 | | |
149 | 149 | | |
150 | 150 | | |
151 | | - | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
152 | 200 | | |
153 | | - | |
154 | | - | |
| 201 | + | |
| 202 | + | |
155 | 203 | | |
156 | 204 | | |
157 | 205 | | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
158 | 212 | | |
159 | 213 | | |
160 | 214 | | |
| |||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
0 commit comments