Interacting with Data Using SunPy Maps¶

In this example you will be learning how to create and modify SunPy Map objects.

Start by importing the necessary modules.

from __future__ import print_function, division

import numpy as np
import astropy.units as u

import sunpy.map
import sunpy.data.sample

SunPy Maps store 2D data in a numpy array and additional data in a metadata dictionary giving information relating to the data and instrument. You can create a Map in a number of ways, including loading a FITS file or URL: mymap = sunpy.map.Map('file1.fits') mymap = sunpy.map.Map(url_str) Or using creating manually by using tuple with the data/header within:

data = np.random.rand(20,15)
header = {}
manual_map = sunpy.map.Map((data, header))

The data numpy array and metadata dictionary can easily be accessed:

print(manual_map.data)
print(manual_map.meta)
# In this case notice that the metadata has been populated by default with the
# naxis details that correspond to the array used for the data.

Out:

[[ 0.87987039  0.88428832  0.18133907  0.85559469  0.36600718  0.87454892
   0.73274409  0.5929866   0.42875518  0.30435023  0.96783684  0.18174132
   0.68067461  0.12932423  0.73874073]
 [ 0.80708754  0.67551072  0.26995843  0.46304623  0.80478898  0.4977363
   0.94417458  0.47402293  0.31358679  0.44275658  0.0914493   0.77033357
   0.84120588  0.97153386  0.51428648]
 [ 0.88138684  0.75364508  0.70246631  0.66026325  0.75255372  0.07243291
   0.60166659  0.35320182  0.1563402   0.32114716  0.83943689  0.59226108
   0.09021067  0.82682454  0.1542023 ]
 [ 0.55312417  0.88870305  0.79230821  0.03760994  0.45503018  0.4111762
   0.03779422  0.04182737  0.77987062  0.57576946  0.35165827  0.041496
   0.2524596   0.62022436  0.57519477]
 [ 0.52176624  0.28318118  0.4754051   0.88107134  0.05145509  0.66184034
   0.35870606  0.46674685  0.75474809  0.80413746  0.53090789  0.58791527
   0.30611458  0.16341617  0.46711915]
 [ 0.1435594   0.34305685  0.44948706  0.4141934   0.90702976  0.97397574
   0.71676797  0.925368    0.22204285  0.21269639  0.7598522   0.98975594
   0.97296928  0.62482447  0.7107081 ]
 [ 0.01127958  0.3708024   0.12906618  0.9239633   0.47850921  0.42681913
   0.06158989  0.41043715  0.61625619  0.01958393  0.37338753  0.25785656
   0.14849693  0.950376    0.63833317]
 [ 0.59515613  0.57950063  0.31118563  0.31906969  0.79190029  0.75438604
   0.62034526  0.65310332  0.43894242  0.27658458  0.47395717  0.13391133
   0.18025899  0.52390855  0.24653993]
 [ 0.06622627  0.57463038  0.48194394  0.13862779  0.37076541  0.32369601
   0.94413383  0.04304433  0.85696371  0.63113456  0.44018732  0.2223016
   0.27419419  0.29255488  0.17017664]
 [ 0.37059674  0.98394165  0.6786722   0.17150933  0.37891613  0.54337419
   0.99989423  0.63134795  0.85401258  0.64223087  0.95755259  0.04514029
   0.97083617  0.29938725  0.62057163]
 [ 0.43103587  0.93276658  0.35161436  0.10672888  0.90965289  0.37883743
   0.79627408  0.58734627  0.2912509   0.60499579  0.08096594  0.92744351
   0.54573215  0.41024351  0.0018923 ]
 [ 0.83967401  0.14065143  0.65914804  0.95566821  0.45366652  0.35360154
   0.23200155  0.97162609  0.88837794  0.46147473  0.56742242  0.97575279
   0.37801188  0.62555038  0.06352013]
 [ 0.23144142  0.29390281  0.41876471  0.97910303  0.34884746  0.30524939
   0.97790119  0.51133755  0.43669785  0.63639137  0.49013842  0.86613404
   0.08970083  0.67257294  0.29542379]
 [ 0.04019196  0.15953304  0.62648097  0.90156888  0.79482907  0.64842413
   0.27964301  0.80913304  0.27807797  0.84649316  0.34592261  0.26784197
   0.46790291  0.79395196  0.61703731]
 [ 0.06874631  0.05465628  0.46389213  0.76739392  0.86039751  0.61062175
   0.21072933  0.60554522  0.87977544  0.0440477   0.40136693  0.4921424
   0.27573964  0.65668406  0.44377476]
 [ 0.16727574  0.45536507  0.90541728  0.8977888   0.6277735   0.24991105
   0.89234006  0.65658679  0.94428288  0.77035275  0.66946677  0.86360182
   0.20970779  0.9154731   0.98822772]
 [ 0.59278358  0.3490507   0.58607587  0.68438766  0.89681184  0.47267771
   0.53947898  0.87914084  0.81746005  0.77851366  0.68369746  0.67164809
   0.59533956  0.15209213  0.495982  ]
 [ 0.63180384  0.57404319  0.0304359   0.66931214  0.32140534  0.58394334
   0.29354216  0.27104586  0.64070456  0.50440807  0.86619183  0.50469247
   0.84578658  0.41269343  0.72458537]
 [ 0.12610759  0.48705781  0.29029406  0.34786974  0.95810433  0.40401336
   0.40884923  0.82017804  0.73406893  0.36076349  0.03994598  0.98161074
   0.39171626  0.31508206  0.7212248 ]
 [ 0.00182715  0.62360651  0.07718317  0.20758937  0.97724645  0.68212084
   0.34076011  0.62194185  0.7430077   0.46476359  0.32841176  0.31083964
   0.01160321  0.03315488  0.68899257]]
MapMeta([('naxis1', 15), ('naxis2', 20), ('naxis', 2)])

You can quickly plot a map using the peek method:

manual_map.peek()
../../../_images/sphx_glr_plot_maps_example_001.png

SunPy Maps have a number of attributes that can be accessed easily, such as the x and y ranges:

print(manual_map.xrange)
print(manual_map.yrange)
# These return astropy Quantity objects.
# In general the attributes are populated using details in the metadata and in
# this case there is no centre pixel or pixel size information given so SunPy
# is defaulting to assuming each pixel is 1 arcsec.
# This is in Helioprojective tangent projection in both longitude and latitude:
print(manual_map.coordinate_system)

Out:

[-7.  8.] arcsec
[ -9.5  10.5] arcsec
Pair(x='HPLN-TAN', y='HPLT-TAN')

A real map example is given in the sample data, where the sunpy.data.sample.NAME returns the location of the given FITS file.

aia_map = sunpy.map.Map(sunpy.data.sample.AIA_171_IMAGE)
aia_map.peek(draw_limb=True)
../../../_images/sphx_glr_plot_maps_example_002.png

This has comprehensive metadata:

print(aia_map.meta)

Out:

MapMeta([('simple', True), ('bitpix', 32), ('naxis', 2), ('naxis1', 1024), ('naxis2', 1024), ('extend', True), ('comment', "FITS (Flexible Image Transport System) format is defined in 'Astronomy  and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H"), ('origin', 'SDO/JSOC-SDP'), ('date', '2011-03-19T11:08:25'), ('telescop', 'SDO/AIA'), ('instrume', 'AIA_3'), ('date-obs', '2011-03-19T10:54:00.34'), ('t_obs', '2011-03-19T10:54:01.34Z'), ('tobsstep', 90.0), ('tobsepoc', '1977.01.01_00:00:00_TAI'), ('camera', 3), ('img_type', 'LIGHT'), ('exptime', 1.999601), ('expsdev', 0.00016), ('int_time', 2.273438), ('wavelnth', 171), ('waveunit', 'angstrom'), ('wave_str', '171_THIN'), ('fsn', 22642033), ('fid', 0), ('lvl_num', 1.5), ('quallev0', 0), ('quality', 1073741824), ('totvals', 16777216), ('datavals', 16777216), ('missvals', 0), ('percentd', 100.0), ('datamin', -7), ('datamax', 16228), ('datamedn', 192), ('datamean', 236.57), ('datarms', 294.02), ('dataskew', 4.63), ('datakurt', 49.56), ('oscnmean', 'nan'), ('oscnrms', 'nan'), ('flat_rec', 'aia.flatfield[:#7]'), ('ctype1', 'HPLN-TAN'), ('cunit1', 'arcsec'), ('crval1', 0.0), ('cdelt1', 2.4), ('crpix1', 512.5), ('ctype2', 'HPLT-TAN'), ('cunit2', 'arcsec'), ('crval2', 0.0), ('cdelt2', 2.4), ('crpix2', 512.5), ('crota2', 0.0), ('r_sun', 1608.94397), ('mpo_rec', 'sdo.master_pointing[:#116]'), ('inst_rot', 0.102488), ('imscl_mp', 0.599076), ('x0_mp', 2052.399902), ('y0_mp', 2046.589966), ('rsun_lf', 'nan'), ('x0_lf', 'nan'), ('y0_lf', 'nan'), ('asd_rec', 'sdo.lev0_asd_0004[:#8948067]'), ('sat_y0', -0.365593), ('sat_z0', 14.820671), ('sat_rot', -8.8e-05), ('acs_mode', 'SCIENCE'), ('acs_eclp', 'NO'), ('acs_sunp', 'YES'), ('acs_safe', 'NO'), ('acs_cgt', 'GT3'), ('orb_rec', 'sdo.fds_orbit_vectors[2011.03.19_10:54:00_UTC]'), ('dsun_ref', 149597870691.0), ('dsun_obs', 148940609626.98), ('rsun_ref', 696000000.0), ('rsun_obs', 963.879683), ('gciec_x', 'nan'), ('gciec_y', 'nan'), ('gciec_z', 'nan'), ('hciec_x', 'nan'), ('hciec_y', 'nan'), ('hciec_z', 'nan'), ('obs_vr', -2132.568376), ('obs_vw', 30775.731671), ('obs_vn', 2177.6711), ('crln_obs', 315.285065), ('crlt_obs', -7.064078), ('car_rot', 2108), ('roi_nwin', -2147483648), ('roi_sum', -2147483648), ('roi_nax1', -2147483648), ('roi_nay1', -2147483648), ('roi_llx1', -2147483648), ('roi_lly1', -2147483648), ('roi_nax2', -2147483648), ('roi_nay2', -2147483648), ('roi_llx2', -2147483648), ('roi_lly2', -2147483648), ('ispsname', 'aia.lev0_isp_0011'), ('isppktim', '2011-03-19T10:53:57.50Z'), ('isppktvn', '001.197'), ('aivnmst', 453), ('aimgots', 1679223275), ('asqhdr', 2170125681), ('asqtnum', 2), ('asqfsn', 22642033), ('aiahfsn', 22642025), ('aecdelay', 1540), ('aiaecti', 0), ('aiasen', 0), ('aifdbid', 241), ('aimgotss', 5339), ('aifcps', 10), ('aiftswth', 0), ('aifrmlid', 3024), ('aiftsid', 40960), ('aihismxb', 7), ('aihis192', 8381297), ('aihis348', 8388262), ('aihis604', 8388597), ('aihis860', 8388603), ('aifwen', 204), ('aimgshce', 2000), ('aectype', 0), ('aecmode', 'ON'), ('aistate', 'CLOSED'), ('aiaecenf', 1), ('aifiltyp', 0), ('aimshobc', 41.099998), ('aimshobe', 26.076), ('aimshotc', 55.312), ('aimshote', 69.316002), ('aimshcbc', 2040.791992), ('aimshcbe', 2025.864014), ('aimshctc', 2054.875977), ('aimshcte', 2068.676025), ('aicfgdl1', 0), ('aicfgdl2', 137), ('aicfgdl3', 201), ('aicfgdl4', 236), ('aifoenfl', 1), ('aimgfsn', 5), ('aimgtyp', 0), ('aiawvlen', 7), ('aiagp1', 0), ('aiagp2', 0), ('aiagp3', 0), ('aiagp4', 0), ('aiagp5', 0), ('aiagp6', 0), ('aiagp7', 0), ('aiagp8', 393), ('aiagp9', 457), ('aiagp10', 748), ('agt1svy', 18), ('agt1svz', 10), ('agt2svy', 10), ('agt2svz', 8), ('agt3svy', 2), ('agt3svz', 0), ('agt4svy', 14), ('agt4svz', 0), ('aimgshen', 4), ('recnum', 76202), ('blank', -2147483648), ('bzero', 0.0), ('bscale', 0.0625), ('checksum', 'J7qAL7o6J7oAJ7o5'), ('datasum', '3958014355'), ('history', ''), ('keycomments', {'EXTEND': 'FITS dataset may contain extensions', 'NAXIS2': 'length of data axis 2', 'BITPIX': 'number of bits per data pixel', 'NAXIS': 'number of data axes', 'CHECKSUM': 'HDU checksum updated 2011-03-19T11:08:18', 'DATASUM': 'data unit checksum updated 2011-03-19T11:08:18', 'SIMPLE': 'file does conform to FITS standard', 'NAXIS1': 'length of data axis 1'}), ('detector', 'AIA')])

Which allows it to accurately specify ranges:

print(aia_map.xrange)
print(aia_map.yrange)

# And find out information about the observation device and date:
print(aia_map.date)
print(aia_map.observatory)
print(aia_map.detector)
print(aia_map.exposure_time)
print(aia_map.coordinate_system)
print(aia_map.measurement)

Out:

[-1227.6  1230. ] arcsec
[-1227.6  1230. ] arcsec
2011-03-19 10:54:00.340000
SDO
AIA
1.999601 s
Pair(x='HPLN-TAN', y='HPLT-TAN')
171.0 Angstrom

To see only a part of the image you create a submap, specifying ranges in AstroPy Quantities:

rangex = u.Quantity([aia_map.xrange[0], 0 * u.arcsec])
rangey = u.Quantity([aia_map.yrange[0], 0 * u.arcsec])
aia_submap = aia_map.submap(rangex, rangey)
aia_submap.peek(draw_limb=True)
../../../_images/sphx_glr_plot_maps_example_003.png

Similarly, if you want to reduce the angular resolution of the map you can use the resample method, specifying the dimensions as an Astropy Quantity in pixels:

dimensions = u.Quantity([50, 50], u.pixel)
aia_resampled_map = aia_map.resample(dimensions)
aia_resampled_map.peek(draw_limb=True, draw_grid=True)
../../../_images/sphx_glr_plot_maps_example_004.png

Similar to resampling you can use the superpixel method, this will reduce the resolution of the image by combining the number of pixels (in each dimension) in the dimensions argument into one single pixel. This can be used to increase the signal to noise ratio. For this the new dimensions must divide original image size exactly.

dimensions = u.Quantity(aia_map.dimensions) / 16
aia_superpixel_map = aia_map.superpixel(dimensions)
aia_superpixel_map.peek(draw_limb=True)
../../../_images/sphx_glr_plot_maps_example_005.png

Maps can also be rotated using the rotate method:

aia_rotated_submap = aia_submap.rotate(angle = 10 * u.deg)
aia_rotated_submap.peek(draw_limb=True, draw_grid=True)
# Note: the data array is expanded so that none of the original data is lost
# through clipping.
../../../_images/sphx_glr_plot_maps_example_006.png

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

Generated by Sphinx-Gallery