SunPy map


One of core classes in SunPy is a Map. A SunPy Map object is simply a spatially-aware data array, often an image. In order to make it easy to work with image data in SunPy, the Map object provides a number of methods for commonly performed operations.

2D map objects are subclasses of MapBase and all Map objects are created using the Map factory Map.

A number of instrument are supported by subclassing this base object. See Instrument Map Classes to see a list of all of them. More complex subclasses are also available. See Map Classes.

Creating Map Objects

SunPy Map objects are constructed using the special factory class Map:

>>> x ='file.fits')  

The result of a call to Map will be either a GenericMap object, or a subclass of GenericMap which either deals with a specific type of data, e.g. AIAMap or LASCOMap (see Map Classes to see a list of all of them), or if no instrument matches, a 2D map GenericMap.

Fixing map metadata

If you need to fix the metadata of a fits file before it is handed to Map, this can be done as follows:

>>> [data, header] = # doctest: +SKIP
>>> header['cunit1'] = 'arcsec' # doctest: +SKIP
>>> header['cunit2'] = 'arcsec' # doctest: +SKIP
>>> map =, header) # doctest: +SKIP
class, additional_validation_functions=[], registry=None)[source] [edit on github]

Map(*args, **kwargs)

Map factory class. Used to create a variety of Map objects. Valid map types are specified by registering them with the factory.


>>> import
>>> from import fits
>>> import  # doctest: +REMOTE_DATA
>>> mymap =  # doctest: +REMOTE_DATA

The SunPy Map factory accepts a wide variety of inputs for creating maps

  • Preloaded tuples of (data, header) pairs

>>> mymap =, header))   # doctest: +SKIP

headers are some base of dict or collections.OrderedDict, including or sunpy.util.MetaDict classes.

  • data, header pairs, not in tuples

>>> mymap =, header)   # doctest: +SKIP
  • data, wcs object, in tuple

>>> from astropy.wcs import WCS
>>> wcs = WCS(     # doctest: +REMOTE_DATA
>>> data = fits.getdata(    # doctest: +REMOTE_DATA
>>> mymap =, wcs))    # doctest: +REMOTE_DATA
  • data, wcs object, not in tuple

>>> from astropy.wcs import WCS
>>> wcs = WCS(     # doctest: +REMOTE_DATA
>>> data = fits.getdata(    # doctest: +REMOTE_DATA
>>> mymap =, wcs)   # doctest: +REMOTE_DATA
  • File names

>>> mymap ='file1.fits')   # doctest: +SKIP
  • All fits files in a directory by giving a directory

>>> mymap ='local_dir/sub_dir')   # doctest: +SKIP
  • Some regex globs

>>> mymap ='eit_*.fits')   # doctest: +SKIP
  • URLs

>>> mymap =   # doctest: +SKIP
  • DatabaseEntry

>>> mymap =   # doctest: +SKIP
  • Lists of any of the above

>>> mymap =['file1.fits', 'file2.fits', 'file3.fits', 'directory1/'])  # doctest: +SKIP
  • Any mixture of the above not in a list

>>> mymap =, header), data2, header2, 'file1.fits', url_str, 'eit_*.fits'))  # doctest: +SKIP

Using Map Objects

Once a map object has been created using Map it will be a instance or a subclass of the GenericMap class. Irrespective of the instrument the map is constructed for, all maps behave the same and are interchangeable with one another. It is possible to manipulate the map or access meta data about the map from the methods and properties of the map class. The following documentation of GenericMap lists the attributes and methods that are available on all Map objects.

class, header, plot_settings=None, **kwargs)[source] [edit on github]

A Generic spatially-aware 2D data array

  • data (numpy.ndarray, list) – A 2d list or ndarray containing the map data.

  • header (dict) – A dictionary of the original image header tags.

  • plot_settings (dict, optional) – Plot settings.

Other Parameters

**kwargs – Additional keyword arguments are passed to NDData init.


>>> import
>>> import  # doctest: +REMOTE_DATA
>>> aia =  # doctest: +REMOTE_DATA
>>> aia   # doctest: +REMOTE_DATA
SunPy Map
Observatory:                 SDO
Instrument:          AIA 3
Detector:            AIA
Measurement:                 171.0 Angstrom
Wavelength:          171.0 Angstrom
Observation Date:    2011-06-07 06:33:02
Exposure Time:               0.234256 s
Dimension:           [1024. 1024.] pix
Coordinate System:   helioprojective
Scale:                       [2.402792 2.402792] arcsec / pix
Reference Pixel:     [512.5 512.5] pix
Reference Coord:     [3.22309951 1.38578135] arcsec
array([[ -95.92475  ,    7.076416 ,   -1.9656711, ..., -127.96519  ,
        -127.96519  , -127.96519  ],
       [ -96.97533  ,   -5.1167884,    0.       , ...,  -98.924576 ,
        -104.04137  , -127.919716 ],
       [ -93.99607  ,    1.0189276,   -4.0757103, ...,   -5.094638 ,
         -37.95505  , -127.87541  ],
       [-128.01454  , -128.01454  , -128.01454  , ..., -128.01454  ,
        -128.01454  , -128.01454  ],
       [-127.899666 , -127.899666 , -127.899666 , ..., -127.899666 ,
        -127.899666 , -127.899666 ],
       [-128.03072  , -128.03072  , -128.03072  , ..., -128.03072  ,
        -128.03072  , -128.03072  ]], dtype=float32)
>>> aia.spatial_units   # doctest: +REMOTE_DATA
SpatialPair(axis1=Unit("arcsec"), axis2=Unit("arcsec"))
>>> aia.peek()   # doctest: +SKIP


A number of the properties of this class are returned as two-value named tuples that can either be indexed by position ([0] or [1]) or be accessed by the names (.x and .y) or (.axis1 and .axis2). Things that refer to pixel axes use the .x, .y convention, where x and y refer to the FITS axes (x for columns y for rows). Spatial axes use .axis1 and .axis2 which correspond to the first and second axes in the header. axis1 corresponds to the coordinate axis for x and axis2 corresponds to y.

This class makes some assumptions about the WCS information contained in the meta data. The first and most extensive assumption is that it is FITS-like WCS information as defined in the FITS WCS papers.

Within this scope it also makes some other assumptions.

  • In the case of APIS convention headers where the CROTAi/j arguments are provided it assumes that these can be converted to the standard PCi_j notation using equations 32 in Thompson (2006).

  • If a CDi_j matrix is provided it is assumed that it can be converted to a PCi_j matrix and CDELT keywords as described in Greisen & Calabretta (2002)

  • The ‘standard’ FITS keywords that are used by this class are the PCi_j matrix and CDELT, along with the other keywords specified in the WCS papers. All subclasses of this class must convert their header information to this formalism. The CROTA to PCi_j conversion is done in this class.


This class currently assumes that a header with the CDi_j matrix information also includes the CDELT keywords, without these keywords this class will not process the WCS. Also the rotation_matrix does not work if the CDELT1 and CDELT2 keywords are exactly equal. Also, if a file with more than two dimensions is feed into the class, only the first two dimensions (NAXIS1, NAXIS2) will be loaded and the rest will be discarded.


The physical coordinate for the bottom left [0,0] pixel.


Carrington longitude (crln_obs).


Return a coordinate object for the center pixel of the array.


An astropy.coordinates.BaseFrame instance created from the coordinate information for this Map.


Coordinate system used for x and y axes (ctype1/2).


Image observation time.


Detector name.


The dimensions of the array (x axis first, y axis second).

draw_contours(levels: Unit("%"), axes=None, **contour_args)[source] [edit on github]

Draw contours of the data.

  • levels (Quantity) – A list of numbers indicating the level curves to draw given in percent.

  • axes (matplotlib.axes.Axes) – The axes on which to plot the rectangle, defaults to the current axes.


cs (list) – The QuadContourSet object, after it has been added to axes.


Extra keyword arguments to this function are passed through to the contour function.

draw_grid(axes=None, grid_spacing: Unit("deg") = <Quantity 15. deg>, **kwargs)[source] [edit on github]

Draws a coordinate overlay on the plot in the Heliographic Stonyhurst coordinate system.

To overlay other coordinate systems see the WCSAxes Documentation

  • axes (axes or None) –

  • to plot limb on or None to use current axes. (Axes) –

  • grid_spacing (Quantity) – Spacing for longitude and latitude grid, if length two it specifies (lon, lat) spacing.


overlay (CoordinatesMap) – The wcsaxes coordinate overlay instance.


Keyword arguments are passed onto the sunpy.visualization.wcsaxes_compat.wcsaxes_heliographic_overlay function.

draw_limb(axes=None, **kwargs)[source] [edit on github]

Draws a circle representing the solar limb


axes (axes or None) – Axes to plot limb on or None to use current axes.


circ (list) – A list containing the Circle object that has been added to the axes.


Keyword arguments are passed onto matplotlib.patches.Circle.

draw_rectangle(bottom_left, width: Unit("deg"), height: Unit("deg"), axes=None, **kwargs)[source] [edit on github]

Draw a rectangle defined in world coordinates on the plot.


rect (list) – A list containing the Rectangle object, after it has been added to axes.


Extra keyword arguments to this function are passed through to the Rectangle instance.


The observer distance from the Sun.


The numpy.dtype of the array of the map.


Exposure time of the image in seconds.


A Header representation of the meta attribute.


Heliographic latitude.


Heliographic longitude.


Instrument name.


LaTeX formatted description of the Map.

max(*args, **kwargs)[source] [edit on github]

Calculate the maximum value of the data array.

mean(*args, **kwargs)[source] [edit on github]

Calculate the mean of the data array.


Measurement name, defaults to the wavelength of image.

min(*args, **kwargs)[source] [edit on github]

Calculate the minimum value of the data array.


Human-readable description of the Map.


The value of numpy.ndarray.ndim of the data array of the map.


An abbreviated human-readable description of the map-type; part of the Helioviewer data model.


Observatory or Telescope name.


The Heliographic Stonyhurst Coordinate of the observer.

peek(draw_limb=False, draw_grid=False, colorbar=True, basic_plot=False, **matplot_args)[source] [edit on github]

Displays the map in a new figure.

  • draw_limb (bool) – Whether the solar limb should be plotted.

  • draw_grid (bool or Quantity) – Whether solar meridians and parallels are plotted. If Quantity then sets degree difference between parallels and meridians.

  • colorbar (bool) – Whether to display a colorbar next to the plot.

  • basic_plot (bool) – If true, the data is plotted by itself at it’s natural scale; no title, labels, or axes are shown.

  • **matplot_args (dict) – Matplotlib Any additional imshow arguments that should be used when plotting.

pixel_to_world(x: Unit("pix"), y: Unit("pix"), origin=0)[source] [edit on github]

Convert a pixel coordinate to a data (world) coordinate by using wcs_pix2world.

  • x (Quantity) – Pixel coordinate of the CTYPE1 axis. (Normally solar-x).

  • y (Quantity) – Pixel coordinate of the CTYPE2 axis. (Normally solar-y).

  • origin (int) – Origin of the top-left corner. i.e. count from 0 or 1. Normally, origin should be 0 when passing numpy indices, or 1 if passing values from FITS header or map attributes. See wcs_pix2world for more information.


coord (astropy.coordinates.SkyCoord) – A coordinate object representing the output coordinate.

plot(annotate=True, axes=None, title=True, clip_interval: Unit("%") = None, **imshow_kwargs)[source] [edit on github]

Plots the map object using matplotlib, in a method equivalent to plt.imshow() using nearest neighbour interpolation.

  • annotate (bool, optional) – If True, the data is plotted at its natural scale; with title and axis labels.

  • axes (axes or None) – If provided the image will be plotted on the given axes. Else the current matplotlib axes will be used.

  • title (bool, optional) – If True, include the title.

  • clip_interval (two-element Quantity, optional) – If provided, the data will be clipped to the percentile interval bounded by the two numbers.

  • **imshow_kwargs (dict) – Any additional imshow arguments that should be used when plotting.


>>> # Simple Plot with color bar
>>> aia.plot()   # doctest: +SKIP
>>> plt.colorbar()   # doctest: +SKIP
>>> # Add a limb line and grid
>>> aia.plot()   # doctest: +SKIP
>>> aia.draw_limb()   # doctest: +SKIP
>>> aia.draw_grid()   # doctest: +SKIP

Returns the FITS processing level if present.


Reference point WCS axes in data units (i.e. crval1, crval2). This value includes a shift if one is set.


Reference point axes in pixels (i.e. crpix1, crpix2).

resample(dimensions: Unit("pix"), method='linear')[source] [edit on github]

Returns a new Map that has been resampled up or down

Arbitrary resampling of the Map to new dimension sizes.

Uses the same parameters and creates the same co-ordinate lookup points as IDL’’s congrid routine, which apparently originally came from a VAX/VMS routine of the same name.

  • dimensions (Quantity) – Pixel dimensions that new Map should have. Note: the first argument corresponds to the ‘x’ axis and the second argument corresponds to the ‘y’ axis.

  • method ({'neighbor' | 'nearest' | 'linear' | 'spline'}) –

    Method to use for resampling interpolation.
    • neighbor - Closest value from original data

    • nearest and linear - Uses n x 1-D interpolations using scipy.interpolate.interp1d

    • spline - Uses ndimage.map_coordinates


out (GenericMap or subclass) – A new Map which has been resampled to the desired dimensions.


rotate(angle=None, rmatrix=None, order=4, scale=1.0, recenter=False, missing=0.0, use_scipy=False)[source] [edit on github]

Returns a new rotated and rescaled map.

Specify either a rotation angle or a rotation matrix, but not both. If neither an angle or a rotation matrix are specified, the map will be rotated by the rotation angle in the metadata.

The map will be rotated around the reference coordinate defined in the meta data.

This method also updates the rotation_matrix attribute and any appropriate header data so that they correctly describe the new map.

  • angle (Quantity) – The angle (degrees) to rotate counterclockwise.

  • rmatrix (2x2) – Linear transformation rotation matrix.

  • order (int 0-5) – Interpolation order to be used. When using scikit-image this parameter is passed into skimage.transform.warp() (e.g., 4 corresponds to bi-quartic interpolation). When using scipy it is passed into scipy.ndimage.interpolation.affine_transform() where it controls the order of the spline. Faster performance may be obtained at the cost of accuracy by using lower values. Default: 4

  • scale (float) – A scale factor for the image, default is no scaling

  • recenter (bool) – If True, position the axis of rotation at the center of the new map Default: False

  • missing (float) – The numerical value to fill any missing points after rotation. Default: 0.0

  • use_scipy (bool) – If True, forces the rotation to use scipy.ndimage.interpolation.affine_transform(), otherwise it uses the skimage.transform.warp(). Default: False, unless scikit-image can’t be imported


out (GenericMap or subclass) – A new Map instance containing the rotated and rescaled data of the original map.

See also


The routine this method calls



This function will remove old CROTA keywords from the header. This function will also convert a CDi_j matrix to a PCi_j matrix.

See sunpy.image.transform.affine_transform() for details on the transformations, situations when the underlying data is modified prior to rotation, and differences from IDL’s rot().


Matrix describing the rotation required to align solar North with the top of the image.


Radius of the sun in meters.


Radius of the Sun.

save(filepath, filetype='auto', **kwargs)[source] [edit on github]

Saves the SunPy Map object to a file.

Currently SunPy can only save files in the FITS format. In the future support will be added for saving to other formats.

  • filepath (str) – Location to save file to.

  • filetype (str) – ‘auto’ or any supported file extension.

  • Keywords

  • --------

  • hdu_type (None, CompImageHDU) – None will return a normal FITS files. CompImageHDU will rice compress the FITS file.


Image scale along the x and y axes in units/pixel (i.e. cdelt1, cdelt2).

shift(axis1: Unit("deg"), axis2: Unit("deg"))[source] [edit on github]

Returns a map shifted by a specified amount to, for example, correct for a bad map location. These values are applied directly to the reference_coordinate. To check how much shift has already been applied see shifted_value

  • axis1 (Quantity) – The shift to apply to the Longitude (solar-x) coordinate.

  • axis2 (Quantity) – The shift to apply to the Latitude (solar-y) coordinate


out (GenericMap or subclass) – A new shifted Map.


The total shift applied to the reference coordinate by past applications of shift.


The number of pixels in the array of the map.


Image coordinate units along the x and y axes (i.e. cunit1, cunit2).

std(*args, **kwargs)[source] [edit on github]

Calculate the standard deviation of the data array.

submap(bottom_left, top_right=None)[source] [edit on github]

Returns a submap of the map defined by the rectangle given by the [bottom_left, top_right] coordinates.

  • bottom_left (astropy.units.Quantity or SkyCoord) – The bottom_left coordinate of the rectangle. If a SkyCoord it can have shape (2,) and also define top_right. If specifying pixel coordinates it must be given as an Quantity object with units of pixel.

  • top_right (astropy.units.Quantity or SkyCoord) – The top_right coordinate of the rectangle. Can only be omitted if bottom_left has shape (2,).


out (GenericMap or subclass) – A new map instance is returned representing to specified sub-region.


>>> import astropy.units as u
>>> from astropy.coordinates import SkyCoord
>>> import
>>> import  # doctest: +REMOTE_DATA
>>> aia =  # doctest: +REMOTE_DATA
>>> bl = SkyCoord(-300*u.arcsec, -300*u.arcsec, frame=aia.coordinate_frame)  # doctest: +REMOTE_DATA
>>> tr = SkyCoord(500*u.arcsec, 500*u.arcsec, frame=aia.coordinate_frame)  # doctest: +REMOTE_DATA
>>> aia.submap(bl, tr)   # doctest: +REMOTE_DATA
SunPy Map
Observatory:             SDO
Instrument:              AIA 3
Detector:                AIA
Measurement:             171.0 Angstrom
Wavelength:              171.0 Angstrom
Observation Date:        2011-06-07 06:33:02
Exposure Time:           0.234256 s
Dimension:               [334. 334.] pix
Coordinate System:       helioprojective
Scale:                   [2.402792 2.402792] arcsec / pix
Reference Pixel:         [127.5 126.5] pix
Reference Coord:         [3.22309951 1.38578135] arcsec
array([[ 450.4546 ,  565.81494,  585.0416 , ..., 1178.3234 , 1005.28284,
        977.8161 ],
    [ 474.20004,  516.1865 ,  555.7032 , ..., 1024.9636 , 1010.1449 ,
        1010.1449 ],
    [ 548.1609 ,  620.9256 ,  620.9256 , ...,  933.8139 , 1074.4924 ,
        1108.4492 ],
    [ 203.58617,  195.52335,  225.75891, ...,  612.7742 ,  580.52295,
        560.3659 ],
    [ 206.00058,  212.1806 ,  232.78065, ...,  650.96185,  622.12177,
        537.6615 ],
    [ 229.32516,  236.07002,  222.5803 , ...,  517.1058 ,  586.8026 ,
        591.2992 ]], dtype=float32)
>>> aia.submap([0,0]*u.pixel, [5,5]*u.pixel)   # doctest: +REMOTE_DATA
SunPy Map
Observatory:             SDO
Instrument:              AIA 3
Detector:                AIA
Measurement:             171.0 Angstrom
Wavelength:              171.0 Angstrom
Observation Date:        2011-06-07 06:33:02
Exposure Time:           0.234256 s
Dimension:               [5. 5.] pix
Coordinate System:       helioprojective
Scale:                   [2.402792 2.402792] arcsec / pix
Reference Pixel:         [512.5 512.5] pix
Reference Coord:         [3.22309951 1.38578135] arcsec
array([[-95.92475   ,   7.076416  ,  -1.9656711 ,  -2.9485066 ,
    [-96.97533   ,  -5.1167884 ,   0.        ,   0.        ,
        0.9746264 ],
    [-93.99607   ,   1.0189276 ,  -4.0757103 ,   2.0378551 ,
        -2.0378551 ],
    [-96.97533   ,  -8.040668  ,  -2.9238791 ,  -5.1167884 ,
        -0.9746264 ],
    [-95.92475   ,   6.028058  ,  -4.9797    ,  -1.0483578 ,
        -3.9313421 ]], dtype=float32)
superpixel(dimensions: Unit("pix"), offset: Unit("pix") = <Quantity [0., 0.] pix>, func=<function sum>)[source] [edit on github]

Returns a new map consisting of superpixels formed by applying ‘func’ to the original map data.

  • dimensions (tuple) – One superpixel in the new map is equal to (dimension[0], dimension[1]) pixels of the original map. Note: the first argument corresponds to the ‘x’ axis and the second argument corresponds to the ‘y’ axis.

  • offset (tuple) – Offset from (0,0) in original map pixels used to calculate where the data used to make the resulting superpixel map starts.

  • func (function applied to the original data) – The function ‘func’ must take a numpy array as its first argument, and support the axis keyword with the meaning of a numpy axis keyword (see the description of sum for an example.) The default value of ‘func’ is sum; using this causes superpixel to sum over (dimension[0], dimension[1]) pixels of the original map.


out (GenericMap or subclass) – A new Map which has superpixels of the required size.



The physical coordinate for the top left pixel.


Wavelength of the observation.


The WCS property of the map.

world_to_pixel(coordinate, origin=0)[source] [edit on github]

Convert a world (data) coordinate to a pixel coordinate by using wcs_world2pix.

  • coordinate (SkyCoord or BaseFrame) – The coordinate object to convert to pixel coordinates.

  • origin (int) – Origin of the top-left corner. i.e. count from 0 or 1. Normally, origin should be 0 when passing numpy indices, or 1 if passing values from FITS header or map attributes. See wcs_world2pix for more information.


  • x (Quantity) – Pixel coordinate on the CTYPE1 axis.

  • y (Quantity) – Pixel coordinate on the CTYPE2 axis.

Map Classes

Defined in are a set of GenericMap subclasses which convert the specific metadata and other differences in each instruments data to the standard GenericMap interface. These ‘sources’ also define things like the colormap and default normalisation for each instrument. These subclasses also provide a method, which describes to the Map factory which data and metadata pairs match its instrument.


CompositeMap(map1 [,map2,..])

A Composite Map class

GenericMap(data, header[, plot_settings])

A Generic spatially-aware 2D data array

MapSequence(*args[, sortby, derotate])

A series of Maps in a single object.

Class Inheritance Diagram

Inheritance diagram of,,

Instrument Map Classes Package

Datasource-specific classes

This is where datasource specific logic is implemented. Each mission should have its own file with one or more classes defined. Typically, these classes will be subclasses of the :mod`` class.


source_stretch(meta, fits_stretch)

Assign the correct source-dependent image stretching function.


XRTMap(data, header, **kwargs)

Hinode XRT map definition.

SOTMap(data, header, **kwargs)

Hinode SOT Image Map definition.

SWAPMap(data, header, **kwargs)

PROBA2 SWAP Image Map.

RHESSIMap(data, header, **kwargs)

RHESSI Image Map.

AIAMap(data, header, **kwargs)

AIA Image Map.

HMIMap(data, header, **kwargs)

HMI Image Map.

EITMap(data, header, **kwargs)

SOHO EIT Image Map.

LASCOMap(data, header, **kwargs)


MDIMap(data, header, **kwargs)

SOHO MDI Image Map

EUVIMap(data, header, **kwargs)


CORMap(data, header, **kwargs)

STEREO-SECCHI CORonograph Image Map.

HIMap(data, header, **kwargs)

STEREO-SECCHI Heliospheric Imager (HI) Map.

SXTMap(data, header, **kwargs)

Yohkoh SXT Image Map

SJIMap(data, header, **kwargs)

A 2D IRIS Slit Jaw Imager Map.

TRACEMap(data, header, **kwargs)

TRACE Image Map

KCorMap(data, header, **kwargs)

K-Cor Image Map.

Class Inheritance Diagram

Inheritance diagram of,,,,,,,,,,,,,,,

Writing a new Instrument Map Class

Any subclass of GenericMap which defines a method named is_datasource_for will automatically be registered with the Map factory. The is_datasource_for method describes the form of the data and metadata for which the GenericMap subclass is valid. For example it might check the value of the INSTRUMENT key in the metadata dictionary. This makes it straightforward to define your own GenericMap subclass for a new instrument or a custom data source like simulated data. These classes only have to be imported for this to work, as demonstrated by the following example.

class FutureMap(

    def __init__(self, data, header, **kwargs):

        super(FutureMap, self).__init__(data, header, **kwargs)

        # Any Future Instrument specific keyword manipulation

   # Specify a classmethod that determines if the data-header pair matches
   # the new instrument
   def is_datasource_for(cls, data, header, **kwargs):
        """Determines if header corresponds to an AIA image"""
        return header.get('instrume', '').startswith('FUTURESCOPE')

This class will now be available through the Map factory as long as this class has been defined, i.e. imported into the current session.

If you do not want to create a method named is_datasource_for you can manually register your class and matching method using the following method

import, FutureMap.some_matching_method)