def draw_zenith(self, radius=1.0, **kwargs): """ Plot a to-scale representation of the zenith. Parameters ---------- radius : radius of zenith circle (deg) kwargs : passed to plotting routines Returns ------- None """ defaults = dict( color='green', alpha=0.75, lw=1.5, ) setdefaults(kwargs, defaults) # RA and Dec of zenith zra, zdec = np.degrees(self.observer.radec_of(0, '90')) self.plot(zra, zdec, marker='+', ms=10, mew=1.5, **kwargs) if radius: kwargs['edgecolor'] = kwargs.pop('color') kwargs['facecolor'] = 'none' self.tissot(zra, zdec, radius, **kwargs)
def draw_des17(self, **kwargs): """ Draw the DES footprint. """ defaults = dict(edgecolor='red') setdefaults(kwargs, defaults) filename = get_datafile('des-round17-poly.txt') return self.draw_footprint(filename, **kwargs)
def draw_decals(self, **kwargs): """ Draw DECaLS footprint. """ defaults = dict(edgecolor='blue') setdefaults(kwargs, defaults) filename = get_datafile('decals-poly.txt') return self.draw_footprint(filename, **kwargs)
def draw_bliss(self, **kwargs): """Draw the BLISS footprint""" defaults = dict(edgecolor='magenta') setdefaults(kwargs, defaults) filename = get_datafile('bliss-poly.txt') self.draw_footprint(filename, **kwargs)
def draw_des_sn(self, **kwargs): defaults = dict(facecolor='none', edgecolor='k', lw=1, zorder=10) setdefaults(kwargs, defaults) ra = [v['ra'] for v in DES_SN.values()] dec = [v['dec'] for v in DES_SN.values()] self.tissot(ra, dec, DECAM, **kwargs)
def draw_polygon_radec(self, ra, dec, **kwargs): """Draw a shapely Polygon from a list of ra,dec coordinates. Parameters ---------- ra : right dec : declination kwargs: passed to add_geometries Returns ------- poly : the Polygon """ defaults = dict(crs=ccrs.Geodetic(), facecolor='none', edgecolor='red') setdefaults(kwargs, defaults) ra = np.asarray(ra).flatten() dec = np.asarray(dec).flatten() coords = np.vstack([ra, dec]).T poly = Polygon(coords) self.ax.add_geometries([poly], **kwargs) if 'label' in kwargs: self.ax.plot(np.nan, np.nan, color=kwargs['edgecolor'], label=kwargs['label']) return poly
def draw_maglites(self, **kwargs): """Draw the MagLiteS footprint """ defaults = dict(edgecolor='blue') setdefaults(kwargs, defaults) filename = get_datafile('maglites-poly.txt') self.draw_footprint(filename, **kwargs)
def draw_inset_colorbar(self, *args, **kwargs): defaults = dict(loc=3, width="30%", height="4%", bbox_to_anchor=(0, 0.05, 1, 1)) setdefaults(kwargs, defaults) super(DESSkymapMcBryde, self).draw_inset_colorbar(*args, **kwargs)
def draw_inset_colorbar(self, format=None, label=None, ticks=None, fontsize=11, **kwargs): defaults = dict(width="25%", height="5%", loc=7, bbox_to_anchor=(0., -0.04, 1, 1)) setdefaults(kwargs, defaults) ax = plt.gca() im = plt.gci() cax = inset_axes(ax, bbox_transform=ax.transAxes, **kwargs) cmin, cmax = im.get_clim() if (ticks is None) and (cmin is not None) and (cmax is not None): cmed = (cmax + cmin) / 2. delta = (cmax - cmin) / 10. ticks = np.array([cmin + delta, cmed, cmax - delta]) tmin = np.min(np.abs(ticks[0])) tmax = np.max(np.abs(ticks[1])) if format is None: if (tmin < 1e-2) or (tmax > 1e3): format = '$%.1e$' elif (tmin > 0.1) and (tmax < 100): format = '$%.1f$' elif (tmax > 100): format = '$%i$' else: format = '$%.2g$' # format = '%.2f' kwargs = dict(format=format, ticks=ticks, orientation='horizontal') if format == 'custom': ticks = np.array([cmin, 0.85 * cmax]) kwargs.update(format='$%.0e$', ticks=ticks) cbar = plt.colorbar(cax=cax, **kwargs) cax.xaxis.set_ticks_position('top') cax.tick_params(axis='x', labelsize=fontsize) if format == 'custom': ticklabels = cax.get_xticklabels() for i, lab in enumerate(ticklabels): val, exp = ticklabels[i].get_text().split('e') ticklabels[i].set_text(r'$%s \times 10^{%i}$' % (val, int(exp))) cax.set_xticklabels(ticklabels) if label is not None: cbar.set_label(label, size=fontsize) cax.xaxis.set_label_position('top') plt.sca(ax) return cbar, cax
def __init__(self, projection='cyl', **kwargs): setdefaults(kwargs, self.defaults) do_allsky = kwargs.pop('allsky', True) do_grid = kwargs.pop('gridlines', True) do_celestial = kwargs.pop('celestial', True) self.set_observer(kwargs.pop('observer', None)) self.set_date(kwargs.pop('date', None)) # Eventually want to subclass GeoAxes ax = plt.gca() fig = ax.figure subspec = ax.get_subplotspec() fig.delaxes(ax) self.projection = cartosky.proj.Proj(projection, **kwargs) self.ax = fig.add_subplot(subspec, projection=self.projection) if do_allsky: self.ax.set_global() if do_celestial: self.ax.invert_xaxis() if do_grid: self.grid = self.ax.gridlines() self.grid.rotate_labels = False # Better grid lines? # https://github.com/SciTools/cartopy/pull/1117 self.wrap_angle = np.mod(kwargs['lon_0'] + 180, 360)
def __init__(self, *args, **kwargs): defaults = dict(projection='splaea', lon_0=60, boundinglat=-20, round=True, celestial=True, parallels=True) setdefaults(kwargs, defaults) super(SurveySkymap, self).__init__(*args, **kwargs)
def hspmap(self, hspmap, pixel=None, nside=None, xsize=800, lonra=None, latra=None, badval=healpix.UNSEEN, smooth=None, **kwargs): """ Draw a healpix map with pcolormesh. Parameters ---------- hpxmap: input healpix or HealSparse map pixel: explicit pixel indices in RING scheme (required for partial healpix maps) nside: explicit nside of the map (required for partial healpix maps) if passed while visualizing a HealSparse map it will doegrade the map to this nside. xsize: resolution of the output image lonra: longitude range [-180,180] (deg) latra: latitude range [-90,90] (deg) badval: set of values considered "bad" smooth: gaussian smoothing kernel (deg) kwargs: passed to pcolormesh Returns ------- im,lon,lat,values : mpl image with pixel longitude, latitude (deg), and values """ # ADW: probably still not the best way to do this... import healsparse as hsp import healpy as hp if not isinstance(hspmap, hsp.HealSparseMap): # Assume that it is a healpix map in RING ordering hpxmap = hp.reorder(hspmap, r2n=True) hspmap = hsp.HealSparseMap(healpix_map=hpxmap, nside_coverage=nside) lon, lat, values = healpix.hsp2xy(hspmap, xsize=xsize, lonra=lonra, latra=latra) if smooth: msg = "Healsparse smoothing not implemented." raise Exception(msg) vmin, vmax = np.percentile(values.compressed(), [2.5, 97.5]) defaults = dict(rasterized=True, vmin=vmin, vmax=vmax) setdefaults(kwargs, defaults) im = self.pcolormesh(lon, lat, values, **kwargs) self._sci(im) return im, lon, lat, values
def draw_smash(self, **kwargs): """ Draw the SMASH fields. """ defaults = dict(facecolor='none', edgecolor='k', lw=1, zorder=10) setdefaults(kwargs, defaults) filename = get_datafile('smash_fields_final.txt') smash = np.genfromtxt(filename, dtype=[('ra', float), ('dec', float)], usecols=[4, 5]) self.tissot(smash['ra'], smash['dec'], DECAM, **kwargs)
def hpxmap(self, hpxmap, pixel=None, nside=None, xsize=800, lonra=None, latra=None, badval=healpix.UNSEEN, smooth=None, **kwargs): """ Draw a healpix map with pcolormesh. Parameters ---------- hpxmap: input healpix or HealSparse map pixel: explicit pixel indices in RING scheme (required for partial healpix maps) nside: explicit nside of the map (required for partial healpix maps) if passed while visualizing a HealSparse map it will doegrade the map to this nside. xsize: resolution of the output image lonra: longitude range [-180,180] (deg) latra: latitude range [-90,90] (deg) badval: set of values considered "bad" smooth: gaussian smoothing kernel (deg) kwargs: passed to pcolormesh Returns ------- im,lon,lat,values : mpl image with pixel longitude, latitude (deg), and values """ healpix.check_hpxmap(hpxmap, pixel, nside) hpxmap = healpix.masked_array(hpxmap, badval) if smooth: # To smooth we need the full map... # It'd be good to check we aren't going to blow anything up hpxmap = healpix.create_map(hpxmap, pixel, nside, badval) pixel, nside = None, None hpxmap = healpix.masked_array(hpxmap, badval) hpxmap = healpix.smooth(hpxmap, sigma=smooth) vmin, vmax = np.percentile(hpxmap.compressed(), [2.5, 97.5]) defaults = dict(rasterized=True, vmin=vmin, vmax=vmax) setdefaults(kwargs, defaults) lon, lat, values = healpix.hpx2xy(hpxmap, pixel=pixel, nside=nside, xsize=xsize, lonra=lonra, latra=latra) im = self.pcolormesh(lon, lat, values, **kwargs) self._sci(im) return im, lon, lat, values
def default_gridlines(self, func, *args, **kwargs): """ Default gridlines options. """ fmt = mticker.FuncFormatter(lambda v, pos: '{:g}'.format(v)) defaults = dict(linestyle=':', xformatter=fmt, yformatter=fmt, draw_labels=True, crs=ccrs.PlateCarree()) setdefaults(kwargs, defaults) result = func(self, *args, **kwargs) return result
def __init__(self, *args, **kwargs): defaults = dict(projection='laea', lon_0=120, lat_0=-90, llcrnrlon=-110, llcrnrlat=8, urcrnrlon=60, urcrnrlat=-15, round=False, celestial=False) setdefaults(kwargs, defaults) super(SurveySkymap, self).__init__(*args, **kwargs)
def draw_meridians(self, *args, **kwargs): defaults = dict(labels=[1, 1, 1, 1], fontsize=14, labelstyle='+/-') setdefaults(kwargs, defaults) _ = kwargs.pop('cardinal', False) meridict = super(OrthoSkymap, self).draw_meridians(*args, **kwargs) # We've switched to celestial, need to update meridian text for k, v in meridict.items(): text = v[1][0].get_text() if text.startswith('-'): text = text.replace('-', '+') elif text.startswith('+'): text = text.replace('+', '-') v[1][0].set_text(text) return meridict
def draw_smc(self, **kwargs): from cartosky.constants import RA_SMC, DEC_SMC, RADIUS_SMC defaults = dict(fc='0.7', ec='0.5') setdefaults(kwargs, defaults) proj = self.proj(RA_SMC, DEC_SMC) self.tissot(RA_SMC, DEC_SMC, RADIUS_SMC, **kwargs) plt.text(proj[0], proj[1], 'SMC', weight='bold', fontsize=8, ha='center', va='center', color='k')
def __init__(self, rect=None, *args, **kwargs): defaults = dict(gridlines=False, celestial=True) setdefaults(kwargs, defaults) do_celestial = kwargs['celestial'] super(SurveyZoom, self).__init__(*args, **kwargs) self.set_axes_limits() self.create_axes(rect) self.set_axes_limits() self.ax.set_frame_on(False) self.aa.grid(True, linestyle=':', color='k', lw=0.5) if do_celestial: self.invert_xaxis()
def draw_footprint(self, filename, **kwargs): """ Draw survey footpring polygon Parameters ---------- filename : path to polygon file to draw **kwargs : passed to draw_polygon Returns ------- poly : polygon """ defaults = dict(edgecolor='k', facecolor='none', lw=2) setdefaults(kwargs, defaults) self.draw_polygon(filename, **kwargs)
def draw_sfd(self, **kwargs): import healpy as hp from matplotlib.colors import LogNorm defaults = dict(rasterized=True, cmap=plt.cm.binary, norm=LogNorm()) setdefaults(kwargs, defaults) filename = get_datafile('lambda_sfd_ebv.fits') if not os.path.exists(filename): import subprocess url = "https://lambda.gsfc.nasa.gov/data/foregrounds/SFD/lambda_sfd_ebv.fits" print("Downloading SFD map from:\n %s" % url) subprocess.check_output(['curl', url, '--output', filename]) galhpx = hp.read_map(filename, verbose=False) celhpx = healpix.gal2cel(galhpx) return self.draw_hpxmap(celhpx, **kwargs)
def draw_parallels(self, *args, **kwargs): defaults = dict(labels=[0, 0, 0, 0]) setdefaults(kwargs, defaults) ret = super(DESLambert, self).draw_parallels(*args, **kwargs) ax = plt.gca() for k in ret.keys(): ax.annotate(r"$%+d{}^{\circ}$" % (k), self(0, k), xycoords='data', xytext=(+5, +5), textcoords='offset points', va='top', ha='left', fontsize=12) return ret
def draw_fields(self, fields, **kwargs): # Scatter point size is figsize dependent... defaults = dict(edgecolor='none', s=15) # case insensitive without changing input array names = dict([(n.lower(), n) for n in fields.dtype.names]) if self.projection == 'ortho': defaults.update(s=50) if 'filter' in names: colors = [COLORS[b] for b in fields[names['filter']]] defaults.update(c=colors) elif 'band' in names: colors = [COLORS[b] for b in fields[names['band']]] defaults.update(c=colors) setdefaults(kwargs, defaults) ra, dec = fields[names['ra']], fields[names['dec']] self.scatter(ra, dec, **kwargs)
def draw_milky_way(self, width=10, **kwargs): """ Draw the Milky Way galaxy. """ defaults = dict(lw=1.5, ls='-') setdefaults(kwargs, defaults) glon = np.linspace(0, 360, 500) glat = np.zeros_like(glon) ra, dec = gal2cel(glon, glat) line = self.draw_line_radec(ra, dec, **kwargs) ret = [line] if width: kwargs.update(ls='--', lw=1) for delta in [+width, -width]: ra, dec = gal2cel(glon, glat + delta) line = self.draw_line_radec(ra, dec, **kwargs) ret += [line] return ret
def draw_meridians(self, *args, **kwargs): def lon2str(deg): # This is a function just to remove some weird string formatting deg -= 360. * (deg >= 180) if (np.abs(deg) == 0): return r"$%d{}^{\circ}$" % (deg) elif (np.abs(deg) == 180): return r"$%+d{}^{\circ}$" % (np.abs(deg)) else: return r"$%+d{}^{\circ}$" % (deg) # defaults = dict(labels=[1,1,1,1],labelstyle='+/-', # fontsize=14,fmt=lon2str) defaults = dict(fmt=lon2str, labels=[1, 1, 1, 1], fontsize=14) if not args: defaults.update(meridians=np.arange(0, 360, 60)) setdefaults(kwargs, defaults) # return self.drawmeridians(*args,**kwargs) return super(DESLambert, self).draw_meridians(*args, **kwargs)
def draw_focal_planes(self, ra, dec, **kwargs): from cartosky.instrument.decam import DECamFocalPlane defaults = dict(alpha=0.2, color='red', edgecolors='none', lw=0, transform=ccrs.PlateCarree()) setdefaults(kwargs, defaults) ra, dec = np.atleast_1d(ra, dec) if len(ra) != len(dec): msg = "Dimensions of 'ra' and 'dec' do not match" raise ValueError(msg) decam = DECamFocalPlane() # Should make sure axis exists.... ax = plt.gca() for _ra, _dec in zip(ra, dec): corners = decam.rotate(_ra, _dec) collection = matplotlib.collections.PolyCollection( corners, **kwargs) ax.add_collection(collection) plt.draw()
def draw_line_radec(self, ra, dec, **kwargs): """Draw a line assuming a Geodetic transform. Parameters ---------- ra : right ascension (deg) dec : declination (deg) kwargs: passed to plot Returns ------- feat : cartopy.FeatureArtist """ # Color will fill a polygon... # https://github.com/SciTools/cartopy/issues/856 color = kwargs.pop('c', kwargs.pop('color', 'k')) defaults = dict(crs=ccrs.Geodetic(), edgecolor=color, facecolor='none') setdefaults(kwargs, defaults) line = LineString(list(zip(ra, dec))[::-1]) return self.ax.add_geometries([line], **kwargs)
def draw_inset_colorbar(self, *args, **kwargs): defaults = dict(bbox_to_anchor=(-0.01, 0.07, 1, 1)) setdefaults(kwargs, defaults) return super(DESLambert, self).draw_inset_colorbar(*args, **kwargs)
def __init__(self, *args, **kwargs): setdefaults(kwargs, self.defaults) super(BlissSkymap, self).__init__(*args, **kwargs)
def figure(cls, **kwargs): """ Create a figure of proper size """ defaults = dict(figsize=cls.FIGSIZE) setdefaults(kwargs, defaults) return plt.figure(**kwargs)