A short course in Python for astronomers

21
A short course in Python for astronomers Neal Jackson, September 2012 1. General introduction The Python language has major advantages - it is concise - I can usually write Python scripts in about a quarter of the length of a C program intuitive - it is very easy to guess what you need to type to do something you want scripted - there is no compilation free!! - you don’t need to spend hundreds of pounds on a licence high-level - many basic, and lots of not-so-basic, functions have already been written, leaving you to concentrate on the problem you want to solve adopted by many users - if you have a problem, googling “python” followed by your problem usually gets you something useful. It has one disadvantage; it’s slower than compiled languages such as Fortran or C. This disad- vantage can be considerably mitigated in the way you write code. Start python by typing python It is an interactive language - you can test things, and then put them into a script to run non- interactively. To run non-interactively, type the commands into a file (conventionally ending in .py) and run the script with python filename.py Comment lines in scripts are introduced with # (anything after a hash on a line is ignored by the processor). Python is fussy about indentation: each line must be unindented in a simple script 1 . If you need to continue on to the next line, you need to write a backslash before continuing with the next line. To exit, use CTRL-D; to get help on something, type help(something), and if you want to find out what you can do to something, type dir(something). Using existing routines usually requires the import command. For example, to use mathematical functions you need to type import math which is American for “maths”, or write it in a script. You can then access a function called name by using math.name(arguments). If there are imports that you do a lot, then you may wish to make a file called pythonstart.py which contains all the things you would like Python to do on each startup. In order for Python to see this file, it must be in a directory with the logical name PYTHONSTARTUP, which you can arrange in Linux by 1 As we will see later, code inside loops is indented, but all such code must be indented consistently 1

description

pythonIt is an interactive language - you can test things, and then put them into a script to run non-interactively.concise - I can usually write Python scripts in about a quarter of the length of a C program

Transcript of A short course in Python for astronomers

AshortcourseinPythonforastronomersNealJackson,September20121. GeneralintroductionThePythonlanguagehasmajoradvantages-itisconcise - I can usually write Python scripts in about a quarter of the length of a C programintuitive-itisveryeasytoguesswhatyouneedtotypetodosomethingyouwantscripted-thereisnocompilationfree!! -youdontneedtospendhundredsofpoundsonalicencehigh-level - many basic, and lots of not-so-basic, functions have already been written, leavingyoutoconcentrateontheproblemyouwanttosolveadopted by many users - if you have a problem, googling python followed by your problemusuallygetsyousomethinguseful.Ithasonedisadvantage; itsslowerthancompiledlanguagessuchasFortranorC. Thisdisad-vantagecanbeconsiderablymitigatedinthewayyouwritecode.StartpythonbytypingpythonItisaninteractivelanguage-youcantestthings, andthenputthemintoascripttorunnon-interactively. Torunnon-interactively, typethecommandsintoale(conventionallyendingin.py)andrunthescriptwithpython filename.pyComment lines in scripts are introduced with # (anything after a hash on a line is ignored by theprocessor). Pythonisfussyaboutindentation: eachlinemustbeunindentedinasimplescript1.Ifyouneedtocontinueontothenextline,youneedtowriteabackslashbeforecontinuingwiththenextline. Toexit,useCTRL-D;togethelponsomething,typehelp(something),andifyouwanttondoutwhatyoucandotosomething,typedir(something).Using existing routines usually requires the import command. For example, to use mathematicalfunctionsyouneedtotypeimport mathwhich is American for maths, or write it in a script. You can then access a function called namebyusingmath.name(arguments). Ifthereareimportsthatyoudoalot,thenyoumaywishtomakealecalledpythonstart.pywhichcontainsallthethingsyouwouldlikePythontodooneachstartup. InorderforPythontoseethisle,itmustbeinadirectorywiththelogicalnamePYTHONSTARTUP,whichyoucanarrangeinLinuxby1As we will see later, code inside loops is indented, but all such code must be indented consistently1setenv PYTHONSTARTUP [directory-name]/pythonstart.pyFinally,youcanusePythonasacalculator:2+3Exercises1. [If you are working on a Linux system, either remotely via VNC or on your own machine.] Makeyourself apythonstartleandputthesetenvdeclarationinyour/home/[username]/.cshrcle. Youwillthenonlyneedtoeditthisleinfuture,inordertoloadprogramsbydefault.2. Trytogetpythontogenerateanerrormessage,bytypingsomethingwhichyouthinkitwillnotunderstand,ortryingtodividebyzero. Trytogetatleastthreedierenterrormessages.3. Use Python to nd the sin of 40 degrees. (Note that like most calculators, Python uses radians,andthatthevalueofpiismath.pi).2. DatatypesPythonhasvemaindatatypes: integer, float, string, complex, boolean.IntegersandoatsNotetheresultof2.0/3.02./3.2/3.2/32%319%415%6Hence the rule that any oat in an expression implies the rest are oat not integers. As usual withprogramminglanguages,divisionoftwointegersyieldsaninteger,anyremainderbeingignored.Whatdoyouthinkthe%operatordoes?StringdatatypesTypethefollowing:a=testb=this is a c=2d=2.0Examinevaluesjustbytypingthevariablenamee.g.a2orusingtheprintstatement(argumentsseparatedbycommas)print The value of a is,aWhatwouldyoupredictforthefollowing? Try(andrecord)them; theyillustrateanumberofveryimportantfunctions.b+ac*ad*aa-bb[0]b[1]b[2]c==2 # note the use of == as a testc==3his in ahis in b # note the use of in - it is very useful!len(b)len(a)+len(b)int(a) # NB the int function turns things into integersstr(d) # ... and str into strings, if possiblestr(len(a)+len(b))*2Moral: Pythonhasahabitof doingwhatyouwouldexpect- orgivinganerrorif somethingobviouslydoesntmakesense.OperationsonstringdatatypesHeresonethingyoucantdo: tryb[2]=qandnotethecomplaint. Moral: youcannotreplaceelementsofstrings.Nowtrysomethingthatdoeswork:b.replace(s,z)Notethisdoesnotchangethevalueofb! Youneedtoassigntoanothervariabletodothise.g.e=b.replace(s,z)Youcangetacompletelistofthingsyoucandotostrings: dir(b)Try a few. Useful ones includeb.swapcase(), b.rfind(a), b.split( ), b.split(s).Workoutwhateachofthesedoes(thelastonereturnsalist;seethenextsection).ComplexnumbersTheseworkasyoumightexpect:a=2.0+1.0jb=1.0+2.0jTryafewoperationse.g. a+b,a-b,a/b,a.real,b.imag.3BooleanStartwithtwovariablesa=Trueb=FalseTrythefollowing: not(a),a&b,a&a,b&b(andthesamethreewith|insteadof&. Deducewhattheseoperatorsmean.Exercises1. Writeascriptwhoserstlineisa=wombatandwhichprintsthersttwoandlasttwolettersofthestringa. Whenthisworks,experimentwitha=doanda=zastherstline.2. If a=wombat, nd an expression which does not involve the letter b or B that will give a)w*mbat, b) wombatWQMBAT, c) WombatWombat, d) [wo,bat] (two strings). e) 00000000000000wombat(withouttypingany0s). Youwillneedtolookatdir(a)foratleastoneofthese.3. Write a script which begins by dening two strings a and b, and outputs a Spoonerised versionofthetwostringsseparatedbyahyphen,i.e.a=wombatb=kangaroo[ your code here ]returnskombat-wangaroo.4. Ifa=2.473+3.476j,writeascripttowriteaintheform[float]e**[float]i.5. Hence or otherwise write a script to rotate a complex number by a given number of degrees inthecomplexplane-e.g.a=1.0+1.0jb=90.0[your-code-here]returns-1.0+1.0j.3. ControlowYouneedto knowfour basiccontrolloops;if,for,while andtry. Notecarefully (i) thecolons(ii) the use of== for a test of equality, and (iii) the indentation structure. Not indenting things isanerror. Guesswhateachwilldo,andthentryeachonetocheckthatyouknowwhatyouwillgetineachcase.4a=3if a==2:b=3elif a==3:b=5else:b=7for i in range (3,10):if i>5:print ielse:print i,is not bigger than 5i=0while i1dimension):for i in range(2):for j in range(2):print a[i,j]Oneveryusefulfeatureofthesearraysisthepowerfulsyntaxforarrayindexing. First,youcantakesubarraysusingcolons. Forexample,ifaisanimage,thenb = a[2:5,3:6]takes a sub-image from the fourth to the sixth x-pixel, inclusive, and the third to the fth y-pixel.Notethatthex-axisof animage, beingthefastestvarying, isthesecondargument; thatbothindicesofthearraybeginatzero;andthatthenumberafterthecolonrepresentstherstindexwhichisnotpartoftheoutputarray. Allofthesethreepointsarefrequentsourcesoferror.Twootherthingstonote: if youleaveoanindex, Pythondoesthesensiblething(i.e. goesfrom the beginning or to the end), and if you use negative indices, Python counts down from thelastpixel insteadof upwardsfromthebottom. Soif youwantedtoshaveothetoprowandright-handcolumnofanimage,youwantb=a[:-1,:-1].Asecondverypowerfulfeatureisimplicitarrayindexing. Supposethatarrayaisatwodimen-sionalarray:10 17 2013 41 5018 19 34wherethehorizontalaxisisthefastestvarying. Youwoulddeclarethisarrayusing:a=np.array([[10,17,20],[13,41,50],[18,19,34]]) .9(Tryalsothecommanda.sum()). Thenthecommandb=a[a[:,1]>20]will select all rows of the arraywhose secondmember is greater than20. This will leave bcontainingjustthemiddleline:b=[[13,41,50]]Note that the output is still a 2-D array, because the input is a 2-D array. To get a one-dimensionalarrayyouwouldneedb=a[a[:,1]>20][0].Ifyouwantmorethanonecondition,youneedtousebracketsand&and|forandandorrespectively,forexample:b=a[(a[:,1]>18)&(a[:,1]4.5,1.0)aThis replaces just one element of the array. Note the use ofnp.nan, which is the not-a-numbervalue used by Python to represent undetermined array elements (for example, bad pixels in an im-age). If you wanted to replace NaN elements with zero, you would use np.putmask(a,np.isnan(a),0.0).Notealsothatthisroutinemodiesthevalueofa.If youwanttoknowwhereinanarraysomethingis, youarelikelytoneednp.argwhere. Forexample,a=np.array([1.,2.,3.,4.,5.,4.,3.,2])np.argwhere(a==3.0)12returns a21array, [[2],[6]]. Youcandothis for >1Darrays too; for example, trythefollowingandbesureyouunderstandtheoutput:a=np.array([[1.,2.,3.,4.],[5.,4.,3.,2]])np.argwhere(a==3.0)You can delete or insert rows or columns of an array with the two routines np.delete(a,index,axis)ornp.insert(a,index,axis). Try,forexample,a=np.array([[0,1,2,3],[4,5,6,7],[8,9,10,11],[12,13,14,15]])b=np.delete(a,[0,2],0) # delete 1st and 3rd rowsbb=np.delete(a,[0,2],1) # delete 1st and 3rd columnsbAlsotrynp.insert.A further, slightly more complicated, function is np.take (array,indexarray,[axis,out,mode])whose function is to select subarrays in a wide variety of ways, based on indices given in the secondargument. Again,thisisbestillustratedbyexample:a=np.array([[1,2,3],[4,5,6]])np.take(a,[1],axis=1) -> [[2],[5]]np.take(a,[1],axis=0) -> [4,5,6]np.take(a,[0,1],axis=0) -> [[1,2,3],[4,5,6]]np.take(a,[0,1],axis=1) -> [[1,2],[4,5]]If there is something you need to do to an array which is not covered, again trydir(np) and thehelpfunction. Youmaywishtochecknp.place,np.put,np.roll.Afunctionwhichisoftenuseful isnp.unique. Thisreturnsthesorted, uniquemembersof anarray, atteningittoonedimensionif necessary. Forexample, np.unique([4,5,3,4,2,3,5])gives[2,3,4,5].ExercisesDonotuseforloopsinthefollowingexercises,exceptforthelastpartofexercise3.1. Makea2-Dimagefullofemptysky,whosesizeandcountsperpixelcanbespeciedbytheuser. Thenoiseineachpixelshouldbethesquarerootofthenumberofcounts.2. Make a 2-D image whose values at each pixel are the distance from a pixel which is specied bytheuser. Thenmakea2-DimagewhichcontainsaGaussianwithauser-speciedwidth,centre(inpixels)andpeakux.3. Makean2arrayof RAanddeclination(indegrees)of all FIRSTsourceswithtotal uxdensity>100mJy. Findthetwo>100mJysourceswiththesmallestseparationindeclination.137. Functions,subroutinesandsysteminteractionSofaryouhavewrittensimplescriptswithoutsubroutinesorfunctioncalls. LikeCorFortran,Pythonprovidesa wayto do thisusing thedef statement. Hereisanexample;supposewehavealemyprog.pywhichconsistsofthefollowingcodeimport numpy as npdef func1 (a,multiplier=2.0,index=3):try:b = func2 (a,multiplier,index)return bexcept:print Errorreturn np.nandef func2 (a,m,i):return m * a[i]The code takes an input array a, multiplies its indexth element by multiplier, and returns this.If an error is found (for example if the array is shorter than length index), a Not-A-Number valueisreturned. Notethefollowingfeatures: numpymustbedeclaredatthebeginningusingtheimportstatement.Eachsubroutineisintroducedbythedefdeclaration, whichmustendwithacolon. Allsubsequentlinesareindented,untiltheendofthefunction.Arguments are given in brackets. Any argument which does not contain an equals sign mustbegivenwhentheprogramiscalled. Anyargumentwhichcontainsanequalssignneednot be specied; if not, the default value is given after the equals sign. Required argumentsmustprecededefaultedarguments.Notetheuseof thetry: except: syntax. Becausefunc2isinsideoneof theseloops,any error encountered in func2 (such as a[i] not existing because the array is shorter thanindex elements) will not cause the program to stop, but will trigger theexcept statement.Thereturnstatementexitsthecurrentsubroutineandreturnsavalue. Youdonotneedto return a value. You can return scalar values or arrays, or return more than one quantity(e.g. return b,b*4).Thisscriptcanberunfromthepythoncommandlinebyimportingthele,andrunningfunc1:import myprogmyprog.func1(np.array([1,2,3,4]),2,3)14Therearevariousalternatives. Youcanimportusingfrom myprog import *; inthiscaseyoucan invoke func1 instead of myprog.func1, although you then do risk clashes if a subroutine calledfunc1 is declared in another program. You can give the arguments in a dierent order by specify-ing the name of the argument: for example myprog.func1([1,2,3,4],index=2,multiplier=3).Interactionwiththeoperatingsystemiscarriedoutbydeclaringimport osatthebeginningofascript. ThismodulecontainsalargenumberofroutinesforperformingsystemfunctionsfromwithinaPythonprogram, ofwhichbyfarthemostuseful isos.system(command). Thissendscommandtobeexecutedbytheoperatingsystem.Afurther useful pieceof systeminteractionis providedbyimport glob. globcontains oneuseful program, glob, whichprovidesanunsortedlistof lesinthecurrentworkingdirectorywhichmatchtheargument. ThisprovidesawaytorunPythoncodeonparticularleswithinadirectory. Thus,thefollowingisafairlystandardpieceofcode:import globimport numpy as npfor i in np.sort (glob.glob(*.fits)):do\_something(i)will run the functiondosomething on every le in the current directory which ends in the sux.fits.8. Furtherinputandoutput: pickles,textandFITSTherearethreefurtherimportantthingsyouneedtoknowaboutinputandoutput.a)Intheory, youcanuseforloopstosaveanyPythonstructuretoadiskleintextformat.Thisisgenerallyslowandinecient. Python/numpyprovidesauseful waytosaveastructureandretrieveitlater:a=np.array([1,2,3,4,5,6])np.save(thing,a)b=np.load(thing.npy)This code copiesa intob, via a disk le calledthing.npy (note that the.npy extension is addedautomaticallybynp.save. This le is not readable withaneditor, but onlywithnp.load;retrievalistypicallyafactor5-10fasterthanfromatextle.b)numpyprovidesawayof readingtextles, eachof whoselinescontainthesamenumberofcolumns. This is thenp.loadtxt routine. All rows and columns are assumed to be interpretableas oating-point numbers. If this is not the case, you can read the le as an array of strings usinga = np.loadtxt(filename, dtype=S))and then use other numpy routines to deal with the array. For example, if you know that all of thesecondcolumnconsistsofoats,thenyoucanspecifycol2 = np.asarray(a,dtype=float).15Amoreexibleverationofnp.loadtxtisnp.genfromtxtwhichcanhandlemissingvaluesinavarietyofways. Readthehelpleforfulldetails.c)AnotherimportanttypeofleistheFITSle. Thisisanextremelycommonwayofstoringastronomical data, includingbothimagesandradiointerferometervisibilitydata. AFITSleconsistsof anumberof 80-characterheaders, containingdataaboutthele(forexample, thenumberofaxesandsizeofeachaxisofanimage,togetherwiththecoordinatesofthecentreoftheimage. ThepyfitsmodulehandlesinteractionofPythonwithFITSles. Itisveryexibleandpowerful,andhasitsownseparatedocumentationonthepyfitswebpage. Torstorder,allyouneedtoknowisimport pyfitsa=getdata(filename.fits)h=getheader(filename.fits)pyfits.writeto(newfile.fits,a,h)Inthisexample,datafromfilename.fitsisreadintoaPythonarraya,andtheheaderinfor-mationintotheliststructureh. Thesearethenwrittenoutintonewfile.fits;youcantreataexactlyasanyothernumpyarrayandmodifyitbeforewritingitout. Youcanalsomodifyeldsof theheader. Forexample, h[CRVAL1]=130.0changestherst(right-ascension)coordinateoftheimagereferencepixelto130degrees. Youcangetacompletelistofwhatisintheheaderusingprint h. Again,thepyfitsdocumentationgoesintomoredetail.Exercises1. Writeascripttowritea100100FITSlecontainingaGaussianwithacentreposition,centraluxandwidthspeciedbytheuser.2. Foreachleendingin.fitsinthecurrentdirectory,ndthebrightestpixelanditspositioninrightascensionanddeclination;writethisinformationincolumnsinale.3. Writeascripttoforciblyconvertarectangulararraytooatingpoint, replacinganyvaluesthatcannotbeconvertedwithNot-A-Number.4. Write a script to take the resulting array and write out another le consisting of the second andthirdcolumn,providedthateitherofthetwoisnotNaN,forallrowsinwhichtherstcolumnisgreaterthan0. Theprogramshouldexitgracefullyifanerroroccurs(e.g. thelehasfewerthanthreecolumns).9. Scienticfunctions: numpyandscipynumpyprovidessomehigher-levelfunctions,notablypolynomialtting;furtherroutinesarepro-videdbythe Scientic Pythonpackage, scipy. This sectiongives anoverviewof the mostimportant,whichoccuroverandoveragainindataanalysisandsimulation: polynomialtting,Fouriermethods,arrayinterpolation,andoptimization/functionminimization.a)PolynomialttingThis is done using the numpy.polyfit routine. It has three compulsory arguments: x, the samplepointarray,y,thearrayofmeasurements,anddeg,thedesireddegreeofthepolynomialtot.16b)FouriertransformationThereareseveralFourierpackagesavailableforPython. Probablythebestisthescipypackagefftpack,whichyoucanimportusing,forexample,import scipy as spfrom scipy import fftpack as ffThis package provides both 1-D and 2-D Fourier transforms. For 2-D FFTs, the forward transformisgivenbyff.fft2 (a)andthebackwardtransformff.ifft2 (a). Notethatingeneral thearrays produced are complex; if you want the real parts only you need to takea.real ora.imag.c)InterpolationAusefulandoftenneeded1-Dinterpolationroutinecanbefoundinnumpy:a = np.interp (x, xp, fp, left=None, right=None)Givenasetof measuredvaluesfpatpointsxp, theroutinereturnsaninterpolatedarrayaofvaluesevaluatedatadierentsetofpoints,x.Thereisalsoaninterp2droutineinthepackagescipy.interpolate. Herestheexamplefromthe scipy documentation. You create an interpolator using the function dened on the existinggrid(xx,yyhere)andtheninterpolateontoanew,nergrid(x,y).from scipy import interpolatex = np.arange(-5.01, 5.01, 0.25)y = np.arange(-5.01, 5.01, 0.25)xx, yy = np.meshgrid(x, y)z = np.sin(xx**2+yy**2)f = interpolate.interp2d(x, y, z, kind=cubic)xnew = np.arange(-5.01, 5.01, 1e-2)ynew = np.arange(-5.01, 5.01, 1e-2)znew = f(xnew, ynew)d)OptimizationThis routine is accessed by importing the scipy.optimize package, followed by from scipy.optimizeimport fmin. The fmin routine uses a downhill simplex algorithm to nd the minimum of a func-tion(andtheoptimizepackagealsoprovidesotherwaysofdoingthis).Letssupposethatyouhaveasubroutinecalledmyfuncwhichcalculatesthevalueofafunction,givenanarrayofinputparameters, whicharetobeadjustedinordertominimisethefunctionvalue, x0andanarrayof other information, x. Your functionis requiredtohavethesetwoarguments:def myfunc (x0, *x):[ some code here ]return value17The subroutine which performs the minimisation must rst set the values of x0 to some reasonableinitial values, and the values of *x in order to pass any supplementary information which is neededbymyfunc to calculate the current function value, but which is not to be adjusted. You then callthefminroutinefromwithinthemainprogramusingxopt,fopt = fmin(myfunc, x0, x)andonexit,xoptwillcontaintheoptimizedparameterarray,inthesameorderasx0,andfoptwillcontainthenalminimisedvalueforthefunction.e)IntegrationoffunctionsHereshowtointegrateafunction(inthiscaseaBesselfunction,J2.5(x),from0.0to4.5):import numpy as npimport scipy as spfrom scipy import integratefrom scipy import specialresult = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)print resultNote: AlambdafunctionisasmallanonymousfunctionthatisrestrictedtoasingleexpressionherexistheargumentandthefunctioncalculatestheBesselfunctionforvaluex.Nowcomparewiththeanalyticsolution:I = sqrt(2/pi)*(18.0/27*sqrt(2)*cos(4.5)-4.0/27*sqrt(2)*sin(4.5)+ \sqrt(2*pi)*special.fresnel(3/sqrt(pi))[0])print IExercise. 1. Find the coecients of the second-order polynomial ax2+bx+c which give the bestttothefunctiony=exbetweenx=0andx=1, usingdiscretevaluesof thefunctionatintervals of 0.1 in x. Do this in two ways: (i) by a polynomial t and (ii, harder) by optimization.10. PlottingwithmatplotlibAllplottingfunctionsareimportedwiththefollowingincantation:import matplotlibfrom matplotlib import pyplot as pltDepending on the machine you are running on, you may also need to specify matplotlib.use(Qt4Agg)(itsalongstory).a)Plotting2-Dimages18If youhave a 2-dimensional array a, this canbe plottedwith plt.imshow(a), followedbyplt.show()toputtheplotonthescreen. Trythiswithanarbitraryarraya.Thedefaultistointerpolatebetweenpixelsandtoplotthey-axisthewrongwayround-i.e.withy= 0atthetop. Youcanchangethisusingplt.rcParams[image.interpolation]=nearestplt.rcParams[image.origin]=lowerIfyoulikethiswaybetter,thenyoumaywishtoincludethisinyourpythonstartup.py.Youcanalsoaddcolourwedgesandmakemultipleplots. Foryourfavouritearraya,tryplt.subplot(221);plt.imshow(a);plt.colorbar()plt.subplot(224);plt.imshow(a*2.0);plt.colorbar()plt.show()Youcangetlabelsfortheplotwithplt.xlabel,plt.ylabel,andplt.title. Youcanchangethecolourlookupusingtheargumentcmap=matplotlib.cm.XX,whereXXisoneofalistwhichyoucangetusingdir(matplotlib.cm). Youcanalsochangethexandy-limitsusingthetwo-argumentfunctionsplt.xlimandplt.ylim(whichyouneedtoinvokeaftertheplt.imshow).If you want dierent black and white levels, you can get them using the arguments vmin and vmaxtoplt.imshow.Finally, tosavethegureinsteadof viewingitonthescreen, useplt.savefig(filename). Iffilenameendsin.ps,youwillgetapostscriptle,otherwisePNGisthedefault.b)ScatterandlineplotsPoints specied by an abscissa array x and ordinate array y can be plotted using plt.plot(x,y,ct).chereshouldbereplacedbyaletterrepresentingthecolouryouwant;allarereasonablyob-viousexceptthatblackisk. tshouldbereplacedbythetypeofpointyouwant: -forlines, --fordottedlines, oforcircles, sforsquares. Seehelp(plt.plot)forafulllist,andhelponmorecomplicatedoptions.Youcanplotseveral dierentarraysononeplot; all youneedistodoseveral plt.plotcallsbeforetheplt.showorplt.savefig.If youareparticularlyfussyabouttheticklabelsonaplotyoucanmakecustomtickarrays.Forexample, plt.xticks([0.0,100.0,200.0])willplotjustthreeticksandticklabelsonthex-axis,at0,100and200.Youcanwritetextonplots; plt.text(x,y,s)will dothis, wherexandyareoatingpointnumbersandsisastring.Quite often you will need to make plots with logarithmic axes. Matplotlib provides three functionsfor this: plt.loglog, plt.semilogx and plt.semilogy. Apart from the scaling of the axes, theseroutinesfunctioninthesamewayasplt.plot.c)Histograms19Theseareeasier; givenanarraya, youneedonlyplt.hist(a). Optional arguments includebins,thenumberofbinsandrange,aPythonlistoftwonumbersforthex-rangefortheplot.11. SomespecialistastronomicalapplicationsThere are two packages which are worth installing and importing routinely as part of your pythonpackage.astLibisaseriesof routinesforperformingcommonastronomical calculations. Itconsistsofthreemainlibraries. Therst is astCalc, whichperforms anumber of commoncalculationsincluding angular diameter and luminosity distances, and comoving volumes (all of which take oneargument, the redshift). These are controlled by the values of constants such as astCalc.OMEGALandastCalc.H0whichdefaulttoastandardCDMcosmology,andwhichyoucanchange(youcanevenchangeastCalc.CLIGHTifyoulike).astCoords carries out common coordinate conversion calculations. Most useful is the conversionbetweenhexadecimal-type coordinates (e.g. 23 45 36.87for right ascension) anddecimaldegrees. Thesearedoneusingfourroutines;trythem.astCoords.hms2decimal (23 45 32.47, )astCoords.dms2decimal (-00 23 42.32, )astCoords.decimal2hms (324.37483, )astCoords.decimal2dms (-1.473845, )The second argument in each case is the separator between the three components of the hexadec-imalrepresentation.Also useful is astCoords.calcAngSepDeg (ra1,dec1,ra2,dec2) which calculates the AngSepDegbetweentwoobjects.astWCSThishandlesthepositioninformationinlessuchasFITSleswhichtell youaboutthecoordinatesysteminimages. Theycanalsobeusedfor makingastronomical plots, withproperlabellingofRAandDec. Probablyeasier,however,istoimportthe...pywcsgrid2 package, which allows you to do astronomical plots in a wide variety of ways. Heresarecipeforplottingdatainalecalledinput.fits,whichhasappropriateheaderinformationtellingyouabouttheRA/deccoordinatesystem:import pywcsgrid2a = getdata(input.fits)h = getheader(input.fits)pywcsgrid2.subplot(111,header=h)plt.imshow(a)plt.show()Exercises1. Makea2-DimagecontainingaGaussianandsomerandomnoise. Plottheresult.202. Fouriertransformthisimageandplottheresult. CheckthatitiswhatyouwouldexpectfordierentwidthsofGaussian.3. Writeascripttotforthecentre,widthanduxoftheGaussian,giveninitialguessesfromtheuser. CheckthatitreproducestheGaussianyoumadeearlier.4. Make an Aito plot of all sources in the FIRST catalogue with uxes >100mJy. (The procedureisasnormal,exceptyouneedprojection=aitoffasanextraargumenttoplt.subplot).5. Writeaprogramtotakeasetof pointsfromale, witherrorsaswell asvaluesonthey-axis, anduseaminimisationroutinetotapolynomial of theorderspeciedbytheuser, byminimisingthe2ofthet.21