Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit 06c9a6b

Browse files
authored
Merge pull request #29 from rubin-dp0/tickets/PREOPS-583
tickets/PREOPS-583
2 parents 64711c2 + 603a34c commit 06c9a6b

1 file changed

Lines changed: 61 additions & 35 deletions

File tree

03_Image_Display_and_Manipulation.ipynb

Lines changed: 61 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
"%matplotlib inline\n",
7373
"import matplotlib.pyplot as plt # imports matplotlib.pyplot as plt\n",
7474
"import warnings # imports the warnings library\n",
75-
"\n",
75+
"import gc # imports python's garbage collector\n",
7676
"from astropy.wcs import WCS # imports astropy's World Coordinate System function WCS"
7777
]
7878
},
@@ -95,6 +95,30 @@
9595
"warnings.simplefilter(\"ignore\", category=UserWarning)"
9696
]
9797
},
98+
{
99+
"cell_type": "markdown",
100+
"metadata": {},
101+
"source": [
102+
"Matplotlib stores the data array associated with an image that is plotted. Since the LSST images are large (~4k x 4k pixels), this can eventually lead to a memory overflow, which will cause the notebook kernel to die. To mitigate this issue, we define a function to clean up after we plot them."
103+
]
104+
},
105+
{
106+
"cell_type": "code",
107+
"execution_count": null,
108+
"metadata": {},
109+
"outputs": [],
110+
"source": [
111+
"def remove_figure(fig):\n",
112+
" \"\"\"Remove a figure to reduce memory footprint. \"\"\"\n",
113+
" # get the axes and clear their images\n",
114+
" for ax in fig.get_axes():\n",
115+
" for im in ax.get_images():\n",
116+
" im.remove()\n",
117+
" fig.clf() # clear the figure\n",
118+
" plt.close(fig) # close the figure\n",
119+
" gc.collect() # call the garbage collector"
120+
]
121+
},
98122
{
99123
"cell_type": "markdown",
100124
"metadata": {},
@@ -178,10 +202,6 @@
178202
"metadata": {},
179203
"outputs": [],
180204
"source": [
181-
"# Note that the keys are slightly different for DC2/LSSTCam\n",
182-
"# You can view all the keys by creating the butler and calling:\n",
183-
"# print(butler.getKeys('calexp'))\n",
184-
"\n",
185205
"dataId = {'visit': 192350, 'detector': 175, 'band': 'i'}\n",
186206
"# Note: because the combination of visit+detector already uniquely identifies\n",
187207
"# the exposure, specifying \"band\" above is unnecessary.\n",
@@ -234,15 +254,17 @@
234254
"outputs": [],
235255
"source": [
236256
"# create a matplotlib.pyplot figure\n",
237-
"plt.figure()\n",
257+
"fig, ax = plt.subplots()\n",
238258
"# get an alias to the lsst.afw.display.Display() method\n",
239-
"display = afwDisplay.Display()\n",
259+
"display = afwDisplay.Display(frame=fig)\n",
240260
"# set the image stretch algorithm and range\n",
241261
"display.scale('asinh', 'zscale')\n",
242262
"# load the image into the display\n",
243263
"display.mtv(calexp.image)\n",
244264
"# show the corresponding pyplot figure\n",
245-
"plt.show()"
265+
"plt.show()\n",
266+
"# clean up memory\n",
267+
"remove_figure(fig)"
246268
]
247269
},
248270
{
@@ -260,17 +282,20 @@
260282
"metadata": {},
261283
"outputs": [],
262284
"source": [
263-
"plt.figure()\n",
285+
"fig = plt.figure()\n",
264286
"# Set the figure's projection to be the WCS of the calexp\n",
265287
"plt.subplot(projection=WCS(calexp.getWcs().getFitsMetadata()))\n",
266288
"# Display the calexp image data array using the gray colormap (cmap)\n",
267289
"# and use approximately the same min and max scale values as above\n",
268-
"plt.imshow(calexp.image.array, cmap='gray', vmin=-200.0, vmax=400, origin='lower')\n",
290+
"im = plt.imshow(calexp.image.array, cmap='gray', vmin=-200.0, vmax=400, origin='lower')\n",
269291
"# Add solid white grid lines\n",
270292
"plt.grid(color='white', ls='solid')\n",
271293
"# Label axes\n",
272294
"plt.xlabel('Right Ascension')\n",
273-
"plt.ylabel('Declination')"
295+
"plt.ylabel('Declination')\n",
296+
"plt.show()\n",
297+
"# Clean up memory\n",
298+
"remove_figure(fig)"
274299
]
275300
},
276301
{
@@ -287,18 +312,16 @@
287312
"outputs": [],
288313
"source": [
289314
"fig, ax = plt.subplots(1, 2, figsize=(14, 7))\n",
290-
"\n",
291315
"plt.sca(ax[0]) # set the first axis as current\n",
292316
"display1 = afwDisplay.Display(frame=fig)\n",
293317
"display1.scale('linear', 'zscale')\n",
294318
"display1.mtv(calexp.image)\n",
295-
"\n",
296319
"plt.sca(ax[1]) # set the second axis as current\n",
297320
"display2 = afwDisplay.Display(frame=fig)\n",
298321
"display2.mtv(calexp.mask)\n",
299-
"\n",
300322
"plt.tight_layout()\n",
301-
"plt.show()"
323+
"plt.show()\n",
324+
"remove_figure(fig)"
302325
]
303326
},
304327
{
@@ -314,11 +337,12 @@
314337
"metadata": {},
315338
"outputs": [],
316339
"source": [
317-
"fig = plt.figure()\n",
318-
"display = afwDisplay.Display()\n",
340+
"fig, ax = plt.subplots()\n",
341+
"display = afwDisplay.Display(frame=fig)\n",
319342
"display.scale('linear', 'zscale')\n",
320343
"display.mtv(calexp.maskedImage)\n",
321-
"plt.show()"
344+
"plt.show()\n",
345+
"remove_figure(fig)"
322346
]
323347
},
324348
{
@@ -355,9 +379,9 @@
355379
"outputs": [],
356380
"source": [
357381
"# create a matplotlib.pyplot figure\n",
358-
"plt.figure()\n",
382+
"fig, ax = plt.subplots()\n",
359383
"# get an alias to the lsst.afw.display.Display() method\n",
360-
"afw_display = afwDisplay.Display()\n",
384+
"afw_display = afwDisplay.Display(frame=fig)\n",
361385
"# set the image stretch algorithm and range\n",
362386
"afw_display.scale('asinh', 'zscale')\n",
363387
"# set the transparency of the mask plane (1 = opaque)\n",
@@ -367,7 +391,9 @@
367391
"# load the image and mask plane into the display\n",
368392
"afw_display.mtv(calexp)\n",
369393
"# show the corresponding pyplot figure\n",
370-
"plt.show()"
394+
"plt.show()\n",
395+
"# clean up memory\n",
396+
"remove_figure(fig)"
371397
]
372398
},
373399
{
@@ -544,14 +570,16 @@
544570
"outputs": [],
545571
"source": [
546572
"# create a matplotlib.pyplot figure\n",
547-
"plt.figure()\n",
573+
"fig, ax = plt.subplots()\n",
548574
"# get an alias to the lsst.afw.display.Display() method\n",
549-
"display = afwDisplay.Display()\n",
575+
"display = afwDisplay.Display(frame=fig)\n",
550576
"# set the image stretch algorithm and range\n",
551577
"display.scale('asinh', 'zscale')\n",
552578
"# load the image into the display\n",
553579
"display.mtv(coadd_calexp.image)\n",
554-
"plt.show()"
580+
"plt.show()\n",
581+
"# clean up memory\n",
582+
"remove_figure(fig)"
555583
]
556584
},
557585
{
@@ -616,11 +644,13 @@
616644
"metadata": {},
617645
"outputs": [],
618646
"source": [
619-
"fig = plt.figure()\n",
620-
"afw_display = afwDisplay.Display(1)\n",
647+
"fig, ax = plt.subplots()\n",
648+
"afw_display = afwDisplay.Display(frame=fig)\n",
621649
"afw_display.scale('asinh', 'zscale')\n",
622650
"afw_display.mtv(cutout_image.image)\n",
623-
"plt.gca().axis('off')"
651+
"ax.axis('off')\n",
652+
"plt.show()\n",
653+
"remove_figure(fig)"
624654
]
625655
},
626656
{
@@ -766,7 +796,10 @@
766796
"\n",
767797
"ax[0].set_axis_off()\n",
768798
"ax[1].set_axis_off()\n",
769-
"plt.show()"
799+
"plt.show()\n",
800+
"\n",
801+
"# clean up memory\n",
802+
"remove_figure(fig)"
770803
]
771804
},
772805
{
@@ -789,13 +822,6 @@
789822
"* [afw.display GitHub website](https://github.com/RobertLuptonTheGood/afw/tree/master/python/lsst/afw/display) \n",
790823
"* [Getting Started on Image Display (pipelines.lsst.io)](https://pipelines.lsst.io/getting-started/display.html)"
791824
]
792-
},
793-
{
794-
"cell_type": "code",
795-
"execution_count": null,
796-
"metadata": {},
797-
"outputs": [],
798-
"source": []
799825
}
800826
],
801827
"metadata": {

0 commit comments

Comments
 (0)