|
5 | 5 | import os
|
6 | 6 | import sys
|
7 | 7 | import aplpy
|
| 8 | +import argparse |
| 9 | +import numpy as np |
| 10 | +import matplotlib.pyplot as plt |
| 11 | +from astropy.io import fits |
8 | 12 |
|
9 |
| -# dims for an [ra,dec,vel] cube |
10 |
| -dims = [0,1] # ra-dec |
11 |
| -#dims = [1,2] # dec-vel |
12 |
| -#dims = [0,2] # ra-vel |
13 | 13 |
|
14 |
| -fitsfile = sys.argv[1] |
15 |
| -if len(sys.argv) > 2: |
16 |
| - plane = int(sys.argv[2]) |
| 14 | +help_main = ["Simple color plot of a FITS image", |
| 15 | + "with options to pick a plane (if a cube) or slicing method", |
| 16 | + "colormaps and plot file extension can also be changed", |
| 17 | + "plot file name is derived from input FITS file", |
| 18 | + ] |
| 19 | + |
| 20 | +help_color = ['Popular colors: viridis, gist_heat gist_ncar (default)', |
| 21 | + ' rainbow, jet, nipy_spectral', |
| 22 | + 'https://matplotlib.org/stable/tutorials/colors/colormaps.html'] |
| 23 | + |
| 24 | + |
| 25 | +parser = argparse.ArgumentParser(description="\n".join(help_main), |
| 26 | + formatter_class=argparse.RawTextHelpFormatter) |
| 27 | + # formatter_class=argparse.ArgumentDefaultsHelpFormatter) |
| 28 | + |
| 29 | + |
| 30 | + |
| 31 | +parser.add_argument('fitsfile', help="input FITS file", default=None) |
| 32 | +parser.add_argument('--plane', help="plane (if cube) [-1]", default=-1, type=int) |
| 33 | +parser.add_argument('--pvar', help="plane var (x,y,[z])", default='z') |
| 34 | +parser.add_argument('--color', help="\n".join(help_color), default='gist_ncar') |
| 35 | +parser.add_argument('--ext', help="plot type ([png],pdf)", default='png') |
| 36 | +parser.add_argument('--hist', help="add histogram", action="store_true") |
| 37 | +parser.add_argument('--size', help="plot size (inch)", default=8, type=float) |
| 38 | + |
| 39 | +args = parser.parse_args() |
| 40 | + |
| 41 | + |
| 42 | +fitsfile = args.fitsfile |
| 43 | +plane = args.plane |
| 44 | +color = args.color |
| 45 | +ext = args.ext |
| 46 | +pvar = args.pvar |
| 47 | +size = args.size |
| 48 | + |
| 49 | +if pvar == 'z': |
| 50 | + dims = [0,1] # ra-dec |
| 51 | +elif pvar == 'y': |
| 52 | + dims = [0,2] # ra-vel |
| 53 | +elif pvar == 'x': |
| 54 | + dims = [1,2] # dec-vel |
17 | 55 | else:
|
18 |
| - plane = -1 |
19 |
| - |
| 56 | + dims = [0,1] |
| 57 | + |
| 58 | +hdu = fits.open(fitsfile) |
20 | 59 | if plane < 0:
|
21 |
| - f = aplpy.FITSFigure(fitsfile) |
| 60 | + data = hdu[0].data |
22 | 61 | else:
|
23 |
| - f = aplpy.FITSFigure(fitsfile, slices=[plane], dimensions=dims) |
| 62 | + data = hdu[0].data[plane] |
| 63 | + |
| 64 | +data = data[~np.isnan(data)] |
| 65 | +data = data[data != 0] |
| 66 | + |
| 67 | +dmin = np.min(data) |
| 68 | +dmax = np.max(data) |
| 69 | +dmean = np.mean(data) |
| 70 | +dstd = np.std(data) |
| 71 | +print("Data min/max/mean/sig: %g %g %g %g" % (dmin,dmax,dmean,dstd)) |
| 72 | +dmin = dmean - 3*dstd; |
| 73 | +dmax = dmean + 3*dstd; |
| 74 | +print("Data min/max: %g %g" % (dmin,dmax)) |
| 75 | +bins = np.linspace(dmin, dmax, 32) |
| 76 | +if args.hist: |
| 77 | + print("BINS: ",bins) |
| 78 | + |
| 79 | +if args.hist: |
| 80 | + # side by side |
| 81 | + f=0.7 |
| 82 | + #box1 = [0.1,0.1,0.8,0.8] # full size, image |
| 83 | + box2 = [0.05,0.1,0.5/f,0.5/f] # left side, image |
| 84 | + box3 = [0.55/f,0.1,0.2,f] # right side, histo |
| 85 | +else: |
| 86 | + # just a square image |
| 87 | + box1 = [0.1,0.1,0.8,0.8] # full size, image |
| 88 | + #box2 = [0.1,0.1,0.5,0.5] # left side, image |
| 89 | + #box3 = [0.7,0.15,0.2,0.4] # right side, histo |
| 90 | + |
| 91 | +try: |
| 92 | + if args.hist: |
| 93 | + fig = plt.figure(figsize=(size, f*size)) |
| 94 | + else: |
| 95 | + fig = plt.figure(figsize=(size, size)) |
24 | 96 |
|
25 |
| -f.show_grayscale() |
26 |
| -f.show_colorscale(cmap='gist_heat') |
27 |
| -f.add_colorbar() |
28 |
| -# Cannot show beam when WCS is not celestial |
29 |
| -# perhaps doesn't like VRAD, but our fits files are not good enough |
30 |
| -# for 2D maps, ccdfits ndim=2 will help |
| 97 | + if plane < 0: |
| 98 | + if args.hist: |
| 99 | + f1 = aplpy.FITSFigure(fitsfile, figure=fig, subplot=box2) |
| 100 | + ax_hist = fig.add_axes(box3) |
| 101 | + ax_hist.hist(data, bins=bins, orientation='horizontal', facecolor='blue',log=True) |
| 102 | + else: |
| 103 | + f1 = aplpy.FITSFigure(fitsfile, figure=fig, subplot=box1) |
| 104 | + else: |
| 105 | + if args.hist: |
| 106 | + f1 = aplpy.FITSFigure(fitsfile, slices=[plane], dimensions=dims, figure=fig, subplot=box2) |
| 107 | + ax_hist = fig.add_axes(box3) |
| 108 | + ax_hist.hist(data, bins=bins, orientation='horizontal', facecolor='blue',log=True) |
| 109 | + else: |
| 110 | + f1 = aplpy.FITSFigure(fitsfile, slices=[plane], dimensions=dims, figure=fig, subplot=box1) |
| 111 | +except: |
| 112 | + print("problem processing %s in %s" % (fitsfile,os.getcwd())) |
| 113 | + sys.exit(0) |
| 114 | + |
| 115 | +f1.show_grayscale() |
| 116 | +f1.show_colorscale(cmap=color) |
| 117 | +f1.add_colorbar() |
31 | 118 |
|
32 | 119 | try:
|
33 |
| - f.add_beam() |
| 120 | + f1.add_beam() |
34 | 121 | except:
|
35 | 122 | pass
|
36 | 123 |
|
37 | 124 | # f.show_contour(fitsfile, levels=10)
|
38 |
| -f.add_grid() |
39 |
| -f.save(fitsfile + ".pdf") |
| 125 | +f1.add_grid() |
| 126 | +fig.canvas.draw() |
| 127 | + |
| 128 | +idx = fitsfile.rfind('.fits') |
| 129 | +if plane < 0: |
| 130 | + pfile = fitsfile[:idx] + ".%s" % ext |
| 131 | +else: |
| 132 | + pfile = fitsfile[:idx] + ".%04d.%s" % (plane,ext) |
| 133 | +# fig.subplots_adjust(right=0.15) |
| 134 | +fig.savefig(pfile) |
| 135 | +print("Writing ",pfile) |
| 136 | +# plt.show() |
0 commit comments