Python is the useful high-level computational language for science, machine learing, IoT and web design. The language is quite simliar with the MATLAB but the license is free and no need to access LAN. There are many user communities.
From this second tutorial we learn the basic command line for the data handling and graphics.
This tutorial is uploaded on the 'Tutorials' menu at https://jhkang.netlify.com
The basic resource of python for scientist is available in Scipy Lecture Notes.
To call an array in python, we should import the numpy
import numpy as np
a = np.array([1,2,3,4,5])
a
array([1, 2, 3, 4, 5])
a.shape
(5,)
a.ndim
1
a.dtype
dtype('int32')
a = a.astype(float)
a.dtype
dtype('float64')
a = np.array([1,2,3,4,5],dtype=float)
Slicing
a[3]
4.0
a[-1]
5.0
a[0:2]
array([1., 2.])
a[2:5]
array([3., 4., 5.])
a[:]
array([1., 2., 3., 4., 5.])
a[0:5:2]
array([1., 3., 5.])
a[-1:0:-1]
array([5., 4., 3., 2.])
a[::-1]
array([5., 4., 3., 2., 1.])
Convert this row array to the column array
col = a[:,None]
col
array([[1.], [2.], [3.], [4.], [5.]])
col.shape
(5, 1)
newarr = a[None,:,None]
newarr
array([[[1.], [2.], [3.], [4.], [5.]]])
newarr.shape
(1, 5, 1)
Array appending
a = np.append(a,[6,7])
a
array([1., 2., 3., 4., 5., 6., 7.])
b = np.concatenate([a, a])
b
array([1., 2., 3., 4., 5., 6., 7., 1., 2., 3., 4., 5., 6., 7.])
Note) np.array(1) and np.array([1]) are different
a1 = np.array(1)
a2 = np.array([1])
a1
array(1)
a2
array([1])
a1[0]
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-31-24bd6a1fc18f> in <module>() ----> 1 a1[0] IndexError: too many indices for array
a2[0]
1
a1 = a1.flatten()
a1
array([1])
a1[0]
1
Make 2D array.
arr2d = np.array([[1,2,3],[4,5,6]], dtype=float)
arr2d
array([[1., 2., 3.], [4., 5., 6.]])
arr2d[0]
array([1., 2., 3.])
arr2d[0,0]
1.0
arr2d[0][0]
1.0
From the np.arange or np.linspace, we can generate the evenly spaced array automatically.
np.arange([start,]stop,[step,]dtype=None)
Return evenly spaced values within a given interval.
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0)
Return evenly spaced numbers over a specified interval.
arange
ara = np.arange(6)
ara
array([0, 1, 2, 3, 4, 5])
ara2 = np.arange(2,6,0.5)
ara2
array([2. , 2.5, 3. , 3.5, 4. , 4.5, 5. , 5.5])
linspace
alin = np.linspace(0,6,5)
alin
array([0. , 1.5, 3. , 4.5, 6. ])
The high adventage for array handling in python is broadcasting.
Basic operations on numpy arrays (addition, etc.) are elementwise This works on arrays of the same size. Nevertheless, It’s also possible to do operations on arrays of different sizes if NumPy can transform these arrays so that they all have the same size: this conversion is called broadcasting.
a = np.linspace(1,9,9)
b = np.arange(45).reshape(5,9)
a
array([1., 2., 3., 4., 5., 6., 7., 8., 9.])
b
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8], [ 9, 10, 11, 12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23, 24, 25, 26], [27, 28, 29, 30, 31, 32, 33, 34, 35], [36, 37, 38, 39, 40, 41, 42, 43, 44]])
a+b
array([[ 1., 3., 5., 7., 9., 11., 13., 15., 17.], [10., 12., 14., 16., 18., 20., 22., 24., 26.], [19., 21., 23., 25., 27., 29., 31., 33., 35.], [28., 30., 32., 34., 36., 38., 40., 42., 44.], [37., 39., 41., 43., 45., 47., 49., 51., 53.]])
acol = a[:,None]
acol.shape
(9, 1)
a*acol
array([[ 1., 2., 3., 4., 5., 6., 7., 8., 9.], [ 2., 4., 6., 8., 10., 12., 14., 16., 18.], [ 3., 6., 9., 12., 15., 18., 21., 24., 27.], [ 4., 8., 12., 16., 20., 24., 28., 32., 36.], [ 5., 10., 15., 20., 25., 30., 35., 40., 45.], [ 6., 12., 18., 24., 30., 36., 42., 48., 54.], [ 7., 14., 21., 28., 35., 42., 49., 56., 63.], [ 8., 16., 24., 32., 40., 48., 56., 64., 72.], [ 9., 18., 27., 36., 45., 54., 63., 72., 81.]])
one=np.ones([9,1])
one
array([[1.], [1.], [1.], [1.], [1.], [1.], [1.], [1.], [1.]])
a*one
array([[1., 2., 3., 4., 5., 6., 7., 8., 9.], [1., 2., 3., 4., 5., 6., 7., 8., 9.], [1., 2., 3., 4., 5., 6., 7., 8., 9.], [1., 2., 3., 4., 5., 6., 7., 8., 9.], [1., 2., 3., 4., 5., 6., 7., 8., 9.], [1., 2., 3., 4., 5., 6., 7., 8., 9.], [1., 2., 3., 4., 5., 6., 7., 8., 9.], [1., 2., 3., 4., 5., 6., 7., 8., 9.], [1., 2., 3., 4., 5., 6., 7., 8., 9.]])
x = np.arange(5)
x
array([0, 1, 2, 3, 4])
x.sum()
10
x.mean()
2.0
Sum by rows and by columns:
x2 = np.arange(30).reshape(5,6)
x2
array([[ 0, 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10, 11], [12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23], [24, 25, 26, 27, 28, 29]])
x2.shape
(5, 6)
x2.sum(0) # colums (first dimension)
array([60, 65, 70, 75, 80, 85])
x2.sum(1) # rows (second dimension)
array([ 15, 51, 87, 123, 159])
From this session, we learn how to visulize the arrays by using matplotlib package.
At first, enable interactive plots:
matplotlib
Using matplotlib backend: Qt5Agg
Let's import the 2D plotting package, matplotlib.
import matplotlib.pyplot as plt
x = np.arange(10)
y = x**2
plt.plot(x,y)
[<matplotlib.lines.Line2D at 0x2f2bf4c7b8>]
plt.plot(x,y,'o',color='black')
[<matplotlib.lines.Line2D at 0x2f2c0f4748>]
x2 = x * x[:,None]
x2
array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18], [ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27], [ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36], [ 0, 5, 10, 15, 20, 25, 30, 35, 40, 45], [ 0, 6, 12, 18, 24, 30, 36, 42, 48, 54], [ 0, 7, 14, 21, 28, 35, 42, 49, 56, 63], [ 0, 8, 16, 24, 32, 40, 48, 56, 64, 72], [ 0, 9, 18, 27, 36, 45, 54, 63, 72, 81]])
plt.imshow(x2)
<matplotlib.image.AxesImage at 0x2f2c1269e8>
plt.colorbar()
<matplotlib.colorbar.Colorbar at 0x2f2cf78e10>
im = plt.imshow(x2,origin='lower', cmap=plt.cm.jet)
plt.colorbar(im)
<matplotlib.colorbar.Colorbar at 0x2f2d027c18>
im.set_cmap(plt.cm.gray)
im.set_interpolation('bilinear')
Plot 2D data on 3D plot
At first we import 3D axes
from mpl_toolkits.mplot3d import Axes3D
x = np.linspace(-4,4,40)
xx, yy = np.meshgrid(x,x)
R = np.sqrt(xx**2 +yy**2)
zz = np.sin(R)
data = zz
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_aspect('equal')
ax.plot_surface(xx,yy,data,cmap=plt.cm.plasma)
<mpl_toolkits.mplot3d.art3d.Poly3DCollection at 0x2f2c4067f0>
plane = np.ones((data.shape))
ax.plot_surface(xx,yy,plane*-2,facecolors=plt.cm.plasma(data/data.max()),shade=False)
<mpl_toolkits.mplot3d.art3d.Poly3DCollection at 0x2f2ccc17b8>
fig.tight_layout()
from mpl_toolkits.axes_grid1 import ImageGrid
fig = plt.figure()
grid = ImageGrid(fig, 111, nrows_ncols=(2, 5),
axes_pad=0, share_all=True,
label_mode='1')
img = np.arange(10) * np.ones((10,10))
# grid[i].imshow(images)
for i in grid:
i.imshow(img,origin='lower')
AstroPy is the useful python package for astronomers. From this we learn how to read the fits file and its header.
Download the sample fits file.
from astropy.io import fits
Read fits
data = fits.getdata('C:/Users/User/Downloads/HorseHead.fits')
data.shape
(893, 891)
plt.imshow(data,origin='lower')
<matplotlib.image.AxesImage at 0x2f30a14d68>
plt.imshow(data.T,origin='lower')
<matplotlib.image.AxesImage at 0x2f30c99240>
plt.imshow(data.T[:,::-1],origin='lower')
<matplotlib.image.AxesImage at 0x2f30cf2c88>
Read header
h = fits.getheader('C:/Users/User/Downloads/HorseHead.fits')
h
SIMPLE = T /FITS: Compliance BITPIX = 16 /FITS: I*2 Data NAXIS = 2 /FITS: 2-D Image Data NAXIS1 = 891 /FITS: X Dimension NAXIS2 = 893 /FITS: Y Dimension EXTEND = T /FITS: File can contain extensions DATE = '2014-01-09 ' /FITS: Creation Date ORIGIN = 'STScI/MAST' /GSSS: STScI Digitized Sky Survey SURVEY = 'SERC-ER ' /GSSS: Sky Survey REGION = 'ER768 ' /GSSS: Region Name PLATEID = 'A0JP ' /GSSS: Plate ID SCANNUM = '01 ' /GSSS: Scan Number DSCNDNUM= '00 ' /GSSS: Descendant Number TELESCID= 4 /GSSS: Telescope ID BANDPASS= 36 /GSSS: Bandpass Code COPYRGHT= 'AAO/ROE ' /GSSS: Copyright Holder SITELAT = -31.277 /Observatory: Latitude SITELONG= 210.934 /Observatory: Longitude TELESCOP= 'UK Schmidt - Doubl' /Observatory: Telescope INSTRUME= 'Photographic Plate' /Detector: Photographic Plate EMULSION= 'IIIaF ' /Detector: Emulsion FILTER = 'OG590 ' /Detector: Filter PLTSCALE= 67.20 /Detector: Plate Scale arcsec per mm PLTSIZEX= 355.000 /Detector: Plate X Dimension mm PLTSIZEY= 355.000 /Detector: Plate Y Dimension mm PLATERA = 85.5994550000 /Observation: Field centre RA degrees PLATEDEC= -4.94660910000 /Observation: Field centre Dec degrees PLTLABEL= 'OR14052 ' /Observation: Plate Label DATE-OBS= '1990-12-22T13:49:00' /Observation: Date/Time EXPOSURE= 65.0 /Observation: Exposure Minutes PLTGRADE= 'AD2 ' /Observation: Plate Grade OBSHA = 0.158333 /Observation: Hour Angle OBSZD = 26.3715 /Observation: Zenith Distance AIRMASS = 1.11587 /Observation: Airmass REFBETA = 66.3196420000 /Observation: Refraction Coeff REFBETAP= -0.0820000000000 /Observation: Refraction Coeff REFK1 = 6423.52290000 /Observation: Refraction Coeff REFK2 = -102122.550000 /Observation: Refraction Coeff CNPIX1 = 12237 /Scan: X Corner CNPIX2 = 19965 /Scan: Y Corner XPIXELS = 23040 /Scan: X Dimension YPIXELS = 23040 /Scan: Y Dimension XPIXELSZ= 15.0295 /Scan: Pixel Size microns YPIXELSZ= 15.0000 /Scan: Pixel Size microns PPO1 = -3069417.00000 /Scan: Orientation Coeff PPO2 = 0.000000000000 /Scan: Orientation Coeff PPO3 = 177500.000000 /Scan: Orientation Coeff PPO4 = 0.000000000000 /Scan: Orientation Coeff PPO5 = 3069417.00000 /Scan: Orientation Coeff PPO6 = 177500.000000 /Scan: Orientation Coeff PLTRAH = 5 /Astrometry: Plate Centre H PLTRAM = 42 /Astrometry: Plate Centre M PLTRAS = 23.86 /Astrometry: Plate Centre S PLTDECSN= '- ' /Astrometry: Plate Centre +/- PLTDECD = 4 /Astrometry: Plate Centre D PLTDECM = 56 /Astrometry: Plate Centre M PLTDECS = 47.9 /Astrometry: Plate Centre S EQUINOX = 2000.0 /Astrometry: Equinox AMDX1 = 67.1550859799 /Astrometry: GSC1 Coeff AMDX2 = 0.0431478884485 /Astrometry: GSC1 Coeff AMDX3 = -292.435619180 /Astrometry: GSC1 Coeff AMDX4 = -2.68934864702E-005 /Astrometry: GSC1 Coeff AMDX5 = 1.99133423290E-005 /Astrometry: GSC1 Coeff AMDX6 = -2.37011931379E-006 /Astrometry: GSC1 Coeff AMDX7 = 0.000000000000 /Astrometry: GSC1 Coeff AMDX8 = 2.21426387429E-006 /Astrometry: GSC1 Coeff AMDX9 = -8.12841581455E-008 /Astrometry: GSC1 Coeff AMDX10 = 2.48169090021E-006 /Astrometry: GSC1 Coeff AMDX11 = 2.77618933926E-008 /Astrometry: GSC1 Coeff AMDX12 = 0.000000000000 /Astrometry: GSC1 Coeff AMDX13 = 0.000000000000 /Astrometry: GSC1 Coeff AMDX14 = 0.000000000000 /Astrometry: GSC1 Coeff AMDX15 = 0.000000000000 /Astrometry: GSC1 Coeff AMDX16 = 0.000000000000 /Astrometry: GSC1 Coeff AMDX17 = 0.000000000000 /Astrometry: GSC1 Coeff AMDX18 = 0.000000000000 /Astrometry: GSC1 Coeff AMDX19 = 0.000000000000 /Astrometry: GSC1 Coeff AMDX20 = 0.000000000000 /Astrometry: GSC1 Coeff AMDY1 = 67.1593591466 /Astrometry: GSC1 Coeff AMDY2 = -0.0471363749174 /Astrometry: GSC1 Coeff AMDY3 = 316.004963520 /Astrometry: GSC1 Coeff AMDY4 = 2.86798151430E-005 /Astrometry: GSC1 Coeff AMDY5 = -2.00968236347E-005 /Astrometry: GSC1 Coeff AMDY6 = 2.27840393227E-005 /Astrometry: GSC1 Coeff AMDY7 = 0.000000000000 /Astrometry: GSC1 Coeff AMDY8 = 2.23885090381E-006 /Astrometry: GSC1 Coeff AMDY9 = -2.28360163464E-008 /Astrometry: GSC1 Coeff AMDY10 = 2.44828851495E-006 /Astrometry: GSC1 Coeff AMDY11 = -5.76717487998E-008 /Astrometry: GSC1 Coeff AMDY12 = 0.000000000000 /Astrometry: GSC1 Coeff AMDY13 = 0.000000000000 /Astrometry: GSC1 Coeff AMDY14 = 0.000000000000 /Astrometry: GSC1 Coeff AMDY15 = 0.000000000000 /Astrometry: GSC1 Coeff AMDY16 = 0.000000000000 /Astrometry: GSC1 Coeff AMDY17 = 0.000000000000 /Astrometry: GSC1 Coeff AMDY18 = 0.000000000000 /Astrometry: GSC1 Coeff AMDY19 = 0.000000000000 /Astrometry: GSC1 Coeff AMDY20 = 0.000000000000 /Astrometry: GSC1 Coeff AMDREX1 = 67.1532034737 /Astrometry: GSC2 Coeff AMDREX2 = 0.0434354199559 /Astrometry: GSC2 Coeff AMDREX3 = -292.435438892 /Astrometry: GSC2 Coeff AMDREX4 = 4.60919247070E-006 /Astrometry: GSC2 Coeff AMDREX5 = -3.21138058537E-006 /Astrometry: GSC2 Coeff AMDREX6 = 7.23651736725E-006 /Astrometry: GSC2 Coeff AMDREX7 = 0.000000000000 /Astrometry: GSC2 Coeff AMDREX8 = 0.000000000000 /Astrometry: GSC2 Coeff AMDREX9 = 0.000000000000 /Astrometry: GSC2 Coeff AMDREX10= 0.000000000000 /Astrometry: GSC2 Coeff AMDREX11= 0.000000000000 /Astrometry: GSC2 Coeff AMDREX12= 0.000000000000 /Astrometry: GSC2 Coeff AMDREX13= 0.000000000000 /Astrometry: GSC2 Coeff AMDREX14= 0.000000000000 /Astrometry: GSC2 Coeff AMDREX15= 0.000000000000 /Astrometry: GSC2 Coeff AMDREX16= 0.000000000000 /Astrometry: GSC2 Coeff AMDREX17= 0.000000000000 /Astrometry: GSC2 Coeff AMDREX18= 0.000000000000 /Astrometry: GSC2 Coeff AMDREX19= 0.000000000000 /Astrometry: GSC2 Coeff AMDREX20= 0.000000000000 /Astrometry: GSC2 Coeff AMDREY1 = 67.1522589487 /Astrometry: GSC2 Coeff AMDREY2 = -0.0481758265285 /Astrometry: GSC2 Coeff AMDREY3 = 315.995683716 /Astrometry: GSC2 Coeff AMDREY4 = -7.47397531230E-006 /Astrometry: GSC2 Coeff AMDREY5 = 9.55221105409E-007 /Astrometry: GSC2 Coeff AMDREY6 = 7.60954485251E-006 /Astrometry: GSC2 Coeff AMDREY7 = 0.000000000000 /Astrometry: GSC2 Coeff AMDREY8 = 0.000000000000 /Astrometry: GSC2 Coeff AMDREY9 = 0.000000000000 /Astrometry: GSC2 Coeff AMDREY10= 0.000000000000 /Astrometry: GSC2 Coeff AMDREY11= 0.000000000000 /Astrometry: GSC2 Coeff AMDREY12= 0.000000000000 /Astrometry: GSC2 Coeff AMDREY13= 0.000000000000 /Astrometry: GSC2 Coeff AMDREY14= 0.000000000000 /Astrometry: GSC2 Coeff AMDREY15= 0.000000000000 /Astrometry: GSC2 Coeff AMDREY16= 0.000000000000 /Astrometry: GSC2 Coeff AMDREY17= 0.000000000000 /Astrometry: GSC2 Coeff AMDREY18= 0.000000000000 /Astrometry: GSC2 Coeff AMDREY19= 0.000000000000 /Astrometry: GSC2 Coeff AMDREY20= 0.000000000000 /Astrometry: GSC2 Coeff ASTRMASK= 'er.mask ' /Astrometry: GSC2 Mask WCSAXES = 2 /GetImage: Number WCS axes WCSNAME = 'DSS ' /GetImage: Local WCS approximation from full plat RADESYS = 'ICRS ' /GetImage: GSC-II calibration using ICRS system CTYPE1 = 'RA---TAN ' /GetImage: RA-Gnomic projection CRPIX1 = 446.000000 /GetImage: X reference pixel CRVAL1 = 85.274970 /GetImage: RA of reference pixel CUNIT1 = 'deg ' /GetImage: degrees CTYPE2 = 'DEC--TAN ' /GetImage: Dec-Gnomic projection CRPIX2 = 447.000000 /GetImage: Y reference pixel CRVAL2 = -2.458265 /GetImage: Dec of reference pixel CUNIT2 = 'deg ' /Getimage: degrees CD1_1 = -0.0002802651 /GetImage: rotation matrix coefficient CD1_2 = 0.0000003159 /GetImage: rotation matrix coefficient CD2_1 = 0.0000002767 /GetImage: rotation matrix coefficient CD2_2 = 0.0002798187 /GetImage: rotation matrix coefficient OBJECT = 'data ' /GetImage: Requested Object Name DATAMIN = 3759 /GetImage: Minimum returned pixel value DATAMAX = 22918 /GetImage: Maximum returned pixel value OBJCTRA = '05 41 06.000 ' /GetImage: Requested Right Ascension (J2000) OBJCTDEC= '-02 27 30.00 ' /GetImage: Requested Declination (J2000) OBJCTX = 12682.48 /GetImage: Requested X on plate (pixels) OBJCTY = 20411.37 /GetImage: Requested Y on plate (pixels)
h['exposure']
65.0
h['date-obs']
'1990-12-22T13:49:00'
As we use the astropy.units and constants module, we can easily calculate the physical parameters
import astropy.constants as con
con.R_sun
con.R_sun.cgs
con.R_sun.to('nm')
con.c
con.au / con.c
(con.au / con.c).to('min')
unit module
import astropy.units as u
u.cm
1*u.cm
con.au + 1e13*u.cm
Time module
from astropy.time import Time
date = h['date-obs']
date
'1990-12-22T13:49:00'
t = Time(date)
t
<Time object: scale='utc' format='isot' value=1990-12-22T13:49:00.000>
t + 1*u.year
<Time object: scale='utc' format='isot' value=1991-12-22T19:48:59.000>
t.jd # julian date
2448248.0756944446