def __init__(self, lons, lats, face_nodes, img): """ lons, lats : 1d array in node index order face_nodes: iterable of iterable of node index img: 1d array of source data. Same length as face nodes """ # convert to 3d space self._geocent = ccrs.Geocentric(globe=ccrs.Globe()) self.img = img xyz = self._geocent.transform_points(ccrs.Geodetic(), lons, lats) self._nodes_xyz = xyz start = time.time() self._kd = KDTree(xyz) end = time.time() logging.info('KD Construction time ({} points): {}'.format( lons.size, end - start)) self._face_nodes = np.array(face_nodes) self._node_faces = fmgc.create_node_faces_array(self._face_nodes, num_nodes=len(lons))
def test_transform_points_xyz(self): # Test geodetic transforms when using z value rx = np.array([2574.32516e3]) ry = np.array([837.562e3]) rz = np.array([5761.325e3]) src_proj = ccrs.Geocentric() target_proj = ccrs.Geodetic() res = target_proj.transform_points(x=rx, y=ry, z=rz, src_crs=src_proj) glat = res[..., 0] glon = res[..., 1] galt = res[..., 2] # Solution generated by pyproj solx = np.array([18.0224043189]) soly = np.array([64.9796515089]) solz = np.array([5048.03893734]) assert_arr_almost_eq(glat, solx) assert_arr_almost_eq(glon, soly) assert_arr_almost_eq(galt, solz)
def mpl_plot(data2d,lon,lat,title,longname,units,proj,clev,cmap,gllfile): # Setup the plot figure = pyplot.figure(figsize=(15, 10)) dataproj=crs.PlateCarree() # pcolor/tripcolor doesn't use nelvels or contour intervals if len(clev)==1: vmin=None vmax=None nlevels=int(round(clev[0])) else: vmin=clev[0] vmax=clev[1] nlevels=int(round( (clev[1]-clev[0])/clev[2] )) if proj=="latlon": plotproj=crs.PlateCarree(central_longitude=0.0) ax = pyplot.axes(projection=plotproj) ax.set_global() elif proj=="US1": plotproj=plotproj=crs.PlateCarree(central_longitude=0.0) ax = pyplot.axes(projection=plotproj) ax.set_extent([-180, 0, -30, 75],crs=dataproj) elif proj=="andes": plotproj=plotproj=crs.PlateCarree(central_longitude=0.0) ax = pyplot.axes(projection=plotproj) ax.set_extent([-100, -40, -40, 15],crs=dataproj) elif proj=="himalaya": plotproj=plotproj=crs.PlateCarree(central_longitude=90.0) ax = pyplot.axes(projection=plotproj) ax.set_extent([50, 110, 0, 60],crs=dataproj) elif proj=="oro": plotproj=crs.Orthographic(central_longitude=-45.0, central_latitude=45.0) ax = pyplot.axes(projection=plotproj) ax.set_global() else: print("Bad projection argument: ",projection) sys.exit(3) ax.coastlines(linewidth=0.2) # strucgtured lat/lon or unstructured data? struct=False if len(lon)*len(lat) == numpy.prod(data2d.shape): struct=True compute_tri=True if ~struct and os.path.isfile(gllfile): cfile = Nio.open_file(gllfile,"r") ec=cfile.variables["element_corners"] nd=ec.shape # by Euler, number of subcells is number of gll nodes -2 if (nd[1] == len(lat)-2): ntris=nd[1]*2 tri=numpy.empty((ntris,3), dtype=int) tri[::2,0]=ec[0,:] tri[::2,1]=ec[1,:] tri[::2,2]=ec[2,:] tri[1::2,0]=ec[0,:] tri[1::2,1]=ec[2,:] tri[1::2,2]=ec[3,:] tri=tri-1 # zero indexing compute_tri=False print("data min/max=",numpy.amin(data2d),numpy.amax(data2d)) print("colormap min/max=",vmin,vmax) if struct: data2d_ext, lon2 = add_cyclic_point(data2d, coord=lon,axis=1) print("MPL plotting structured data (with added cyclic point)") pl=ax.pcolormesh(lon2, lat, data2d_ext,vmin=vmin,vmax=vmax, transform=dataproj, cmap=cmap) #pl=ax.contourf(lon2, lat, data2d_ext, nlevels,vmin=vmin,vmax=vmax, # transform=dataproj, cmap=cmap) elif compute_tri: print("MPL plot using internal Delaunay triangulation") # do the triangulation in the plot coordinates for better results tcoords = plotproj.transform_points(dataproj,lon[:],lat[:]) # need to remove non-visible points xi=tcoords[:,0]!=numpy.inf tc=tcoords[xi,:] datai=data2d[:][xi] # convert to numpy array, then subset pl = ax.tripcolor(tc[:,0],tc[:,1], datai,vmin=vmin, vmax=vmax, shading='gouraud',cmap=cmap) else: print("MPL plot using gll subcell triangulation") # latlon->cartesian->local coords. this will put any seams at plot boundaries proj3d=crs.Geocentric() # for cartesian (x,y,z) representation x3d = proj3d.transform_points(dataproj,lon[:],lat[:]) tcoords = plotproj.transform_points(proj3d,x3d[:,0],x3d[:,1],x3d[:,2]) #Remove bad triangles: x0=tcoords[tri[:,0],0] y0=tcoords[tri[:,0],1] x1=tcoords[tri[:,1],0] y1=tcoords[tri[:,1],1] x2=tcoords[tri[:,2],0] y2=tcoords[tri[:,2],1] d=numpy.empty(tri.shape) d[:,0]=((x0-x1)**2 + (y0-y1)**2)**0.5 d[:,1]=((x0-x2)**2 + (y0-y2)**2)**0.5 d[:,2]=((x1-x2)**2 + (y1-y2)**2)**0.5 dmax=numpy.amax(d,axis=1) gmin=numpy.nanmin(dmax[dmax != numpy.inf]) gmax=numpy.nanmax(dmax[dmax != numpy.inf]) print("triangle max lengths: ",gmin,gmax) mask = numpy.logical_or( dmax > 25*gmin, numpy.isnan(dmax)) # gouraud shading requires we remove non-visable triangles pl = ax.tripcolor(tcoords[:,0],tcoords[:,1],tri,data2d,vmin=vmin,vmax=vmax, mask=mask,shading='gouraud',cmap=cmap) # plot some of the triangles to make sure they are ok: #ax.triplot(tcoords[:,0],tcoords[:,1],tri[1:100,:],'go-') cb = pyplot.colorbar(pl, orientation='horizontal', label='%s (%s)'%(longname, units),shrink=0.75, pad=0.1)