I will show you how to make a three-color composite diagram, which is often used in astronomical, using python.
Astronomy manages images in a file format called FITS. You can also download it at SkyView Virtual Observatory. You can also download it from a web browser, but this time I will try to download it automatically using python.
download.py
from astroquery.skyview import SkyView
import astropy.units
target = 'M17'
surveys = ['2MASS-J', '2MASS-H', '2MASS-K']
radius = 0.3 * astropy.units.deg
pixels = 1000
hdu = SkyView.get_images(target, surveys, radius=radius, pixels=pixels)
hdu[0].writeto('M17-2MASS-J.fits', clobber=True)
hdu[1].writeto('M17-2MASS-H.fits', clobber=True)
hdu[2].writeto('M17-2MASS-K.fits', clobber=True)
M17 is Omega It is a diffused nebula known as a nebula, which is a region where NGC6618 clusters containing many massive stars ionize the surrounding molecular gas. It is a fairly active massive star-forming region in the Milky Way galaxy.
2MASS is a near-infrared all-sky survey observation project. Data for the J band (1.2 μm), H band (1.7 μm), and Ks band (2.2 μm) are available.
Create a three-color composite diagram using the three downloaded data. As a procedure,
plot.py
import numpy
import PIL.Image
import astropy.io.fits
r = astropy.io.fits.open('M17-2MASS-K.fits')[0].data[::-1,:]
g = astropy.io.fits.open('M17-2MASS-H.fits')[0].data[::-1,:]
b = astropy.io.fits.open('M17-2MASS-J.fits')[0].data[::-1,:]
pix_y, pix_x = r.shape
def scale(data, scale_min=None, scale_max=None, stretch='linear'):
if stretch == 'linear':
scale_func = scale_linear
elif stretch == 'log':
scale_func = scale_log
else:
scale_func = scale_linear
pass
if scale_min is None:
scale_min = numpy.nanmin(data)
pass
if scale_max is None:
scale_max = numpy.nanmax(data)
pass
scaled = scale_func(data, scale_min, scale_max)
scaled = numpy.uint8(scaled * 255)
return scaled
def scale_linear(data, scale_min, scale_max):
print('%f, %f'%(scale_min, scale_max))
scaled = (data - scale_min) / (scale_max - scale_min)
scaled[numpy.where(scaled<0)] = 0
scaled[numpy.where(scaled>=1)] = 1
return scaled
def scale_log(data, scale_min, scale_max):
print('%e, %e'%(scale_min, scale_max))
scaled = scale_linear(data, scale_min, scale_max)
scaled = numpy.log10((scaled * 9) + 1)
return scaled
img = numpy.zeros([pix_y, pix_x, 3], dtype=numpy.uint8)
img[:,:,0] = scale(r, 630, 840, 'log')
img[:,:,1] = scale(g, 595, 730, 'log')
img[:,:,2] = scale(b, 150, 190, 'log')
PIL.Image.fromarray(img).save('rgbimage-M17-2MASS.png')
An image like this will appear.
Specify the range, check the image, specify the range, and so on to find a good color scheme. It's hard to repeat a lot, so I made a tool that can be operated with GUI.
--Download and save rgbimage.py
--Run: python rgbimage.py
--Load the file, specify the range and save
When you run it, you will see a window like this.
--Click "Open" and a dialog will open where you can select the FITS file --Option menu labeled "linear": Select stretch from'linear','log','sqrt' -"min text box": Lower limit of range specification bar -"max text box": Upper limit of range specification bar -"min slide bar": Specifies the minimum color range -"max slide bar": Specifies the maximum color range
It looks like this when various settings are made.
Finally, click "Save as" to save the image.
Try plotting with matplotlib using astropy.wcs.
plot_with_coordinate.py
import astropy.io.fits
import astropy.wcs
import astropy.units
import matplotlib.pyplot
import PIL.Image
matplotlib.rcParams['font.family'] = 'arial'
hdu = astropy.io.fits.open('M17-2MASS-K.fits')[0]
wcs = astropy.wcs.WCS(hdu.header)
img = PIL.Image.open('rgbimage-M17-2MASS.png')
fig = matplotlib.pyplot.figure()
ax = fig.add_subplot(111, projection=wcs)
ax.imshow(img)
ax.grid(color='w', linestyle='-')
ax.coords[0].set_major_formatter('hh:mm:ss')
ax.coords[1].set_major_formatter('dd:mm')
ax.set_xlabel('R.A. (J2000)')
ax.set_ylabel('Dec. (J2000)')
ax2 = ax.get_coords_overlay('galactic')
ax2[0].set_ticks(spacing=0.05*astropy.units.deg)
ax2[1].set_ticks(spacing=0.05*astropy.units.deg)
ax2[0].set_major_formatter('d.dd')
ax2[1].set_major_formatter('d.dd')
ax2[0].set_axislabel('Galactic Longitude')
ax2[1].set_axislabel('Galactic Latitude')
ax2.grid(color='y', linestyle='-')
fig.savefig('rgbimage-M17-2MASS-withcoord.png')
An image like this appears.