SunPy coordinates

This sub-package contains:

  • A robust framework for working with solar-physics coordinate systems

  • Functions to obtain the locations of solar-system bodies (sunpy.coordinates.ephemeris)

  • Functions to calculate Sun-specific coordinate information (sunpy.coordinates.sun)

The SunPy coordinate framework extends the Astropy coordinates framework.

Supported Coordinate Systems

Coordinate system


SunPy/Astropy equivalent


Heliocentric Aries Ecliptic (Mean)

HAE (also HEC)

Astropy’s HeliocentricMeanEcliptic

Heliocentric Cartesian



Heliocentric Earth Ecliptic



Heliocentric Earth Equatorial

HEEQ (also HEQ)


Use a Cartesian representation

Heliocentric Inertial



Heliocentric Radial


similar to Heliocentric

Use a cylindrical representation, but with a 90-degree offset in psi

Heliocentric/Heliographic Radial-Tangential-Normal


similar to Heliocentric

The axes are permuted, with HCC X, Y, Z equivalent respectively to HGRTN Y, Z, X

Heliographic Carrington



Heliographic Stonyhurst



Helioprojective Cartesian



Geocentric Earth Equatorial (Mean)





Astropy’s ITRS

The precise geographic definitions may differ

Geocentric Solar Ecliptic



For a description of these coordinate systems, see Thompson (2006) and Franz & Harper (2002) (and corrected version).

Getting Started

The easiest interface to work with coordinates is through the SkyCoord class:

>>> import astropy.units as u
>>> from astropy.coordinates import SkyCoord
>>> from sunpy.coordinates import frames

>>> c = SkyCoord(-100*u.arcsec, 500*u.arcsec, frame=frames.Helioprojective)
>>> c = SkyCoord(x=-72241.0*, y=361206.1*, z=589951.4*, frame=frames.Heliocentric)
>>> c = SkyCoord(70*u.deg, -30*u.deg, frame=frames.HeliographicStonyhurst)
>>> c
<SkyCoord (HeliographicStonyhurst: obstime=None): (lon, lat, radius) in (deg, deg, km)
    (70., -30., 695700.)>

It is also possible to use strings to specify the frame but in that case make sure to explicitly import sunpy.coordinates as it registers SunPy’s coordinate frames with the Astropy coordinates framework:

>>> import astropy.units as u
>>> from astropy.coordinates import SkyCoord

>>> import sunpy.coordinates
>>> c = SkyCoord(-100*u.arcsec, 500*u.arcsec, frame='helioprojective', observer='earth')
>>> c
<SkyCoord (Helioprojective: obstime=None, rsun=695700.0 km, observer=earth): (Tx, Ty) in arcsec
    (-100., 500.)>

SkyCoord and all coordinate frames support array coordinates. These work the same as single-value coordinates, but they store multiple coordinates in a single object. When you’re going to apply the same operation to many different coordinates, this is a better choice than a list of SkyCoord objects, because it will be much faster than applying the operation to each SkyCoord in a for loop:

>>> c = SkyCoord([-500, 400]*u.arcsec, [100, 200]*u.arcsec, frame=frames.Helioprojective)
>>> c
<SkyCoord (Helioprojective: obstime=None, rsun=695700.0 km, observer=None): (Tx, Ty) in arcsec
    [(-500.,  100.), ( 400.,  200.)]>
>>> c[0]
<SkyCoord (Helioprojective: obstime=None, rsun=695700.0 km, observer=None): (Tx, Ty) in arcsec
    (-500.,  100.)>

Accessing Coordinates

Individual coordinates can be accessed via attributes on the SkyCoord object, but the names of the components of the coordinates can depend on the the frame and the chosen representation (e.g., Cartesian versus spherical).


For the helioprojective frame, the theta_x and theta_y components are accessed as Tx and Ty, respectively:

>>> c = SkyCoord(-500*u.arcsec, 100*u.arcsec, frame=frames.Helioprojective)
>>> c.Tx
<Longitude -500. arcsec>
>>> c.Ty
<Latitude 100. arcsec>


Heliocentric is typically used with Cartesian components:

>>> c = SkyCoord(-72241.0*, 361206.1*, 589951.4*, frame=frames.Heliocentric)
>>> c.x
<Quantity -72241. km>
>>> c.y
<Quantity 361206.1 km>
>>> c.z
<Quantity 589951.4 km>

HeliographicStonyhurst and HeliographicCarrington

Both of the heliographic frames have the components of latitude, longitude and radius:

>>> c = SkyCoord(70*u.deg, -30*u.deg, frame=frames.HeliographicStonyhurst)
<Latitude -30. deg>
>>> c.lon
<Longitude 70. deg>
>>> c.radius
<Distance 695700. km>

Heliographic Stonyhurst, when used with Cartesian components, is known as Heliocentric Earth Equatorial (HEEQ). Here’s an example of how to use HeliographicStonyhurst for HEEQ coordinates:

>>> c = SkyCoord(-72241.0*, 361206.1*, 589951.4*,
...              representation_type='cartesian', frame=frames.HeliographicStonyhurst)
>>> c.x
<Quantity -72241. km>
>>> c.y
<Quantity 361206.1 km>
>>> c.z
<Quantity 589951.4 km>

Transforming Between Coordinate Frames

Both SkyCoord and BaseCoordinateFrame instances have a transform_to method. This can be used to transform the frame to any other frame, either implemented in SunPy or in Astropy (see also Transforming between Systems). An example of transforming the center of the solar disk to Carrington coordinates is:

>>> c = SkyCoord(0*u.arcsec, 0*u.arcsec, frame=frames.Helioprojective, obstime="2017-07-26",
...              observer="earth")
>>> c
<SkyCoord (Helioprojective: obstime=2017-07-26T00:00:00.000, rsun=695700.0 km, observer=<HeliographicStonyhurst Coordinate for 'earth'>): (Tx, Ty) in arcsec
    (0., 0.)>
>>> c.transform_to(frames.HeliographicCarrington)
<SkyCoord (HeliographicCarrington: obstime=2017-07-26T00:00:00.000, observer=<HeliographicStonyhurst Coordinate for 'earth'>): (lon, lat, radius) in (deg, deg, AU)
    (283.95956776, 5.31701821, 0.00465047)>

It is also possible to transform to any coordinate system implemented in Astropy. This can be used to find the position of the solar limb in AltAz equatorial coordinates:

>>> from astropy.coordinates import EarthLocation, AltAz
>>> time = '2017-07-11 15:00'
>>> greenbelt = EarthLocation(lat=39.0044*u.deg, lon=-76.8758*u.deg)
>>> greenbelt_frame = AltAz(obstime=time, location=greenbelt)
>>> west_limb = SkyCoord(900*u.arcsec, 0*u.arcsec, frame=frames.Helioprojective,
...                      observer=greenbelt.get_itrs(greenbelt_frame.obstime), obstime=time)  
>>> west_limb.transform_to(greenbelt_frame)  
<SkyCoord (AltAz: obstime=2017-07-11 15:00:00.000, location=(1126916.53031967, -4833386.58391627, 3992696.622115747) m, pressure=0.0 hPa, temperature=0.0 deg_C, relative_humidity=0, obswl=1.0 micron): (az, alt, distance) in (deg, deg, m)
    (111.40839101, 57.16645715, 1.51860261e+11)>

Observer Location Information

The Helioprojective, Heliocentric and HeliographicCarrington frames are defined by the location of the observer. For example in Helioprojective the observer is at the origin of the coordinate system. This information is encoded in such observer-based frames as the observer attribute, which is itself an instance of the HeliographicStonyhurst frame. The observer can be a string for a solar-system body (e.g., “earth” or “mars”), and get_body_heliographic_stonyhurst will be used with the specified obstime to fully specify the observer location. If the observer location is not fully specified, or not present at all, most transformations cannot be performed. The location of the observer is automatically populated from meta data when coordinate frames are created using map.

It is possible to convert from a Helioprojective frame with one observer location to another Helioprojective frame with a different observer location, by converting through Heliographic, this does involve making an assumption of the radius of the Sun to calculate the position on the solar sphere. The conversion can be performed as follows:

# Input coordinate
>>> hpc1 = SkyCoord(0*u.arcsec, 0*u.arcsec, observer="earth", obstime="2017-07-26", frame=frames.Helioprojective)

Define a new Helioprojective frame with a different observer.
>>> import sunpy.coordinates
>>> hpc_out = sunpy.coordinates.Helioprojective(observer="venus", obstime="2017-07-26")

Perform the transformation from one to the other.
>>> hpc2 = hpc1.transform_to(hpc_out)

An example with two maps, named aia and stereo:

>>> hpc1 = SkyCoord(0*u.arcsec, 0*u.arcsec, frame=aia.coordinate_frame)  
>>> hpc2 = hpc1.transform_to(stereo.coordinate_frame)  

Design of the Coordinates Sub-Package

This sub-package works by defining a collection of Frames (sunpy.coordinates.frames), which exists on a transformation graph, where the transformations between the coordinate frames are then defined and registered with the transformation graph (sunpy.coordinates.transformations). It is also possible to transform SunPy frames to Astropy frames.

Positions within these Frames are stored as a Representation of a coordinate, a representation being a description of a point in a Cartesian, spherical or cylindrical system (see Using and Designing Coordinate Representations). A frame that contains a representation of one or many points is said to have been ‘realized’.

For a more in depth look at the design and concepts of the Astropy coordinates system see Overview of astropy.coordinates Concepts

Frames and SkyCoord

The SkyCoord class is a high level wrapper around the astropy.coordinates sub-package. It provides an easier way to create and transform coordinates, by using string representations for frames rather than the classes themselves and some other usability improvements, for more information see the SkyCoord documentation.

The main advantage provided by SkyCoord is the support it provides for caching Frame attributes. Frame attributes are extra data specified with a frame, some examples in sunpy.coordinates are obstime or observer for observer location. Only the frames where this data is meaningful have these attributes, i.e. only the Helioprojective frames have observer. However, when you transform into another frame and then back to a projective frame using SkyCoord it will remember the attributes previously provided, and repopulate the final frame with them. If you were to do transformations using the Frames alone this would not happen.

The most important implication for this in sunpy.coordinates is the rsun parameter in the projective frames. If you create a projective frame with a rsun attribute, if you convert back to a projective frame it will be set correctly. It should also be noted that, if you create a Heliographic frame and then transform to a projective frame with an rsun attribute, it will not match the radius coordinate in the Heliographic frame. This is because you may mean to be describing a point above the defined ‘surface’ of the Sun.


sunpy.coordinates Package

This subpackage contains:

The diagram below shows all of Sun-based and Earth-based coordinate systems available through sunpy.coordinates, as well as the transformations between them. Each frame is labeled with the name of its class and its alias (useful for converting other coordinates to them using attribute-style access).

The frames colored in cyan are implemented in astropy.coordinates, and there are other astronomical frames that can be transformed to that are not shown below (see astropy.coordinates.builtin_frames).

digraph AstropyCoordinateTransformGraph { node [style=filled fillcolor=lightcyan] graph [rankdir=LR] ICRS [shape=oval label="ICRS\n`icrs`"]; CIRS [shape=oval label="CIRS\n`cirs`"]; GCRS [shape=oval label="GCRS\n`gcrs`"]; HCRS [shape=oval label="HCRS\n`hcrs`"]; HeliocentricMeanEcliptic [shape=oval label="HeliocentricMeanEcliptic\n`heliocentricmeanecliptic`"]; HeliocentricTrueEcliptic [shape=oval label="HeliocentricTrueEcliptic\n`heliocentrictrueecliptic`"]; Astropy [shape=box3d style=filled fillcolor=lightcyan label="Other frames\nin Astropy"]; AltAz [shape=oval label="AltAz\n`altaz`"]; ITRS [shape=oval label="ITRS\n`itrs`"]; PrecessedGeocentric [shape=oval label="PrecessedGeocentric\n`precessedgeocentric`"]; GeocentricMeanEcliptic [shape=oval label="GeocentricMeanEcliptic\n`geocentricmeanecliptic`"]; GeocentricTrueEcliptic [shape=oval label="GeocentricTrueEcliptic\n`geocentrictrueecliptic`"]; HeliographicStonyhurst [fillcolor=white shape=oval label="HeliographicStonyhurst\n`heliographic_stonyhurst`"]; HeliocentricEarthEcliptic [fillcolor=white shape=oval label="HeliocentricEarthEcliptic\n`heliocentricearthecliptic`"]; GeocentricEarthEquatorial [fillcolor=white shape=oval label="GeocentricEarthEquatorial\n`geocentricearthequatorial`"]; HeliographicCarrington [fillcolor=white shape=oval label="HeliographicCarrington\n`heliographic_carrington`"]; Heliocentric [fillcolor=white shape=oval label="Heliocentric\n`heliocentric`"]; HeliocentricInertial [fillcolor=white shape=oval label="HeliocentricInertial\n`heliocentricinertial`"]; Helioprojective [fillcolor=white shape=oval label="Helioprojective\n`helioprojective`"]; GeocentricSolarEcliptic [fillcolor=white shape=oval label="GeocentricSolarEcliptic\n`geocentricsolarecliptic`"]; ICRS -> CIRS[ color = "#d95f02" ]; ICRS -> GCRS[ color = "#d95f02" ]; ICRS -> HCRS[ color = "#555555" ]; ICRS -> HeliocentricMeanEcliptic[ color = "#555555" ]; ICRS -> HeliocentricTrueEcliptic[ color = "#555555" ]; ICRS -> Astropy[ color = "#000000" ]; CIRS -> ICRS[ color = "#d95f02" ]; CIRS -> CIRS[ color = "#d95f02" ]; CIRS -> AltAz[ color = "#d95f02" ]; CIRS -> GCRS[ color = "#d95f02" ]; CIRS -> ITRS[ color = "#d95f02" ]; GCRS -> ICRS[ color = "#d95f02" ]; GCRS -> GCRS[ color = "#d95f02" ]; GCRS -> HCRS[ color = "#d95f02" ]; GCRS -> CIRS[ color = "#d95f02" ]; GCRS -> PrecessedGeocentric[ color = "#d95f02" ]; GCRS -> GeocentricMeanEcliptic[ color = "#d95f02" ]; GCRS -> GeocentricTrueEcliptic[ color = "#d95f02" ]; HCRS -> ICRS[ color = "#555555" ]; HCRS -> HCRS[ color = "#d95f02" ]; HCRS -> HeliographicStonyhurst[ color = "#555555" ]; AltAz -> CIRS[ color = "#d95f02" ]; AltAz -> AltAz[ color = "#d95f02" ]; ITRS -> CIRS[ color = "#d95f02" ]; ITRS -> ITRS[ color = "#d95f02" ]; PrecessedGeocentric -> GCRS[ color = "#d95f02" ]; GeocentricMeanEcliptic -> GCRS[ color = "#d95f02" ]; HeliocentricMeanEcliptic -> ICRS[ color = "#555555" ]; HeliocentricMeanEcliptic -> HeliocentricEarthEcliptic[ color = "#d95f02" ]; HeliocentricMeanEcliptic -> GeocentricEarthEquatorial[ color = "#d95f02" ]; GeocentricTrueEcliptic -> GCRS[ color = "#d95f02" ]; HeliocentricTrueEcliptic -> ICRS[ color = "#555555" ]; HeliographicStonyhurst -> HeliographicCarrington[ color = "#d95f02" ]; HeliographicStonyhurst -> Heliocentric[ color = "#d95f02" ]; HeliographicStonyhurst -> HCRS[ color = "#555555" ]; HeliographicStonyhurst -> HeliographicStonyhurst[ color = "#d95f02" ]; HeliographicStonyhurst -> HeliocentricInertial[ color = "#d95f02" ]; HeliographicCarrington -> HeliographicStonyhurst[ color = "#d95f02" ]; HeliographicCarrington -> HeliographicCarrington[ color = "#d95f02" ]; Heliocentric -> Helioprojective[ color = "#d95f02" ]; Heliocentric -> HeliographicStonyhurst[ color = "#d95f02" ]; Heliocentric -> Heliocentric[ color = "#d95f02" ]; Helioprojective -> Heliocentric[ color = "#d95f02" ]; Helioprojective -> Helioprojective[ color = "#d95f02" ]; HeliocentricEarthEcliptic -> HeliocentricMeanEcliptic[ color = "#d95f02" ]; HeliocentricEarthEcliptic -> HeliocentricEarthEcliptic[ color = "#d95f02" ]; HeliocentricEarthEcliptic -> GeocentricSolarEcliptic[ color = "#d95f02" ]; GeocentricSolarEcliptic -> HeliocentricEarthEcliptic[ color = "#d95f02" ]; GeocentricSolarEcliptic -> GeocentricSolarEcliptic[ color = "#d95f02" ]; HeliocentricInertial -> HeliographicStonyhurst[ color = "#d95f02" ]; HeliocentricInertial -> HeliocentricInertial[ color = "#d95f02" ]; GeocentricEarthEquatorial -> HeliocentricMeanEcliptic[ color = "#d95f02" ]; GeocentricEarthEquatorial -> GeocentricEarthEquatorial[ color = "#d95f02" ]; Astropy -> ICRS[ color = "#000000" ]; overlap=false rankdir=LR {rank=same; ICRS; HCRS; Astropy} }

  • SunPy frames:

  • Astropy frames:

  • AffineTransform:

  • FunctionTransform:

  • FunctionTransformWithFiniteDifference:

  • StaticMatrixTransform:

  • DynamicMatrixTransform:


get_body_heliographic_stonyhurst(body[, …])

Return a HeliographicStonyhurst frame for the location of a solar-system body at a specified time.


Return a SkyCoord for the location of the Earth at a specified time in the HeliographicStonyhurst frame.

get_horizons_coord(body[, time, id_type])

Queries JPL HORIZONS and returns a SkyCoord for the location of a solar-system body at a specified time.

solar_frame_to_wcs_mapping(frame[, projection])

For a given frame, this function returns the corresponding WCS object.


This function registers the coordinates frames to their FITS-WCS coordinate type values in the astropy.wcs.utils.wcs_to_celestial_frame registry.


Context manager for coordinate transformations to ignore the motion of the center of the Sun.


GeocentricEarthEquatorial(*args, **kwargs)

A coordinate or frame in the Geocentric Earth Equatorial (GEI) system.

GeocentricSolarEcliptic(*args, **kwargs)

A coordinate or frame in the Geocentric Solar Ecliptic (GSE) system.

Heliocentric(*args, **kwargs)

A coordinate or frame in the Heliocentric system, which is observer-based.

HeliocentricEarthEcliptic(*args, **kwargs)

A coordinate or frame in the Heliocentric Earth Ecliptic (HEE) system.

HeliocentricInertial(*args, **kwargs)

A coordinate or frame in the Heliocentric Inertial (HCI) system.

HeliographicCarrington(*args, **kwargs)

A coordinate or frame in the Carrington Heliographic (HGC) system.

HeliographicStonyhurst(*args, **kwargs)

A coordinate or frame in the Stonyhurst Heliographic (HGS) system.

Helioprojective(*args, **kwargs)

A coordinate or frame in the Helioprojective Cartesian (HPC) system, which is observer-based.


A frame which is offset from another frame such that it shares the same origin, but has its “north pole” (i.e., the Z axis) in a different direction.

RotatedSunFrame(*args, **kwargs)

A frame that applies solar rotation to a base coordinate frame.

Class Inheritance Diagram

Inheritance diagram of sunpy.coordinates.frames.GeocentricEarthEquatorial, sunpy.coordinates.frames.GeocentricSolarEcliptic, sunpy.coordinates.frames.Heliocentric, sunpy.coordinates.frames.HeliocentricEarthEcliptic, sunpy.coordinates.frames.HeliocentricInertial, sunpy.coordinates.frames.HeliographicCarrington, sunpy.coordinates.frames.HeliographicStonyhurst, sunpy.coordinates.frames.Helioprojective, sunpy.coordinates.metaframes.NorthOffsetFrame, sunpy.coordinates.metaframes.RotatedSunFrame

sunpy.coordinates.ephemeris Module

Ephemeris calculations using SunPy coordinate frames


get_body_heliographic_stonyhurst(body[, …])

Return a HeliographicStonyhurst frame for the location of a solar-system body at a specified time.


Return a SkyCoord for the location of the Earth at a specified time in the HeliographicStonyhurst frame.

get_horizons_coord(body[, time, id_type])

Queries JPL HORIZONS and returns a SkyCoord for the location of a solar-system body at a specified time.

sunpy.coordinates.sun Module

Sun-specific coordinate calculations



Return the angular radius of the Sun as viewed from Earth.

sky_position([t, equinox_of_date])

Returns the apparent position of the Sun (right ascension and declination) on the celestial sphere using the equatorial coordinate system, referred to the true equinox of date (as default).


Return the Carrington rotation number.


Return the time of a given Carrington rotation.


Returns the Sun’s true geometric longitude, referred to the mean equinox of date.


Returns the Sun’s apparent longitude, referred to the true equinox of date.


Returns the Sun’s true geometric latitude, referred to the mean equinox of date.


Returns the Sun’s apparent latitude, referred to the true equinox of date.


Returns the mean obliquity of the ecliptic, using the IAU 2006 definition.

true_rightascension([t, equinox_of_date])

Returns the Sun’s true geometric right ascension relative to Earth, referred to the mean equinox of date (as default).

true_declination([t, equinox_of_date])

Returns the Sun’s true geometric declination relative to Earth, referred to the mean equinox of date (as default).


Returns the true obliquity of the ecliptic, using the IAU 2006 definition.

apparent_rightascension([t, equinox_of_date])

Returns the Sun’s apparent right ascension relative to Earth, referred to the true equinox of date (as default).

apparent_declination([t, equinox_of_date])

Returns the Sun’s apparent declination relative to Earth, referred to the true equinox of date (as default).


Print out a summary of solar ephemeris.


Return the B0 angle for the Sun at a specified time, which is the heliographic latitude of the of the center of the disk of the Sun as seen from Earth.

L0([time, light_travel_time_correction, …])

Return the L0 angle for the Sun at a specified time, which is the apparent Carrington longitude of the Sun-disk center as seen from Earth.


Return the position (P) angle for the Sun at a specified time, which is the angle between geocentric north and solar north as seen from Earth, measured eastward from geocentric north.


Return the distance between the Sun and the Earth at a specified time.

orientation(location[, time])

Return the orientation angle for the Sun from a specified Earth location and time.

sunpy.coordinates.utils Module

Miscellaneous utilities related to coordinates


get_rectangle_coordinates(bottom_left, *[, …])

Specify a rectangular region of interest in longitude and latitude in a given coordinate frame.


GreatArc(start, end[, center, points])

Calculate the properties of a great arc at user-specified points between a start and end point on a sphere.


Some of this documentation was adapted from Astropy under the terms of the BSD License.

This sub-package was initially developed by Pritish Chakraborty as part of GSOC 2014 and Stuart Mumford.