Note
Go to the end to download the full example code.
Creating a visualization with ArrayAnimatorWCS#
This example shows how to create a simple visualization using
ArrayAnimatorWCS
.
import matplotlib.pyplot as plt
import astropy.units as u
import astropy.wcs
from astropy.visualization import AsinhStretch, ImageNormalize
import sunpy.map
from sunpy.data.sample import AIA_171_IMAGE, AIA_193_IMAGE
from sunpy.time import parse_time
from mpl_animators import ArrayAnimatorWCS
WARNING: SunpyUserWarning: Importing sunpy.map without its extra dependencies may result in errors.
The following packages are not installed:
['mpl-animators>=1.0.0', 'reproject>=0.10.0']
To install sunpy with these dependencies use `pip install sunpy[map]` or `pip install sunpy[all]` for all extras.
If you installed sunpy via conda, please report this to the community channel: https://matrix.to/#/#sunpy:openastronomy.org [sunpy.util.sysinfo]
WARNING: SunpyUserWarning: Importing sunpy.visualization without its extra dependencies may result in errors.
The following packages are not installed:
['mpl-animators>=1.0.0']
To install sunpy with these dependencies use `pip install sunpy[visualization]` or `pip install sunpy[all]` for all extras.
If you installed sunpy via conda, please report this to the community channel: https://matrix.to/#/#sunpy:openastronomy.org [sunpy.util.sysinfo]
Files Downloaded: 0%| | 0/1 [00:00<?, ?file/s]
AIA20110607_063302_0171_lowres.fits: 0%| | 0.00/973k [00:00<?, ?B/s]
AIA20110607_063302_0171_lowres.fits: 80%|████████ | 780k/973k [00:00<00:00, 2.31MB/s]
Future exception was never retrieved
future: <Future finished exception=ClientConnectionError('Connection lost: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application data after close notify (_ssl.c:2775)')>
Traceback (most recent call last):
File "/usr/lib/python3.13/asyncio/sslproto.py", line 651, in _do_shutdown
self._sslobj.unwrap()
~~~~~~~~~~~~~~~~~~~^^
File "/usr/lib/python3.13/ssl.py", line 955, in unwrap
return self._sslobj.shutdown()
~~~~~~~~~~~~~~~~~~~~~^^
ssl.SSLError: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application data after close notify (_ssl.c:2775)
The above exception was the direct cause of the following exception:
aiohttp.client_exceptions.ClientConnectionError: Connection lost: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application data after close notify (_ssl.c:2775)
Files Downloaded: 100%|██████████| 1/1 [00:00<00:00, 1.02file/s]
Files Downloaded: 100%|██████████| 1/1 [00:01<00:00, 1.00s/file]
Files Downloaded: 0%| | 0/1 [00:00<?, ?file/s]
AIA20110607_063307_0193_lowres.fits: 0%| | 0.00/1.00M [00:00<?, ?B/s]
Future exception was never retrieved
future: <Future finished exception=ClientConnectionError('Connection lost: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application data after close notify (_ssl.c:2775)')>
Traceback (most recent call last):
File "/usr/lib/python3.13/asyncio/sslproto.py", line 651, in _do_shutdown
self._sslobj.unwrap()
~~~~~~~~~~~~~~~~~~~^^
File "/usr/lib/python3.13/ssl.py", line 955, in unwrap
return self._sslobj.shutdown()
~~~~~~~~~~~~~~~~~~~~~^^
ssl.SSLError: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application data after close notify (_ssl.c:2775)
The above exception was the direct cause of the following exception:
aiohttp.client_exceptions.ClientConnectionError: Connection lost: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application data after close notify (_ssl.c:2775)
Files Downloaded: 100%|██████████| 1/1 [00:00<00:00, 1.33file/s]
Files Downloaded: 100%|██████████| 1/1 [00:00<00:00, 1.29file/s]
To showcase how to visualize a sequence of 2D images using
ArrayAnimatorWCS
, we will use images from
our sample data. The problem with this is that they are not part of
a continuous dataset. To overcome this we will do two things.
Create a stacked array of the images and create a WCS
header.
The easiest method for the array is to create a MapSequence
.
# Here we only use two files but you could pass in a larger selection of files.
map_sequence = sunpy.map.Map(AIA_171_IMAGE, AIA_193_IMAGE, sequence=True)
# Now we can just cast the sequence away into a NumPy array.
sequence_array = map_sequence.as_array()
# We'll also define a common normalization to use in the animations
norm = ImageNormalize(vmin=0, vmax=3e4, stretch=AsinhStretch(0.01))
/usr/lib/python3.13/site-packages/astropy/io/fits/hdu/image.py:631: VerifyWarning: Invalid 'BLANK' keyword in header. The 'BLANK' keyword is only applicable to integer data, and will be ignored in this HDU.
warnings.warn(msg, VerifyWarning)
/build/python-mpl-animators/src/mpl_animators-1.2.3/examples/arrayanimatorwcs.py:33: SunpyDeprecationWarning: The as_array function is deprecated and will be removed in sunpy 7.1. Use the data and mask properties instead.
sequence_array = map_sequence.as_array()
Now we need to create the WCS
header that
ArrayAnimatorWCS
will need.
To create the new header we can use the stored meta information from the
map_sequence
.
# Now we need to get the time difference between the two observations.
t0, t1 = map(parse_time, [k["date-obs"] for k in map_sequence.all_meta()])
time_diff = (t1 - t0).to(u.s)
m = map_sequence[0]
wcs = astropy.wcs.WCS(naxis=3)
wcs.wcs.crpix = u.Quantity([0 * u.pix, *list(m.reference_pixel)])
wcs.wcs.cdelt = [time_diff.value, *list(u.Quantity(m.scale).value)]
wcs.wcs.crval = [0, m._reference_longitude.value, m._reference_latitude.value]
wcs.wcs.ctype = ["TIME", *list(m.coordinate_system)]
wcs.wcs.cunit = ["s", *list(m.spatial_units)]
wcs.wcs.aux.rsun_ref = m.rsun_meters.to_value(u.m)
# Now the resulting WCS object will look like:
print(wcs)
/build/python-mpl-animators/src/mpl_animators-1.2.3/examples/arrayanimatorwcs.py:45: SunpyDeprecationWarning: The all_meta function is deprecated and will be removed in sunpy 7.1. Use the meta property instead.
t0, t1 = map(parse_time, [k["date-obs"] for k in map_sequence.all_meta()])
WCS Keywords
Number of WCS axes: 3
CTYPE : 'TIME' 'HPLN-TAN' 'HPLT-TAN'
CRVAL : 0.0 3.223099507700556 1.385781353025793
CRPIX : 0.0 511.5 511.5
PC1_1 PC1_2 PC1_3 : 1.0 0.0 0.0
PC2_1 PC2_2 PC2_3 : 0.0 1.0 0.0
PC3_1 PC3_2 PC3_3 : 0.0 0.0 1.0
CDELT : 5.0700000000020395 2.402792 2.402792
NAXIS : 0 0
Now we can create the animation.
ArrayAnimatorWCS
requires you to select which
axes you want to plot on the image. All other axes should have a 0
and
sliders will be created to control the value for this axis.
wcs_anim = ArrayAnimatorWCS(sequence_array, wcs, [0, "x", "y"], norm=norm).get_animation()
plt.show()
You might notice that the animation could do with having the axes look
neater. ArrayAnimatorWCS
provides a way of setting
some display properties of the WCSAxes
object on every frame of the animation via use of the coord_params
dict.
They keys of the coord_params
dict are either the first half of the
CTYPE
key, the whole CTYPE
key or the entries in
wcs.world_axis_physical_types
here we use the short ctype identifiers for
the latitude and longitude axes.
coord_params = {
"hpln": {"axislabel": "Helioprojective Longitude", "ticks": {"spacing": 10 * u.arcmin, "color": "black"}},
"hplt": {"axislabel": "Helioprojective Latitude", "ticks": {"spacing": 10 * u.arcmin, "color": "black"}},
}
# We have to recreate the visualization since we displayed it earlier.
wcs_anim = ArrayAnimatorWCS(sequence_array, wcs, [0, "x", "y"], norm=norm, coord_params=coord_params).get_animation()
plt.show()
Total running time of the script: (0 minutes 4.530 seconds)