def xy2vec(self, x, y=None, direct=False): if y is None: x,y = npy.asarray(x) else: x,y = npy.asarray(x),npy.asarray(y) flip = self._flip theta = pi/2.-y*dtor # convert in radian phi = flip*x*dtor # convert in radian if not direct: return self.rotator.I(R.dir2vec(theta,phi)) else: return R.dir2vec(theta,phi)
def xy2vec(self, x, y=None, direct=False): if y is None: x, y = npy.asarray(x) else: x, y = npy.asarray(x), npy.asarray(y) flip = self._flip theta = pi / 2. - y * dtor # convert in radian phi = flip * x * dtor # convert in radian if not direct: return self.rotator.I(R.dir2vec(theta, phi)) else: return R.dir2vec(theta, phi)
def xy2vec(self, x, y=None, direct=False): if y is None: x,y = np.asarray(x) else: x,y = np.asarray(x),np.asarray(y) flip = self._flip theta = pi/2.-y*dtor # convert in radian phi = flip*x*dtor # convert in radian # dir2vec does not support 2d arrays, so first use flatten and then # reshape back to previous shape if not direct: vec = self.rotator.I(R.dir2vec(theta.flatten(),phi.flatten())) else: vec = R.dir2vec(theta.flatten(),phi.flatten()) vec = [v.reshape(theta.shape) for v in vec] return vec
def projtext(self,theta,phi,s, *args,**kwds): """Projtext is a wrapper around Axes.text to take into account the spherical projection. Modification of projtext vs text: Three args allowed: - theta, phi, text Additional keywords : - lonlat: if True, theta and phi are interpreted as longitude and latitude in degree, otherwise, as theta, phi in radian - coord: the coordinate system of the points, only used if the coordinate coordinate system of the Axes has been defined and in this case, a rotation is performed - rot: rotation to be applied =(a,b,c) : a,b will be position of the new Z axis, and c is rotation around this axis, all in degree. if None, no rotation is performed - direct: if True, the rotation to center the projection is not taken into account """ if phi is None: theta,phi = npy.asarray(theta) else: theta, phi = npy.asarray(theta), npy.asarray(phi) rot=kwds.pop('rot',None) if rot is not None: rot = npy.array(npy.atleast_1d(rot),copy=1) rot.resize(3) rot[1] = rot[1]-90. coord=self.proj.mkcoord(kwds.pop('coord',None))[::-1] lonlat=kwds.pop('lonlat',False) vec = R.dir2vec(theta,phi,lonlat=lonlat) vec = (R.Rotator(rot=rot,coord=coord,eulertype='Y')).I(vec) x,y = self.proj.vec2xy(vec,direct=kwds.pop('direct',False)) return self.text(x,y,s,*args,**kwds)
def projscatter(self, theta, phi=None, *args, **kwds): """Projscatter is a wrapper around :func:`matplotlib.Axes.scatter` to take into account the spherical projection. You can call this function as:: projscatter(theta, phi) # plot points at coord (theta, phi) projplot(thetaphi) # plot points at coord (thetaphi[0], thetaphi[1]) Parameters ---------- theta, phi : float, array-like Coordinates of point to plot. Can be put into one 2-d array, first line is then *theta* and second line is *phi*. See *lonlat* parameter for unit. lonlat : bool, optional If True, theta and phi are interpreted as longitude and latitude in degree, otherwise, as colatitude and longitude in radian coord : {'E', 'G', 'C', None}, optional The coordinate system of the points, only used if the coordinate coordinate system of the axes has been defined and in this case, a rotation is performed rot : None or sequence, optional rotation to be applied =(lon, lat, psi) : lon, lat will be position of the new Z axis, and psi is rotation around this axis, all in degree. if None, no rotation is performed direct : bool, optional if True, the rotation to center the projection is not taken into account Notes ----- Other keywords are passed to :func:`matplotlib.Axes.plot`. See Also -------- projplot, projtext """ save_input_data = hasattr(self.figure, 'zoomtool') if save_input_data: input_data = (theta, phi, args, kwds.copy()) if phi is None: theta, phi = np.asarray(theta) else: theta, phi = np.asarray(theta), np.asarray(phi) rot = kwds.pop('rot', None) if rot is not None: rot = np.array(np.atleast_1d(rot), copy=1) rot.resize(3) rot[1] = rot[1] - 90. coord = self.proj.mkcoord(kwds.pop('coord', None))[::-1] lonlat = kwds.pop('lonlat', False) vec = R.dir2vec(theta, phi, lonlat=lonlat) vec = (R.Rotator(rot=rot, coord=coord, eulertype='Y')).I(vec) x, y = self.proj.vec2xy(vec, direct=kwds.pop('direct', False)) s = self.scatter(x, y, *args, **kwds) if save_input_data: if not hasattr(self, '_scatter_data'): self._scatter_data = [] self._scatter_data.append((s, input_data)) return s
def projscatter(self,theta, phi=None,*args,**kwds): """Projscatter is a wrapper around :func:`matplotlib.Axes.scatter` to take into account the spherical projection. You can call this function as:: projscatter(theta, phi) # plot points at coord (theta, phi) projplot(thetaphi) # plot points at coord (thetaphi[0], thetaphi[1]) Parameters ---------- theta, phi : float, array-like Coordinates of point to plot. Can be put into one 2-d array, first line is then *theta* and second line is *phi*. See *lonlat* parameter for unit. lonlat : bool, optional If True, theta and phi are interpreted as longitude and latitude in degree, otherwise, as colatitude and longitude in radian coord : {'E', 'G', 'C', None}, optional The coordinate system of the points, only used if the coordinate coordinate system of the axes has been defined and in this case, a rotation is performed rot : None or sequence, optional rotation to be applied =(lon, lat, psi) : lon, lat will be position of the new Z axis, and psi is rotation around this axis, all in degree. if None, no rotation is performed direct : bool, optional if True, the rotation to center the projection is not taken into account Notes ----- Other keywords are passed to :func:`matplotlib.Axes.plot`. See Also -------- projplot, projtext """ save_input_data = hasattr(self.figure, 'zoomtool') if save_input_data: input_data = (theta, phi, args, kwds.copy()) if phi is None: theta,phi = np.asarray(theta) else: theta, phi = np.asarray(theta), np.asarray(phi) rot=kwds.pop('rot',None) if rot is not None: rot = np.array(np.atleast_1d(rot),copy=1) rot.resize(3) rot[1] = rot[1]-90. coord=self.proj.mkcoord(kwds.pop('coord',None))[::-1] lonlat=kwds.pop('lonlat',False) vec = R.dir2vec(theta,phi,lonlat=lonlat) vec = (R.Rotator(rot=rot,coord=coord,eulertype='Y')).I(vec) x,y = self.proj.vec2xy(vec,direct=kwds.pop('direct',False)) s = self.scatter(x, y, *args, **kwds) if save_input_data: if not hasattr(self, '_scatter_data'): self._scatter_data = [] self._scatter_data.append((s, input_data)) return s
def projtext(self, theta, phi, s, *args, **kwds): """Projtext is a wrapper around Axes.text to take into account the spherical projection. Modification of projtext vs text: Three args allowed: - theta, phi, text Additional keywords : - lonlat: if True, theta and phi are interpreted as longitude and latitude in degree, otherwise, as theta, phi in radian - coord: the coordinate system of the points, only used if the coordinate coordinate system of the Axes has been defined and in this case, a rotation is performed - rot: rotation to be applied =(a,b,c) : a,b will be position of the new Z axis, and c is rotation around this axis, all in degree. if None, no rotation is performed - direct: if True, the rotation to center the projection is not taken into account """ if phi is None: theta, phi = npy.asarray(theta) else: theta, phi = npy.asarray(theta), npy.asarray(phi) rot = kwds.pop('rot', None) if rot is not None: rot = npy.array(npy.atleast_1d(rot), copy=1) rot.resize(3) rot[1] = rot[1] - 90. coord = self.proj.mkcoord(kwds.pop('coord', None))[::-1] lonlat = kwds.pop('lonlat', False) vec = R.dir2vec(theta, phi, lonlat=lonlat) vec = (R.Rotator(rot=rot, coord=coord, eulertype='Y')).I(vec) x, y = self.proj.vec2xy(vec, direct=kwds.pop('direct', False)) return self.text(x, y, s, *args, **kwds)
def projtext(self, theta, phi, s, **kwds): """Projtext is a wrapper around :func:`matplotlib.Axes.text` to take into account the spherical projection. Parameters ---------- theta, phi : float, array-like Coordinates of point to plot. Can be put into one 2-d array, first line is then *theta* and second line is *phi*. See *lonlat* parameter for unit. text : str The text to be displayed. lonlat : bool, optional If True, theta and phi are interpreted as longitude and latitude in degree, otherwise, as colatitude and longitude in radian coord : {'E', 'G', 'C', None}, optional The coordinate system of the points, only used if the coordinate coordinate system of the axes has been defined and in this case, a rotation is performed rot : None or sequence, optional rotation to be applied =(lon, lat, psi) : lon, lat will be position of the new Z axis, and psi is rotation around this axis, all in degree. if None, no rotation is performed direct : bool, optional if True, the rotation to center the projection is not taken into account Notes ----- Other keywords are passed to :func:`matplotlib.Axes.text`. See Also -------- projplot, projscatter """ if phi is None: theta,phi = npy.asarray(theta) else: theta, phi = npy.asarray(theta), npy.asarray(phi) rot=kwds.pop('rot',None) if rot is not None: rot = npy.array(npy.atleast_1d(rot),copy=1) rot.resize(3) rot[1] = rot[1]-90. coord=self.proj.mkcoord(kwds.pop('coord',None))[::-1] lonlat=kwds.pop('lonlat',False) vec = R.dir2vec(theta,phi,lonlat=lonlat) vec = (R.Rotator(rot=rot,coord=coord,eulertype='Y')).I(vec) x,y = self.proj.vec2xy(vec,direct=kwds.pop('direct',False)) return self.text(x,y,s,**kwds)
def projtext(self, theta, phi, s, **kwds): """Projtext is a wrapper around :func:`matplotlib.Axes.text` to take into account the spherical projection. Parameters ---------- theta, phi : float, array-like Coordinates of point to plot. Can be put into one 2-d array, first line is then *theta* and second line is *phi*. See *lonlat* parameter for unit. text : str The text to be displayed. lonlat : bool, optional If True, theta and phi are interpreted as longitude and latitude in degree, otherwise, as colatitude and longitude in radian coord : {'E', 'G', 'C', None}, optional The coordinate system of the points, only used if the coordinate coordinate system of the axes has been defined and in this case, a rotation is performed rot : None or sequence, optional rotation to be applied =(lon, lat, psi) : lon, lat will be position of the new Z axis, and psi is rotation around this axis, all in degree. if None, no rotation is performed direct : bool, optional if True, the rotation to center the projection is not taken into account Notes ----- Other keywords are passed to :func:`matplotlib.Axes.text`. See Also -------- projplot, projscatter """ if phi is None: theta, phi = npy.asarray(theta) else: theta, phi = npy.asarray(theta), npy.asarray(phi) rot = kwds.pop('rot', None) if rot is not None: rot = npy.array(npy.atleast_1d(rot), copy=1) rot.resize(3) rot[1] = rot[1] - 90. coord = self.proj.mkcoord(kwds.pop('coord', None))[::-1] lonlat = kwds.pop('lonlat', False) vec = R.dir2vec(theta, phi, lonlat=lonlat) vec = (R.Rotator(rot=rot, coord=coord, eulertype='Y')).I(vec) x, y = self.proj.vec2xy(vec, direct=kwds.pop('direct', False)) return self.text(x, y, s, **kwds)
def projscatter(self,theta, phi=None,*args,**kwds): """Projscatter is a wrapper around Axes.scatter to take into account the spherical projection. Modification of projscatter vs scatter: One or two args allowed: - if one arg: arg = [theta,phi] - if two args: args[0]=theta,args[1]=phi Additional keywords : - lonlat: if True, theta and phi are interpreted as longitude and latitude in degree, otherwise, as theta, phi in radian - coord: the coordinate system of the points, only used if the coordinate coordinate system of the Axes has been defined and in this case, a rotation is performed - rot: rotation to be applied =(a,b,c) : a,b will be position of the new Z axis, and c is rotation around this axis, all in degree. if None, no rotation is performed - direct: if True, the rotation to center the projection is not taken into account """ save_input_data = hasattr(self.figure, 'zoomtool') if save_input_data: input_data = (theta, phi, args, kwds.copy()) if phi is None: theta,phi = npy.asarray(theta) else: theta, phi = npy.asarray(theta), npy.asarray(phi) rot=kwds.pop('rot',None) if rot is not None: rot = npy.array(npy.atleast_1d(rot),copy=1) rot.resize(3) rot[1] = rot[1]-90. coord=self.proj.mkcoord(kwds.pop('coord',None))[::-1] lonlat=kwds.pop('lonlat',False) vec = R.dir2vec(theta,phi,lonlat=lonlat) vec = (R.Rotator(rot=rot,coord=coord,eulertype='Y')).I(vec) x,y = self.proj.vec2xy(vec,direct=kwds.pop('direct',False)) s = self.scatter(x, y, *args, **kwds) if save_input_data: if not hasattr(self, '_scatter_data'): self._scatter_data = [] self._scatter_data.append((s, input_data)) return s
def projscatter(self, theta, phi=None, *args, **kwds): """Projscatter is a wrapper around Axes.scatter to take into account the spherical projection. Modification of projscatter vs scatter: One or two args allowed: - if one arg: arg = [theta,phi] - if two args: args[0]=theta,args[1]=phi Additional keywords : - lonlat: if True, theta and phi are interpreted as longitude and latitude in degree, otherwise, as theta, phi in radian - coord: the coordinate system of the points, only used if the coordinate coordinate system of the Axes has been defined and in this case, a rotation is performed - rot: rotation to be applied =(a,b,c) : a,b will be position of the new Z axis, and c is rotation around this axis, all in degree. if None, no rotation is performed - direct: if True, the rotation to center the projection is not taken into account """ save_input_data = hasattr(self.figure, 'zoomtool') if save_input_data: input_data = (theta, phi, args, kwds.copy()) if phi is None: theta, phi = npy.asarray(theta) else: theta, phi = npy.asarray(theta), npy.asarray(phi) rot = kwds.pop('rot', None) if rot is not None: rot = npy.array(npy.atleast_1d(rot), copy=1) rot.resize(3) rot[1] = rot[1] - 90. coord = self.proj.mkcoord(kwds.pop('coord', None))[::-1] lonlat = kwds.pop('lonlat', False) vec = R.dir2vec(theta, phi, lonlat=lonlat) vec = (R.Rotator(rot=rot, coord=coord, eulertype='Y')).I(vec) x, y = self.proj.vec2xy(vec, direct=kwds.pop('direct', False)) s = self.scatter(x, y, *args, **kwds) if save_input_data: if not hasattr(self, '_scatter_data'): self._scatter_data = [] self._scatter_data.append((s, input_data)) return s
def xy2vec(self, x, y=None, direct=False): if y is None: x,y = x if hasattr(x,'__len__'): x,y = np.asarray(x),np.asarray(y) if self.arrayinfo is None: raise TypeError("No projection plane array information defined for" " this projector") half_sky = self.arrayinfo['half_sky'] flip = self._flip # re-fold back of sphere mask = None if not half_sky: if hasattr(x,'__len__'): if np.any(x>0.0): mask = (x>0.0) x[mask] *= -1 elif x>0: mask = 0 x = -x x+=1.0 r = np.sqrt(x**2+y**2) if hasattr(r,'__len__'): r[r>1] = np.nan elif r>1: r = np.nan c = np.arcsin(r) if hasattr(y,'__len__'): y[np.abs(y)>1] = np.nan elif np.abs(y)>1: y = np.nan lat = np.arcsin(y) phi = np.arctan2(x,np.cos(c)) phi *= flip if not mask is None: if hasattr(phi,'__len__'): phi[mask] = pi-phi[mask] else: phi = pi-phi theta = pi/2. - lat vec = R.dir2vec(theta,phi) if not direct: return self.rotator.I(vec) else: return vec
def projplot(self,*args,**kwds): """projplot is a wrapper around :func:`matplotlib.Axes.plot` to take into account the spherical projection. You can call this function as:: projplot(theta, phi) # plot a line going through points at coord (theta, phi) projplot(theta, phi, 'bo') # plot 'o' in blue at coord (theta, phi) projplot(thetaphi) # plot a line going through points at coord (thetaphi[0], thetaphi[1]) projplot(thetaphi, 'bx') # idem but with blue 'x' Parameters ---------- theta, phi : float, array-like Coordinates of point to plot. Can be put into one 2-d array, first line is then *theta* and second line is *phi*. See *lonlat* parameter for unit. fmt : str A format string (see :func:`matplotlib.Axes.plot` for details) lonlat : bool, optional If True, theta and phi are interpreted as longitude and latitude in degree, otherwise, as colatitude and longitude in radian coord : {'E', 'G', 'C', None} The coordinate system of the points, only used if the coordinate coordinate system of the Axes has been defined and in this case, a rotation is performed rot : None or sequence rotation to be applied =(lon, lat, psi) : lon, lat will be position of the new Z axis, and psi is rotation around this axis, all in degree. if None, no rotation is performed direct : bool if True, the rotation to center the projection is not taken into account Notes ----- Other keywords are passed to :func:`matplotlib.Axes.plot`. See Also -------- projscatter, projtext """ fmt = None if len(args) < 1: raise ValueError("No argument given") if len(args) == 1: theta,phi = np.asarray(args[0]) elif len(args) == 2: if type(args[1]) is str: fmt=args[1] theta,phi = np.asarray(args[0]) else: theta,phi = np.asarray(args[0]),np.asarray(args[1]) elif len(args) == 3: if type(args[2]) is not str: raise TypeError("Third argument must be a string") else: theta,phi = np.asarray(args[0]),np.asarray(args[1]) fmt = args[2] else: raise TypeError("Three args maximum") rot=kwds.pop('rot',None) if rot is not None: rot = np.array(np.atleast_1d(rot),copy=1) rot.resize(3) rot[1] = rot[1]-90. coord=self.proj.mkcoord(kwds.pop('coord',None))[::-1] lonlat=kwds.pop('lonlat',False) vec = R.dir2vec(theta,phi,lonlat=lonlat) vec = (R.Rotator(rot=rot,coord=coord,eulertype='Y')).I(vec) x,y = self.proj.vec2xy(vec,direct=kwds.pop('direct',False)) x,y = self._make_segment(x,y,threshold=kwds.pop('threshold', self._segment_threshold)) thelines = [] for xx,yy in zip(x,y): if fmt is not None: linestyle, marker, color = axes._process_plot_format(fmt) kwds.setdefault('linestyle',linestyle) kwds.setdefault('marker',marker) if color is not None: kwds.setdefault('color',color) l = lines.Line2D(xx,yy,**kwds) self.add_line(l) thelines.append(l) return thelines
def projplot(self,*args,**kwds): """projplot is a wrapper around Axes.plot to take into account the spherical projection. Modification of projplot vs plot: One, two or three args allowed: - if one arg: theta,phi = args[0][0],args[0][1] - if two : either theta,phi or [theta,phi],fmt - if three: theta,phi,fmt with fmt the format string. Additional keywords : - lonlat: if True, theta and phi are interpreted as longitude and latitude in degree, otherwise, as theta, phi in radian - coord: the coordinate system of the points, only used if the coordinate coordinate system of the Axes has been defined and in this case, a rotation is performed - rot: rotation to be applied =(a,b,c) : a,b will be position of the new Z axis, and c is rotation around this axis, all in degree. if None, no rotation is performed - direct: if True, the rotation to center the projection is not taken into account """ fmt = None if len(args) < 1: raise ValueError("No argument given") if len(args) == 1: theta,phi = npy.asarray(args[0]) elif len(args) == 2: if type(args[1]) is str: fmt=args[1] theta,phi = npy.asarray(args[0]) else: theta,phi = npy.asarray(args[0]),npy.asarray(args[1]) elif len(args) == 3: if type(args[2]) is not str: raise TypeError("Third argument must be a string") else: theta,phi = npy.asarray(args[0]),npy.asarray(args[1]) fmt = args[2] else: raise TypeError("Three args maximum") rot=kwds.pop('rot',None) if rot is not None: rot = npy.array(npy.atleast_1d(rot),copy=1) rot.resize(3) rot[1] = rot[1]-90. coord=self.proj.mkcoord(kwds.pop('coord',None))[::-1] lonlat=kwds.pop('lonlat',False) vec = R.dir2vec(theta,phi,lonlat=lonlat) vec = (R.Rotator(rot=rot,coord=coord,eulertype='Y')).I(vec) x,y = self.proj.vec2xy(vec,direct=kwds.pop('direct',False)) x,y = self._make_segment(x,y,threshold=kwds.pop('threshold', self._segment_threshold)) thelines = [] for xx,yy in zip(x,y): if fmt is not None: linestyle, marker, color = axes._process_plot_format(fmt) kwds.setdefault('linestyle',linestyle) kwds.setdefault('marker',marker) if color is not None: kwds.setdefault('color',color) l = lines.Line2D(xx,yy,**kwds) self.add_line(l) thelines.append(l) return thelines
def graticule(self, dpar=None, dmer=None, coord=None, local=None, verbose=True, **kwds): """Draw a graticule. Input: - dpar: angular separation between parallels in degree - dmer: angular separation between meridians in degree - coord: coordinate system of the graticule ('G', 'E' or 'C') - local: if True, no rotation performed at all """ gratargs = (dpar, dmer, coord, local) gratkwds = kwds if dpar is None: dpar = self._gratdef['dpar'] if local is None: local = self._gratdef['local'] if dmer is None: dmer = dpar dpar = abs(dpar) * dtor dmer = abs(dmer) * dtor if not local: vec = R.dir2vec(self.proj.get_center()) vec0 = R.Rotator(coord=self.proj.mkcoord(coord=coord)).I(vec) else: vec = (1, 0, 0) vec0 = (1, 0, 0) u_pmin, u_pmax = kwds.pop('pmax', None), kwds.pop('pmin', None) u_mmin, u_mmax = kwds.pop('mmin', None), kwds.pop('mmax', None) if u_pmin: u_pmin = (pi / 2. - u_pmin * dtor) % pi if u_pmax: u_pmax = (pi / 2. - u_pmax * dtor) % pi if u_mmin: u_mmin = (((u_mmin + 180.) % 360) - 180) * dtor if u_mmax: u_mmax = (((u_mmax + 180.) % 360) - 180) * dtor pmin, pmax = self.get_parallel_interval(vec0) mmin, mmax = self.get_meridian_interval(vec0) if u_pmin: pmin = u_pmin if u_pmax: pmax = u_pmax if u_mmin: mmin = u_mmin if u_mmax: mmax = u_pmax if verbose: print pmin / dtor, pmax / dtor, mmin / dtor, mmax / dtor if not kwds.pop('force', False): dpar, dmer = self._get_interv_graticule(pmin, pmax, dpar, mmin, mmax, dmer, verbose=verbose) theta_list = np.around( np.arange(pmin, pmax + 0.5 * dpar, dpar) / dpar) * dpar phi_list = np.around( np.arange(mmin, mmax + 0.5 * dmer, dmer) / dmer) * dmer theta = np.arange(pmin, pmax, min((pmax - pmin) / 100., self._segment_step_rad)) phi = np.arange(mmin, mmax, min((mmax - mmin) / 100., self._segment_step_rad)) equator = False gratlines = [] kwds.setdefault('lw', 1) kwds.setdefault('color', 'k') for t in theta_list: if abs(t - pi / 2.) < 1.e-10: fmt = '-' equator = True elif abs(t) < 1.e-10: # special case: north pole t = 1.e-10 fmt = '-' elif abs(t - pi) < 1.e-10: # special case: south pole t = pi - 1.e-10 fmt = '-' else: fmt = ':' gratlines.append( self.projplot(phi * 0. + t, phi, fmt, coord=coord, direct=local, **kwds)) if not equator and pmin <= pi / 2. and pi / 2 <= pmax: gratlines.append( self.projplot(phi * 0. + pi / 2., phi, '-', coord=coord, direct=local, **kwds)) for p in phi_list: if abs(p) < 1.e-10: fmt = '-' else: fmt = ':' gratlines.append( self.projplot(theta, theta * 0. + p, fmt, coord=coord, direct=local, **kwds)) # Now the borders (only useful for full sky projection) if hasattr(self, '_do_border') and self._do_border: theta = np.arange(0, 181) * dtor gratlines.append( self.projplot(theta, theta * 0 - pi, '-k', lw=1, direct=True)) gratlines.append( self.projplot(theta, theta * 0 + 0.9999 * pi, '-k', lw=1, direct=True)) phi = np.arange(-180, 180) * dtor gratlines.append( self.projplot(phi * 0 + 1.e-10, phi, '-k', lw=1, direct=True)) gratlines.append( self.projplot(phi * 0 + pi - 1.e-10, phi, '-k', lw=1, direct=True)) if hasattr(self, '_graticules'): self._graticules.append((gratargs, gratkwds, gratlines)) else: self._graticules = [(gratargs, gratkwds, gratlines)] return dpar, dmer
def projplot(self, *args, **kwds): """projplot is a wrapper around :func:`matplotlib.Axes.plot` to take into account the spherical projection. You can call this function as:: projplot(theta, phi) # plot a line going through points at coord (theta, phi) projplot(theta, phi, 'bo') # plot 'o' in blue at coord (theta, phi) projplot(thetaphi) # plot a line going through points at coord (thetaphi[0], thetaphi[1]) projplot(thetaphi, 'bx') # idem but with blue 'x' Parameters ---------- theta, phi : float, array-like Coordinates of point to plot. Can be put into one 2-d array, first line is then *theta* and second line is *phi*. See *lonlat* parameter for unit. fmt : str A format string (see :func:`matplotlib.Axes.plot` for details) lonlat : bool, optional If True, theta and phi are interpreted as longitude and latitude in degree, otherwise, as colatitude and longitude in radian coord : {'E', 'G', 'C', None} The coordinate system of the points, only used if the coordinate coordinate system of the Axes has been defined and in this case, a rotation is performed rot : None or sequence rotation to be applied =(lon, lat, psi) : lon, lat will be position of the new Z axis, and psi is rotation around this axis, all in degree. if None, no rotation is performed direct : bool if True, the rotation to center the projection is not taken into account Notes ----- Other keywords are passed to :func:`matplotlib.Axes.plot`. See Also -------- projscatter, projtext """ fmt = None if len(args) < 1: raise ValueError("No argument given") if len(args) == 1: theta, phi = np.asarray(args[0]) elif len(args) == 2: if type(args[1]) is str: fmt = args[1] theta, phi = np.asarray(args[0]) else: theta, phi = np.asarray(args[0]), np.asarray(args[1]) elif len(args) == 3: if type(args[2]) is not str: raise TypeError("Third argument must be a string") else: theta, phi = np.asarray(args[0]), np.asarray(args[1]) fmt = args[2] else: raise TypeError("Three args maximum") rot = kwds.pop('rot', None) if rot is not None: rot = np.array(np.atleast_1d(rot), copy=1) rot.resize(3) rot[1] = rot[1] - 90. coord = self.proj.mkcoord(kwds.pop('coord', None))[::-1] lonlat = kwds.pop('lonlat', False) vec = R.dir2vec(theta, phi, lonlat=lonlat) vec = (R.Rotator(rot=rot, coord=coord, eulertype='Y')).I(vec) x, y = self.proj.vec2xy(vec, direct=kwds.pop('direct', False)) x, y = self._make_segment(x, y, threshold=kwds.pop('threshold', self._segment_threshold)) thelines = [] for xx, yy in zip(x, y): if fmt is not None: linestyle, marker, color = axes._process_plot_format(fmt) kwds.setdefault('linestyle', linestyle) kwds.setdefault('marker', marker) if color is not None: kwds.setdefault('color', color) l = lines.Line2D(xx, yy, **kwds) self.add_line(l) thelines.append(l) return thelines
def projplot(self, *args, **kwds): """projplot is a wrapper around Axes.plot to take into account the spherical projection. Modification of projplot vs plot: One, two or three args allowed: - if one arg: theta,phi = args[0][0],args[0][1] - if two : either theta,phi or [theta,phi],fmt - if three: theta,phi,fmt with fmt the format string. Additional keywords : - lonlat: if True, theta and phi are interpreted as longitude and latitude in degree, otherwise, as theta, phi in radian - coord: the coordinate system of the points, only used if the coordinate coordinate system of the Axes has been defined and in this case, a rotation is performed - rot: rotation to be applied =(a,b,c) : a,b will be position of the new Z axis, and c is rotation around this axis, all in degree. if None, no rotation is performed - direct: if True, the rotation to center the projection is not taken into account """ fmt = None if len(args) < 1: raise ValueError("No argument given") if len(args) == 1: theta, phi = npy.asarray(args[0]) elif len(args) == 2: if type(args[1]) is str: fmt = args[1] theta, phi = npy.asarray(args[0]) else: theta, phi = npy.asarray(args[0]), npy.asarray(args[1]) elif len(args) == 3: if type(args[2]) is not str: raise TypeError("Third argument must be a string") else: theta, phi = npy.asarray(args[0]), npy.asarray(args[1]) fmt = args[2] else: raise TypeError("Three args maximum") rot = kwds.pop('rot', None) if rot is not None: rot = npy.array(npy.atleast_1d(rot), copy=1) rot.resize(3) rot[1] = rot[1] - 90. coord = self.proj.mkcoord(kwds.pop('coord', None))[::-1] lonlat = kwds.pop('lonlat', False) vec = R.dir2vec(theta, phi, lonlat=lonlat) vec = (R.Rotator(rot=rot, coord=coord, eulertype='Y')).I(vec) x, y = self.proj.vec2xy(vec, direct=kwds.pop('direct', False)) x, y = self._make_segment(x, y, threshold=kwds.pop('threshold', self._segment_threshold)) thelines = [] for xx, yy in zip(x, y): if fmt is not None: linestyle, marker, color = axes._process_plot_format(fmt) kwds.setdefault('linestyle', linestyle) kwds.setdefault('marker', marker) if color is not None: kwds.setdefault('color', color) l = lines.Line2D(xx, yy, **kwds) self.add_line(l) thelines.append(l) return thelines
def ang2xy(self, theta, phi=None, lonlat=False, direct=False): return self.vec2xy(R.dir2vec(theta,phi,lonlat=lonlat),direct=direct)
def graticule(self,dpar=None,dmer=None,coord=None,local=None,verbose=True,**kwds): """Draw a graticule. Input: - dpar: angular separation between parallels in degree - dmer: angular separation between meridians in degree - coord: coordinate system of the graticule ('G', 'E' or 'C') - local: if True, no rotation performed at all """ gratargs = (dpar,dmer,coord,local) gratkwds = kwds if dpar is None: dpar=self._gratdef['dpar'] if local is None: local=self._gratdef['local'] if dmer is None: dmer = dpar dpar = abs(dpar)*dtor dmer = abs(dmer)*dtor if not local: vec = R.dir2vec(self.proj.get_center()) vec0 = R.Rotator(coord=self.proj.mkcoord(coord=coord)).I(vec) else: vec = (1,0,0) vec0 = (1,0,0) u_pmin,u_pmax = kwds.pop('pmax',None),kwds.pop('pmin',None) u_mmin,u_mmax = kwds.pop('mmin',None),kwds.pop('mmax',None) if u_pmin: u_pmin = (pi/2.-u_pmin*dtor)%pi if u_pmax: u_pmax = (pi/2.-u_pmax*dtor)%pi if u_mmin: u_mmin = ( ((u_mmin+180.)%360)-180)*dtor if u_mmax: u_mmax = ( ((u_mmax+180.)%360)-180)*dtor pmin,pmax = self.get_parallel_interval(vec0) mmin,mmax = self.get_meridian_interval(vec0) if u_pmin: pmin = u_pmin if u_pmax: pmax = u_pmax if u_mmin: mmin = u_mmin if u_mmax: mmax = u_pmax if verbose: print pmin/dtor,pmax/dtor,mmin/dtor,mmax/dtor if not kwds.pop('force',False): dpar,dmer = self._get_interv_graticule(pmin,pmax,dpar, mmin,mmax,dmer, verbose=verbose) theta_list = np.around(np.arange(pmin,pmax+0.5*dpar,dpar)/dpar)*dpar phi_list = np.around(np.arange(mmin,mmax+0.5*dmer,dmer)/dmer)*dmer theta = np.arange(pmin,pmax,min((pmax-pmin)/100., self._segment_step_rad)) phi = np.arange(mmin,mmax,min((mmax-mmin)/100., self._segment_step_rad)) equator = False gratlines = [] kwds.setdefault('lw',1) kwds.setdefault('color','k') for t in theta_list: if abs(t-pi/2.)<1.e-10: fmt = '-' equator=True elif abs(t) < 1.e-10: # special case: north pole t = 1.e-10 fmt = '-' elif abs(t-pi) < 1.e-10: # special case: south pole t = pi-1.e-10 fmt = '-' else: fmt =':' gratlines.append(self.projplot(phi*0.+t, phi,fmt, coord=coord, direct=local,**kwds)) if not equator and pmin <= pi/2. and pi/2 <= pmax: gratlines.append(self.projplot(phi*0.+pi/2., phi,'-', coord=coord, direct=local,**kwds)) for p in phi_list: if abs(p)<1.e-10: fmt = '-' else: fmt =':' gratlines.append(self.projplot(theta, theta*0.+p,fmt, coord=coord, direct=local,**kwds)) # Now the borders (only useful for full sky projection) if hasattr(self,'_do_border') and self._do_border: theta = np.arange(0,181)*dtor gratlines.append(self.projplot(theta, theta*0-pi,'-k', lw=1,direct=True)) gratlines.append(self.projplot(theta, theta*0+0.9999*pi,'-k', lw=1,direct=True)) phi = np.arange(-180,180)*dtor gratlines.append(self.projplot(phi*0+1.e-10, phi,'-k', lw=1,direct=True)) gratlines.append(self.projplot(phi*0+pi-1.e-10, phi,'-k', lw=1,direct=True)) if hasattr(self,'_graticules'): self._graticules.append((gratargs,gratkwds,gratlines)) else: self._graticules = [(gratargs,gratkwds,gratlines)] return dpar,dmer