Skip to content

Commit 647539b

Browse files
ianhiclaude
andcommitted
Test: Add comprehensive test notebook for rcParams support
- 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 - Addresses issues #138, #234, #339 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 7954aad commit 647539b

1 file changed

Lines changed: 304 additions & 0 deletions

File tree

test_rcparams_save.ipynb

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Test ipympl Download Button with rcParams\n",
8+
"\n",
9+
"This notebook tests that the Download button respects matplotlib's `savefig.*` rcParams.\n",
10+
"\n",
11+
"**Issues being tested:**\n",
12+
"- #138: Download button should respect `savefig.format`\n",
13+
"- #234: Download button should respect `savefig.transparent` and `savefig.facecolor`\n",
14+
"- #339: Enable PDF downloads for vector graphics\n",
15+
"\n",
16+
"**How to test:**\n",
17+
"1. Run each cell\n",
18+
"2. Click the Download button (floppy disk icon) in the toolbar\n",
19+
"3. Check the downloaded file has the correct format and properties"
20+
]
21+
},
22+
{
23+
"cell_type": "code",
24+
"execution_count": null,
25+
"metadata": {},
26+
"outputs": [],
27+
"source": [
28+
"%matplotlib ipympl\n",
29+
"import matplotlib.pyplot as plt\n",
30+
"import numpy as np"
31+
]
32+
},
33+
{
34+
"cell_type": "markdown",
35+
"metadata": {},
36+
"source": [
37+
"## Test 1: Default Behavior (PNG)\n",
38+
"\n",
39+
"Without setting any rcParams, the download should default to PNG format."
40+
]
41+
},
42+
{
43+
"cell_type": "code",
44+
"execution_count": null,
45+
"metadata": {},
46+
"outputs": [],
47+
"source": [
48+
"# Reset to defaults\n",
49+
"plt.rcdefaults()\n",
50+
"\n",
51+
"fig, ax = plt.subplots()\n",
52+
"ax.plot([1, 2, 3, 4], [1, 4, 2, 3], 'ro-')\n",
53+
"ax.set_title('Test 1: Default PNG')\n",
54+
"ax.set_xlabel('X axis')\n",
55+
"ax.set_ylabel('Y axis')\n",
56+
"plt.tight_layout()\n",
57+
"\n",
58+
"# Expected: Downloads as 'Figure 1.png'"
59+
]
60+
},
61+
{
62+
"cell_type": "markdown",
63+
"metadata": {},
64+
"source": [
65+
"## Test 2: PDF Format\n",
66+
"\n",
67+
"Setting `savefig.format = 'pdf'` should download as PDF (vector graphics)."
68+
]
69+
},
70+
{
71+
"cell_type": "code",
72+
"execution_count": null,
73+
"metadata": {},
74+
"outputs": [],
75+
"source": [
76+
"plt.rcParams['savefig.format'] = 'pdf'\n",
77+
"\n",
78+
"fig, ax = plt.subplots()\n",
79+
"x = np.linspace(0, 2*np.pi, 100)\n",
80+
"ax.plot(x, np.sin(x), label='sin(x)')\n",
81+
"ax.plot(x, np.cos(x), label='cos(x)')\n",
82+
"ax.set_title('Test 2: PDF Format')\n",
83+
"ax.legend()\n",
84+
"plt.tight_layout()\n",
85+
"\n",
86+
"# Expected: Downloads as 'Figure 2.pdf'\n",
87+
"# Can verify it's a real PDF by opening in a PDF viewer"
88+
]
89+
},
90+
{
91+
"cell_type": "markdown",
92+
"metadata": {},
93+
"source": [
94+
"## Test 3: SVG Format\n",
95+
"\n",
96+
"Setting `savefig.format = 'svg'` should download as SVG (vector graphics)."
97+
]
98+
},
99+
{
100+
"cell_type": "code",
101+
"execution_count": null,
102+
"metadata": {},
103+
"outputs": [],
104+
"source": [
105+
"plt.rcParams['savefig.format'] = 'svg'\n",
106+
"\n",
107+
"fig, ax = plt.subplots()\n",
108+
"categories = ['A', 'B', 'C', 'D']\n",
109+
"values = [23, 45, 56, 78]\n",
110+
"ax.bar(categories, values, color='steelblue')\n",
111+
"ax.set_title('Test 3: SVG Format')\n",
112+
"ax.set_ylabel('Values')\n",
113+
"plt.tight_layout()\n",
114+
"\n",
115+
"# Expected: Downloads as 'Figure 3.svg'\n",
116+
"# Can verify it's SVG by opening in text editor - should see XML"
117+
]
118+
},
119+
{
120+
"cell_type": "markdown",
121+
"metadata": {},
122+
"source": [
123+
"## Test 4: Transparent Background (PNG)\n",
124+
"\n",
125+
"Setting `savefig.transparent = True` should create PNG with transparent background."
126+
]
127+
},
128+
{
129+
"cell_type": "code",
130+
"execution_count": null,
131+
"metadata": {},
132+
"outputs": [],
133+
"source": [
134+
"plt.rcParams['savefig.format'] = 'png'\n",
135+
"plt.rcParams['savefig.transparent'] = True\n",
136+
"\n",
137+
"fig, ax = plt.subplots()\n",
138+
"fig.patch.set_facecolor('red') # Set red background in notebook\n",
139+
"ax.plot([1, 2, 3, 4], [2, 4, 1, 3], 'go-', linewidth=2)\n",
140+
"ax.set_title('Test 4: Transparent Background')\n",
141+
"plt.tight_layout()\n",
142+
"\n",
143+
"# Expected: Downloads as 'Figure 4.png'\n",
144+
"# Background should be TRANSPARENT, not red\n",
145+
"# Can verify by opening PNG in image viewer with transparency support"
146+
]
147+
},
148+
{
149+
"cell_type": "markdown",
150+
"metadata": {},
151+
"source": [
152+
"## Test 5: Custom Face Color\n",
153+
"\n",
154+
"Setting `savefig.facecolor` should use that background color."
155+
]
156+
},
157+
{
158+
"cell_type": "code",
159+
"execution_count": null,
160+
"metadata": {},
161+
"outputs": [],
162+
"source": [
163+
"plt.rcParams['savefig.format'] = 'png'\n",
164+
"plt.rcParams['savefig.transparent'] = False\n",
165+
"plt.rcParams['savefig.facecolor'] = '#111111' # Dark gray\n",
166+
"\n",
167+
"fig, ax = plt.subplots()\n",
168+
"ax.plot([1, 2, 3, 4], [1, 3, 2, 4], 'y-', linewidth=3)\n",
169+
"ax.set_title('Test 5: Dark Background', color='white')\n",
170+
"ax.tick_params(colors='white')\n",
171+
"ax.spines['bottom'].set_color('white')\n",
172+
"ax.spines['top'].set_color('white')\n",
173+
"ax.spines['left'].set_color('white')\n",
174+
"ax.spines['right'].set_color('white')\n",
175+
"plt.tight_layout()\n",
176+
"\n",
177+
"# Expected: Downloads as 'Figure 5.png'\n",
178+
"# Background should be dark gray (#111111)"
179+
]
180+
},
181+
{
182+
"cell_type": "markdown",
183+
"metadata": {},
184+
"source": [
185+
"## Test 6: High DPI PNG\n",
186+
"\n",
187+
"Setting `savefig.dpi` should affect resolution of raster formats."
188+
]
189+
},
190+
{
191+
"cell_type": "code",
192+
"execution_count": null,
193+
"metadata": {},
194+
"outputs": [],
195+
"source": [
196+
"plt.rcParams['savefig.format'] = 'png'\n",
197+
"plt.rcParams['savefig.transparent'] = False\n",
198+
"plt.rcParams['savefig.facecolor'] = 'white'\n",
199+
"plt.rcParams['savefig.dpi'] = 300 # High resolution\n",
200+
"\n",
201+
"fig, ax = plt.subplots(figsize=(6, 4))\n",
202+
"x = np.linspace(0, 10, 1000)\n",
203+
"ax.plot(x, np.sin(x) * np.exp(-x/10), 'b-')\n",
204+
"ax.set_title('Test 6: High DPI (300)')\n",
205+
"ax.grid(True, alpha=0.3)\n",
206+
"plt.tight_layout()\n",
207+
"\n",
208+
"# Expected: Downloads as 'Figure 6.png'\n",
209+
"# File should be larger than test 1 (higher resolution)\n",
210+
"# Dimensions should be ~1800x1200 pixels (6*300 x 4*300)"
211+
]
212+
},
213+
{
214+
"cell_type": "markdown",
215+
"metadata": {},
216+
"source": [
217+
"## Test 7: JPEG Format\n",
218+
"\n",
219+
"Setting `savefig.format = 'jpg'` should download as JPEG."
220+
]
221+
},
222+
{
223+
"cell_type": "code",
224+
"execution_count": null,
225+
"metadata": {},
226+
"outputs": [],
227+
"source": [
228+
"plt.rcParams['savefig.format'] = 'jpg'\n",
229+
"plt.rcParams['savefig.dpi'] = 'figure' # Reset to default\n",
230+
"\n",
231+
"fig, ax = plt.subplots()\n",
232+
"ax.scatter(np.random.randn(100), np.random.randn(100), \n",
233+
" c=np.random.randn(100), cmap='viridis', s=100, alpha=0.6)\n",
234+
"ax.set_title('Test 7: JPEG Format')\n",
235+
"plt.colorbar(ax.collections[0], ax=ax)\n",
236+
"plt.tight_layout()\n",
237+
"\n",
238+
"# Expected: Downloads as 'Figure 7.jpg'\n",
239+
"# JPEG format (lossy compression, no transparency support)"
240+
]
241+
},
242+
{
243+
"cell_type": "markdown",
244+
"metadata": {},
245+
"source": [
246+
"## Test 8: Verify Backward Compatibility\n",
247+
"\n",
248+
"If we somehow call the old code path, it should still work."
249+
]
250+
},
251+
{
252+
"cell_type": "code",
253+
"execution_count": null,
254+
"metadata": {},
255+
"outputs": [],
256+
"source": [
257+
"# Test that default matplotlib savefig still works\n",
258+
"fig, ax = plt.subplots()\n",
259+
"ax.plot([1, 2, 3], [1, 4, 2])\n",
260+
"ax.set_title('Test 8: Backward Compatibility')\n",
261+
"\n",
262+
"# Use regular savefig to compare\n",
263+
"fig.savefig('/tmp/test_savefig.png')\n",
264+
"print(\"Regular savefig to /tmp/test_savefig.png works\")\n",
265+
"\n",
266+
"# Now test the widget button\n",
267+
"# Expected: Downloads as 'Figure 8.jpg' (jpg still set from Test 7)"
268+
]
269+
},
270+
{
271+
"cell_type": "markdown",
272+
"metadata": {},
273+
"source": [
274+
"## Verification Checklist\n",
275+
"\n",
276+
"After running all tests and clicking Download on each figure, verify:\n",
277+
"\n",
278+
"- [ ] Test 1: File named `Figure 1.png`, PNG format\n",
279+
"- [ ] Test 2: File named `Figure 2.pdf`, can open in PDF viewer\n",
280+
"- [ ] Test 3: File named `Figure 3.svg`, can open as text/XML\n",
281+
"- [ ] Test 4: File named `Figure 4.png`, has transparent background\n",
282+
"- [ ] Test 5: File named `Figure 5.png`, has dark (#111111) background\n",
283+
"- [ ] Test 6: File named `Figure 6.png`, is high resolution (~1800x1200)\n",
284+
"- [ ] Test 7: File named `Figure 7.jpg`, JPEG format\n",
285+
"- [ ] Test 8: File named `Figure 8.jpg`, downloads successfully\n",
286+
"\n",
287+
"All tests passing indicates rcParams are properly respected! 🎉"
288+
]
289+
}
290+
],
291+
"metadata": {
292+
"kernelspec": {
293+
"display_name": "Python 3",
294+
"language": "python",
295+
"name": "python3"
296+
},
297+
"language_info": {
298+
"name": "python",
299+
"version": "3.14.2"
300+
}
301+
},
302+
"nbformat": 4,
303+
"nbformat_minor": 4
304+
}

0 commit comments

Comments
 (0)