Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make a 2D histogram with HEALPix pixellization using healpy

The data are coordinates of objects in the sky, for example as follows:

import pylab as plt
import numpy as np
l = np.random.uniform(-180, 180, 2000)
b = np.random.uniform(-90, 90, 2000)

I want to do a 2D histogram in order to plot a map of the density of some point with (l, b) coordinates in the sky, using HEALPix pixellization on Mollweide projection. How can I do this using healpy ?

The tutorial:

http://healpy.readthedocs.io/en/v1.9.0/tutorial.html

says how to plot a 1D array, or a fits file, but I don't find how to do a 2d histogram using this pixellization.

I also found this function, but it is not working , so I am stuck.

hp.projaxes.MollweideAxes.hist2d(l, b, bins=10)

I can do a plot of these points in Mollweide projection this way :

l_axis_name ='Latitude l (deg)'
b_axis_name = 'Longitude b (deg)'

fig = plt.figure(figsize=(12,9))
ax = fig.add_subplot(111, projection="mollweide")
ax.grid(True)

ax.scatter(np.array(l)*np.pi/180., np.array(b)*np.pi/180.)

plt.show()

Thank you very much in advance for your help.

like image 358
AlbertBranson Avatar asked May 23 '18 08:05

AlbertBranson


1 Answers

Great question! I've written a short function to convert a catalogue into a HEALPix map of number counts:

from astropy.coordinates import SkyCoord
import healpy as hp
import numpy as np

def cat2hpx(lon, lat, nside, radec=True):
    """
    Convert a catalogue to a HEALPix map of number counts per resolution
    element.

    Parameters
    ----------
    lon, lat : (ndarray, ndarray)
        Coordinates of the sources in degree. If radec=True, assume input is in the icrs
        coordinate system. Otherwise assume input is glon, glat

    nside : int
        HEALPix nside of the target map

    radec : bool
        Switch between R.A./Dec and glon/glat as input coordinate system.

    Return
    ------
    hpx_map : ndarray
        HEALPix map of the catalogue number counts in Galactic coordinates

    """

    npix = hp.nside2npix(nside)

    if radec:
        eq = SkyCoord(lon, lat, 'icrs', unit='deg')
        l, b = eq.galactic.l.value, eq.galactic.b.value
    else:
        l, b = lon, lat

    # conver to theta, phi
    theta = np.radians(90. - b)
    phi = np.radians(l)

    # convert to HEALPix indices
    indices = hp.ang2pix(nside, theta, phi)

    idx, counts = np.unique(indices, return_counts=True)

    # fill the fullsky map
    hpx_map = np.zeros(npix, dtype=int)
    hpx_map[idx] = counts

    return hpx_map

You can then use that to populate the HEALPix map:

l = np.random.uniform(-180, 180, 20000)
b = np.random.uniform(-90, 90, 20000)

hpx_map = hpx.cat2hpx(l, b, nside=32, radec=False)

Here, the nside determines how fine or coarse your pixel grid is.

hp.mollview(np.log10(hpx_map+1))

enter image description here

Also note that by sampling uniformly in Galactic latitude, you'll prefer data points at the Galactic poles. If you want to avoid that, you can scale that down with a cosine.

hp.orthview(np.log10(hpx_map+1), rot=[0, 90])
hp.graticule(color='white')

enter image description here

like image 54
Daniel Lenz Avatar answered Sep 20 '22 17:09

Daniel Lenz