# In[12]: import mplleaflet #geodetic = ccrs.Geodetic(globe=ccrs.Globe(datum='WGS84')) #fig, ax = make_map(projection=geodetic) fig, ax = make_map() kw = dict(marker='.', linestyle='-', alpha=0.85, color='darkgray') kw = dict(linestyle='-', color='red') ax.triplot(triang, **kw) # or lon, lat, triangules; ax.set_extent([-87.5, -82.5, 29.4, 31]) # In[ ]: from cartopy.io.img_tiles import MapQuestOpenAerial, MapQuestOSM, OSM geodetic = ccrs.Geodetic(globe=ccrs.Globe(datum='WGS84')) fig = plt.figure(figsize=(12, 8)) tiler = MapQuestOpenAerial() ax = plt.axes(projection=tiler.crs) bbox = [-71, -69.3, 42, 42.8] #ax = plt.axes(projection=ccrs.PlateCarree()) ax.set_extent(bbox) ax.add_image(tiler, 8) #ax.coastlines() kw = dict(marker='.', linestyle='-', alpha=0.85, color='darkgray',
ax2 = plt.axes(rect, projection=ccrs.PlateCarree(), ) ax2.set_extent((110, 160, -45, -10)) # ax2.set_global() will show the whole world as context ax2.coastlines(resolution='110m', zorder=2) ax2.add_feature(cfeature.LAND) ax2.add_feature(cfeature.OCEAN) ax2.gridlines() lon0, lon1, lat0, lat1 = ax.get_extent() box_x = [lon0, lon1, lon1, lon0, lon0] box_y = [lat0, lat0, lat1, lat1, lat0] plt.plot(box_x, box_y, color='red', transform=ccrs.Geodetic()) # -------------------------------- Title ----------------------------- # set up map title top 4% of figure, right 80% of figure left = 0.2 bottom = 0.95 width = 0.8 height = 0.04 rect = [left, bottom, width, height] ax6 = plt.axes(rect) ax6.text(0.5, 0.0, 'Multi-Axes Map Example', ha='center', fontsize=20) blank_axes(ax6) # ---------------------------------North Arrow ---------------------------- #
import numpy as np import matplotlib.pyplot as plt import matplotlib.patches as patches import cartopy.crs as ccrs import cartopy.io.img_tiles as cimgt from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter from seisnn.io import read_hyp, read_event_list from seisnn.utils import get_config W, E, S, N = 119, 123, 21.5, 25.7 stamen_terrain = cimgt.Stamen('terrain-background') fig = plt.figure(figsize=(8, 10)) ax = fig.add_subplot(1, 1, 1, projection=stamen_terrain.crs) ax.set_extent([W, E, S, N], crs=ccrs.Geodetic()) ax.add_image(stamen_terrain, 11) events = read_event_list('HL201718') HL_eq = [] for event in events: HL_eq.append([event.origins[0].longitude, event.origins[0].latitude]) HL_eq = np.array(HL_eq).T ax.scatter(HL_eq[0], HL_eq[1], label='Earthquake', transform=ccrs.Geodetic(), color='#333333', edgecolors='k', linewidth=0.3, marker='o',
#for tick in ax.xaxis.get_major_ticks(): # tick.label.set_fontsize(SMFONT) # Label the end-points of the gridlines using the custom tick makers: #ax.xaxis.set_major_formatter(LONGITUDE_FORMATTER) #ax.yaxis.set_major_formatter(LATITUDE_FORMATTER) #mct_xticks(ax, xticks) #mct_yticks(ax, yticks) # Set the map bounds ax.set_xlim(cartopy_xlim(lsmask)) ax.set_ylim(cartopy_ylim(lsmask)) ax.plot(df_hko_obv['lon']/10., df_hko_obv['lat']/10., color='black', marker='o', linewidth=2, markersize=5, transform=ccrs.Geodetic(), label='HKO bestTrack') ax.plot(df_cma_obv['lon']/10., df_cma_obv['lat']/10., color='dimgray', marker='*', linewidth=2, linestyle='dashed', markersize=8, transform=ccrs.Geodetic(), label='CMA bestTrack') dateparse = lambda x: datetime.datetime.strptime(x, '%Y%m%d%H%M%S') for (line_type,casename) in zip(line_libs,cases): sen_path='/home/metctm1/array/data/1911-COAWST/'+casename+'/trck.'+casename+'.d02' df_sen=pd.read_csv(sen_path,parse_dates=True,index_col='timestamp', sep='\s+', date_parser=dateparse) df_sen_period=df_sen df_sen_period.replace(0, np.nan, inplace=True) # replace 0 by nan df_sen_period=df_sen_period.dropna() ax.plot(df_sen_period['lon'], df_sen_period['lat'], line_type, linewidth=1, markersize=3, transform=ccrs.Geodetic(), label=casename)
def plot_map(gf, snwe, vectorFile=None, zoom=8): """Plot dinosar inventory on a static map. Parameters ---------- gf : GeoDataFrame A geopandas GeoDataFrame snwe : list bounding coordinates [south, north, west, east]. vectorFile: str path to region of interest polygon zoom: int zoom level for WMTS """ pad = 1 S, N, W, E = snwe plot_CRS = ccrs.PlateCarree() geodetic_CRS = ccrs.Geodetic() x0, y0 = plot_CRS.transform_point(W - pad, S - pad, geodetic_CRS) x1, y1 = plot_CRS.transform_point(E + pad, N + pad, geodetic_CRS) fig, ax = plt.subplots(figsize=(8, 8), dpi=100, subplot_kw=dict(projection=plot_CRS)) ax.set_xlim((x0, x1)) ax.set_ylim((y0, y1)) url = 'http://tile.stamen.com/terrain/{z}/{x}/{y}.png' tiler = GoogleTiles(url=url) # NOTE: going higher than zoom=8 is slow... ax.add_image(tiler, zoom) states_provinces = cfeature.NaturalEarthFeature( category='cultural', name='admin_1_states_provinces_lines', scale='110m', facecolor='none') ax.add_feature(states_provinces, edgecolor='k', linestyle=':') ax.coastlines(resolution='10m', color='black', linewidth=2) ax.add_feature(cfeature.BORDERS) # Add region of interest polygon in specified if vectorFile: tmp = gpd.read_file(vectorFile) ax.add_geometries(tmp.geometry.values, ccrs.PlateCarree(), facecolor='none', edgecolor='m', lw=2, linestyle='dashed') orbits = gf.relativeOrbit.unique() colors = plt.cm.jet(np.linspace(0, 1, orbits.size)) for orbit, color in zip(orbits, colors): df = gf.query('relativeOrbit == @orbit') poly = df.geometry.cascaded_union if df.flightDirection.iloc[0] == 'ASCENDING': linestyle = '--' xpos, ypos = poly.centroid.x, poly.bounds[3] else: linestyle = '-' xpos, ypos = poly.centroid.x, poly.bounds[1] ax.add_geometries([poly], ccrs.PlateCarree(), facecolor='none', edgecolor=color, lw=2, linestyle=linestyle) ax.text(xpos, ypos, orbit, color=color, fontsize=16, fontweight='bold', transform=geodetic_CRS) gl = ax.gridlines(plot_CRS, draw_labels=True, linewidth=0.5, color='gray', alpha=0.5, linestyle='-') gl.xlabels_top = False gl.ylabels_left = False gl.xformatter = LONGITUDE_FORMATTER gl.yformatter = LATITUDE_FORMATTER plt.title('Orbital Footprints') plt.savefig('map.pdf', bbox_inches='tight')
############################################################################### # Create plot # Create plot figure fig = plt.figure(figsize=(8, 8)) # Add axes for lambert conformal map # Set dimensions of axes with [X0, Y0, width, height] argument. Each value is a fraction of total figure size. ax = plt.axes([.05, -.05, .9, 1], projection=ccrs.LambertConformal(), frameon=False) # Set latitude and longitude extent of map ax.set_extent([-119, -74, 18, 50], ccrs.Geodetic()) # Set shape name of map (which depicts the United States) shapename = 'admin_1_states_provinces_lakes_shp' states_shp = shpreader.natural_earth(resolution='110m', category='cultural', name=shapename) # Set title and title fontsize of plot using gvutil function instead of matplotlib function call gvutil.set_titles_and_labels( ax, maintitle= "Average Annual Precipiation \n Computed for the period 1899-1999 \n NCDC climate division data \n", maintitlefontsize=18) # Add outlines of each state within the United States
def studyarea(path_plot): '''Create a plot of the study area used in the Smartmove paper Args ---- path_plot: str Path and filename for plot to be saved. If 'None', no plot will be saved (Defualt: None) ''' def plot_coords(ax, proj, lon, lat, marker='o', color='black'): '''Plot points at specified lon(s) and lat(s)''' import cartopy.crs as ccrs import numpy lon = numpy.asarray(lon) lat = numpy.asarray(lat) points = proj.transform_points(ccrs.Geodetic(), lon, lat) ax.scatter(points[:, 0], points[:, 1], marker='.', color=color) return ax import cartopy.crs as ccrs from io import BytesIO import matplotlib.pyplot as plt from matplotlib import rcParams import numpy import os from owslib.wms import WebMapService import PIL import seaborn from . import maps # Plotting configuration rcParams.update({'figure.autolayout': True}) seaborn.set_context('paper') sns_config = { 'axes.linewidth': 0.1, 'xtick.color': 'black', 'xtick.major.size': 4.0, 'xtick.direction': 'out', 'ytick.color': 'black', 'ytick.major.size': 4.0, 'ytick.direction': 'out' } seaborn.set_style('white', sns_config) # Bounding box lon0 = 18.565148 # BL lat0 = 69.618893 # BL lon1 = 19.071205 # TR lat1 = 69.768302 # TR layer = 'Vannflate' srs = 'EPSG:32634' # Create wms object for handling WMS calls url = 'http://openwms.statkart.no/skwms1/wms.topo3?' wms = WebMapService(url) # Project bounding box bbox = maps.project_bbox(srs, lon0, lat0, lon1, lat1) owslib_img = maps.get_wms_png(wms, bbox, layer, srs, width=1600, transparent=True) # Convert binary png data to PIL Image data color_land = (131, 196, 146, 255 ) #(230, 230, 230, 255) # Hex color #f2f2f2 color_water = (237, 239, 242, 255) # Hex color #cccccc # https://stackoverflow.com/a/43514640/943773 img = PIL.Image.open(BytesIO(owslib_img.read())) land = PIL.Image.new('RGB', img.size, color_land) water = PIL.Image.new('RGBA', img.size, color_water) land.paste(water, mask=img.split()[3]) proj = ccrs.epsg(srs.split(':')[1]) # Create project axis and set extent to bounding box ax = plt.axes(projection=proj) extent = (bbox[0], bbox[2], bbox[1], bbox[3]) ax.set_extent(extent, proj) # Plot projected image ax.imshow(land, origin='upper', extent=extent, transform=proj) # Project and plot Tromsø and study area positions wgs84 = ccrs.Geodetic() # Tromso plot_coords(ax, proj, 18.955364, 69.649197, marker='o', color='#262626') # Study area plot_coords(ax, proj, 18.65125, 69.69942, marker='^', color='#a35d61') # CTD plot_coords(ax, proj, 18.65362, 69.70214, marker='o', color='#42a4f4') # Create WGS84 axes labels with WGS84 axes positions ticks_lon, xlabels = maps.map_ticks(lon0, lon1, 4) ticks_lat, ylabels = maps.map_ticks(lat0, lat1, 4) # Create list of lons/lats at axis edge for projecting ticks_lon/lats lat_iter = numpy.array([lat0] * len(ticks_lon)) # Project ticks_lon/lats and set to axis labels xpos = proj.transform_points(ccrs.Geodetic(), ticks_lon, lat_iter)[:, 0] ypos = proj.transform_points(ccrs.Geodetic(), ticks_lon, ticks_lat)[:, 1] ax.set_xticks(xpos) ax.set_xticklabels(xlabels, ha='right', rotation=45) ax.xaxis.tick_bottom() ax.set_yticks(ypos) ax.set_yticklabels(ylabels) ax.yaxis.tick_right() # Turn off grid for seaborn styling ax.grid(False) # Write image data if `path_plot` passed if path_plot: import pickle # Save png of WMS data filename_png = os.path.join(path_plot, '{}.png'.format(layer)) with open(filename_png, 'wb') as f: f.write(owslib_img.read()) # Convert png to GEOTIFF data maps.png2geotiff(filename_png, srs, bbox) # Save pickle of `PIL` image data file_pickle_img = os.path.join(path_plot, '{}_img.p'.format(layer)) pickle.dump(img, open(file_pickle_img, 'wb')) # Save Cartopy plot file_plot = os.path.join(path_plot, 'study_area.eps') plt.savefig(file_plot, dpi=600) plt.show() return None
def add_inset(fig,extent,pos,bounds,label=None,polygon=None,anom=None,draw_cmap_y=None,hillshade=True,markup_sub=None,sub_pos=None,sub_adj=None): sub_ax = fig.add_axes(pos, projection=ccrs.Robinson(), label=label) sub_ax.set_extent(extent, ccrs.Geodetic()) sub_ax.add_feature(cfeature.NaturalEarthFeature('physical', 'ocean', '50m', facecolor='gainsboro')) sub_ax.add_feature(cfeature.NaturalEarthFeature('physical', 'land', '50m', facecolor='dimgrey')) # if anom is not None: # shape_feature = ShapelyFeature(Reader(shp_buff).geometries(), ccrs.PlateCarree(), edgecolor='black', alpha=0.5, # facecolor='black', linewidth=1) # sub_ax.add_feature(shape_feature) if polygon is None and bounds is not None: polygon = poly_from_extent(bounds) if bounds is not None: verts = mpath.Path(latlon_extent_to_robinson_axes_verts(polygon)) sub_ax.set_boundary(verts, transform=sub_ax.transAxes) if hillshade: def out_of_poly_mask(geoimg, poly_coords): poly = ot.poly_from_coords(inter_poly_coords(poly_coords)) srs = osr.SpatialReference() srs.ImportFromEPSG(54030) # put in a memory vector ds_shp = ot.create_mem_shp(poly, srs) return ot.geoimg_mask_on_feat_shp_ds(ds_shp, geoimg) def inter_poly_coords(polygon_coords): list_lat_interp = [] list_lon_interp = [] for i in range(len(polygon_coords) - 1): lon_interp = np.linspace(polygon_coords[i][0], polygon_coords[i + 1][0], 50) lat_interp = np.linspace(polygon_coords[i][1], polygon_coords[i + 1][1], 50) list_lon_interp.append(lon_interp) list_lat_interp.append(lat_interp) all_lon_interp = np.concatenate(list_lon_interp) all_lat_interp = np.concatenate(list_lat_interp) return np.array(list(zip(all_lon_interp, all_lat_interp))) img = GeoImg(fn_hs) hs_tmp = hs_land.copy() hs_tmp_nl = hs_notland.copy() mask = out_of_poly_mask(img, polygon) hs_tmp[~mask] = 0 hs_tmp_nl[~mask] = 0 sub_ax.imshow(np.flip(hs_tmp[:, :], axis=0), extent=ext, transform=ccrs.Robinson(), cmap=cmap2, zorder=2) sub_ax.imshow(np.flip(hs_tmp_nl[:, :], axis=0), extent=ext, transform=ccrs.Robinson(), cmap=cmap22, zorder=2) sub_ax.outline_patch.set_edgecolor('white') if anom is not None: if anom == 'dh': col_bounds = np.array([-0.8, -0.4, 0, 0.2, 0.4]) cb = [] cb_val = np.linspace(0, 1, len(col_bounds)) for j in range(len(cb_val)): cb.append(mpl.cm.RdYlBu(cb_val[j])) cmap_cus = mpl.colors.LinearSegmentedColormap.from_list('my_cb', list( zip((col_bounds - min(col_bounds)) / (max(col_bounds - min(col_bounds))), cb)), N=1000) vals = dhs lab = 'Decadal difference in mean elevation change rate (m yr$^{-1}$)' elif anom == 'dt': col_bounds = np.array([-0.3, -0.15, 0, 0.3, 0.6]) cb = [] cb_val = np.linspace(0, 1, len(col_bounds)) for j in range(len(cb_val)): cb.append(mpl.cm.RdBu_r(cb_val[j])) cmap_cus = mpl.colors.LinearSegmentedColormap.from_list('my_cb', list( zip((col_bounds - min(col_bounds)) / (max(col_bounds - min(col_bounds))), cb)), N=1000) vals = dts lab = 'Decadal difference in temperature (K)' elif anom == 'dp': col_bounds = np.array([-0.2, -0.1, 0, 0.1, 0.2]) cb = [] cb_val = np.linspace(0, 1, len(col_bounds)) for j in range(len(cb_val)): cb.append(mpl.cm.BrBG(cb_val[j])) cmap_cus = mpl.colors.LinearSegmentedColormap.from_list('my_cb', list( zip((col_bounds - min(col_bounds)) / (max(col_bounds - min(col_bounds))), cb)), N=1000) vals = dps lab = 'Decadal difference in precipitation (m)' # elif anom == 'du': # col_bounds = np.array([-1, -0.5, 0, 0.5, 1]) # cb = [] # cb_val = np.linspace(0, 1, len(col_bounds)) # for j in range(len(cb_val)): # cb.append(mpl.cm.RdBu_r(cb_val[j])) # cmap_cus = mpl.colors.LinearSegmentedColormap.from_list('my_cb', list( # zip((col_bounds - min(col_bounds)) / (max(col_bounds - min(col_bounds))), cb)), N=1000) # # vals = dus # lab = 'Wind speed anomaly (m s$^{-1}$)' # # elif anom == 'dz': # # col_bounds = np.array([-100, -50, 0, 50, 100]) # cb = [] # cb_val = np.linspace(0, 1, len(col_bounds)) # for j in range(len(cb_val)): # cb.append(mpl.cm.RdBu_r(cb_val[j])) # cmap_cus = mpl.colors.LinearSegmentedColormap.from_list('my_cb', list( # zip((col_bounds - min(col_bounds)) / (max(col_bounds - min(col_bounds))), cb)), N=1000) # # vals = dzs # lab = 'Geopotential height anomaly at 500 hPa (m)' # # elif anom =='dk': # # col_bounds = np.array([-200000, -100000, 0, 100000, 200000]) # cb = [] # cb_val = np.linspace(0, 1, len(col_bounds)) # for j in range(len(cb_val)): # cb.append(mpl.cm.RdBu_r(cb_val[j])) # cmap_cus = mpl.colors.LinearSegmentedColormap.from_list('my_cb', list( # zip((col_bounds - min(col_bounds)) / (max(col_bounds - min(col_bounds))), cb)), N=1000) # # vals = dks # lab = 'Net clear-sky downwelling SW surface radiation anomaly (J m$^{-2}$)' if draw_cmap_y is not None: sub_ax_2 = fig.add_axes([0.2, draw_cmap_y, 0.6, 0.05]) sub_ax_2.set_xticks([]) sub_ax_2.set_yticks([]) sub_ax_2.spines['top'].set_visible(False) sub_ax_2.spines['left'].set_visible(False) sub_ax_2.spines['right'].set_visible(False) sub_ax_2.spines['bottom'].set_visible(False) cbaxes = sub_ax_2.inset_axes([0,0.85,1,0.2],label='legend_'+label) norm = mpl.colors.Normalize(vmin=min(col_bounds), vmax=max(col_bounds)) sm = plt.cm.ScalarMappable(cmap=cmap_cus, norm=norm) sm.set_array([]) cb = plt.colorbar(sm, cax=cbaxes, ticks=col_bounds, orientation='horizontal', extend='both', shrink=0.9) # cb.ax.tick_params(labelsize=12) cb.set_label(lab) for i in range(len(tiles)): lat, lon = SRTMGL1_naming_to_latlon(tiles[i]) if group_by_spec: lat, lon, s = latlon_to_spec_center(lat, lon) else: lat = lat + 0.5 lon = lon + 0.5 s = (1,1) # fac = 0.02 fac = 7000000. rad = 10000. + np.nanmax((0.,0.2-errs[i]))**3*fac div=(1+max(0,errs[i]-0.2)*10)**2 if ~np.isnan(vals[i]) and areas[i] > 0.2: val = vals[i] val_col = max(0.0001, min(0.9999, (val - min(col_bounds)) / (max(col_bounds) - min(col_bounds)))) col = cmap_cus(val_col) elif areas[i] <= 5: continue else: col = plt.cm.Greys(0.7) # xy = [lon,lat] xy = coordXform(ccrs.PlateCarree(), ccrs.Robinson(), np.array([lon]), np.array([lat]))[0][0:2] rw = rad rh = rad x,y=xy # sub_ax.add_patch( # mpatches.Circle(xy=xy, radius=rad, color=col, alpha=1, transform=ccrs.Robinson(), zorder=30)) xl = 0.1*s[0] + 0.9*s[0]/div yl =0.1*s[1] + 0.9*s[1]/div sub_ax.add_patch(mpatches.Rectangle((lon-xl/2,lat-yl/2),xl,yl,facecolor=col,alpha=1,transform=ccrs.PlateCarree(),zorder=30)) if markup_sub is not None and anom == 'dh': lon_min = np.min(list(zip(*polygon))[0]) lon_max = np.max(list(zip(*polygon))[0]) lon_mid = 0.5*(lon_min+lon_max) lat_min = np.min(list(zip(*polygon))[1]) lat_max = np.max(list(zip(*polygon))[1]) lat_mid = 0.5*(lat_min+lat_max) robin = np.array(list(zip([lon_min,lon_min,lon_min,lon_mid,lon_mid,lon_max,lon_max,lon_max],[lat_min,lat_mid,lat_max,lat_min,lat_max,lat_min,lat_mid,lat_max]))) if sub_pos=='lb': rob_x = robin[0][0] rob_y = robin[0][1] ha='left' va='bottom' elif sub_pos=='lm': rob_x = robin[1][0] rob_y = robin[1][1] ha='left' va='center' elif sub_pos=='lt': rob_x = robin[2][0] rob_y = robin[2][1] ha='left' va='top' elif sub_pos=='mb': rob_x = robin[3][0] rob_y = robin[3][1] ha='center' va='bottom' elif sub_pos=='mt': rob_x = robin[4][0] rob_y = robin[4][1] ha='center' va='top' elif sub_pos=='rb': rob_x = robin[5][0] rob_y = robin[5][1] ha='right' va='bottom' elif sub_pos=='rm': rob_x = robin[6][0] rob_y = robin[6][1] ha='right' va='center' elif sub_pos=='rt': rob_x = robin[7][0] rob_y = robin[7][1] ha='right' va='top' if sub_pos[0] == 'r': rob_x = rob_x - 100000 elif sub_pos[0] == 'l': rob_x = rob_x + 100000 if sub_pos[1] == 'b': rob_y = rob_y + 100000 elif sub_pos[1] == 't': rob_y = rob_y - 100000 if sub_adj is not None: rob_x += sub_adj[0] rob_y += sub_adj[1] sub_ax.text(rob_x,rob_y,markup_sub, horizontalalignment=ha, verticalalignment=va, transform=ccrs.Robinson(), color='black',fontsize=10,bbox=dict(facecolor='white', alpha=1),fontweight='bold',zorder=25)
], dtype=int), coords=[ ds_force_yearly[start_year]['lat'], ds_force_yearly[start_year]['lon'] ], dims=['lat', 'lon']) # --- Plot VIC and GPM domain to check --- # fig = plt.figure(figsize=(16, 8)) ax = plt.axes(projection=ccrs.PlateCarree()) ax.set_extent([ float(da_gpm_domain['lon'].min().values) - 0.5, float(da_gpm_domain['lon'].max().values) + 0.5, float(da_gpm_domain['lat'].min().values) - 0.5, float(da_gpm_domain['lat'].max().values) + 0.5 ], ccrs.Geodetic()) gl = add_gridlines(ax, xlocs=np.arange( float(da_gpm_domain['lon'].min().values) - 0.5, float(da_gpm_domain['lon'].max().values) + 0.5, 1), ylocs=np.arange( float(da_gpm_domain['lat'].min().values) - 0.5, float(da_gpm_domain['lat'].max().values) + 0.5, 1), alpha=0) # Plot GPM grids lon_edges = edges_from_centers(da_gpm_domain['lon'].values) lat_edges = edges_from_centers(da_gpm_domain['lat'].values) lonlon, latlat = np.meshgrid(lon_edges, lat_edges) cs = plt.pcolormesh(lonlon, latlat, da_gpm_domain.values,
inds.append(i) else: daily_mean_speed.append(np.mean(data.speed_2d[inds])) next_day += 1 inds = [] plt.figure(figsize=(8, 6)) plt.plot(daily_mean_speed) plt.xlabel("Day") plt.ylabel("Mean Speed (m/s)") import cartopy.crs as ccrs import cartopy.feature as cfeature proj = ccrs.Mercator() plt.figure(figsize=(10, 10)) ax = plt.axes(projection=proj) ax.set_extent((-25.0, 20.0, 52.0, 10.0)) ax.add_feature(cfeature.LAND) ax.add_feature(cfeature.OCEAN) ax.add_feature(cfeature.COASTLINE) ax.add_feature(cfeature.BORDERS, linestyle=':') for name in bird_names: ix = birddata["bird_name"] == name x, y = birddata.longitude[ix], birddata.latitude[ix] ax.plot(x, y, ".", transform=ccrs.Geodetic(), label=name) plt.xlabel("Longitude") plt.ylabel("Latitude") plt.legend(loc="upper left") plt.savefig("map.pdf")
norm=wv_norm) # Add the text, complete with outline text = ax.text(0.99, 0.01, timestamp.strftime('%d %B %Y %H%MZ'), horizontalalignment='right', transform=ax.transAxes, color='white', fontsize='x-large', weight='bold') text.set_path_effects( [patheffects.withStroke(linewidth=2, foreground='black')]) # PLOT 300-hPa Geopotential Heights and Wind Barbs ax.set_extent([-132, -95, 25, 47], ccrs.Geodetic()) cs = ax.contour(lon, lat, Z_300, colors='black', transform=ccrs.PlateCarree()) ax.clabel(cs, fontsize=12, colors='k', inline=1, inline_spacing=8, fmt='%i', rightside_up=True, use_clabeltext=True) ax.barbs(lon, lat, U_300.to('knots').m, V_300.to('knots').m, color='tab:red',
2 35946 98.4729 183.8200 0001770 165.0632 195.0663 14.37587360447041''' s = '''ISS (ZARYA) 1 25544U 98067A 18107.44763100 .00001858 00000-0 35119-4 0 9997 2 25544 51.6430 321.5086 0002048 0.7561 69.2289 15.54271367109073''' xtle = TwoLineElement(s) msat = Satellite.Satellite(xtle) #t = Tracker(msat) #t.plot_position() #t.plot_position(datetime.strptime('May 22 2018 12:20AM', '%b %d %Y %I:%M%p')) #t.show_footprint() plt.figure(figsize=(15, 25)) plt.axes(projection=ccrs.PlateCarree()).stock_img() fig = plt.gcf() fig.show() fig.canvas.draw() flag = True color = ['r', 'g', 'b', 'y', 'm'] i = 0 t = datetime.utcnow() while flag: pos = msat.get_position(t) plt.plot(pos[1], pos[0], 'ro', transform=ccrs.Geodetic()) t += timedelta(minutes=1) plt.pause(1) i = (i + 1) % len(color) break plt.show()
# fig = plt.figure(figsize = (20, 20)) # ax = fig.add_subplot(1, 1, 1, projection=ccrs.Orthographic(ortho_trans[0], ortho_trans[1])) #(long, lat) ax.add_feature(cfeature.OCEAN, zorder=0) ax.add_feature(cfeature.LAND, zorder=0, edgecolor='grey') ax.add_feature(cfeature.BORDERS, zorder=0, edgecolor='grey') ax.add_feature(cfeature.LAKES, zorder=0) ax.set_global() ax.gridlines() num_sta = len(list_of_stations) longs = np.zeros(num_sta) lats = np.zeros(num_sta) for i in range(num_sta): longs[i] = station_coords.longitude.loc[dict(station = list_of_stations[i])] lats[i] = station_coords.latitude.loc[dict(station = list_of_stations[i])] ax.scatter(longs, lats, transform = ccrs.Geodetic()) line, = ax.quiver(np.array([]), np.array([]), np.array([]), np.array([]), transform = ccrs.PlateCarree(), width = 0.002, color = "g") def init(): # plswork = yz.plot_stations(list_of_stations, ortho_trans) station_coords = csv_to_coords("First Pass/20190420-12-15-supermag-stations.csv") # fig = plt.figure(figsize = (20, 20)) # ax = fig.add_subplot(1, 1, 1, projection=ccrs.Orthographic(ortho_trans[0], ortho_trans[1])) #(long, lat) ax.add_feature(cfeature.OCEAN, zorder=0) ax.add_feature(cfeature.LAND, zorder=0, edgecolor='grey')
def main(): fig = plt.figure() ax = fig.add_axes([0, 0, 1, 1], projection=ccrs.LambertConformal()) ax.set_extent([-125, -66.5, 20, 50], ccrs.Geodetic()) shapename = 'admin_1_states_provinces_lakes_shp' states_shp = shpreader.natural_earth(resolution='110m', category='cultural', name=shapename) lons, lats = sample_data() # to get the effect of having just the states without a map "background" # turn off the outline and background patches ax.background_patch.set_visible(False) ax.outline_patch.set_visible(False) ax.set_title('US States which intersect the track of ' 'Hurricane Katrina (2005)') # turn the lons and lats into a shapely LineString track = sgeom.LineString(zip(lons, lats)) # buffer the linestring by two degrees (note: this is a non-physical # distance) track_buffer = track.buffer(2) for state in shpreader.Reader(states_shp).geometries(): # pick a default color for the land with a black outline, # this will change if the storm intersects with our track facecolor = [0.9375, 0.9375, 0.859375] edgecolor = 'black' if state.intersects(track): facecolor = 'red' elif state.intersects(track_buffer): facecolor = '#FF7E00' ax.add_geometries([state], ccrs.PlateCarree(), facecolor=facecolor, edgecolor=edgecolor) ax.add_geometries([track_buffer], ccrs.PlateCarree(), facecolor='#C8A2C8', alpha=0.5) ax.add_geometries([track], ccrs.PlateCarree(), facecolor='none', edgecolor='k') # make two proxy artists to add to a legend direct_hit = mpatches.Rectangle((0, 0), 1, 1, facecolor="red") within_2_deg = mpatches.Rectangle((0, 0), 1, 1, facecolor="#FF7E00") labels = [ 'State directly intersects\nwith track', 'State is within \n2 degrees of track' ] ax.legend([direct_hit, within_2_deg], labels, loc='lower left', bbox_to_anchor=(0.025, -0.1), fancybox=True) plt.show()
ax.add_feature(feat.LAKES, zorder=-1) ax.coastlines(resolution='110m', zorder=2, color='black') ax.add_feature(state_boundaries, edgecolor='black') ax.add_feature(feat.BORDERS, linewidth=2, edgecolor='black') # Set plot bounds ax.set_extent((-109.9, -101.8, 36.5, 41.3)) # Plot each station, labeling based on departure for stn in range(len(pcpn)): if pcpn_dep[stn] >= 0 and pcpn_dep[stn] < 2: ax.plot(lon[stn], lat[stn], 'g+', markersize=7, transform=ccrs.Geodetic()) ax.text(lon[stn], lat[stn], pcpn[stn], transform=ccrs.Geodetic()) elif pcpn_dep[stn] >= 2: ax.plot(lon[stn], lat[stn], 'm+', markersize=7, transform=ccrs.Geodetic()) ax.text(lon[stn], lat[stn], pcpn[stn], transform=ccrs.Geodetic()) elif pcpn_dep[stn] < 0: ax.plot(lon[stn], lat[stn], 'r+', markersize=7, transform=ccrs.Geodetic()) ax.text(lon[stn], lat[stn], pcpn[stn], transform=ccrs.Geodetic())
with gzip.open("srtm_1240-1300E_4740-4750N.asc.gz") as fp: srtm = np.loadtxt(fp, skiprows=8) # origin of data grid as stated in SRTM data file header # create arrays with all lon/lat values from min to max and lats = np.linspace(47.8333, 47.6666, srtm.shape[0]) lons = np.linspace(12.6666, 13.0000, srtm.shape[1]) # Prepare figure and Axis object with a proper projection and extent projection = ccrs.PlateCarree() fig = plt.figure(dpi=150) ax = fig.add_subplot(111, projection=projection) ax.set_extent((12.75, 12.95, 47.69, 47.81)) # create grids and compute map projection coordinates for lon/lat grid grid = projection.transform_points(ccrs.Geodetic(), *np.meshgrid(lons, lats), # unpacked x, y srtm) # z from topo data # Make contour plot ax.contour(*grid.T, transform=projection, levels=30) # Draw country borders with red ax.add_feature(cfeature.BORDERS.with_scale('50m'), edgecolor='red') # Draw a lon/lat grid and format the labels gl = ax.gridlines(crs=projection, draw_labels=True) gl.xlocator = mticker.FixedLocator([12.75, 12.8, 12.85, 12.9, 12.95]) gl.ylocator = mticker.FixedLocator([47.7, 47.75, 47.8]) gl.xformatter = LongitudeFormatter()
latitude.append(float(row1[6])) IATA.append(row1[4]) ################# # map making part ################# plt.figure(figsize=(15, 10)) ax = plt.axes(projection=ccrs.PlateCarree()) ax.set_title("Flights From Tallinn") # add coastline, land and borders to the map ax.add_feature(cfeat.COASTLINE) ax.add_feature(cfeat.OCEAN) ax.add_feature(cfeat.LAND) ax.add_feature(cfeat.BORDERS) # add airports to map with IATA for i in range(len(IATA)): x = [src[1], longitude[i]] y = [src[2], latitude[i]] ax.plot(x, y, marker="o", transform=ccrs.Geodetic(), color="blue") ax.text(longitude[i] + 0.2, latitude[i] + 0.2, IATA[i], weight="bold") # add IATA to tallinn airport ax.text(src[1], src[2], src[0], weight="bold") # save figure plt.savefig("FFT_map.png", dpi=300) plt.show()
def _compute_extra_keys(self): """Compute our extra keys.""" global unknown_string self.extra_keys = {} # work out stuff based on these values from the message edition = self.edition # time-processed forcast time is from reference time to start of period if edition == 2: forecastTime = self.forecastTime uft = np.uint32(forecastTime) BILL = 2**30 # Workaround grib api's assumption that forecast time is positive. # Handles correctly encoded -ve forecast times up to one -1 billion. if hindcast_workaround: if 2 * BILL < uft < 3 * BILL: msg = "Re-interpreting negative forecastTime from " \ + str(forecastTime) forecastTime = -(uft - 2 * BILL) msg += " to " + str(forecastTime) warnings.warn(msg) else: forecastTime = self.startStep #regular or rotated grid? try: longitudeOfSouthernPoleInDegrees = self.longitudeOfSouthernPoleInDegrees latitudeOfSouthernPoleInDegrees = self.latitudeOfSouthernPoleInDegrees except AttributeError: longitudeOfSouthernPoleInDegrees = 0.0 latitudeOfSouthernPoleInDegrees = 90.0 centre = gribapi.grib_get_string(self.grib_message, "centre") #default values self.extra_keys = { '_referenceDateTime': -1.0, '_phenomenonDateTime': -1.0, '_periodStartDateTime': -1.0, '_periodEndDateTime': -1.0, '_levelTypeName': unknown_string, '_levelTypeUnits': unknown_string, '_firstLevelTypeName': unknown_string, '_firstLevelTypeUnits': unknown_string, '_firstLevel': -1.0, '_secondLevelTypeName': unknown_string, '_secondLevel': -1.0, '_originatingCentre': unknown_string, '_forecastTime': None, '_forecastTimeUnit': unknown_string, '_coord_system': None, '_x_circular': False, '_x_coord_name': unknown_string, '_y_coord_name': unknown_string, # These are here to avoid repetition in the rules files, # and reduce the very long line lengths. '_x_points': None, '_y_points': None, '_cf_data': None } # cf phenomenon translation if edition == 1: # Get centre code (N.B. self.centre has default type = string) centre_number = gribapi.grib_get_long(self.grib_message, "centre") # Look for a known grib1-to-cf translation (or None). cf_data = gptx.grib1_phenom_to_cf_info( table2_version=self.table2Version, centre_number=centre_number, param_number=self.indicatorOfParameter) self.extra_keys['_cf_data'] = cf_data elif edition == 2: # Don't attempt to interpret params if 'master tables version' is # 255, as local params may then have same codes as standard ones. if self.tablesVersion != 255: # Look for a known grib2-to-cf translation (or None). cf_data = gptx.grib2_phenom_to_cf_info( param_discipline=self.discipline, param_category=self.parameterCategory, param_number=self.parameterNumber) self.extra_keys['_cf_data'] = cf_data #reference date self.extra_keys['_referenceDateTime'] = \ datetime.datetime(int(self.year), int(self.month), int(self.day), int(self.hour), int(self.minute)) # forecast time with workarounds self.extra_keys['_forecastTime'] = forecastTime #verification date processingDone = self._get_processing_done() #time processed? if processingDone.startswith("time"): if self.edition == 1: validityDate = str(self.validityDate) validityTime = "{:04}".format(int(self.validityTime)) endYear = int(validityDate[:4]) endMonth = int(validityDate[4:6]) endDay = int(validityDate[6:8]) endHour = int(validityTime[:2]) endMinute = int(validityTime[2:4]) elif self.edition == 2: endYear = self.yearOfEndOfOverallTimeInterval endMonth = self.monthOfEndOfOverallTimeInterval endDay = self.dayOfEndOfOverallTimeInterval endHour = self.hourOfEndOfOverallTimeInterval endMinute = self.minuteOfEndOfOverallTimeInterval # fixed forecastTime in hours self.extra_keys['_periodStartDateTime'] = \ (self.extra_keys['_referenceDateTime'] + datetime.timedelta(hours=int(forecastTime))) self.extra_keys['_periodEndDateTime'] = \ datetime.datetime(endYear, endMonth, endDay, endHour, endMinute) else: self.extra_keys[ '_phenomenonDateTime'] = self._get_verification_date() #originating centre #TODO #574 Expand to include sub-centre self.extra_keys['_originatingCentre'] = CENTRE_TITLES.get( centre, "unknown centre %s" % centre) #forecast time unit as a cm string #TODO #575 Do we want PP or GRIB style forecast delta? self.extra_keys['_forecastTimeUnit'] = self._timeunit_string() #shape of the earth #pre-defined sphere if self.shapeOfTheEarth == 0: geoid = coord_systems.GeogCS(semi_major_axis=6367470) #custom sphere elif self.shapeOfTheEarth == 1: geoid = coord_systems.GeogCS( self.scaledValueOfRadiusOfSphericalEarth * 10**-self.scaleFactorOfRadiusOfSphericalEarth) #IAU65 oblate sphere elif self.shapeOfTheEarth == 2: geoid = coord_systems.GeogCS(6378160, inverse_flattening=297.0) #custom oblate spheroid (km) elif self.shapeOfTheEarth == 3: geoid = coord_systems.GeogCS( semi_major_axis=self.scaledValueOfEarthMajorAxis * 10**-self.scaleFactorOfEarthMajorAxis * 1000., semi_minor_axis=self.scaledValueOfEarthMinorAxis * 10**-self.scaleFactorOfEarthMinorAxis * 1000.) #IAG-GRS80 oblate spheroid elif self.shapeOfTheEarth == 4: geoid = coord_systems.GeogCS(6378137, None, 298.257222101) #WGS84 elif self.shapeOfTheEarth == 5: geoid = \ coord_systems.GeogCS(6378137, inverse_flattening=298.257223563) #pre-defined sphere elif self.shapeOfTheEarth == 6: geoid = coord_systems.GeogCS(6371229) #custom oblate spheroid (m) elif self.shapeOfTheEarth == 7: geoid = coord_systems.GeogCS( semi_major_axis=self.scaledValueOfEarthMajorAxis * 10**-self.scaleFactorOfEarthMajorAxis, semi_minor_axis=self.scaledValueOfEarthMinorAxis * 10**-self.scaleFactorOfEarthMinorAxis) elif self.shapeOfTheEarth == 8: raise ValueError("unhandled shape of earth : grib earth shape = 8") else: raise ValueError("undefined shape of earth") gridType = gribapi.grib_get_string(self.grib_message, "gridType") if gridType in [ "regular_ll", "regular_gg", "reduced_ll", "reduced_gg" ]: self.extra_keys['_x_coord_name'] = "longitude" self.extra_keys['_y_coord_name'] = "latitude" self.extra_keys['_coord_system'] = geoid elif gridType == 'rotated_ll': # TODO: Confirm the translation from angleOfRotation to # north_pole_lon (usually 0 for both) self.extra_keys['_x_coord_name'] = "grid_longitude" self.extra_keys['_y_coord_name'] = "grid_latitude" southPoleLon = longitudeOfSouthernPoleInDegrees southPoleLat = latitudeOfSouthernPoleInDegrees self.extra_keys['_coord_system'] = \ iris.coord_systems.RotatedGeogCS( -southPoleLat, math.fmod(southPoleLon + 180.0, 360.0), self.angleOfRotation, geoid) elif gridType == 'polar_stereographic': self.extra_keys['_x_coord_name'] = "projection_x_coordinate" self.extra_keys['_y_coord_name'] = "projection_y_coordinate" if self.projectionCentreFlag == 0: pole_lat = 90 elif self.projectionCentreFlag == 1: pole_lat = -90 else: raise TranslationError("Unhandled projectionCentreFlag") # Note: I think the grib api defaults LaDInDegrees to 60 for grib1. self.extra_keys['_coord_system'] = \ iris.coord_systems.Stereographic( pole_lat, self.orientationOfTheGridInDegrees, 0, 0, self.LaDInDegrees, ellipsoid=geoid) elif gridType == 'lambert': self.extra_keys['_x_coord_name'] = "projection_x_coordinate" self.extra_keys['_y_coord_name'] = "projection_y_coordinate" if self.edition == 1: flag_name = "projectionCenterFlag" else: flag_name = "projectionCentreFlag" if getattr(self, flag_name) == 0: pole_lat = 90 elif getattr(self, flag_name) == 1: pole_lat = -90 else: raise TranslationError("Unhandled projectionCentreFlag") LambertConformal = iris.coord_systems.LambertConformal self.extra_keys['_coord_system'] = LambertConformal( self.LaDInDegrees, self.LoVInDegrees, 0, 0, secant_latitudes=(self.Latin1InDegrees, self.Latin2InDegrees), ellipsoid=geoid) else: raise TranslationError("unhandled grid type: {}".format(gridType)) if gridType in ["regular_ll", "rotated_ll"]: self._regular_longitude_common() j_step = self.jDirectionIncrementInDegrees if not self.jScansPositively: j_step = -j_step self._y_points = (np.arange(self.Nj, dtype=np.float64) * j_step + self.latitudeOfFirstGridPointInDegrees) elif gridType in ['regular_gg']: # longitude coordinate is straight-forward self._regular_longitude_common() # get the distinct latitudes, and make sure they are sorted # (south-to-north) and then put them in the right direction # depending on the scan direction latitude_points = gribapi.grib_get_double_array( self.grib_message, 'distinctLatitudes').astype(np.float64) latitude_points.sort() if not self.jScansPositively: # we require latitudes north-to-south self._y_points = latitude_points[::-1] else: self._y_points = latitude_points elif gridType in ["polar_stereographic", "lambert"]: # convert the starting latlon into meters cartopy_crs = self.extra_keys['_coord_system'].as_cartopy_crs() x1, y1 = cartopy_crs.transform_point( self.longitudeOfFirstGridPointInDegrees, self.latitudeOfFirstGridPointInDegrees, ccrs.Geodetic()) if not np.all(np.isfinite([x1, y1])): raise TranslationError("Could not determine the first latitude" " and/or longitude grid point.") self._x_points = x1 + self.DxInMetres * np.arange(self.Nx, dtype=np.float64) self._y_points = y1 + self.DyInMetres * np.arange(self.Ny, dtype=np.float64) elif gridType in ["reduced_ll", "reduced_gg"]: self._x_points = self.longitudes self._y_points = self.latitudes else: raise TranslationError("unhandled grid type")
def PlateCarree_to_Orthographic(img, llbd, craters, iglobe=None, ctr_sub=False, arad=1737.4, origin="upper", rgcoeff=1.2, slivercut=0.): """Transform Plate Carree image and associated csv file into Orthographic. Parameters ---------- img : PIL.Image.image or str File or filename. llbd : list-like Long/lat limits (long_min, long_max, lat_min, lat_max) of image. craters : pandas.DataFrame Craters catalogue. iglobe : cartopy.crs.Geodetic instance Globe for images. If False, defaults to spherical Moon. ctr_sub : bool, optional If `True`, assumes craters dataframe includes only craters within image. If `False` (default_, llbd used to cut craters from outside image out of (copy of) dataframe. arad : float World radius in km. Default is Moon (1737.4 km). origin : "lower" or "upper", optional Based on imshow convention for displaying image y-axis. "upper" (default) means that [0,0] is upper-left corner of image; "lower" means it is bottom-left. rgcoeff : float, optional Fractional size increase of transformed image height. By default set to 1.2 to prevent loss of fidelity during transform (though warping can be so extreme that this might be meaningless). slivercut : float from 0 to 1, optional If transformed image aspect ratio is too narrow (and would lead to a lot of padding, return null images). Returns ------- imgo : PIL.Image.image Transformed, padded image in PIL.Image format. ctr_xy : pandas.DataFrame Craters with transformed x, y pixel positions and pixel radii. distortion_coefficient : float Ratio between the central heights of the transformed image and original image. centrallonglat_xy : pandas.DataFrame xy position of the central longitude and latitude. """ # If user doesn't provide Moon globe properties. #pdb.set_trace() if not iglobe: iglobe = ccrs.Globe(semimajor_axis=arad * 1000., semiminor_axis=arad * 1000., ellipse=None) # Set up Geodetic (long/lat), Plate Carree (usually long/lat, but not when # globe != WGS84) and Orthographic projections. geoproj = ccrs.Geodetic(globe=iglobe) iproj = ccrs.PlateCarree(globe=iglobe) oproj = ccrs.Orthographic(central_longitude=np.mean(llbd[:2]), central_latitude=np.mean(llbd[2:]), globe=iglobe) # Create and transform coordinates of image corners and edge midpoints. # Due to Plate Carree and Orthographic's symmetries, max/min x/y values of # these 9 points represent extrema of the transformed image. xll = np.array([llbd[0], np.mean(llbd[:2]), llbd[1]]) yll = np.array([llbd[2], np.mean(llbd[2:]), llbd[3]]) xll, yll = np.meshgrid(xll, yll) xll = xll.ravel() yll = yll.ravel() # [:,:2] because we don't need elevation data. res = iproj.transform_points(x=xll, y=yll, src_crs=geoproj)[:, :2] iextent = [min(res[:, 0]), max(res[:, 0]), min(res[:, 1]), max(res[:, 1])] res = oproj.transform_points(x=xll, y=yll, src_crs=geoproj)[:, :2] oextent = [min(res[:, 0]), max(res[:, 0]), min(res[:, 1]), max(res[:, 1])] # Sanity check for narrow images; done before the most expensive part of # the function. oaspect = (oextent[1] - oextent[0]) / (oextent[3] - oextent[2]) # if oaspect < slivercut: # return [None, None] if type(img) != Image.Image: Image.MAX_IMAGE_PIXELS = None img = Image.open(img).convert("L") # Warp image. imgo, imgwshp, offset = WarpImagePad(img, iproj, iextent, oproj, oextent, origin=origin, rgcoeff=rgcoeff, fillbg="black") # Convert crater x, y position. if ctr_sub: llbd_in = None else: llbd_in = llbd ctr_xy = WarpCraterLoc(craters, geoproj, oproj, oextent, imgwshp, llbd=llbd_in, origin=origin) # Shift crater x, y positions by offset (origin doesn't matter for y-shift, # since padding is symmetric). ctr_xy.loc[:, "x"] += offset[0] ctr_xy.loc[:, "y"] += offset[1] # Pixel scale for orthographic determined (for images small enough that # tan(x) approximately equals x + 1/3x^3 + ...) by l = R_moon*theta, # where theta is the latitude extent of the centre of the image. Because # projection transform doesn't guarantee central vertical axis will keep # its pixel resolution, we need to calculate the conversion coefficient # C = (res[7,1]- res[1,1])/(oextent[3] - oextent[2]). # C0*pix height/C = theta # Where theta is the latitude extent and C0 is the theta per pixel # conversion for the Plate Carree image). Thus # l_ctr = R_moon*C0*pix_ctr/C. distortion_coefficient = ((res[7, 1] - res[1, 1]) / (oextent[3] - oextent[2])) if distortion_coefficient < 0.7: raise ValueError("Distortion Coefficient cannot be" " {0:.2f}!".format(distortion_coefficient)) pixperkm = trf.km2pix(imgo.size[1], llbd[3] - llbd[2], dc=distortion_coefficient, a=arad) ctr_xy["Diameter (pix)"] = ctr_xy["Diameter (km)"] * pixperkm # Determine x, y position of central lat/long. centrallonglat = pd.DataFrame({"Long": [xll[4]], "Lat": [yll[4]]}) centrallonglat_xy = WarpCraterLoc(centrallonglat, geoproj, oproj, oextent, imgwshp, llbd=llbd_in, origin=origin) # Shift central long/lat centrallonglat_xy.loc[:, "x"] += offset[0] centrallonglat_xy.loc[:, "y"] += offset[1] return [imgo, ctr_xy, distortion_coefficient, centrallonglat_xy]
def plot_cartopy(lons, lats, size, color, labels=None, projection='global', resolution='110m', continent_fill_color='0.8', water_fill_color='1.0', colormap=None, colorbar=None, marker="o", title=None, colorbar_ticklabel_format=None, show=True, proj_kwargs=None, **kwargs): # @UnusedVariable """ Creates a Cartopy plot with a data point scatter plot. :type lons: list/tuple of floats :param lons: Longitudes of the data points. :type lats: list/tuple of floats :param lats: Latitudes of the data points. :type size: float or list/tuple of floats :param size: Size of the individual points in the scatter plot. :type color: list/tuple of floats (or objects that can be converted to floats, like e.g. :class:`~obspy.core.utcdatetime.UTCDateTime`) :param color: Color information of the individual data points to be used in the specified color map (e.g. origin depths, origin times). :type labels: list/tuple of str :param labels: Annotations for the individual data points. :type projection: str, optional :param projection: The map projection. Currently supported are: * ``"global"`` (Will plot the whole world using :class:`~cartopy.crs.Mollweide`.) * ``"ortho"`` (Will center around the mean lat/long using :class:`~cartopy.crs.Orthographic`.) * ``"local"`` (Will plot around local events using :class:`~cartopy.crs.AlbersEqualArea`.) * Any other Cartopy :class:`~cartopy.crs.Projection`. An instance of this class will be created using the supplied ``proj_kwargs``. Defaults to "global" :type resolution: str, optional :param resolution: Resolution of the boundary database to use. Will be passed directly to the Cartopy module. Possible values are: * ``"110m"`` * ``"50m"`` * ``"10m"`` Defaults to ``"110m"``. For compatibility, you may also specify any of the Basemap resolutions defined in :func:`plot_basemap`. :type continent_fill_color: Valid matplotlib color, optional :param continent_fill_color: Color of the continents. Defaults to ``"0.9"`` which is a light gray. :type water_fill_color: Valid matplotlib color, optional :param water_fill_color: Color of all water bodies. Defaults to ``"white"``. :type colormap: str, any matplotlib colormap, optional :param colormap: The colormap for color-coding the events as provided in `color` kwarg. The event with the smallest `color` property will have the color of one end of the colormap and the event with the highest `color` property the color of the other end with all other events in between. Defaults to None which will use the default matplotlib colormap. :type colorbar: bool, optional :param colorbar: When left `None`, a colorbar is plotted if more than one object is plotted. Using `True`/`False` the colorbar can be forced on/off. :type title: str :param title: Title above plot. :type colorbar_ticklabel_format: str or function or subclass of :class:`matplotlib.ticker.Formatter` :param colorbar_ticklabel_format: Format string or Formatter used to format colorbar tick labels. :type show: bool :param show: Whether to show the figure after plotting or not. Can be used to do further customization of the plot before showing it. :type proj_kwargs: dict :param proj_kwargs: Keyword arguments to pass to the Cartopy :class:`~cartopy.ccrs.Projection`. In this dictionary, you may specify ``central_longitude='auto'`` or ``central_latitude='auto'`` to have this function calculate the latitude or longitude as it would for other projections. Some arguments may be ignored if you choose one of the built-in ``projection`` choices. """ import matplotlib.pyplot as plt min_color = min(color) max_color = max(color) if isinstance(color[0], (datetime.datetime, UTCDateTime)): datetimeplot = True color = [date2num(getattr(t, 'datetime', t)) for t in color] else: datetimeplot = False scal_map = ScalarMappable(norm=Normalize(min_color, max_color), cmap=colormap) scal_map.set_array(np.linspace(0, 1, 1)) fig = plt.figure() # The colorbar should only be plotted if more then one event is # present. if colorbar is not None: show_colorbar = colorbar else: if len(lons) > 1 and hasattr(color, "__len__") and \ not isinstance(color, (str, native_str)): show_colorbar = True else: show_colorbar = False if projection == "local": ax_x0, ax_width = 0.10, 0.80 elif projection == "global": ax_x0, ax_width = 0.01, 0.98 else: ax_x0, ax_width = 0.05, 0.90 proj_kwargs = proj_kwargs or {} if projection == 'global': proj_kwargs['central_longitude'] = np.mean(lons) proj = ccrs.Mollweide(**proj_kwargs) elif projection == 'ortho': proj_kwargs['central_latitude'] = np.mean(lats) proj_kwargs['central_longitude'] = mean_longitude(lons) proj = ccrs.Orthographic(**proj_kwargs) elif projection == 'local': if min(lons) < -150 and max(lons) > 150: max_lons = max(np.array(lons) % 360) min_lons = min(np.array(lons) % 360) else: max_lons = max(lons) min_lons = min(lons) lat_0 = max(lats) / 2. + min(lats) / 2. lon_0 = max_lons / 2. + min_lons / 2. if lon_0 > 180: lon_0 -= 360 deg2m_lat = 2 * np.pi * 6371 * 1000 / 360 deg2m_lon = deg2m_lat * np.cos(lat_0 / 180 * np.pi) if len(lats) > 1: height = (max(lats) - min(lats)) * deg2m_lat width = (max_lons - min_lons) * deg2m_lon margin = 0.2 * (width + height) height += margin width += margin else: height = 2.0 * deg2m_lat width = 5.0 * deg2m_lon # Do intelligent aspect calculation for local projection # adjust to figure dimensions w, h = fig.get_size_inches() aspect = w / h if show_colorbar: aspect *= 1.2 if width / height < aspect: width = height * aspect else: height = width / aspect proj_kwargs['central_latitude'] = lat_0 proj_kwargs['central_longitude'] = lon_0 proj = ccrs.AlbersEqualArea(**proj_kwargs) # User-supplied projection. elif isinstance(projection, type): if 'central_longitude' in proj_kwargs: if proj_kwargs['central_longitude'] == 'auto': proj_kwargs['central_longitude'] = mean_longitude(lons) if 'central_latitude' in proj_kwargs: if proj_kwargs['central_latitude'] == 'auto': proj_kwargs['central_latitude'] = np.mean(lats) if 'pole_longitude' in proj_kwargs: if proj_kwargs['pole_longitude'] == 'auto': proj_kwargs['pole_longitude'] = np.mean(lons) if 'pole_latitude' in proj_kwargs: if proj_kwargs['pole_latitude'] == 'auto': proj_kwargs['pole_latitude'] = np.mean(lats) proj = projection(**proj_kwargs) else: msg = "Projection '%s' not supported." % projection raise ValueError(msg) if show_colorbar: map_ax = fig.add_axes([ax_x0, 0.13, ax_width, 0.77], projection=proj) cm_ax = fig.add_axes([ax_x0, 0.05, ax_width, 0.05]) plt.sca(map_ax) else: ax_y0, ax_height = 0.05, 0.85 if projection == "local": ax_y0 += 0.05 ax_height -= 0.05 map_ax = fig.add_axes([ax_x0, ax_y0, ax_width, ax_height], projection=proj) if projection == 'local': x0, y0 = proj.transform_point(lon_0, lat_0, proj.as_geodetic()) map_ax.set_xlim(x0 - width / 2, x0 + width / 2) map_ax.set_ylim(y0 - height / 2, y0 + height / 2) else: map_ax.set_global() # Pick features at specified resolution. resolution = _CARTOPY_RESOLUTIONS[resolution] try: borders, land, ocean = _CARTOPY_FEATURES[resolution] except KeyError: borders = cfeature.NaturalEarthFeature(cfeature.BORDERS.category, cfeature.BORDERS.name, resolution, edgecolor='none', facecolor='none') land = cfeature.NaturalEarthFeature(cfeature.LAND.category, cfeature.LAND.name, resolution, edgecolor='face', facecolor='none') ocean = cfeature.NaturalEarthFeature(cfeature.OCEAN.category, cfeature.OCEAN.name, resolution, edgecolor='face', facecolor='none') _CARTOPY_FEATURES[resolution] = (borders, land, ocean) # Draw coast lines, country boundaries, fill continents. if MATPLOTLIB_VERSION >= [2, 0, 0]: map_ax.set_facecolor(water_fill_color) else: map_ax.set_axis_bgcolor(water_fill_color) map_ax.add_feature(ocean, facecolor=water_fill_color) map_ax.add_feature(land, facecolor=continent_fill_color) map_ax.add_feature(borders, edgecolor='0.75') map_ax.coastlines(resolution=resolution, color='0.4') # Draw grid lines - TODO: draw_labels=True doesn't work yet. if projection == 'local': map_ax.gridlines() else: # Draw lat/lon grid lines every 30 degrees. map_ax.gridlines(xlocs=range(-180, 181, 30), ylocs=range(-90, 91, 30)) # Plot labels if labels and len(lons) > 0: with map_ax.hold_limits(): for name, xpt, ypt, _colorpt in zip(labels, lons, lats, color): map_ax.text(xpt, ypt, name, weight="heavy", color="k", zorder=100, transform=ccrs.Geodetic(), path_effects=[ PathEffects.withStroke(linewidth=3, foreground="white") ]) scatter = map_ax.scatter(lons, lats, marker=marker, s=size, c=color, zorder=10, cmap=colormap, transform=ccrs.Geodetic()) if title: plt.suptitle(title) # Only show the colorbar for more than one event. if show_colorbar: if colorbar_ticklabel_format is not None: if isinstance(colorbar_ticklabel_format, (str, native_str)): formatter = FormatStrFormatter(colorbar_ticklabel_format) elif hasattr(colorbar_ticklabel_format, '__call__'): formatter = FuncFormatter(colorbar_ticklabel_format) elif isinstance(colorbar_ticklabel_format, Formatter): formatter = colorbar_ticklabel_format locator = MaxNLocator(5) else: if datetimeplot: locator = AutoDateLocator() formatter = AutoDateFormatter(locator) # Compat with old matplotlib versions. if hasattr(formatter, "scaled"): formatter.scaled[1 / (24. * 60.)] = '%H:%M:%S' else: locator = None formatter = None cb = Colorbar(cm_ax, scatter, cmap=colormap, orientation='horizontal', ticks=locator, format=formatter) # Compat with old matplotlib versions. if hasattr(cb, "update_ticks"): cb.update_ticks() if show: plt.show() return fig
def plot_trajectories_ens(traj, savepath, ls=None, config=None): """ plot multiple trajectories into one scene Args: traj (:class:`.trajectory`): trajectory to plot instance to plot savepath (str): path to save ls (:class:`trace_source.land_sfc.land_sfc`, optional): pre loaded land surface information config (dict, optional): the toml derived config dict Returns: None """ import matplotlib matplotlib.use('Agg') import cartopy.crs as ccrs import matplotlib.pyplot as plt if ls is None: ls = trace_source.land_sfc.land_sfc() colors = ['purple', 'darkorange', 'hotpink', 'dimgrey'] c = 'purple' if not os.path.isdir(savepath): os.makedirs(savepath) ### # the map ### fig = plt.figure(figsize=(8, 10)) if config is not None and "centerlon" in config['plotmap']: ax = plt.axes(projection=ccrs.Miller( central_longitude=config['plotmap']['centerlon'])) else: ax = plt.axes(projection=ccrs.Miller(central_longitude=-170.)) ax = plt.axes(projection=ccrs.Miller()) # Projection for the north pole # ax = plt.axes(projection=ccrs.NorthPolarStereo()) raise ValueError('provide plotmap.centerlon in the config file') #### # make a color map of fixed colors cmap = matplotlib.colors.ListedColormap([ 'lightskyblue', 'darkgreen', 'khaki', 'palegreen', 'red', 'white', 'tan' ]) bounds = [-0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5] norm = matplotlib.colors.BoundaryNorm(bounds, cmap.N) #### pcm = ax.pcolormesh(ls.longs, ls.lats, ls.land_sfc, cmap=cmap, norm=norm, transform=ccrs.PlateCarree()) ax.coastlines() for k, v in traj.data.items(): ax.plot(v['longitude'], v['latitude'], linewidth=1.5, color=c, transform=ccrs.Geodetic()) ax.plot(v['longitude'][::24], v['latitude'][::24], '.', color=c, transform=ccrs.Geodetic()) ax.gridlines(linestyle=':') if config is not None and "bounds" in config['plotmap']: ax.set_extent(config['plotmap']['bounds'], crs=ccrs.PlateCarree()) else: # bounds for punta arenas ax.set_extent([-180, 180, -75, 0], crs=ccrs.PlateCarree()) # bounds for atlantic #ax.set_extent([-180, 80, -70, 75], crs=ccrs.PlateCarree()) # bounds for the north pole #ax.set_extent([-180, 180, 50, 90], crs=ccrs.PlateCarree()) raise ValueError('provide plotmap.bounds in the config file') ax.set_title('Trajectory {}UTC\n{} {} '.format( traj.info['date'].strftime('%Y-%m-%d %H'), traj.info['lat'], traj.info['lon']), fontweight='semibold', fontsize=13) savename = savepath + "/" + traj.info['date'].strftime("%Y%m%d_%H") \ + '_' + '{:0>5.0f}'.format(traj.info['height']) + "_trajectories_map.png" fig.savefig(savename, dpi=250) plt.close() ### # the profile ### fig, ax = plt.subplots(4, 1, figsize=(6, 7), sharex=True) ax[0].grid(True, axis='y') for k, v in traj.data.items(): ax[0].plot(v['time'], v['height']) ax[1].plot(v['time'], v['AIR_TEMP'][:] - 273.15) ax[2].plot(v['time'], v['RELHUMID'][:]) ax[3].plot(v['time'], v['RAINFALL'][:]) ax[0].set_ylim(0, 10000) ax[0].set_ylabel('Height [m]') ax[0].xaxis.set_major_locator(matplotlib.dates.DayLocator(interval=2)) ax[0].xaxis.set_minor_locator(matplotlib.dates.HourLocator([0, 12])) ax[0].xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%m-%d')) # ax[1].set_ylim(0,10000) ax[1].set_ylabel('Temperature [°C]') ax[1].set_ylim(-40, 10) ax[1].xaxis.set_major_locator(matplotlib.dates.DayLocator(interval=2)) ax[1].xaxis.set_minor_locator(matplotlib.dates.HourLocator([0, 12])) ax[1].xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%m-%d')) # ax[2].grid(True, axis='y') ax[2].set_ylim(0, 100) ax[2].set_ylabel('rel Humidity [%]') ax[2].xaxis.set_major_locator(matplotlib.dates.DayLocator(interval=2)) ax[2].xaxis.set_minor_locator(matplotlib.dates.HourLocator([0, 12])) ax[2].xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%m-%d')) # ax[3].grid(True, axis='y') ax[3].set_ylim(0, 20) ax[3].set_xlabel('Day') ax[3].set_ylabel('Precip [mm]') ax[3].xaxis.set_major_locator(matplotlib.dates.DayLocator(interval=2)) ax[3].xaxis.set_minor_locator(matplotlib.dates.HourLocator([0, 12])) ax[3].xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%m-%d')) for axis in ax: axis.tick_params(axis='both', which='both', right=True, top=True, direction='in') ax[0].set_title('Trajectory {}UTC\n{} {} '.format( traj.info['date'].strftime('%Y-%m-%d %H'), traj.info['lat'], traj.info['lon']), fontweight='semibold', fontsize=13) fig.tight_layout() savename = savepath + "/" + traj.info['date'].strftime("%Y%m%d_%H") \ + '_' + '{:0>5.0f}'.format(traj.info['height']) + "_trajectories_prof.png" fig.savefig(savename, dpi=250) plt.close()
def plot_all(self, out_path=None, Save = False, num_stations=1000): """ Plotting all stations on a map, divided in color of stations with full observations in the reference period and not. Arguments: num_stations = 1000, selects the number of stations to construct the dataset. out_path, Path of the folder to save pdf of plots Save = False, choosing to hide plots and not saving them. """ #plotting stations with full data in period 1960-1990: fig = plt.figure(figsize=(12,6)) fig.suptitle("Stations with (red) and without (green) full interset period") ax = fig.add_subplot(1,1,1,projection=ccrs.PlateCarree()) ax.set_global() ax.coastlines() ax.gridlines(draw_labels=True) ax.add_feature(cfeature.BORDERS, edgecolor='gray') ax.add_feature(cfeature.LAND) w_interest_lon = [] w_interest_lat = [] wo_interest_lon =[] wo_interest_lat =[] for i in tqdm(range(num_stations)): try: Obs = Observation(self.file_list[i]) Obs.nan_interest_period() if Obs.interest: w_interest_lon.append([Obs.lon_line]) w_interest_lat.append([Obs.lat_line]) ax.plot([Obs.lon_line], [Obs.lat_line], color='red', linewidth=1, marker='o', markersize=2, transform=ccrs.Geodetic()) else: wo_interest_lon.append([Obs.lon_line]) wo_interest_lat.append([Obs.lat_line]) ax.plot([Obs.lon_line], [Obs.lat_line], color='green', linewidth=1, marker='o', markersize=2, transform=ccrs.Geodetic()) except: continue #plotting separately stations with interest period and without interest period fig1 = plt.figure(figsize=(12,6)) fig1.suptitle("Stations with full interset period") ax1 = fig1.add_subplot(1,1,1,projection=ccrs.PlateCarree()) ax1.set_global() ax1.coastlines() ax1.gridlines(draw_labels=True) ax1.add_feature(cfeature.BORDERS, edgecolor='gray') ax1.add_feature(cfeature.LAND) plt.scatter(w_interest_lon, w_interest_lat, color='red',s=3, linewidth=1, marker='o', transform=ccrs.Geodetic()) fig2 = plt.figure(figsize=(12,6)) fig2.suptitle("Stations without full interset period") ax2 = fig2.add_subplot(1,1,1,projection=ccrs.PlateCarree()) ax2.set_global() ax2.coastlines() ax2.gridlines(draw_labels=True) ax2.add_feature(cfeature.BORDERS, edgecolor='gray') ax2.add_feature(cfeature.LAND) plt.scatter(wo_interest_lon, wo_interest_lat, color='green',s = 3, linewidth=1, marker='o', transform=ccrs.Geodetic()) if Save: #Saving plot fig.savefig(out_path + '/All_Stations_Crutem.pdf') fig1.savefig(out_path + '/Stations_full_interest.pdf') fig2.savefig(out_path + '/Station_wo_full_interest.pdf') plt.close()
nc_fid = Dataset( 'J:/REANALYSES/ERA5/SWE_Cumul_Nittasinan/climato/ERA5_Cumul_SWE_climatology_1990-2019.nc', 'r') data = nc_fid.variables['sd'][:].squeeze() lons = nc_fid.variables['longitude'][:].squeeze() lats = nc_fid.variables['latitude'][:].squeeze() #sr_clim_90_2019 = data.mean(axis=0) #sr_clim_90_2019.data[sr_clim_90_2019 == 0] = np.nan fig = plt.figure(figsize=(28, 16)) crs = ccrs.LambertConformal() # crs=ccrs.PlateCarree() ax = plt.axes(projection=crs) plot_background(ax) ax.plot(-69.72, 48.15, "bo", markersize=7, transform=ccrs.Geodetic()) ax.text(-69.5, 48.17, "Tadoussac", color='blue', fontsize=20, fontweight='bold', transform=ccrs.Geodetic()) ax.plot(-66.4, 50.21, "bo", markersize=7, color='blue', transform=ccrs.Geodetic()) ax.text(-66.2,
def cleansing(self, out_path=None, Save = False, sliced = False): """ cleaning the dataframe of stations keeping only the stations with a complete reference period 1960-1990. Subsequently it plots the result and updated self.metadata and self.df Arguments: out_path, Path to save plots. Save = False, Tell if the plots are going to be saved. verbosity = False, Show or not show plots of the cleaning. """ taxis = pd.date_range('1850-01', '2019-01', freq='M') dropped = pd.DataFrame({'time': taxis}) dropped = dropped.set_index(['time']) try: if sliced: self.sliced else: self.df except: print('Full_dataset object needs to be converted into dataframe before cleansing. You can type data = Full_stations(file_list).to_dataset()') return if sliced: for i in tqdm(self.meta_slice.index, desc = 'Cleaning df'): if any(np.isnan(self.sliced[i]['1960-01-31':'1990-01-31'])): dropped = pd.merge(dropped, self.sliced[i], on='time', how = 'left') self.sliced = self.sliced.drop(i, 1) self.meta_slice = self.meta_slice.drop(index = i, axis = 0) self.df = self.df.drop(i, 1) self.metadata = self.metadata.drop(index = i, axis = 0) else: for i in tqdm(self.df.columns, desc = 'Cleaning df'): if any(np.isnan(self.df[i]['1960-01-31':'1990-01-31'])): dropped = pd.merge(dropped, self.df[i], on='time', how = 'left') self.df = self.df.drop(i, 1) self.metadata = self.metadata.drop(index = i, axis = 0) #Cleaning the gridded dataframe from dropped stations try: #if grid exist we go on self.grid #retrieve indices to apply loc. df_indices = self.grid[self.grid['indices'] != 0].index for i in tqdm(df_indices, desc = 'Grid cleaning'): #redefine station_id indices of gridded dataset removing the ones dropped self.grid.loc[i].indices = [x for x in self.grid.loc[i].indices if x not in dropped.columns] self.grid.loc[i].number_station = len(self.grid.loc[i].indices) #if the list is empty after the cleansing then we set the entry to zero if len(self.grid.loc[i].indices) == 0: self.grid.loc[i].indices = 0 self.grid.loc[i].number_station = 0 except: pass if Save: fig = plt.figure(figsize=(12,6)) fig.suptitle("Visualizing cleansing") ax = fig.add_subplot(1,1,1,projection=ccrs.PlateCarree()) ax.gridlines(draw_labels=True) ax.coastlines() ax.stock_img() ax.add_feature(cfeature.LAND) ax.set_global() ax.add_feature(cfeature.BORDERS, edgecolor='gray') if sliced: ax.set_extent([self.ext_lon[0]-3, self.ext_lon[1]+3, self.ext_lat[0]-3, self.ext_lat[1]+3], ccrs.PlateCarree()) ax.plot(self.meta_slice['lon'].values, self.meta_slice['lat'].values, 'bo', markersize=2, transform=ccrs.Geodetic()) else: count = 0 while count < len(self.metadata): ax.plot(self.metadata.lon.values[count], self.metadata.lat.values[count], color='blue', marker='o', markersize=2, transform=ccrs.Geodetic()) count += 1 fig.savefig(out_path + "/Cleansing_slicing:{}.pdf".format(sliced))
def as_cartopy_crs(self): return ccrs.Geodetic(self.as_cartopy_globe())
def grid_contribution(self, grid, out_path=None, Save = False, sliced = False, verbosity = True): """ Plotting which grids contribute with a station marked with an X. Arguments: grid, Takes the grid output of self.regridding to plot out_path, Path to save plots. Save = False, Tell if the plots are going to be saved. verbosity = False, Show or not show plots of the cleaning. """ #plotting contribution cells along with point of the stations #it is defined as a self method of Full_Stations to be able to #record all the files simply. It still takes as input the grid which #needs to be defined outside #getting the steps of the grid grid_lon_step = grid.loc[0, :]['max_long'] - grid.loc[0, :]['min_long'] grid_lat_step = grid.loc[0, :]['max_lat'] - grid.loc[0, :]['min_lat'] #plotting the grid based on the grid step fig = plt.figure(figsize=(12,8)) ax = fig.add_subplot(1,1,1,projection=ccrs.PlateCarree()) ax.set_global() ax.add_feature(cfeature.LAND) if sliced: lat_ext = [int(grid_lat_step* mt.floor(self.ext_lat[0]/grid_lat_step)), int(grid_lat_step * mt.ceil(self.ext_lat[1]/grid_lat_step))] lon_ext = [int(grid_lon_step * mt.floor(self.ext_lon[0]/grid_lon_step)), int(grid_lon_step * mt.ceil(self.ext_lon[1]/grid_lon_step))] #ax.gridlines(xlocs=range(mt.floor(self.ext_lon[0]),mt.floor(self.ext_lon[1]),grid_lon_step), ylocs=range(mt.floor(self.ext_lat[0]),mt.floor(self.ext_lat[1]+1),grid_lat_step)) #ax.set_extent([mt.floor(self.ext_lon[0]),mt.ceil(self.ext_lon[1]), mt.floor(self.ext_lat[0]),mt.ceil(self.ext_lat[1])], ccrs.PlateCarree()) ax.gridlines(xlocs=range(lon_ext[0],lon_ext[1]+grid_lon_step,grid_lon_step), ylocs=range(lat_ext[0], lat_ext[1]+grid_lat_step,grid_lat_step)) ax.set_extent([lon_ext[0], lon_ext[1], lat_ext[0], lat_ext[1]], ccrs.PlateCarree()) else: ax.gridlines(xlocs=range(-180,181,grid_lon_step), ylocs=range(-90,91,grid_lat_step)) ax.coastlines() ax.add_feature(cfeature.BORDERS, edgecolor='gray') #cycling on all grid entries and plotting for i in tqdm(range(len(grid))): #if the indices of the grid is not null (so the cell contains stations) if grid.loc[i, :]['indices'] != 0: #plots an x on the central latitude and longitude central_lat = grid.loc[i, :]['max_lat'] - (grid.loc[i, :]['max_lat'] - grid.loc[i, :]['min_lat'])/2. central_lon = grid.loc[i, :]['max_long'] - (grid.loc[i, :]['max_long'] - grid.loc[i, :]['min_long'])/2. ax.plot([central_lon], [central_lat], color='red', marker='x', markersize=7, transform=ccrs.Geodetic()) for i in grid.loc[i, :]['indices']: #for each station in the cell plots a point at its coordinate. Coordinates #retrieved from the metadata dataset from self if sliced: ax.plot(self.meta_slice.loc[i]['lon'], self.meta_slice.loc[i]['lat'], color='blue', marker='o', markersize=1, transform=ccrs.Geodetic()) else: ax.plot(self.metadata.loc[i]['lon'], self.metadata.loc[i]['lat'], color='blue', marker='o', markersize=1, transform=ccrs.Geodetic()) if not verbosity: plt.close() if Save: fig.savefig(out_path + '/Contributing_Areas.pdf') plt.close()
bird_names = bird_data['bird_name'].unique() bird_data['date_time'] = pd.to_datetime(bird_data['date_time']) bird_data['date'] = bird_data['date_time'].dt.date grouped_bird_data = bird_data.groupby(['bird_name', 'date']) plt.figure(figsize=(6, 6)) ax = plt.axes(projection=ccrs.Mercator()) ax.set_extent((-25, 20, 52, 10)) ax.add_feature(cfeature.LAND) ax.add_feature(cfeature.OCEAN) ax.add_feature(cfeature.COASTLINE) ax.add_feature(cfeature.BORDERS, linestyle=':') for name in bird_names: ix = bird_data['bird_name'] == name x, y = bird_data['longitude'][ix], bird_data['latitude'][ix] plt.plot(x, y, '.', transform=ccrs.Geodetic(), label=name) plt.title("Bird Routes") plt.xlabel("Longitude") plt.ylabel("Latitude") plt.legend(loc='upper left') plt.savefig('plots/bird_migration_1') plt.figure(figsize=(10, 4)) for name in bird_names: ix = bird_data['bird_name'] == name bird_data['speed_2d'][ix].plot(kind='hist', histtype='step', bins=np.linspace(0, 20, 20), normed=True, label=name) plt.title("Speed Histogram")
def test_against_great_circle_and_gmt(self): ll.info('testing depth against gmt extracted depths') gmt = np.array([ -0.648317, 81.9962170001, -2574.32325995, -1.253283, 81.9983000001, -2304.80896863, -1.856417, 81.9994330001, -1992.40861882, -2.396967, 81.9947830001, -2540.36409855, -3.130133, 81.9987830001, -3509.64727122, -3.707333, 81.9998670001, -4018.8108823, -4.296033, 81.997083, -4011.25898682, -4.920717, 81.9994000001, -3525.6963024, -5.50345000001, 82.0028670001, -3023.12097893, -6.130917, 82.0015830001, -3006.31591506, -6.69468300003, 81.9966170001, -3190.38107675, -7.31206699999, 81.9941330001, -3115.38103425, -7.93959999997, 82.000267, -2982.875422, -8.19741700001, 81.9721330001, -2911.32670751, -0.62855, 81.9993830001, -2589.30052845, -0.051117, 81.999717, -2822.43058789, 0.56, 82, -3006.25619309, 1.705833, 81.9945, -3435.51613899, 2.310417, 82.0015, -2030.92420387, 2.89165, 81.9971670001, -1309.44942805, 3.48035, 81.996817, -1136.05331727, 4.093633, 81.99945, -1098.94253697, 4.6825, 81.998917, -1275.39851465, 5.290717, 81.998917, -1345.6958582, 5.878783, 82.000133, -989.180725733, 6.76653300003, 82.0143830001, -796.276219227, 7.07896700002, 82.00315, -777.077539801, ]) gmt = gmt.reshape(27, 3) gmtz = gmt[:, 2] lon = gmt[:, 0] lat = gmt[:, 1] xy = self.i.projection.transform_points(ccrs.Geodetic(), lon, lat) dz = self.i.interp_depth(xy[:, 0], xy[:, 1]) mz = self.i.map_depth(xy[:, 0], xy[:, 1]) plt.figure() plt.plot(lon, mz, label='map_depth') plt.plot(lon, dz, label='interp_depth') plt.plot(lon, gmtz, label='gmt') plt.legend() plt.title('depth') plt.xlabel('Longitude') plt.savefig(os.path.join(outdir, 'depth_vs_gmt.png')) # high atol = 22 needed for python 3.4 np.testing.assert_allclose(gmtz, dz, atol=22) np.testing.assert_allclose(gmtz, mz, atol=22)
flow_feature = ShapelyFeature( Reader('../Structures_files/Shapefiles/UCRBstreams.shp').geometries(), ccrs.PlateCarree(), edgecolor='royalblue', facecolor='None') fig = plt.figure(figsize=(18, 9)) ax = plt.axes(projection=tiles.crs) #ax.add_feature(rivers_10m, facecolor='None', edgecolor='royalblue', linewidth=2, zorder=4) ax.add_image(tiles, 9, interpolation='none', alpha=0.8) ax.set_extent(extent) ax.add_feature(shape_feature, facecolor='#a1a384', alpha=0.6) ax.add_feature(flow_feature, alpha=0.6, linewidth=1.5, zorder=4) points = ax.scatter(structures['X'], structures['Y'], marker='.', s=50, c='black', transform=ccrs.Geodetic(), zorder=5) #geom = geometry.box(extent[0],extent[2], extent[1], extent[3]) #fig = plt.figure(figsize=(18, 9)) #ax = plt.axes(projection=tiles.crs) #ax.add_feature(rivers_10m, facecolor='None', edgecolor='royalblue', linewidth=2, zorder=4) #ax.add_image(tiles, 7, interpolation='none',alpha = 0.8) #ax.set_extent(extent_large) #ax.add_feature(cpf.STATES) #ax.add_geometries([geom], crs=ccrs.PlateCarree(), facecolor='None', edgecolor='black', linewidth=2,) #ax.add_feature(shape_feature, facecolor='#a1a384',alpha = 0.6)
D = pc.data().from_h5('ramp_pass_ll.h5') latR = np.array([np.nanmin(D.latitude), np.nanmax(D.latitude)]) lonR = np.array([np.nanmin(D.longitude), np.nanmax(D.longitude)]) if True: # Create a Stamen terrain background instance. bg_image = cimgt.GoogleTiles(style='satellite') #Stamen('terrain-background') fig = plt.figure(figsize=(10, 10)) # Create a GeoAxes in the tile's projection. ax = fig.add_subplot(1, 1, 1, projection=bg_image.crs) # Limit the extent of the map to a small longitude/latitude range. ax.set_extent([lonR[0], lonR[1], latR[0], latR[1]], crs=ccrs.Geodetic()) # Add the Stamen data at zoom level 8. ax.add_image(bg_image, 10) #plt.plot(D.longitude.reshape([1, -1]), D.latitude.reshape([1, -1]), color='k', marker='.', transform=ccrs.Geodetic()) plt.scatter(D.longitude, D.latitude, 2, c=D.latitude, marker='.', transform=ccrs.Geodetic()) #for lati, loni in zip(D.latitude, D.longitude): # plt.plot(loni, lati, 'k.', transform=ccrs.Geodetic())