Plotting a difference image

How to compute and plot a difference image. The example uses sunpy.map.MapSequence to compute a difference image and then plot it. This basic method works for base difference or running difference. Just change whether you’re subtracting the previous image or the first image in a sequence.

import matplotlib.colors as colors
import matplotlib.pyplot as plt

import astropy.units as u

import sunpy.map
from sunpy.net import Fido
from sunpy.net import attrs as a

First we’ll download a couple images and store them in a sunpy.map.MapSequence. This could be from any channel of any imager. Here, we use SDO/AIA 304 Å.

instrument = a.Instrument.aia
wave = a.Wavelength(30 * u.nm, 31 * u.nm)
result = Fido.search(a.Time('2015-06-18T00:00:00', '2015-06-18T00:00:10') |
                     a.Time('2015-06-18T01:03:30', '2015-06-18T01:03:35'),
                     instrument,
                     wave)
downloaded_files = Fido.fetch(result)
maps = sunpy.map.Map(downloaded_files, sequence=True)

Out:

/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/parfive/downloader.py:100: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self.http_queue = asyncio.Queue(loop=self.loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/asyncio/queues.py:48: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self._finished = locks.Event(loop=loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/parfive/downloader.py:101: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self.http_tokens = asyncio.Queue(maxsize=self.max_conn, loop=self.loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/asyncio/queues.py:48: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self._finished = locks.Event(loop=loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/parfive/downloader.py:102: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self.ftp_queue = asyncio.Queue(loop=self.loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/asyncio/queues.py:48: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self._finished = locks.Event(loop=loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/parfive/downloader.py:103: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self.ftp_tokens = asyncio.Queue(maxsize=self.max_conn, loop=self.loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/asyncio/queues.py:48: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self._finished = locks.Event(loop=loop)

Files Downloaded:   0%|          | 0/2 [00:00<?, ?file/s]/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/parfive/downloader.py:312: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  done, _ = await asyncio.wait(futures, loop=self.loop)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/aiohttp/connector.py:964: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  hosts = await asyncio.shield(self._resolve_host(
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/aiohttp/connector.py:964: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  hosts = await asyncio.shield(self._resolve_host(
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/aiohttp/locks.py:21: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self._event = asyncio.Event(loop=loop)


aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:   0%|          | 0.00/7.92M [00:00<?, ?B/s]/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/aiohttp/connector.py:964: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  hosts = await asyncio.shield(self._resolve_host(



aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:   0%|          | 0.00/7.95M [00:00<?, ?B/s]/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/aiohttp/connector.py:964: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  hosts = await asyncio.shield(self._resolve_host(



aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:   0%|          | 100/7.95M [00:12<276:41:50, 7.98B/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:   1%|          | 50.8k/7.95M [00:12<192:27:12, 11.4B/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:   2%|1         | 137k/7.95M [00:12<133:15:18, 16.3B/s] 

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:   0%|          | 100/7.92M [00:13<292:30:08, 7.52B/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:   3%|3         | 242k/7.95M [00:12<92:01:07, 23.3B/s] 

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:   1%|          | 49.7k/7.92M [00:13<203:28:16, 10.7B/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:   5%|5         | 398k/7.95M [00:13<63:06:55, 33.2B/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:   7%|7         | 560k/7.95M [00:13<43:13:47, 47.5B/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:   2%|1         | 124k/7.92M [00:13<141:05:13, 15.3B/s] 


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:   9%|9         | 742k/7.95M [00:13<29:30:58, 67.8B/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:   3%|3         | 258k/7.92M [00:13<97:03:40, 21.9B/s] 


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  13%|#2        | 1.03M/7.95M [00:13<19:50:55, 96.9B/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:   6%|5         | 461k/7.92M [00:13<66:08:42, 31.3B/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  16%|#6        | 1.31M/7.95M [00:13<13:19:42, 138B/s] 

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:   9%|9         | 741k/7.92M [00:13<44:33:52, 44.7B/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  20%|##        | 1.61M/7.95M [00:13<8:54:02, 198B/s] 

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:  13%|#2        | 1.01M/7.92M [00:14<30:00:48, 63.9B/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  25%|##4       | 1.98M/7.95M [00:13<5:51:56, 282B/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:  17%|#6        | 1.32M/7.92M [00:14<20:04:55, 91.3B/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  30%|###       | 2.41M/7.95M [00:13<3:48:47, 404B/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:  21%|##1       | 1.70M/7.92M [00:14<13:14:55, 130B/s] 


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  37%|###6      | 2.90M/7.95M [00:13<2:25:54, 576B/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:  26%|##5       | 2.04M/7.92M [00:14<8:45:48, 186B/s] 


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  43%|####3     | 3.44M/7.95M [00:13<1:31:18, 823B/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:  31%|###1      | 2.47M/7.92M [00:14<5:41:04, 266B/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  50%|#####     | 3.98M/7.95M [00:14<56:12, 1.18kB/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:  37%|###6      | 2.90M/7.92M [00:14<3:39:55, 380B/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  56%|#####5    | 4.44M/7.95M [00:14<34:45, 1.68kB/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:  43%|####2     | 3.38M/7.92M [00:14<2:19:21, 543B/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  63%|######2   | 4.98M/7.95M [00:14<20:35, 2.40kB/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:  49%|####8     | 3.87M/7.92M [00:14<1:26:56, 776B/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  69%|######8   | 5.47M/7.95M [00:14<12:03, 3.43kB/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:  56%|#####5    | 4.42M/7.92M [00:14<52:38, 1.11kB/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  75%|#######4  | 5.94M/7.95M [00:14<06:50, 4.89kB/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:  63%|######2   | 4.97M/7.92M [00:14<31:03, 1.58kB/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  80%|########  | 6.39M/7.95M [00:14<03:42, 6.99kB/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:  71%|#######1  | 5.66M/7.92M [00:15<16:39, 2.26kB/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:  82%|########1 | 6.46M/7.92M [00:15<07:30, 3.23kB/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  86%|########5 | 6.82M/7.95M [00:14<01:53, 9.97kB/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits:  91%|######### | 7.17M/7.92M [00:15<02:41, 4.62kB/s]

aia_lev1_304a_2015_06_18t00_00_07_12z_image_lev1.fits: 100%|#########9| 7.91M/7.92M [00:15<00:01, 6.59kB/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  90%|######### | 7.17M/7.95M [00:15<00:54, 14.2kB/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  94%|#########4| 7.48M/7.95M [00:15<00:23, 20.2kB/s]


aia_lev1_304a_2015_06_18t01_03_31_13z_image_lev1.fits:  98%|#########7| 7.77M/7.95M [00:15<00:06, 28.8kB/s]
Files Downloaded:  50%|#####     | 1/2 [00:25<00:25, 25.28s/file]
Files Downloaded: 100%|##########| 2/2 [00:25<00:00, 17.81s/file]
Files Downloaded: 100%|##########| 2/2 [00:25<00:00, 12.83s/file]
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/asyncio/base_events.py:654: ResourceWarning: unclosed event loop <_UnixSelectorEventLoop running=False closed=False debug=False>
  _warn(f"unclosed event loop {self!r}", ResourceWarning, source=self)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/asyncio/selector_events.py:694: ResourceWarning: unclosed transport <_SelectorSocketTransport fd=19>
  _warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/asyncio/selector_events.py:694: ResourceWarning: unclosed transport <_SelectorSocketTransport fd=21>
  _warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/asyncio/selector_events.py:694: ResourceWarning: unclosed transport <_SelectorSocketTransport fd=22>
  _warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/asyncio/selector_events.py:694: ResourceWarning: unclosed transport <_SelectorSocketTransport fd=20>
  _warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/asyncio/selector_events.py:694: ResourceWarning: unclosed transport <_SelectorSocketTransport fd=23>
  _warn(f"unclosed transport {self!r}", ResourceWarning, source=self)

Now we’ll do a standard plot of the second image just to see it.

plt.figure()
ax = plt.subplot(projection=maps[1])
maps[1].plot()
AIA $304 \; \mathrm{\mathring{A}}$ 2015-06-18 01:03:31

Out:

<matplotlib.image.AxesImage object at 0x7fa69b659fd0>

And now we can do take the actual difference.

diff = maps[1].data - maps[0].data

But we have to decide what to do with the metadata. For example, what time does this difference image correspond to? The time of the first or second image? The mean time? You’ll have to decide what makes most sense for your application. Here we’ll just use the metadata from the second image. Then we can store the difference and header back in a Map.

meta = maps[1].meta
diff_map = sunpy.map.Map(diff, meta)

Finally, we’ll plot it. We’ll apply a colormap and renormalize the intensity so that it shows up well.

plt.figure()
ax_diff = plt.subplot(projection=diff_map)
diff_map.plot(cmap='Greys_r',
              norm=colors.Normalize(vmin=-50, vmax=50))
plt.show()
AIA $304 \; \mathrm{\mathring{A}}$ 2015-06-18 01:03:31

Total running time of the script: ( 0 minutes 34.162 seconds)

Gallery generated by Sphinx-Gallery