Putting matplotlib hexbin into an Aitoff projection

Viewed 3827

I have the nice hexbin plot below, but I'm wondering if there is any way to get hexbin into an Aitoff projection? The salient code is:

import numpy as np
import math
import matplotlib.pyplot as plt
from astropy.io import ascii

filename = 'WISE_W4SNRge3_and_W4MPRO_lt_6.0_RADecl_nohdr.dat'
datafile= path+filename
data = ascii.read(datafile)  
points = np.array([data['ra'], data['dec']])

color_map = plt.cm.Spectral_r 
points = np.array([data['ra'], data['dec']]) 
xbnds = np.array([ 0.0,360.0]) 
ybnds = np.array([-90.0,90.0]) 
extent = [xbnds[0],xbnds[1],ybnds[0],ybnds[1]] 

fig = plt.figure(figsize=(6, 4)) 
ax = fig.add_subplot(111) 
x, y = points 
gsize = 45 
image = plt.hexbin(x,y,cmap=color_map, 
    gridsize=gsize,extent=extent,mincnt=1,bins='log') 

counts = image.get_array() 
ncnts = np.count_nonzero(np.power(10,counts)) 
verts = image.get_offsets() 

ax.set_xlim(xbnds) 
ax.set_ylim(ybnds) 
plt.xlabel('R.A.')  
plt.ylabel(r'Decl.') 
plt.grid(True) 
cb = plt.colorbar(image, spacing='uniform', extend='max') 
plt.show()

and I've tried:

plt.subplot(111, projection="aitoff")

before doing the plt.hexbin command, but which only gives a nice, but blank, Aitoff grid.

enter image description here

2 Answers

The problem is that the Aitoff projection uses radians, from -π to +π. Not degrees from 0 to 360. I use the Angle.wrap_at function to achieve this, as per this Astropy example (which essentially tells you how to create a proper Aitoff projection plot).

In addition, you can't change the axis limits (that'll lead to an error), and shouldn't use extent (as ImportanceOfBeingErnest's answer also states).

You can change your code as follows to get what you want:

import numpy as np
import matplotlib.pyplot as plt
from astropy.io import ascii
from astropy.coordinates import SkyCoord
from astropy import units

filename = 'WISE_W4SNRge3_and_W4MPRO_lt_6.0_RADecl_nohdr.dat'
data = ascii.read(filename)
coords = SkyCoord(ra=data['ra'], dec=data['dec'], unit='degree')
ra = coords.ra.wrap_at(180 * units.deg).radian
dec = coords.dec.radian

color_map = plt.cm.Spectral_r
fig = plt.figure(figsize=(6, 4))
fig.add_subplot(111, projection='aitoff')
image = plt.hexbin(ra, dec, cmap=color_map,
                   gridsize=45, mincnt=1, bins='log')

plt.xlabel('R.A.')
plt.ylabel('Decl.')
plt.grid(True)
plt.colorbar(image, spacing='uniform', extend='max')
plt.show()

Which gives enter image description here

I guess your problem lies in the use of the extent which is set to something other than the range of the spherical coordinate system.

The following works fine:

import matplotlib.pyplot as plt
import numpy as np

ra = np.linspace(-np.pi/2.,np.pi/2.,1000)
dec = np.sin(ra)*np.pi/2./2.
points = np.array([ra, dec]) 

plt.subplot(111, projection="aitoff")

color_map = plt.cm.Spectral_r 
x, y = points 
gsize = 45 
image = plt.hexbin(x,y,cmap=color_map, 
                   gridsize=45,mincnt=1,bins='log') 

plt.xlabel('R.A.')  
plt.ylabel(r'Decl.') 
plt.grid(True) 
cb = plt.colorbar(image, spacing='uniform', extend='max') 
plt.show()

enter image description here

Related