Transforming from Galactic to Cartesian and ICRS to Cartesian Yielding Different Results

Hi Astropy community,

I’ve been working with a few astronomical catalogs on a project that involves 3D visualization. I want to get the XYZ coordinates of stars and I’m typically working with either or both ICRS and/or Galactic coordinates.

To transform from the ICRS or Galactic frame to Cartesian, I create a Skycoord object and feed it arrays of data as shown in the code below. ‘data’ is a Pandas DataFrame which contains the data in my catalog.

import astropy.coordinates

#transform from ICRS to Cartesian XYZ
icrs_coords = astropy.coordinates.SkyCoord(

data['x'] = icrs_coords.cartesian.x.value
data['y'] = icrs_coords.cartesian.y.value
data['z'] = icrs_coords.cartesian.z.value

#Transform from Galactic to Cartesian XYZ
galactic_coords = astropy.coordinates.SkyCoord(

data['gx'] = galactic_coords.cartesian.x.value
data['gy'] = galactic_coords.cartesian.y.value
data['gz'] = galactic_coords.cartesian.z.value

I expect this to work the same way if I want to go from ICRS to Cartesian or from Galactic to Cartesian, but I notice a distinct difference if I try both ways. Most commonly, I notice that the ICRS to Cartesian transform is rotated about 120 degrees counter-clockwise if i look in the XZ plane. Sometimes, the plots simply look remarkably different. I’ve included two plots generated from my catalogs to demonstrate this. Based on intuition of what the catalogs’ distributions should look like, it looks as if the Galactic to Cartesian transform is working correctly, but the ICRS to Cartesian transform is not. Does anyone know if I’m doing anything wrong or why this is?

Extra context: I’ve done some digging and confirmed that when I transform from ICRS to galactic or vice versa, the resulting coordinates are always approximately equal to those native in the catalog. The galactic coordinates I obtain from a Skycoord object which was given the ICRS coordinates are the same as the galactic coordinates in the catalog, and vice versa. Despite this, the Skycoord object seems to spit out different Cartesian coordinates depending on if it is given RA/Dec versus GLon and GLat.

Hmm, it sounds like you are confused about the difference between coordinate frames and coordinate representations. ICRS and Galactic are examples of coordinate frames, while Cartesian and spherical are examples of coordinate representations. Asking for the Cartesian version of an ICRS coordinate does not modify the coordinate frame, but only what components are used to represent the position of the coordinate.

ICRS defaults to the spherical representation of RA/dec. When you ask for the Cartesian representation of an ICRS coordinate, you are not transforming it to a different coordinate frame. You are simply converting between spherical components and Cartesian components for the same point. For example, the Cartesian X axis for ICRS is aligned with RA=0 and dec=0.

Along the same lines, Galactic defaults to the spherical representation of l/b. The Cartesian X axis for Galactic is aligned with l=0 and b=0.

The Cartesian axes of ICRS and Galactic are not aligned with each other since ICRS has a different orientation than Galactic. Correspondingly, the Cartesian representation of an ICRS coordinate will be different from the Cartesian representation of the same coordinate transformed to Galactic.

In other words, the meaning of the Cartesian X/Y/Z components depends on the coordinate frame.

Does that make sense?

Thank you, that totally clears it up!