def do_plot(header, data, figname, showplot=False): # now plot f = maputils.FITSimage(externalheader=header, externaldata=data) cmap = str('YlGnBu') cmap = str('Greys') X = np.linspace(0., 300., 6) Y = np.linspace(87., 89., 3) plt.close() fig = plt.figure(figsize=(6, 6)) frame = fig.add_axes([0.1, 0.1, 0.8, 0.8]) mplim = f.Annotatedimage(frame, cmap=cmap) mplim.Image(interpolation='nearest') grat = mplim.Graticule(axnum=(1, 2), wylim=(87, 90), wxlim=(-180, 180), startx=X, starty=Y) grat.setp_gratline(color='0.5', lw=0.5) grat.Insidelabels(wcsaxis=0, world=X + 2.5, constval=87.75, fmt='%g^\circ', color='k', fontsize=10, fun=lambda x: x - 2.5 # deltapx=1, deltapy=1, ) grat.Insidelabels( wcsaxis=1, world=Y + 0.06, constval=200, fmt='Dms', color='k', fontsize=10, ) for wcsaxis in range(4): grat.setp_plotaxis(wcsaxis, visible=False) grat.setp_ticklabel(wcsaxis, visible=False) grat.setp_tickmark(wcsaxis, visible=False) mplim.plot() plt.savefig(figname, dpi=75) if showplot: plt.show()
def __init__(self, imagefile): if os.path.isfile(imagefile): imgf = pyfits.open(imagefile) xybinsize = imgf[0].header['IMGBIN'] if xybinsize == 1: print "fine... xybinsize = ", xybinsize self.imagefits = maputils.FITSimage(imagefile) self.imageutil = self.imagefits.Annotatedimage() self.isexist = True else: print "---------------------------------------------------------------------------" print "* Please make image fits again." print "* You must set the image fits rebinned as xybinsize of 1, not 8 or others." print "---------------------------------------------------------------------------" self.isexist = False quit() else: self.isexist = False
#!/usr/bin/env python from kapteyn import wcsgrat, maputils, ellinteract from matplotlib import pylab as plt # Get connected to Matplotlib fig = plt.figure() movieimages = maputils.MovieContainer() # Create a maputils FITS object from a FITS file on disk fitsobject = maputils.FITSimage('rense.fits') #ch = [10,15,20,25,30,35] #ch = range(15,85) ch = [20, 30] count = 0 vmin, vmax = fitsobject.get_dataminmax() print("Vmin, Vmax:", vmin, vmax) for i in ch: fitsobject.set_imageaxes(1, 2, slicepos=i) # fitsobject.set_limits() frame = fig.add_subplot(1, 2, count + 1) # Create an image to be used in Matplotlib mplim = fitsobject.Annotatedimage(frame) mplim.Image() count += 1 # Draw the graticule lines and plot WCS labels mplim.Graticule() mplim.plot() movieimages.append(mplim)
def plot(self, map=None, header=None, title=None, new_figure=True, linewidth=2, percentile=0.01, **kw): """ Plot the pointings' celestial coordinates. Parameters ---------- map : ndarray of dim 2 An optional map to be displayed as background. header : pyfits.Header The optional map's FITS header. title : str The figure's title. new_figure : boolean If true, the display will be done in a new window. linewidth : float The scan line width. percentile : float, tuple of two floats As a float, percentile of values to be discarded, otherwise, percentile of the minimum and maximum values to be displayed. """ import kapteyn.maputils as km import matplotlib.pyplot as mp if isscalarlike(self.masked) and self.masked or np.all(self.masked): if new_figure: raise ValueError('There is no valid coordinates.') return if not isscalarlike(self.masked): ra = self.ra.copy() dec = self.dec.copy() ra[self.masked] = np.nan dec[self.masked] = np.nan else: ra = self.ra dec = self.dec if header is None: header = getattr(map, 'header', None) elif map is not None: map = Map(map, header=header, copy=False) if isinstance(map, Map) and map.has_wcs(): image = map.imshow(title=title, new_figure=new_figure, percentile=percentile, **kw) else: if header is None: header = self.get_map_header(naxis=1) fitsobj = km.FITSimage(externalheader=dict(header)) if new_figure: fig = mp.figure() frame = fig.add_axes((0.1, 0.1, 0.8, 0.8)) else: frame = mp.gca() if title is not None: frame.set_title(title) image = fitsobj.Annotatedimage(frame, blankcolor='w') image.Graticule() image.plot() image.interact_toolbarinfo() image.interact_writepos() mp.show() _plot_scan(image, ra, dec, linewidth=linewidth, **kw) return image
def plotVelocityWCS(self): """ Generates a plot with SDSS file on the background and the slicer velocities on the top. will also plot the centre slit velocity curve. :return: None """ #shift y values by one, because of indexing difference between IRAF and Python yshift = -1 #data manipulation vel = self.info['data'][:, 6].astype(np.float) err = self.info['data'][:, 7].astype(np.float) xp = self.info['data'][:, 2].astype(np.float) yp = self.info['data'][:, 3].astype(np.float) + yshift #finds the middle slit based on the header information and SLICE keyword #does not consider offset position files = self.info['data'][:, 12] slices = [] for file in files: if 'off' in files: slices.append(-5) else: slices.append(pf.open(file)[0].header['SLICE']) midmsk = np.asarray(slices) == 2 #tries to figure out good limits automatically, this step might fail #depending on the galaxy ylims = (np.min(yp) * 0.93, np.max(yp) * 1.07) xlims = (np.min(xp) * 0.85, np.max(xp) * 1.15) tmpdata = pf.open(self.info['directImage'], memmap=1)[0].data tmp = tmpdata[int(np.floor(ylims[0]) * 1.1):int(np.ceil(ylims[1]) * .9), int(np.floor(xlims[0]) * 1.1):int(np.ceil(xlims[1]) * .9)] clipmin = np.min(tmp) * 0.05 #the multiplier is rather arbitrary clipmax = np.max(tmp) * 0.45 #the multiplier is rather arbitrary ticks = np.linspace(clipmin, clipmax, 4) ticks = [np.round(tick, 1) for tick in ticks] #font settings cbfontsize = 10 #opens the FITS file and sets limits f = maputils.FITSimage(self.info['directImage']) f.set_limits(pxlim=xlims, pylim=ylims) #creates a figure and generates two subplots (grids) fig = plt.figure(figsize=(10, 8)) gs = gridspec.GridSpec(1, 2, width_ratios=[3, 1]) ax1 = plt.subplot(gs[0]) ax2 = plt.subplot(gs[1], title='Center Slit') gs.update(wspace=0.0, hspace=0.0, top=0.96, bottom=0.07) #plots the background SDSS image annim = f.Annotatedimage(ax1, cmap='binary', clipmin=clipmin, clipmax=clipmax) annim.Image(alpha=0.95) #cont = annim.Contours(levels=np.arange(1e-4, 1, 1e-1)) #colour bar 1: this is the SDSS background image in nanomaggies inset_axes2 = inset_locator.inset_axes(ax1, width='43%', height='1.5%', loc=2) colbar = annim.Colorbar(frame=inset_axes2, fontsize=cbfontsize, orientation='horizontal', ticks=ticks) colbar.set_label(label=r'flux (nanomaggies)') #modifies the axis labels grat = annim.Graticule() grat.setp_gratline(wcsaxis=0, linestyle=':', zorder=1) grat.setp_gratline(wcsaxis=1, linestyle=':', zorder=1) #grat.setp_ticklabel(rotation=30) grat.setp_tick(fontsize=16) grat.setp_axislabel(fontsize=16) #grat.set_tickmode(plotaxis=['bottom','left'], mode="Switch") grat.setp_ticklabel(plotaxis=['top', 'right'], visible=False) #grat.setp_ticklabel(plotaxis=['right'], visible=False) #adds a ruler ymid = np.mean(yp[midmsk]) ysize = (np.max(yp) - np.min(yp)) * 0.7 xpos = xlims[1] - 5 ruler1 = annim.Ruler(x1=xpos, y1=ymid - ysize, x2=xpos, y2=ymid + ysize, mscale=0.8, fliplabelside=True, lambda0=0.0, step=5.0 / 3600.) ruler1.setp_line(color='k', lw=1.3) ruler1.setp_label(color='k', fontsize=12) annim.plot() #overplot image slicer velocity field s = ax1.scatter(xp, yp, c=vel, s=30, marker='s', cmap=cm.jet, edgecolor='none', alpha=0.9) #set colour bar and modify font sizes inset_axes = inset_locator.inset_axes(ax1, width='43%', height='1.5%', loc=1) c1 = plt.colorbar(s, cax=inset_axes, orientation='horizontal') #inset_axes.xaxis.set_ticks_position('top') c1.set_label('Velocity (km s$^{-1}$)') ticks = np.linspace(int(np.ceil(np.min(vel))), int(np.floor(np.max(vel))), 4) ticks = [int(tick) for tick in ticks] c1.set_ticks(ticks) for j in c1.ax.get_xticklabels(): j.set_fontsize(cbfontsize) #the second plot ax2.errorbar(vel[midmsk], yp[midmsk], xerr=err[midmsk], marker='o', ms=4, ls='None') #set limits ax2.set_ylim(ylims[0], ylims[1]) ax2.set_xlim(np.min(vel[midmsk]) * 0.985, np.max(vel[midmsk]) * 1.015) #modify ticks, plot only every second on x and remove y ticks ax2.set_yticklabels([]) ax2.set_yticks([]) ax2.set_xticks(ax2.get_xticks()[::2]) #set label on x ax2.set_xlabel('Velocity (km s$^{-1}$)') #save figure plt.savefig('VelocityField.pdf')
from kapteyn import maputils from matplotlib import pyplot as plt fitsobj = maputils.FITSimage('example1test.fits') fig = plt.figure(figsize=(5.5,5)) frame = fig.add_axes([0.1, 0.1, 0.8, 0.8]) annim = fitsobj.Annotatedimage(frame) annim.set_aspectratio(1.2) grat = annim.Graticule() maputils.showall()
def show_image(self, beam=None, step=None, chunk=None, major=None, minor=None, finaltype=None, type=None, imin=None, imax=None): ''' Function to show an image in the notebook beam (string): The beam number to show the image for. 'iterate' will iterate over beams. step (string): The step of the pipeline to show the image for. No default. selfcal and final are allowed. chunk (string): The frequency chunk to show the image for. 'iterate' will iterate over chunks. No default. major(string or int): Major iteration of clean to display. Default is last iteration. pm is also possible. Only for selfcal, not for final step. 'iterate' will iterate over images for major cycles. minor (string or int): Minor iteration of clean to display. Default is last iteration. 'iterate' will iterate over images for minor cycles. finaltype(string): Type of final image to show. mf and stack are possible. type(string): Type of image to show. mask, beam, image, residual, and in case of step=final final are possible. 'all' will show image, mask, residual, and model in one plot. imin(float): Minimum cutoff in the image. imax(float): Maximum cutoff in the image. return (string): String with a path and image name to use for displaying. ''' subs.setinit.setinitdirs(self) self.manage_tempdir() # Check if the temporary directory exists and if not create it self.clean_tempdir() # Remove any temorary files from the temporary directory char_set = string.ascii_uppercase + string.digits # Create a charset for random image name generation if any(it == 'iterate' for it in [beam, chunk, major, minor]): if beam == 'iterate': print('### Not implemented yet ###') elif chunk == 'iterate': imagelist = glob.glob(self.selfcaldir + '/*/' + str(major).zfill(2) + '/' + str(type) + '_' + str(minor).zfill(2)) plottext = 'Frequency \nchunk' elif major == 'iterate': imagelist = glob.glob(self.selfcaldir + '/' + str(chunk).zfill(2) + '/*/' + str(type) + '_' + str(minor).zfill(2)) plottext = 'Major \ncycle' elif minor == 'iterate': imagelist = glob.glob(self.selfcaldir + '/' + str(chunk).zfill(2) + '/' + str(major).zfill(2) + '/' + str(type) + '_*') plottext = 'Minor \ncycle' images = [] for image in imagelist: self.fitsimage = self.tempdir + '/' + ''.join(random.sample(char_set * 8, 8)) + '.fits' fits = lib.miriad('fits') fits.op = 'xyout' fits.in_ = image fits.out = self.fitsimage fits.go() images.append(maputils.FITSimage(self.fitsimage)) # Do the autoscaling of the image contrast if imin == None or imax == None: imagedata = pyfits.open(self.fitsimage)[0].data imagestd = np.nanstd(imagedata) if imin == None: imin = -1*imagestd else: pass if imax == None: imax = 3*imagestd else: pass else: pass print('Minimum/maximum colour range for image: ' + str(imin) + '/' + str(imax)) # Draw the plot fig = plt.figure(figsize=(12, 10)) frame = fig.add_axes([0.1, 0.15, 0.85, 0.8]) frame.set_title(str(type).capitalize()) # Add the slider for selecting the image slider_ax = fig.add_axes([0.103, 0.05, 0.672, 0.03]) slider = Slider(slider_ax, plottext, 0, len(images)-1, valinit = 0, valfmt='%1.0f', dragging=False, color='black') # Define the attributes for the plot image_object = images[int(round(slider.val))].Annotatedimage(frame, cmap='gist_gray', clipmin=imin, clipmax=imax) image_object.Image() image_object.Graticule() image_object.Colorbar() image_object.interact_toolbarinfo() image_object.interact_imagecolors() image_object.plot() fig.canvas.draw() # Update the plot if the slider is clicked def slider_on_changed(val): image_object = images[int(round(slider.val))].Annotatedimage(frame, cmap='gist_gray', clipmin=imin, clipmax=imax) image_object.Image() image_object.interact_toolbarinfo() image_object.interact_imagecolors() image_object.plot() fig.canvas.draw() slider.on_changed(slider_on_changed) plt.show() else: if type == 'all': # Make a 2x2 plot of image, residual, mask, and model of a cycle rawimage = self.get_image(beam, step, chunk, major, minor, finaltype, 'image') rawresidual = self.get_image(beam, step, chunk, major, minor, finaltype, 'residual') rawmask = self.get_image(beam, step, chunk, major, minor, finaltype, 'mask') rawmodel = self.get_image(beam, step, chunk, major, minor, finaltype, 'model') self.fitsimage = self.tempdir + '/' + ''.join(random.sample(char_set * 8, 8)) + '.fits' self.fitsresidual = self.tempdir + '/' + ''.join(random.sample(char_set * 8, 8)) + '.fits' self.fitsmask = self.tempdir + '/' + ''.join(random.sample(char_set * 8, 8)) + '.fits' self.fitsmodel = self.tempdir + '/' + ''.join(random.sample(char_set * 8, 8)) + '.fits' fits = lib.miriad('fits') fits.op = 'xyout' fits.in_ = rawimage fits.out = self.fitsimage fits.go() fits.in_ = rawresidual fits.out = self.fitsresidual fits.go() fits.in_ = rawmask fits.out = self.fitsmask fits.go() regrid = lib.miriad('regrid') regrid.in_ = rawmodel tempregrid = self.tempdir + '/' + ''.join(random.sample(char_set * 8, 8)) regrid.out = tempregrid regrid.axes = '1,2' regrid.tin = rawimage regrid.go() fits.in_ = tempregrid fits.out = self.fitsmodel fits.go() im = maputils.FITSimage(self.fitsimage) imdata = pyfits.open(self.fitsimage)[0].data imstd = np.nanstd(imdata) re = maputils.FITSimage(self.fitsresidual) redata = pyfits.open(self.fitsresidual)[0].data restd = np.nanstd(redata) ma = maputils.FITSimage(self.fitsmask) madata = pyfits.open(self.fitsmask)[0].data mastd = np.nanstd(madata) mo = maputils.FITSimage(self.fitsmodel) modata = pyfits.open(self.fitsmodel)[0].data mostd = np.nanstd(modata) fig = plt.figure(figsize=(12, 10)) frame1 = fig.add_axes([0.1,0.58,0.4,0.4]) frame1.set_title('Image') frame2 = fig.add_axes([0.59,0.58,0.4,0.4]) frame2.set_title('Residual') frame3 = fig.add_axes([0.1, 0.12, 0.4, 0.4]) frame3.set_title('Mask') frame4 = fig.add_axes([0.59, 0.12, 0.4, 0.4]) frame4.set_title('Model') annim1 = im.Annotatedimage(frame1, cmap='gist_gray') annim2 = re.Annotatedimage(frame2, cmap='gist_gray') annim3 = ma.Annotatedimage(frame3, cmap='gist_gray') annim4 = mo.Annotatedimage(frame4, cmap='gist_gray') annim1.Image(); annim2.Image(); annim3.Image(); annim4.Image() if imin == None: # Set the displayed colour range if not set immin, remin, mamin, momin = -1*imstd, -1*restd, -1*mastd, -1*mostd else: immin, remin, mamin, momin = imin, imin, imin, imin if imax == None: immax, remax, mamax, momax = 3*imstd, 3*restd, mastd, mostd else: immax, remax, mamax, momax = imax, imax, imax, imax print('Minimum colour range for image: ' + str(immin) + ' residual: ' + str(remin) + ' mask: ' + str(mamin) + ' model: ' + str(momin)) print('Maximum colour range for image: ' + str(immax) + ' residual: ' + str(remax) + ' mask: ' + str(mamax) + ' model: ' + str(momax)) annim1.set_norm(clipmin=immin, clipmax=immax); annim2.set_norm(clipmin=remin, clipmax=remax); annim3.set_norm(clipmin=0.0, clipmax=mamax); annim4.set_norm(clipmin=0.0, clipmax=momax) annim1.Colorbar(); annim2.Colorbar(); annim3.Colorbar(); annim4.Colorbar() annim1.Graticule(); annim2.Graticule(); annim3.Graticule(); annim4.Graticule() annim1.interact_toolbarinfo(); annim2.interact_toolbarinfo(); annim3.interact_toolbarinfo(); annim4.interact_toolbarinfo() annim1.interact_imagecolors(); annim2.interact_imagecolors(); annim3.interact_imagecolors(); annim4.interact_imagecolors() tdict = dict(color='g', fontsize=10, va='bottom', ha='left') fig.text(0.01, 0.01, annim1.get_colornavigation_info(), tdict) maputils.showall() else: # Make a simple plot of one specified image rawimage = self.get_image(beam, step, chunk, major, minor, finaltype, type) self.fitsimage = self.tempdir + '/' + ''.join(random.sample(char_set * 8, 8)) + '.fits' fits = lib.miriad('fits') fits.op = 'xyout' fits.in_ = rawimage fits.out = self.fitsimage fits.go() f = maputils.FITSimage(self.fitsimage) imdata = pyfits.open(self.fitsimage)[0].data imstd = np.nanstd(imdata) fig = plt.figure(figsize=(12,10)) frame = fig.add_axes([0.1, 0.15, 0.85, 0.8]) annim = f.Annotatedimage(frame, cmap='gist_gray') annim.Image() if imin == None: # Set the displayed colour range if not set imin = -1*imstd if imax == None: imax = 3*imstd print('Minimum/maximum colour range for image: ' + str(imin) + '/' + str(imax)) annim.set_norm(clipmin=imin,clipmax=imax) annim.Colorbar() annim.Graticule() annim.interact_toolbarinfo() annim.interact_imagecolors() units = 'unknown' if 'BUNIT' in f.hdr: units = f.hdr['BUNIT'] helptext = "File: [%s] Data units: [%s]\n" % (rawimage, units) helptext += annim.get_colornavigation_info() tdict = dict(color='g', fontsize=10, va='bottom', ha='left') fig.text(0.01, 0.01, helptext, tdict) maputils.showall()
from kapteyn import maputils from matplotlib import pyplot as plt fitsobj = maputils.FITSimage("m101.fits") fitsobj.set_limits((200, 400), (200, 400)) annim = fitsobj.Annotatedimage() annim.Image(alpha=0.5) cont = annim.Contours(linestyles=('solid', 'dashed', 'dashdot', 'dotted'), linewidths=(2, 3, 4), colors=('r', 'g', 'b', 'm')) annim.plot() print("Levels=", cont.clevels) plt.show()
def imshow(self, mask=None, new_figure=True, title=None, xlabel='X', ylabel='Y', interpolation='nearest', origin=None, colorbar=True, percentile=0, **keywords): try: import kapteyn.maputils as km except ImportError: km = None import matplotlib.pyplot as mp if mask is None and self.coverage is not None: mask = self.coverage <= 0 if origin is None: origin = self.origin # check if the map has no astrometry information if not self.has_wcs() or km is None: image = super(Map, self).imshow(mask=mask, new_figure=new_figure, title=title, xlabel=xlabel, ylabel=ylabel, origin=origin, colorbar=colorbar, percentile=percentile, **keywords) return image if np.iscomplexobj(self): data = abs(self.magnitude) else: data = self.magnitude.copy() if isscalarlike(percentile): percentile = percentile / 2, 100 - percentile / 2 unfinite = ~np.isfinite(self.magnitude) if mask is None: mask = unfinite else: mask = np.logical_or(mask, unfinite) data_valid = data[~mask] minval = scipy.stats.scoreatpercentile(data_valid, percentile[0]) maxval = scipy.stats.scoreatpercentile(data_valid, percentile[1]) data[data < minval] = minval data[data > maxval] = maxval data[mask] = np.nan #XXX FIX ME colorbar = False fitsobj = km.FITSimage(externaldata=data, externalheader=dict(self.header)) if new_figure: fig = mp.figure() frame = fig.add_axes((0.1, 0.1, 0.8, 0.8)) else: frame = mp.gca() fontsize = 12. * fig.get_figheight() / 6.125 for tick in frame.xaxis.get_major_ticks(): tick.label1.set_fontsize(fontsize) for tick in frame.yaxis.get_major_ticks(): tick.label1.set_fontsize(fontsize) if title is not None: frame.set_title(title) if colorbar: colorbar = mp.colorbar() for tick in colorbar.ax.get_yticklabels(): tick.set_fontsize(fontsize) annim = fitsobj.Annotatedimage(frame, blankcolor='w') annim.Image(interpolation=interpolation) grat = annim.Graticule() grat.setp_gratline(visible=False) annim.plot() annim.interact_imagecolors() annim.interact_toolbarinfo() annim.interact_writepos() if colorbar: annim.Colorbar() mp.show() return annim
from kapteyn import maputils from re import split Basefits = maputils.FITSimage(promptfie=maputils.prompt_fitsfile) hdr = Basefits.hdr.copy() print("Header") print("-" * 80) print(Basefits.str_header()) hdr = maputils.fitsheader2dict(hdr) crval1, crval2 = hdr['CRVAL1'], hdr['CRVAL2'] print("topixel -> crpix", Basefits.proj.topixel((crval1, crval2))) hdr['CTYPE1'] = 'RA---MER' hdr['CTYPE2'] = 'DEC--MER' #hdr['PV1_1'] = crval1 #hdr['PV1_2'] = crval2 hdr['CRVAL1'] = 0.0 hdr['CRVAL2'] = 0.0 #hdr['LONPOLE'] = crval1 #hdr['LATPOLE'] = +90 f = maputils.FITSimage(externalheader=hdr) crpix1, crpix2 = f.proj.topixel((crval1, crval2)) print("CRPIX=", crpix1, crpix2) #hdr['CRPIX1'] = crpix1 #hdr['CRPIX2'] = crpix2 pxlim = (int(crpix1 - 600), int(crpix1 + 600)) pylim = (int(crpix2 - 600), int(crpix2 + 600)) print(pxlim, pylim)
from kapteyn import maputils from matplotlib import pyplot as plt from math import cos, radians fitsobj = maputils.FITSimage('m101.fits') annim = fitsobj.Annotatedimage() annim.Image() grat = annim.Graticule() grat.setp_ticklabel(wcsaxis=1, fmt='s') # Exclude seconds in label # beam = annim.Beam(210.9619, 54.261039, 0.01, 0.01, 0, hatch='*') # Hatching does not work in mpl 0.98.3 fwhm_maj = 5/60.0 # arcmin to degrees fwhm_min = 4/60.0 lat = 54.347395233845 lon = 210.80254413455 beam = annim.Beam(fwhm_maj, fwhm_min, 90, xc=lon, yc=lat, fc='g', fill=True, alpha=0.6) pos = '210.80254413455 deg, 54.347395233845 deg' beam = annim.Beam(7, 4, units='arcmin', pos=pos, fc='m', fill=True, alpha=0.6) pos = '14h03m12.6105s 54d20m50.622s' beam = annim.Beam(fwhm_maj, fwhm_min, pos=pos, fc='y', fill=True, alpha=0.6) pos = 'ga 102.0354152 {} 59.7725125' beam = annim.Beam(fwhm_maj, fwhm_min, pos=pos, fc='g', fill=True, alpha=0.6) pos = 'ga 102d02m07.494s {} 59.7725125' beam = annim.Beam(fwhm_maj, fwhm_min, pos=pos, fc='b', fill=True, alpha=0.6) pos = '{ecliptic,fk4, j2000} 174.3674627 {} 59.7961737' beam = annim.Beam(fwhm_maj, fwhm_min, pos=pos, fc='r', fill=True, alpha=0.6)
import numpy from kapteyn import maputils from matplotlib.pyplot import show, figure import csv # Read some poitions from file in Comma Separated Values format # Some initializations blankcol = "#334455" # Represent undefined values by this color epsilon = 0.0000000001 figsize = (9, 7) # Figure size in inches plotbox = (0.1, 0.05, 0.8, 0.8) fig = figure(figsize=figsize) frame = fig.add_axes(plotbox) Basefits = maputils.FITSimage( "allsky_raw.fits" ) # Here is your downloaded FITS file in rectangular coordinates Basefits.hdr[ 'CTYPE1'] = 'GLON-CAR' # For transformations we need to give it a projection type Basefits.hdr['CTYPE2'] = 'GLAT-CAR' # CAR is rectangular # Use some header values to define reprojection parameters cdelt1 = Basefits.hdr['CDELT1'] cdelt2 = Basefits.hdr['CDELT2'] naxis1 = Basefits.hdr['NAXIS1'] naxis2 = Basefits.hdr['NAXIS2'] # Header works only with a patched wcslib 4.3 # Note that changing CRVAL1 to 180 degerees, shifts the plot 180 deg. header = { 'NAXIS': 2, 'NAXIS1': naxis1,
from kapteyn import maputils from matplotlib import pyplot as plt # 1. Read the header fitsobj = maputils.FITSimage("manyaxes.fits") # 2. Create a Matplotlib Figure and Axes instance figsize=fitsobj.get_figsize(ysize=12, xsize=11, cm=True) fig = plt.figure(figsize=figsize) frame = fig.add_subplot(1,1,1) # 3. Create a graticule fitsobj.set_imageaxes('freq','pol') mplim = fitsobj.Annotatedimage(frame) grat = mplim.Graticule(starty=1000, deltay=10) # 4. Show the calculated world coordinates along y-axis print("The world coordinates along the y-axis:", grat.ystarts) # 5. Show header information in attributes of the Projection object # The projection object of a graticule is attribute 'gmap' print("CRVAL, CDELT from header:", grat.gmap.crval, grat.gmap.cdelt) # 6. Set a number of properties of the graticules and plot axes grat.setp_tick(plotaxis="bottom", fun=lambda x: x/1.0e9, fmt="%.4f", rotation=-30 ) grat.setp_axislabel("bottom", label="Frequency (GHz)") grat.setp_gratline(wcsaxis=0, position=grat.gmap.crval[0], tol=0.5*grat.gmap.cdelt[0], color='r')
from kapteyn import maputils from matplotlib import pyplot as plt # Read header of FITS file f = maputils.FITSimage('mclean.fits') # Matplotlib fig = plt.figure(figsize=(7,10)) fig.subplots_adjust(left=0.12, bottom=0.05, right=0.97, top=0.97, wspace=0.22, hspace=0.90) fig.text(0.05,0.5,"Radial offset latitude", rotation=90, fontsize=14, va='center') # Get the projection object to get allowed spectral translations altspec = f.proj.altspec crpix = f.proj.crpix[f.proj.specaxnum-1] altspec.insert(0, (None, '')) # Add native to list k = len(altspec) + 1 frame = fig.add_subplot(k,1,1) # Limit range in x to neighbourhood of CRPIX xlim = (crpix-5, crpix+5) f.set_imageaxes(3,2) f.set_limits(pxlim=xlim) mplim = f.Annotatedimage(frame) mplim.set_aspectratio(0.002) print("Native system", f.proj.ctype[f.proj.specaxnum-1], f.proj.cunit[f.proj.specaxnum-1], end=' ') print("Spectral translations") for i, ast in enumerate(altspec):
from kapteyn import maputils from matplotlib import pyplot as plt import numpy # Read first image as base Basefits = maputils.FITSimage(promptfie=maputils.prompt_fitsfile) Basefits.set_imageaxes(promptfie=maputils.prompt_imageaxes) Basefits.set_limits(promptfie=maputils.prompt_box) # Get data from a second image. This sets the spatial output Contourfits = maputils.FITSimage(promptfie=maputils.prompt_fitsfile) Contourfits.set_imageaxes(promptfie=maputils.prompt_imageaxes) print("boxdat contour 0,0", Contourfits.boxdat[0, 0]) print("Contourfits slicepos", Contourfits.slicepos) fig = plt.figure() frame = fig.add_subplot(1, 1, 1) baseim = Basefits.Annotatedimage(frame) baseim.Image() baseim.Graticule() # Set parameters for the interpolation routine pars = dict(cval=numpy.nan, order=1) Reprojfits = Contourfits.reproject_to(Basefits, interpol_dict=pars) print(Reprojfits.boxdat) overlayim = Basefits.Annotatedimage(frame, boxdat=Reprojfits.boxdat) print(overlayim.data) mi, ma = overlayim.clipmin, overlayim.clipmax prompt = "Enter contour levels between %g and %g: " % (mi, ma)
def shapes(proj, fig, plnr, crval2=0.0, **pv): naxis1 = 800 naxis2 = 800 header = { 'NAXIS': 2, 'NAXIS1': naxis1, 'NAXIS2': naxis2, 'CRPIX1': naxis1 / 2.0, 'CRPIX2': naxis2 / 2.0, 'CRVAL1': 0.0, 'CRVAL2': crval2, 'CDELT1': -0.5, 'CDELT2': 0.5, 'CUNIT1': 'deg', 'CUNIT2': 'deg', 'CTYPE1': 'RA---%s' % proj, 'CTYPE2': 'DEC--%s' % proj } if len(pv): header.update(pv) print(header) X = numpy.arange(0, 390.0, 30.0) X[-1] = 180 + 0.00000001 Y = numpy.arange(-90, 91, 30.0) f = maputils.FITSimage(externalheader=header) frame = fig.add_subplot(2, 2, plnr) annim = f.Annotatedimage(frame) grat = annim.Graticule(axnum=(1, 2), wylim=(-90.0, 90.0), wxlim=(-180, 180), startx=X, starty=Y) grat.setp_gratline(color='0.75') if plnr in [1, 2]: grat.setp_axislabel(plotaxis='bottom', visible=False) print("Projection %d is %s" % (plnr, proj)) # Ellipse centered on crossing of two graticule lines try: annim.Skypolygon("ellipse", cpos="5h00m 20d0m", major=50, minor=30, pa=-30.0, fill=False) except: print("Failed to plot ellipse") # Ellipse at given pixel coordinates try: cpos = "%f %f" % (naxis1 / 2.0 + 20, naxis2 / 2.0 + 10) annim.Skypolygon("ellipse", cpos=cpos, major=20, minor=10, pa=-30.0, fc='m') except: print("Failed to plot ellipse") # Circle with radius in arc minutes try: annim.Skypolygon("ellipse", cpos="0 deg 60 deg", major=30, minor=30, fc='g', alpha=0.3, lw=3, ec='r') except: print("Failed to plot circle") # Rectangle at the projection center try: annim.Skypolygon("rectangle", cpos="pc pc", major=50, minor=20, pa=30.0, ec='g', fc='b', alpha=0.3) except: print("Failed to plot rectangle") # Square centered at 315 deg -45 deg and with size equal # to distance on sphere between 300,-30 and 330,-30 deg (=25.9) try: annim.Skypolygon("rectangle", cpos="315 deg -45 deg", major=25.9, minor=25.9, pa=0.0, ec='g', fc='#ff33dd', alpha=0.8) except: print("Failed to plot square") # Regular polygon with 6 angles at some position in galactic coordinates try: annim.Skypolygon("npoly", cpos="ga 102d11m35.239s ga 59d50m25.734", major=20, nangles=6, ec='g', fc='y', alpha=0.3) except: print("Failed to plot regular polygon") # Regular polygon as a triangle try: annim.Skypolygon("npolygon", cpos="ga 0 ga 90", major=70, nangles=3, ec='g', fc='c', alpha=0.7) except: print("Failed to plot triangle") # Set of (absolute) coordinates, no prescription lons = [270, 240, 240, 270] lats = [-60, -60, -30, -30] try: annim.Skypolygon(prescription=None, lons=lons, lats=lats, fc='r', alpha=0.9) except: print("Failed to plot set of coordinates as polygon") grat.Insidelabels(wcsaxis=0, world=list(range(0, 360, 30)), constval=0, fmt='Hms', color='b', fontsize=5) grat.Insidelabels(wcsaxis=1, world=[-60, -30, 30, 60], constval=0, fmt='Dms', color='b', fontsize=5) annim.interact_toolbarinfo() annim.interact_writepos(wcsfmt="%f", zfmt=None, pixfmt=None, hmsdms=False) frame.set_title(proj, y=0.8) annim.plot()
# Mask array could be of type numpy.bool_ instead of numpy.ndarray if numpy.isscalar(xp.mask): xp.mask = numpy.array(xp.mask, 'bool') if numpy.isscalar(yp.mask): yp.mask = numpy.array(yp.mask, 'bool') # Count the number of positions in these list that are inside the box j = 0 for i in range(len(xp)): if not xp.mask[i] and not yp.mask[i]: j += 1 if j > 200: # Threshold to prevent too much detail and big pdf's frame.plot(xp.data, yp.data, color=col) # Get a header and change some values f = maputils.FITSimage("m101.fits") header = f.hdr header['CDELT1'] = 0.1 header['CDELT2'] = 0.1 header['CRVAL1'] = 285 header['CRVAL2'] = 20 # Use the changed header as external source for new object f = maputils.FITSimage(externalheader=header, externaldata=f.dat) fig = plt.figure() frame = fig.add_subplot(1, 1, 1) annim = f.Annotatedimage(frame, cmap="YlGn") annim.Image() grat = annim.Graticule() grat.setp_ticklabel(wcsaxis=0, fmt="%g^{\circ}") grat.setp_ticklabel(wcsaxis=1, fmt='Dms')
from kapteyn import maputils, shapes from matplotlib import pyplot as plt Basefits = maputils.FITSimage("m101big.fits") hdr = Basefits.hdr.copy() hdr['CTYPE1'] = 'RA---MER' hdr['CTYPE2'] = 'DEC--MER' hdr['CRVAL1'] = 0.0 hdr['CRVAL2'] = 0.0 naxis1 = Basefits.hdr['NAXIS1'] naxis2 = Basefits.hdr['NAXIS2'] # Get an estimate of the new corners x = [0] * 5 y = [0] * 5 x[0], y[0] = Basefits.proj.toworld((1, 1)) x[1], y[1] = Basefits.proj.toworld((naxis1, 1)) x[2], y[2] = Basefits.proj.toworld((naxis1, naxis2)) x[3], y[3] = Basefits.proj.toworld((1, naxis2)) x[4], y[4] = Basefits.proj.toworld((naxis1 / 2.0, naxis2)) # Create a dummy object to calculate pixel coordinates # in the new system. Then we can find the area in pixels # that corresponds to the area in the sky. f = maputils.FITSimage(externalheader=hdr) px, py = f.proj.topixel((x, y)) pxlim = [int(min(px)) - 10, int(max(px)) + 10] pylim = [int(min(py)) - 10, int(max(py)) + 10] Reprojfits = Basefits.reproject_to(hdr, pxlim_dst=pxlim, pylim_dst=pylim)
#!/usr/bin/env python from kapteyn import wcsgrat, maputils from matplotlib import pylab as plt # Create a maputils FITS object from a FITS file on disk fitsobject = maputils.FITSimage(promptfie=maputils.prompt_fitsfile) fitsobject.set_imageaxes(promptfie=maputils.prompt_imageaxes) fitsobject.set_limits(promptfie=maputils.prompt_box) fitsobject.set_skyout(promptfie=maputils.prompt_skyout) clipmin, clipmax = maputils.prompt_dataminmax(fitsobject) # Get connected to Matplotlib fig = plt.figure() frame = fig.add_subplot(1, 1, 1) # Create an image to be used in Matplotlib annim = fitsobject.Annotatedimage(frame, clipmin=clipmin, clipmax=clipmax) annim.Image() annim.Graticule() annim.plot() annim.interact_toolbarinfo() annim.interact_imagecolors() annim.interact_writepos() plt.show()
directory = make_outdir_filesresult(source_name, name_method_fond, config_name, image_size, for_integral_flux=False, ereco=energy_reco) fileb = directory + '/residual_morpho_et_flux_step_' file_end = '_' + name + '_' + str("%.2f" % E1) + '_' + str( "%.2f" % E2) + '_TeV.fits' filen = list() for i in range(7): filen.append(fileb + str(i + 1) + file_end) print filen[i], i gc = maputils.FITSimage( "../Final_Plots_paper_Janv2016_LARGEFOV_StandardFit/Model_ipe_south_GAMMAEXP_HardZeta_PtSources_G09_CG_WCS.fits" ) #../Final_Plots_paper_Janv2016_LARGEFOV_StandardFit/Model_ipe_south_GAMMAEXP_HardZeta_bkg_Diff_CGPtSource_WCS.fits") gc.set_limits(pxlim=(modxmin, modxmax), pylim=(modymin, modymax)) imgc = gc.Annotatedimage(frame_fig1, cmap=palette, clipmin=mod_min, clipmax=mod_max) imgc.Image(interpolation='spline36') grat_gc = imgc.Graticule(unitsx='DEGREE', unitsy='DEGREE', deltax=delta_grid, deltay=delta_grid) grat_gc.setp_gratline(visible=visible_grid) grat_gc.setp_tick(wcsaxis=[0, 1], fontsize=14) grat_gc.setp_ticklabel(wcsaxis=[0], visible=False)
from kapteyn import maputils from matplotlib import pyplot as plt # In the comments we show how to set a smaller box t display f_red = maputils.FITSimage('m101_red.fits') #f_red.set_limits((200,300),(200,300)) f_green = maputils.FITSimage('m101_green.fits') #f_green.set_limits((200,300),(200,300)) f_blue = maputils.FITSimage('m101_blue.fits') #f_blue.set_limits((200,300),(200,300)) # Show the three components R,G & B separately # Show Z values when moving the mouse fig = plt.figure() frame = fig.add_subplot(2, 2, 1) frame.set_title("Red with noise") a = f_red.Annotatedimage(frame) a.Image() a.interact_toolbarinfo(wcsfmt=None, zfmt="%g") frame = fig.add_subplot(2, 2, 2) frame.set_title("Greens are 1") a = f_green.Annotatedimage(frame) a.Image() a.interact_toolbarinfo(wcsfmt=None, zfmt="%g") frame = fig.add_subplot(2, 2, 3) frame.set_title("Blues are 1") a = f_blue.Annotatedimage(frame) a.Image() a.interact_toolbarinfo(wcsfmt=None, zfmt="%g") # Plot the composed RGB image
from kapteyn import maputils from matplotlib import pyplot as plt file1 = "scuba850_AFGL2591.fits" file2 = "13CO_3-2_integ_regrid.fits" # Read first image as base Basefits = maputils.FITSimage(file1) Secondfits = maputils.FITSimage(file2) Reprojfits = Secondfits.reproject_to(Basefits) fig = plt.figure() frame = fig.add_subplot(1, 1, 1) baseim = Basefits.Annotatedimage(frame) baseim.Image() baseim.set_histogrameq() baseim.Graticule() overlayim = Basefits.Annotatedimage(frame, boxdat=Reprojfits.boxdat) levels = list(range(20, 200, 20)) overlayim.Contours(levels=levels, colors='w') baseim.plot() overlayim.plot() baseim.interact_toolbarinfo() baseim.interact_imagecolors() plt.show()
from kapteyn import maputils from matplotlib import pylab as plt fitsobject = maputils.FITSimage('ngc6946.fits') print("HEADER:\n") print(fitsobject.str_header()) print("\nAXES INFO:\n") print(fitsobject.str_axisinfo()) print("\nEXTENDED AXES INFO:\n") print(fitsobject.str_axisinfo(int=True)) print("\nAXES INFO for image axes only:\n") print(fitsobject.str_axisinfo(axnum=fitsobject.axperm)) print("\nAXES INFO for non existing axis:\n") print(fitsobject.str_axisinfo(axnum=4)) print("SPECTRAL INFO:\n") fitsobject.set_imageaxes(axnr1=1, axnr2=3) print(fitsobject.str_spectrans())
if __name__ == '__main__': start = time() #plot set up units = r'$\log_{10}()$' limy = limx = (200, 2100) rows = 3 cols = 2 #plotting fig = plt.figure(figsize=(16, 20)) #first frame frame1 = fig.add_subplot(rows, cols, 1) f = maputils.FITSimage('StokesISmooth15.fits') frame1.set_title(f.filename, y=1.01) f.set_limits(limx, limy) f = maputils.FITSimage(externalheader=f.hdr, externaldata=np.log10(f.boxdat)) mplim = f.Annotatedimage(frame1, cmap="spectral", clipmin=-5.5, clipmax=-3) mplim.Image() cb = mplim.Colorbar(fontsize=8) cb.set_label(label=units, fontsize=9) grat = mplim.Graticule() grat.setp_ticklabel(plotaxis=['top', 'right'], visible=False) grat.setp_ticklabel(wcsaxis=1, fmt='s') # Exclude seconds in label grat.setp_gratline(wcsaxis=0, linestyle=':', zorder=1) grat.setp_gratline(wcsaxis=1, linestyle=':', zorder=1) #region file r = pyregion.open('region_forHST.reg').as_imagecoord(
from kapteyn import maputils from matplotlib import pyplot as plt from numpy import fft, log, abs, angle f = maputils.FITSimage("m101.fits") yshift = -0.1 fig = plt.figure(figsize=(8, 6)) fig.subplots_adjust(left=0.01, bottom=0.1, right=1.0, top=0.98, wspace=0.03, hspace=0.16) frame = fig.add_subplot(2, 3, 1) frame.text(0.5, yshift, "M101", ha='center', va='center', transform=frame.transAxes) mplim = f.Annotatedimage(frame, cmap="spectral") mplim.Image() fftA = fft.rfft2(f.dat, f.dat.shape) frame = fig.add_subplot(2, 3, 2) frame.text(0.5, yshift, "Amplitude of FFT", ha='center', va='center',
def _areaLossPlot(maglimit, b, l, z, blow, bhigh, llow, lhigh, bnum, lnum, title, output): """ Generate a plot showing the area loss as a function of galactic coordinates for given magnitude limit. :param maglimit: :param b: :param l: :param z: :param blow: :param bhigh: :param llow: :param lhigh: :param bnum: :param lnum: :return: """ from kapteyn import maputils header = { 'NAXIS': 2, 'NAXIS1': len(l), 'NAXIS2': len(b), 'CTYPE1': 'GLON', 'CRVAL1': llow, 'CRPIX1': 0, 'CUNIT1': 'deg', 'CDELT1': float(bhigh - blow) / bnum, 'CTYPE2': 'GLAT', 'CRVAL2': blow, 'CRPIX2': 0, 'CUNIT2': 'deg', 'CDELT2': float(lhigh - llow) / lnum } fig = plt.figure(figsize=(12, 7)) frame1 = fig.add_axes([0.1, 0.1, 0.85, 0.85]) #generate image f = maputils.FITSimage(externalheader=header, externaldata=z) im1 = f.Annotatedimage(frame1) grat1 = im1.Graticule(skyout='Galactic', starty=blow, deltay=10, startx=llow, deltax=20) colorbar = im1.Colorbar(orientation='horizontal') colorbar.set_label( label=r'Imaging Area Lost Because of Saturated Pixels [\%]', fontsize=18) im1.Image() im1.plot() title += r' $V \leq %.1f$' % maglimit frame1.set_title(title, y=1.02) plt.savefig(output + '%i.pdf' % maglimit) plt.close()
from kapteyn import maputils f = maputils.FITSimage("ngc6946.fits") # Get an XV slice at DEC=51 f.set_imageaxes(1, 3, slicepos=51) f.set_spectrans("FREQ-???") annim = f.Annotatedimage() # Which pixel coordinates correspond to CRVAL's? crpix = annim.projection.crpix print("CRPIX from header", crpix) # Convert these to world coordinates x = crpix[0] y = crpix[1] lon, velo, lat = annim.toworld(x, y, matchspatial=True) print("lon, velo, lat =", lon, velo, lat) print("Should be equivalent to CRVAL:", annim.projection.crval) x, y, slicepos = annim.topixel(lon, velo, matchspatial=True) print("Back to pixel coordinates: x, y =", x, y, slicepos)
from kapteyn import maputils from matplotlib import pyplot as plt import numpy # Read first image as base Basefits = maputils.FITSimage(promptfie=maputils.prompt_fitsfile) print(type(Basefits), isinstance(Basefits, maputils.FITSimage)) # Get data from a second image. This is the data that # should be reprojected to fit the header of Basefits. Secondfits = maputils.FITSimage(promptfie=maputils.prompt_fitsfile) #Secondfits.set_imageaxes(promptfie=maputils.prompt_imageaxes) #Secondfits.set_limits(promptfie=maputils.prompt_box) # Now we want to overlay the data of this Base fits object onto # the wcs of the second fits object. This is done with the # reproject_to() method of # the first FITSimage object (the data object) with the second # FITSimage object as parameter. This results in a new fits file #Reprojfits = Basefits.reproject_to(Secondfits.hdr, plimlo=(2,1), plimhi=(2,1)) #Reprojfits = Basefits.reproject_to(Secondfits.hdr, pxlim=(100,400), pylim=(100,400)) Reprojfits = Basefits.reproject_to(Secondfits.hdr) Reprojfits.writetofits("reproj.fits", clobber=True)
'CDELT1': -5.0, 'CTYPE2': 'DEC--PCO', 'CRVAL2': 0.0, 'CRPIX2': 40, 'CUNIT2': 'deg', 'CDELT2': 5.0 } X = polrange() Y = numpy.arange(-75, 90, 15.0) # !!!!!! Let the world coordinates for constant latitude run from 180,180 # instead of 0,360. Then one prevents the connection between the two points # 179.9999 and 180.0001 which is a jump, but smaller than the definition of # a rejected jump in the wcsgrat module. # Also we need to increase the value of 'gridsamples' to # increase the relative size of a jump. f = maputils.FITSimage(externalheader=header) annim = f.Annotatedimage(frame) grat = annim.Graticule(axnum=(1, 2), wylim=(-90, 90.0), wxlim=(-180, 180), startx=X, starty=Y, gridsamples=2000) grat.setp_lineswcs0(0, lw=2) grat.setp_lineswcs1(0, lw=2) # Remove the left 180 deg and print the right 180 deg instead w1 = numpy.arange(0, 151, 30.0) w2 = numpy.arange(180, 360, 30.0) w2[0] = 180 + epsilon lon_world = numpy.concatenate((w1, w2)) lat_world = [-60, -30, 30, 60]
def _plotGalaxy(self): """ Very simple method to plot an image of the galaxy and spectral information :Warning: Does not work since version 0.5 of the class. :Note: At the moment the low and high end clipping values for scaling the image has been hardcoded. At some point these could be transferred to be read from the configuration file. """ tol = np.floor(self.direct['postageTolerance'] / self.direct['platescale']) xp = self.direct['xposition'] yp = self.direct['yposition'] #make a figure fig = plt.figure(1) ax = fig.add_subplot(111) #from Kapteyn f = maputils.FITSimage(self.direct['rotatedFile']) annim = f.Annotatedimage(ax, clipmin=0.01, clipmax=1) annim.Image(alpha=0.9) grat = annim.Graticule() grat.setp_gratline(wcsaxis=0, linestyle=':') grat.setp_gratline(wcsaxis=1, linestyle=':') annim.plot() plt.savefig('Galaxy.pdf') plt.close() #number of spectra spects = len(self.slits.keys()) + 1 #zoomed in version with the spectra fig = plt.figure(figsize=(15, 15)) ax1 = fig.add_subplot(spects, 1, 1) f = maputils.FITSimage(self.direct['rotatedFile']) f.set_limits(pxlim=(xp - tol, xp + tol), pylim=(yp - tol, yp + tol)) annim = f.Annotatedimage(ax1, clipmin=0.01, clipmax=1) annim.Image() grat = annim.Graticule() grat.setp_gratline(wcsaxis=0, linestyle=':') grat.setp_gratline(wcsaxis=1, linestyle=':') units = r'nanomaggies' colbar = annim.Colorbar(fontsize=7) colbar.set_label(label=units, fontsize=14) annim.plot() i = 2 for slit in self.slits: ax = fig.add_subplot(spects, 1, i) f = maputils.FITSimage(slit) #f.set_imageaxes('Wavelength [AA]','Pixels') m = f.Annotatedimage(ax) m.Image() grat = m.Graticule() grat.setp_gratline(wcsaxis=0, linestyle=':') grat.setp_gratline(wcsaxis=1, linestyle=':') ax.set_xlabel('Wavelength [AA]') ax.set_ylabel('Pixels') m.plot() i += 1 #annim.interact_toolbarinfo() #annim.interact_imagecolors() #annim.interact_writepos() #plt.show() plt.savefig('GalaxyZoomed.pdf') plt.close()