def test_web_tiles(): extent = [-15, 0.1, 50, 60] target_domain = sgeom.Polygon([[extent[0], extent[1]], [extent[2], extent[1]], [extent[2], extent[3]], [extent[0], extent[3]], [extent[0], extent[1]]]) map_prj = cimgt.GoogleTiles().crs ax = plt.subplot(3, 2, 1, projection=map_prj) gt = cimgt.GoogleTiles() gt._image_url = types.MethodType(ctest_tiles.GOOGLE_IMAGE_URL_REPLACEMENT, gt) img, extent, origin = gt.image_for_domain(target_domain, 1) ax.imshow(np.array(img), extent=extent, transform=gt.crs, interpolation='bilinear', origin=origin) ax.coastlines(color='white') ax = plt.subplot(3, 2, 2, projection=map_prj) qt = cimgt.QuadtreeTiles() img, extent, origin = qt.image_for_domain(target_domain, 1) ax.imshow(np.array(img), extent=extent, transform=qt.crs, interpolation='bilinear', origin=origin) ax.coastlines(color='white') ax = plt.subplot(3, 2, 3, projection=map_prj) mq_osm = cimgt.MapQuestOSM() img, extent, origin = mq_osm.image_for_domain(target_domain, 1) ax.imshow(np.array(img), extent=extent, transform=mq_osm.crs, interpolation='bilinear', origin=origin) ax.coastlines() ax = plt.subplot(3, 2, 4, projection=map_prj) mq_oa = cimgt.MapQuestOpenAerial() img, extent, origin = mq_oa.image_for_domain(target_domain, 1) ax.imshow(np.array(img), extent=extent, transform=mq_oa.crs, interpolation='bilinear', origin=origin) ax.coastlines() ax = plt.subplot(3, 2, 5, projection=map_prj) osm = cimgt.OSM() img, extent, origin = osm.image_for_domain(target_domain, 1) ax.imshow(np.array(img), extent=extent, transform=osm.crs, interpolation='bilinear', origin=origin) ax.coastlines()
def osm_api(): request = cimgt.OSM() fig, ax = make_map(projection=request.crs) extent = [-50.5, -47.4, -31, -25] ax.set_extent(extent) ax.add_image(request, 10) plt.show()
def test_web_tiles(): extent = [-15, 0.1, 50, 60] target_domain = shapely.geometry.Polygon([[extent[0], extent[1]], [extent[2], extent[1]], [extent[2], extent[3]], [extent[0], extent[3]], [extent[0], extent[1]]]) ax = plt.subplot(3, 2, 1, projection=ccrs.Mercator()) gt = cimgt.GoogleTiles() img, extent, origin = gt.image_for_domain(target_domain, 1) ax.imshow(np.array(img), extent=extent, transform=ccrs.Mercator(), interpolation='bilinear', origin=origin) ax.coastlines(color='white') ax = plt.subplot(3, 2, 2, projection=ccrs.Mercator()) qt = cimgt.QuadtreeTiles() img, extent, origin = qt.image_for_domain(target_domain, 1) ax.imshow(np.array(img), extent=extent, transform=ccrs.Mercator(), interpolation='bilinear', origin=origin) ax.coastlines(color='white') ax = plt.subplot(3, 2, 3, projection=ccrs.Mercator()) mq_osm = cimgt.MapQuestOSM() img, extent, origin = mq_osm.image_for_domain(target_domain, 1) ax.imshow(np.array(img), extent=extent, transform=ccrs.Mercator(), interpolation='bilinear', origin=origin) ax.coastlines() ax = plt.subplot(3, 2, 4, projection=ccrs.Mercator()) mq_oa = cimgt.MapQuestOpenAerial() img, extent, origin = mq_oa.image_for_domain(target_domain, 1) ax.imshow(np.array(img), extent=extent, transform=ccrs.Mercator(), interpolation='bilinear', origin=origin) ax.coastlines() ax = plt.subplot(3, 2, 5, projection=ccrs.Mercator()) osm = cimgt.OSM() img, extent, origin = osm.image_for_domain(target_domain, 1) ax.imshow(np.array(img), extent=extent, transform=ccrs.Mercator(), interpolation='bilinear', origin=origin) ax.coastlines()
def info_plot(self,out_file=None): """Print information about the link and plot it on a low resolution map """ # TODO: Deal with protection links or links for which only # unidirectional data is available print '=============================================================' print 'ID: ' + self.metadata['link_id'] print '-------------------------------------------------------------' print ' Site A Site B' if 'ip' in self.metadata['site_A'].keys() and \ 'ip' in self.metadata['site_B'].keys(): print ' IP: ' + self.metadata['site_A']['ip'] + ' ' \ + self.metadata['site_B']['ip'] print ' L: ' + str(self.metadata['length_km']) + ' km' if 'site_A' in self.metadata and 'site_B' in self.metadata: if 'lat' in self.metadata['site_A'] and \ 'lon' in self.metadata['site_A'] and \ 'lat' in self.metadata['site_B'] and \ 'lon' in self.metadata['site_B']: print ' Lat: ' + str(self.metadata['site_A']['lat'])+ ' ' \ + str(self.metadata['site_B']['lat']) print ' Lon: ' + str(self.metadata['site_A']['lon']) + ' ' \ + str(self.metadata['site_B']['lon']) area=[min(self.metadata['site_A']['lon'],self.metadata['site_B']['lon'])-.15, max(self.metadata['site_A']['lon'],self.metadata['site_B']['lon'])+.15, min(self.metadata['site_A']['lat'],self.metadata['site_B']['lat'])-.1, max(self.metadata['site_A']['lat'],self.metadata['site_B']['lat'])+.1] plt.figure(figsize=(12, 8)) ax = plt.axes(projection=cartopy.crs.PlateCarree()) ax.set_extent((area[0], area[1], area[2], area[3]), crs=cartopy.crs.PlateCarree()) gg_tiles=img_tiles.OSM(style='satellite') ax.add_image(gg_tiles, 11) plt.plot([self.metadata['site_A']['lon'],self.metadata['site_B']['lon']], [self.metadata['site_A']['lat'],self.metadata['site_B']['lat']], linewidth=3,color='k', transform=cartopy.crs.Geodetic()) xy= mapping.label_loc(self.metadata['site_A']['lon'], self.metadata['site_A']['lat'], self.metadata['site_B']['lon'], self.metadata['site_B']['lat']) plt.text(xy[0],xy[1],'A',fontsize=15,transform=cartopy.crs.Geodetic()) plt.text(xy[2],xy[3],'B',fontsize=15,transform=cartopy.crs.Geodetic()) #plt.tight_layout() #plt.show() print '=============================================================' if out_file is not None: plt.savefig(out_file,format='png',bbox_inches='tight', dpi=300)
def plot_osm_map(extent, size=(13, 13)): plt.figure(figsize=size) img = cimgt.OSM() ax = plt.axes(projection=img.crs) ax.set_extent(extent) ax.add_image(img, 7, interpolation='bicubic')
def make_cartopy(self, projection, ax=None, figsize=(10, 10)): self.projection = projection if ax is None: # Create figure instance fig, ax = plt.subplots(figsize=figsize, subplot_kw=dict(projection=projection)) Lat_1 = self.mapcorners[1] Lat_2 = self.mapcorners[3] Lon_1 = self.mapcorners[0] Lon_2 = self.mapcorners[2] xlocs_1 = ((round(Lon_1 / 10)) - 1) * 10 xlocs_2 = ((round(Lon_2 / 10)) + 1) * 10 ylocs_1 = ((round(Lat_1 / 10)) - 1) * 10 ylocs_2 = ((round(Lat_2 / 10)) + 1) * 10 extent = [Lon_1, Lon_2, Lat_1, Lat_2] x_space = self.latlon_spacing[0] y_space = self.latlon_spacing[1] xlocs = np.arange(xlocs_1, xlocs_2, x_space) ylocs = np.arange(ylocs_1, ylocs_2, y_space) import cartopy.io.img_tiles as cimgt if self.bg_service == 'Stamen': request = cimgt.Stamen(style=self.bg_style) ax.set_extent(extent, crs=self.projection) ax.add_image(request, self.xsize, interpolation='spline36') if self.bg_service == 'OSM': request = cimgt.OSM() ax.set_extent(extent, crs=self.projection) ax.add_image(request, self.xsize, interpolation='spline36') if self.bg_service == 'Google': request = cimgt.GoogleTiles(style=self.bg_style) ax.set_extent(extent) ax.add_image(request, self.xsize, interpolation='spline36') if self.bg_service == 'Esri': request = cimgt.Esri(style=self.bg_style) ax.set_extent(extent, crs=self.projection) ax.add_image(request, self.xsize, interpolation='spline36') gl = ax.gridlines(draw_labels=self.draw_labels, xlocs=xlocs, ylocs=ylocs, alpha=self.alpha_gl) gl.ylabels_left = self.ylabels_left gl.ylabels_right = self.ylabels_right gl.xlabels_top = self.xlabels_top gl.xlabels_bottom = self.xlabels_bottom gl.xformatter = LONGITUDE_FORMATTER gl.yformatter = LATITUDE_FORMATTER gl.xlabel_style = self.xlabel_style gl.ylabel_style = self.ylabel_style return ax
def info_plot(self, out_file=None, figsize=(12, 8), add_labels=False): """Plot associated links on a map """ plt.figure(figsize=figsize) ax = plt.axes(projection=cartopy.crs.PlateCarree()) lons = [] lats = [] for cml in self.set: lons.append(cml.metadata['site_A']['lon']) lons.append(cml.metadata['site_B']['lon']) lats.append(cml.metadata['site_A']['lat']) lats.append(cml.metadata['site_B']['lat']) area = [ min(lons) - .05, max(lons) + .05, min(lats) - .05, max(lats) + .05 ] ax.set_extent((area[0], area[1], area[2], area[3]), crs=cartopy.crs.PlateCarree()) gg_tiles = img_tiles.OSM() ax.add_image(gg_tiles, 11) for cml in self.set: plt.plot( [cml.metadata['site_A']['lon'], cml.metadata['site_B']['lon']], [cml.metadata['site_A']['lat'], cml.metadata['site_B']['lat']], linewidth=2, color='k', transform=cartopy.crs.Geodetic()) if add_labels: plt.text(cml.metadata['site_A']['lon'] - (cml.metadata['site_A']['lon'] - cml.metadata['site_B']['lon']) / 2, cml.metadata['site_A']['lat'] - (cml.metadata['site_A']['lat'] - cml.metadata['site_B']['lat']) / 2, cml.metadata['link_id'], transform=cartopy.crs.Geodetic(), fontsize=15, color='r') if out_file is not None: plt.savefig(out_file, format='png', bbox_inches='tight', dpi=300)
def plot_scatter_map(quake_df, title, colormap_style = 'magma'): """Function to generate a PNG of a scatter plot on a map of earthquake locations, magnitudes and time since occurence. :param quake_df: a dataframe generated by the json_extraction function from data_pull.py. Contains columns on magnitude, origin time, depth, lat/lon, a Geonet URL and time since origin. Geonet URL not needed currently? :param title: the title to appear above the plot :param colormap_style: the color scheme for the colorbar for time since earthquake origin. Default is magma but other styles available in Matplotlib documentation. """ # OpenStreetMap preferred map style - easy to use and locations fairly identifiable. This pulls map tiles for OSM. osm_img = cimgt.OSM() # figsize arbitrary, maybe should be an option to change? fig = plt.figure(figsize = (12,15)) # sets axes for plotting ax1 = plt.axes(projection = osm_img.crs) ax1.set_title(title) # uses coordinates of first earthquake to base map centering. May lead to unexpected behaviour... Should maybe # change this to mean of each column? The default width is 0.8 degrees lon vs 0.4 degrees lat coords = [quake_df.iloc[0]["lon"] - 0.4, quake_df.iloc[0]["lon"] + 0.4, quake_df.iloc[0]["lat"] - 0.2, quake_df.iloc[0]["lat"] + 0.2] # set the boundary of the map to these ax1.set_extent(coords) # adds image time from openstreetmap, integer value is default zoom? ax1.add_image(osm_img, 14) # plot the scattermap over the empty axis. scatter = ax1.scatter(quake_df["lon"], quake_df["lat"], # s for Size of marker - arbitrary function to make larger mags exponentially greater in radius s= [(int(str(i)[0]) + 1) ** 3.1 * 4 for i in quake_df['magnitude']], marker = 'o', # parameter for colorbar is "time since origin" c = quake_df["since_origin"], cmap = colormap_style, edgecolors = 'black', linewidths = 0.6, transform = ccrs.PlateCarree(), # transparency value to show markers below alpha = 0.6) # display colorbar within plot - negative pad means it's inside. cbar = plt.colorbar(scatter, shrink = 0.25, pad = -0.025) cbar.set_label("Hours since initial quake", rotation = 270, labelpad = 20, fontsize = 12) # remove whitespace fig.subplots_adjust(left=0.05, right = 0.95, bottom = 0.05, top = 0.95) # worth making name of file configurable? Removes even more whitespace. plt.savefig("Swarm_Map.png", pad_inches = 0.1, bbox_inches = 'tight')
def __init__(self, coordinates): self.coordinates = coordinates self.request = cimgt.OSM() plt.switch_backend('Agg') ax = plt.axes(projection=self.request.crs) # assume we're near to huntsville ax.set_extent([-87.6073, -85.573, 34.1928, 35.2612]) ax.add_image(self.request, 10, interpolation='bilinear', zorder=0) gl = ax.gridlines(draw_labels=True, alpha=0.2) gl.xlabels_top = gl.ylabels_right = False gl.xformatter = LONGITUDE_FORMATTER gl.yformatter = LATITUDE_FORMATTER
def __init__(self, lat_min=11.18, lat_max=11.32, lon_min=54.46, lon_max=54.53): self.extent = [lat_min, lat_max, lon_min, lon_max] self.request = cimgt.OSM() # OpenStreetMap self.ax = None self.date = None self.cloud_height = None self.sun_azimuth = None self.sun_elevation = None self.max_elevation_angle = 30 self.shadow_mask = None
def plot_ppi(display,field,vmin,vmax,cmap,gatefilter): #generate figure fig = plt.figure(figsize=axis_sz) ax = plt.subplot(projection = ccrs.PlateCarree()) #generate plot display.plot_ppi_map(field, sweep=0, ax=ax, vmin=vmin, vmax=vmax, cmap=cmap, gatefilter=gatefilter, resolution = '10m',embelish=False) #Range Rings display.plot_range_rings([10,20,30,40,50], ax=ax, col='0.5', ls='--', lw=1) #OSM layers request = cimgt.OSM() ax.add_image(request, 9, zorder = 0) #output out_fn = plt_folder + field + '.png' plt.tight_layout() plt.savefig(out_fn, dpi=75)
def create_map(array, output_file, projection): """ Create map with cartopy based on input xarray DataArray. The DataArray must have "x" and a "y" dimensions. Input: -array xarray DataArray instance -output_file str -projection cartopy.crs.Projection instance """ # create figure fig = plt.figure(figsize=(7, 6), dpi=300) # create geo axes geo_axes = plt.subplot(projection=projection) # add open street map background osm_background = cimgt.OSM() geo_axes.add_image(osm_background, 13) # plot dataset image = xr.plot.imshow(darray=array, x="x", y="y", ax=geo_axes, transform=projection, zorder=10, vmin=20, vmax=28, extend="neither", add_colorbar=False) # add colorbar and label colorbar = plt.colorbar(mappable=image) colorbar.set_label("Velocity (km/h)") # save as image plt.savefig(output_file) # close figure plt.close()
def show(): cwd = os.getcwd() root = plib.Path(cwd).parents[1] coords_path = os.path.join(root, 'data', 'raw', 'massachusetts_cities_coords.csv') coords = mfetch.get_data(coords_path) x = coords['Latitude'].values y = coords['Longitude'].values request = cimgt.OSM() fig, ax = plt.subplots(figsize=(10, 16), subplot_kw=dict(projection=request.crs)) ax.set_extent([-73.41, -69.93, 41.21, 42.92]) ax.add_image(request, 8) county_shape = os.path.join(root, 'data', 'maps', 'county', 'countyl010g.shp') county_reader = cshp.Reader(county_shape) counties = list(county_reader.geometries()) county_features = cfeat.ShapelyFeature(counties, ccrs.PlateCarree()) ax.add_feature(county_features, facecolor='none', edgecolor='gray') ax.set_title('LEED Buildings in Massachusetts') plt.plot(x, y, color='red', linewidth=0, marker='o', transform=ccrs.Geodetic(), label='LEED-Certified Building') ax.legend() plt.show()
import pandas as pd import geopandas as gpd import cartopy.crs as ccrs import matplotlib.pyplot as plt from shapely.geometry import Point import cartopy.io.img_tiles as cimgt import matplotlib.gridspec as gridspec from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER extent = [-110, -84, 30.6, 41.15] #[-107.5, -89.85, 30.6, 41.15] # request = cimgt.OSM() quakes_df = pd.read_csv('../data/okQuakes.csv', parse_dates=['time']) counts_per_year = quakes_df.loc[quakes_df['mag'] > 3.0].groupby( quakes_df['time'].dt.year).count() crs = {'init': 'epsg:4326'} geometry = [ Point(Lat, Lon) for Lat, Lon in zip(quakes_df['longitude'], quakes_df['latitude']) ] quakes_shp = gpd.GeoDataFrame(quakes_df, crs=crs, geometry=geometry) gs = gridspec.GridSpec(2, 1, height_ratios=(3, 1)) for year in range(1973, 2017): fig = plt.figure(figsize=(8, 6))
def maparea(area_name, lat=None, lon=None): clean_name = str(re.sub(r'[^a-zA-Z\d]', '', area_name)) nominatim = Nominatim() if area_name.isdigit(): areaId = int(area_name) else: areaId = nominatim.query(area_name).areaId() overpass = Overpass() query = overpassQueryBuilder(area=areaId, elementType='way', selector='"landuse"="residential"', out='geom') residential_areas = overpass.query(query).ways() or [] query = overpassQueryBuilder(area=areaId, elementType='way', selector='"highway"="footway"', out='geom') roads_footway = overpass.query(query).ways() or [] query = overpassQueryBuilder( area=areaId, elementType='way', selector=['"highway"="service"', '"service"!="parking_aisle"'], out='geom') roads_cycleway = overpass.query(query).ways() or [] query = overpassQueryBuilder(area=areaId, elementType='way', selector='"highway"="residential"', out='geom') roads_residential = overpass.query(query).ways() or [] query = overpassQueryBuilder(area=areaId, elementType='way', selector='"highway"="tertiary"', out='geom') roads_tertiary = overpass.query(query).ways() or [] query = overpassQueryBuilder(area=areaId, elementType='way', selector='"highway"="secondary"', out='geom') roads_secondary = overpass.query(query).ways() or [] query = overpassQueryBuilder(area=areaId, elementType='way', selector='"highway"="primary"', out='geom') roads_primary = overpass.query(query).ways() or [] query = overpassQueryBuilder(area=areaId, elementType='way', selector='"highway"="motorway"', out='geom') roads_motorway = overpass.query(query).ways() or [] query = overpassQueryBuilder(area=areaId, elementType='way', selector='"highway"="trunk"', out='geom') roads_trunk = overpass.query(query).ways() or [] query = overpassQueryBuilder(area=areaId, elementType='way', selector='"highway"="trunk_link"', out='geom') roads_trunk_link = overpass.query(query).ways() or [] query = overpassQueryBuilder(area=areaId, elementType='way', selector='"highway"="unclassified"', out='geom') roads_unclassified = overpass.query(query).ways() or [] #print (result.countElements()) #ax = plt.axes(projection=ccrs.PlateCarree(globe=ccrs.Globe(datum='WGS84', # ellipse='WGS84'))) #print(bbx) request = cimgt.OSM() terrain = cimgt.MapboxTiles( 'pk.eyJ1IjoiZWVzYWhlIiwiYSI6ImNqdGFjMTI1ODA1ZGc0NHRmN28wcG5ybnEifQ.ZBSMcdbWkjfjRgDVQLjfnw', 'terrain-rgb') plt.style.use('dark_background') fig, ax = plt.subplots(num=1, figsize=(10, 10), subplot_kw=dict(projection=request.crs, facecolor='#000000')) #print("trying to save debug terrain img") #plt.savefig("terrain.png") #print("saved") #ax.set_extent([26.6561, 22.6589, 59.611, 60.8409]) #ax.add_image(request, 10, zorder=0) roads = roads_residential + roads_tertiary + roads_secondary + roads_primary + roads_unclassified + roads_trunk + roads_trunk_link def roads_in_bbox(bbox): ret = [] for road in roads: if road._json['bounds']['minlat'] < bbox['maxlat'] and road._json[ 'bounds']['maxlat'] > bbox['minlat'] and road._json[ 'bounds']['minlon'] < bbox['maxlon'] and road._json[ 'bounds']['maxlon'] > bbox['minlon']: ret.append(road) return ret # find areas completely enclosed inside a bounding box (not partially) def residential_areas_enclosed_in_bbox(bbox): ret = [] for area in residential_areas: if area._json['bounds']['maxlat'] < bbox['maxlat'] and area._json[ 'bounds']['minlat'] > bbox['minlat'] and area._json[ 'bounds']['maxlon'] < bbox['maxlon'] and area._json[ 'bounds']['minlon'] > bbox['minlon']: ret.append(area) return ret cll = [] bbx = None ''' processed = 0 roads = roads_residential + roads_tertiary + roads_secondary + roads_primary + roads_unclassified + roads_trunk + roads_trunk_link print("processing total " + str(len(roads)) + " roads") for area in (roads_residential + roads_tertiary + roads_secondary + roads_primary + roads_unclassified + roads_trunk + roads_trunk_link): if(processed % 500 == 0): print("processing number " + str(processed)) geometry = area._json['geometry'] lons = [] lats = [] for point in geometry: lons.append(point['lon']) lats.append(point['lat']) #mycoords.append( (point['lat'], ) ) xs = np.array(lons) ys = np.array(lats) xynps=ax.projection.transform_points(ccrs.Geodetic(), xs, ys) #print(xynps) #break ax.plot(xynps[:,0], xynps[:,1], "r", zorder=11, color='green', marker='o',linewidth=0.2, markersize=0, antialiased=False) processed+=1 ''' print("Found " + str(len(residential_areas)) + " residential areas in " + area_name) # What are we exactly doing here?? ''' for area in residential_areas: #print(vars(area)) geometry = area._json['geometry'] bbx = area._json['bounds'] lons = [] lats = [] for point in geometry: lons.append(point['lon']) lats.append(point['lat']) #mycoords.append( (point['lat'], ) ) xs = np.array(lons) ys = np.array(lats) xynps=ax.projection.transform_points(ccrs.Geodetic(), xs, ys) #print(xynps) #break plt.figure(1) ax.fill(xynps[:,0], xynps[:,1], "b", zorder=10, antialiased=False) cll.append( (lons,lats) ) #print(len(cll)) #ax.axis('off') ''' counter = 0 for area in residential_areas: #if(lat is not None): # bbx['minlon'] = lon # bbx['maxlon'] = lon # bbx['minlat'] = lat # bbx['maxlat'] = lat # width = 0 # height = 0 #else: bbx = area._json['bounds'] width = bbx['maxlon'] - bbx['minlon'] height = bbx['maxlat'] - bbx['minlat'] if (width < 0.0008 or height < 0.0008): print("area too small, skipping") continue #print(width) #print(height) zoom = 0.7 conv_factor = (2.0 * math.pi) / 360.0 lat = bbx['minlat'] lat = lat * conv_factor m1 = 111132.92 # latitude calculation term 1 m2 = -559.82 # latitude calculation term 2 m3 = 1.175 # latitude calculation term 3 m4 = -0.0023 # latitude calculation term 4 p1 = 111412.84 # longitude calculation term 1 p2 = -93.5 # longitude calculation term 2 p3 = 0.118 # longitude calculation term 3 # Calculate the length of a degree of latitude and longitude in meters latlen = m1 + (m2 * math.cos(2 * lat)) + (m3 * math.cos(4 * lat)) + \ (m4 * math.cos(6 * lat)) longlen = (p1 * math.cos(lat)) + (p2 * math.cos(3 * lat)) + \ (p3 * math.cos(5 * lat)) #print("lat len " + str(latlen)) #print("lon len " + str(longlen)) targetWidth = 2500 targetHeight = 2500 currentWidth = longlen * width currentHeight = latlen * height offset_w_meters = (targetWidth - currentWidth) / 2 offset_h_meters = (targetHeight - currentHeight) / 2 offset_w_angles = offset_w_meters / longlen offset_h_angles = offset_h_meters / latlen #print("currentWidth " + str(currentWidth)) #print("currentHeight " + str(currentHeight)) #print("offsetAngleW " + str(offset_w_angles)) #print("offsetAngleH " + str(offset_h_angles)) offsetW = offset_w_angles offsetH = offset_h_angles #my_cos=math.cos(rad) #print("my cos " + str(my_cos)) #test = 0.1 * abs(math.cos(abs(bbx['minlat']))) #print("test " + str(test)) #print("trying to make it " + str(zoom*test) + " degrees wide") #print("testOffsetW" + str(testOffsetW)) #offsetW = ((zoom*0.051122172576223) - width) / 2 #print("realoffsetW" + str(offsetW)) #offsetH = ((zoom*0.038) - height) / 2 #print("offsetH" + str(offsetH)) if offsetW < 0 or offsetH < 0: print("area too big, skipping") continue test_savename = outdir + "/" + clean_name + "_" + str(counter) + ".png" # continue if we already created this file if os.path.isfile(test_savename): counter += 1 continue #print(bbx) new_bbx = bbx.copy() try: new_bbx['minlon'] = bbx['minlon'] - offsetW new_bbx['maxlon'] = bbx['maxlon'] + offsetW new_bbx['minlat'] = bbx['minlat'] - offsetH new_bbx['maxlat'] = bbx['maxlat'] + offsetH except: print("FAILED, BBX: " + str(bbx)) pprint(area._json) # get population density ring = [[new_bbx['minlon'], new_bbx['minlat']], [new_bbx['minlon'], new_bbx['maxlat']], [new_bbx['maxlon'], new_bbx['maxlat']], [new_bbx['maxlon'], new_bbx['minlat']], [new_bbx['minlon'], new_bbx['minlat']]] ring_string = json.dumps(ring) if (lon is None): r = requests.post("http://sedac.ciesin.columbia.edu/arcgis/rest/services/sedac/geoprocessing/GPServer/pes-v1/execute", \ data={'Input_Feature_Set': '{ "geometryType": "esriGeometryPolygon","fields": [{"name": "id","type": "esriFieldTypeInteger"}],"spatialReference": {"wkid": 4326},"features": [{"geometry": {"rings": [ \ ' + ring_string + ' \ ],"spatialReference": {"wkid": 4326}},"attributes": {"id": 1}}]}' , 'f': 'json'}) json_result = json.loads(r.text) attributes = json_result['results'][0]['value']['features'][0][ 'attributes'] pop = attributes['POPULATION05'] area = attributes['LANDAREA'] density = pop / area if (density < 1000): print("density too small") continue #print(new_bbx) #exit() #print("bbx height " + str(new_bbx['maxlat'] - new_bbx['minlat'])) #red_fill = ax.fill(xynps[:,0], xynps[:,1], "r", zorder=10, antialiased=False) plt.figure("terrain") fig_terrain, ax_terrain = plt.subplots(figsize=(10, 10), subplot_kw=dict( projection=request.crs, facecolor='#000000')) try: ax_terrain.set_extent([ new_bbx['minlon'], new_bbx['maxlon'], new_bbx['minlat'], new_bbx['maxlat'] ]) except Exception: print(traceback.format_exc()) print(sys.exc_info()[0]) continue ax_terrain.add_image(terrain, 13) savename = "osm/" + str(re.sub(r'[^a-zA-Z\d]', '', area_name)) + str(counter) + "_t.png" plt.savefig(savename, dpi=_dpi, transparent=True, bbox_inches='tight', pad_inches=0, frameon=None) terrain_raster_261 = cv2.imread(savename) terrain_raster_256_b = terrain_raster_261[3:259, 3:259, 0] terrain_raster_256_g = terrain_raster_261[3:259, 3:259, 1] terrain_raster_256_r = terrain_raster_261[3:259, 3:259, 2] plt.figure(2) fig2, ax2 = plt.subplots(figsize=(10, 10), subplot_kw=dict(projection=request.crs, facecolor='#000000')) xynps = ax.projection.transform_points( ccrs.Geodetic(), np.asarray([new_bbx['minlon'], new_bbx['maxlon']]), np.asarray([new_bbx['minlat'], new_bbx['maxlat']])) #max_lonlat=ax.projection.transform_points(ccrs.Geodetic(), new_bbx['maxlon'], new_bbx['maxlat']) #ax2.set_extent([new_bbx['minlon'], new_bbx['maxlon'], new_bbx['minlat'], new_bbx['maxlat']]) ax2.set_extent([ new_bbx['minlon'], new_bbx['maxlon'], new_bbx['minlat'], new_bbx['maxlat'] ], crs=ccrs.Geodetic()) roads_current = roads_in_bbox(new_bbx) all_areas = residential_areas_enclosed_in_bbox(new_bbx) #print(str(len(all_areas)) + " areas in bbox") red_fills = [] for current_residential_area in (all_areas): bbx = current_residential_area._json['bounds'] width = bbx['maxlon'] - bbx['minlon'] height = bbx['maxlat'] - bbx['minlat'] if (width < 0.001 or height < 0.001): #print("area too small, skipping") continue geometry = current_residential_area._json['geometry'] lons = [] lats = [] for point in geometry: lons.append(point['lon']) lats.append(point['lat']) #mycoords.append( (point['lat'], ) ) xs = np.array(lons) ys = np.array(lats) xynps = ax.projection.transform_points(ccrs.Geodetic(), xs, ys) #print("area " + str(current_residential_area)) red_fill2 = ax2.fill(xynps[:, 0], xynps[:, 1], "k", zorder=11, antialiased=False) red_fills.append(red_fill2) road_refs = [] savename = "osm/" + str(re.sub(r'[^a-zA-Z\d]', '', area_name)) + str(counter) + "_2.png" #print("trying to save file called " +savename) plt.savefig(savename, dpi=_dpi, facecolor='0.0', edgecolor='0.0', transparent=True, bbox_inches='tight', pad_inches=0, frameon=None) #exit() mask_261 = cv2.imread(savename, 0) mask_256 = mask_261[3:259, 3:259] #print("shape:" + str(mask.shape)) #exit() mask_256 = cv2.threshold(mask_256, 127, 255, cv2.THRESH_BINARY_INV)[1] # ensure binary #kernel = np.ones((3,3), np.uint8) kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3)) mask_dilated_256 = cv2.dilate(mask_256, kernel, iterations=2) savename = "osm/" + str(re.sub(r'[^a-zA-Z\d]', '', area_name)) + str(counter) + "_3.png" cv2.imwrite(savename, mask_256) #for road_ref in (road_refs): # l = road_ref.pop(0) # wl = weakref.ref(l) # l.remove() # del l plt.figure(1) ax.set_extent([ new_bbx['minlon'], new_bbx['maxlon'], new_bbx['minlat'], new_bbx['maxlat'] ]) #print("fetch roads") #print("got " + str(len(roads))+ " roads ") #exit() #query = overpassQueryBuilder(bbox=[new_bbx['minlat'], new_bbx['minlon'], new_bbx['maxlat'], new_bbx['maxlon']], elementType='way', selector=['"highway"="residential"', '"highway"="tertiary"', '"highway"="secondary"', '"highway"="primary"', '"highway"="unclassified"', '"highway"="trunk"', '"highway"="trunk_link"'], out='geom') #roads_current = overpass.query(query).ways() #print("got num roads:") if len(roads_current) > 0: #print(len(roads_current)) processed = 0 for area in (roads_current): _type = area._json['tags']['highway'] #print(_type) if _type not in ['primary', 'secondary', 'highway', 'trunk']: continue geometry = area._json['geometry'] lons = [] lats = [] for point in geometry: lons.append(point['lon']) lats.append(point['lat']) #mycoords.append( (point['lat'], ) ) xs = np.array(lons) ys = np.array(lats) xynps = ax.projection.transform_points(ccrs.Geodetic(), xs, ys) #print(xynps) #break plt.figure(1) road_ref = ax.plot(xynps[:, 0], xynps[:, 1], zorder=11, color='#000000', marker='o', linewidth=0.05, markersize=0, antialiased=False) road_refs.append(road_ref) processed += 1 savename = "osm/" + str(re.sub(r'[^a-zA-Z\d]', '', area_name)) + str(counter) + "_0.png" plt.savefig(savename, dpi=_dpi, facecolor='0.0', edgecolor='1.0', transparent=True, bbox_inches='tight', pad_inches=0, frameon=None) roads_primary_secondary_raster_261 = cv2.imread(savename, 0) roads_primary_secondary_raster_256 = roads_primary_secondary_raster_261[ 3:259, 3:259] roads_primary_secondary_raster_256 = cv2.threshold( roads_primary_secondary_raster_256, 127, 255, cv2.THRESH_BINARY_INV)[1] if len(roads_current) > 0: #print(len(roads_current)) processed = 0 for area in (roads_current): #if(processed % 500 == 0): #print("processing number " + str(processed)) geometry = area._json['geometry'] lons = [] lats = [] for point in geometry: lons.append(point['lon']) lats.append(point['lat']) #mycoords.append( (point['lat'], ) ) xs = np.array(lons) ys = np.array(lats) xynps = ax.projection.transform_points(ccrs.Geodetic(), xs, ys) #print(xynps) #break plt.figure(1) road_ref = ax.plot(xynps[:, 0], xynps[:, 1], zorder=11, color='#000000', marker='o', linewidth=0.05, markersize=0, antialiased=False) road_refs.append(road_ref) processed += 1 savename = "osm/" + str(re.sub(r'[^a-zA-Z\d]', '', area_name)) + str(counter) + "_1.png" plt.savefig(savename, dpi=_dpi, facecolor='0.0', edgecolor='1.0', transparent=True, bbox_inches='tight', pad_inches=0, frameon=None) # FINISHED ALL MATPLOTLIB EXPORTS AT THIS POINT roads_raster_261 = cv2.imread(savename, 0) roads_raster_256 = roads_raster_261[3:259, 3:259] #b,g,r = cv2.split(masked_roads)'' roads_raster_256 = cv2.threshold( roads_raster_256, 127, 255, cv2.THRESH_BINARY_INV)[1] # ensure binary # This one will only display the roads that are behind residential areas for the SECOND image masked_roads_256 = cv2.bitwise_and(roads_raster_256, roads_raster_256, mask=mask_dilated_256) #masked_roads = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY_INV)[1] # ensure binary #savename = outdir + str(re.sub(r'[^a-zA-Z\d]', '', area_name)) + str(counter) + "_4.png" #cv2.imwrite(savename, masked_roads) # This one will only show the roads behind residential areas roads_raster_256 = cv2.bitwise_and(roads_raster_256, roads_raster_256, mask=(255 - mask_256)) roads_raster_256 = cv2.bitwise_or(roads_raster_256, roads_primary_secondary_raster_256) __width = mask_256.shape[1] __height = mask_256.shape[0] empty = np.zeros((__height, __width), dtype=np.uint8) #print(str(roads_raster.shape)) #print(str(mask.shape)) #print(str(empty.shape)) out = cv2.merge((roads_raster_256, empty, mask_256)) height = out.shape[0] width = out.shape[1] #print("width") #print(width) if width > 256: out = out[0:height, 0:256] masked_roads = masked_roads[0:height, 0:256] width = 256 if height > 256: out = out[0:256, 0:width] masked_roads = masked_roads[0:256, 0:width] height = 256 if width < 256 or height < 256: width_diff = 256 - width height_diff = 256 - height out = cv2.copyMakeBorder(out, height_diff, 0, width_diff, 0, cv2.BORDER_CONSTANT, value=[0, 0, 0]) masked_roads = cv2.copyMakeBorder(masked_roads, height_diff, 0, width_diff, 0, cv2.BORDER_CONSTANT, value=[0, 0, 0]) height = out.shape[0] width = out.shape[1] #savename = outdir + str(re.sub(r'[^a-zA-Z\d]', '', area_name)) + str(counter) + "_5.png" #cv2.imwrite(savename, out) combined_r = np.zeros((256, 512), dtype=np.uint8) combined_r[0:256, 0:256] = out[:, :, 0] combined_r[0:256, 256:512] = masked_roads_256 combined_g = np.zeros((256, 512), dtype=np.uint8) #combined_g[0:256, 0:256] = terrain_combined_256 #combined_g[0:256, 256:512] = masked_roads combined_b = np.zeros((256, 512), dtype=np.uint8) combined_b[0:256, 0:256] = out[:, :, 2] #combined_b[0:256, 256:512] = masked_roads #b,g,r = cv2.split(terrain_raster) terrain_combined_256 = -10000 + ( (terrain_raster_256_r * 256 * 256 + terrain_raster_256_g * 256 + terrain_raster_256_b) * 0.1) #water = cv2.inRange(terrain_combined_256, 0, 24467) smallest = terrain_combined_256.min() #terrain_combined_256.min() biggest = smallest + 100 # terrain_combined_256.max() #biggest = terrain_combined_256.max() _range = biggest - smallest #print ("biggest " + str(biggest)) #print ("range " + str(_range)) terrain_combined_256 = terrain_combined_256 - smallest print("smallest " + str(terrain_combined_256.min())) print("biggest " + str(terrain_combined_256.max())) terrain_combined_256 = (terrain_combined_256 / _range) * 255 #ret,terrain_combined_256 = cv2.threshold(terrain_combined_256,2,255,cv2.THRESH_BINARY) #terrain_combined_256 = cv2.bitwise_not(terrain_combined_256,terrain_combined_256, mask = water) combined_g[0:256, 0:256] = terrain_combined_256 combined_g[0:256, 0:256] = np.clip(terrain_combined_256, a_min=0, a_max=255) #terrain_debug_savename = outdir + "/" + clean_name + "_" + str(counter) + "_" + str(int(density)) + "_tdbg.png" #cv2.imwrite(terrain_debug_savename,terrain_new) savename = outdir + "/" + clean_name + "_" + str(counter) + "_" + str( int(density)) + ".png" out = cv2.merge((combined_r, combined_g, combined_b)) print("writing out file " + savename) cv2.imwrite(savename, out) for cur_red_fill in (red_fills): l = cur_red_fill.pop(0) wl = weakref.ref(l) l.remove() del l #red_fill2 = ax.fill(xynps[:,0], xynps[:,1], "r", zorder=15, antialiased=False) #savename = "osm/" + str(re.sub(r'[^a-zA-Z\d]', '', area_name)) + str(counter) + "_2.png" #plt.savefig(savename, dpi=128, facecolor='0.0', edgecolor='0.0', transparent=False, bbox_inches='tight', pad_inches=0, frameon=None) counter += 1 #l = red_fill.pop(0) #wl = weakref.ref(l) #l.remove() #del l #counter +=1 #l = red_fill2.pop(0) #wl = weakref.ref(l) #l.remove() #del l for road_ref in (road_refs): l = road_ref.pop(0) wl = weakref.ref(l) l.remove() del l #ax.fill(xynps[:,0], xynps[:,1], "b", zorder=10, antialiased=False) #ax.set_extent([bbx['minlat'], bbx['maxlat'], bbx['minlon'], bbx['maxlon']]) '''
def save_file_png(file_name, file_data, file_geo_x, file_geo_y, scenario_name='NA', scenario_timestamp='NA', fig_color_map_type=None, fig_dpi=150): if fig_color_map_type is None: fig_color_map_type = 'Blues' fig_color_map_obj = load(fig_color_map_type) p = Proj(proj='utm', zone=32, ellps='WGS84') file_lons, file_lats = p(file_geo_x, file_geo_y, inverse=True) file_lon_west = np.min(file_lons) file_lon_east = np.max(file_lons) file_lat_south = np.min(file_lats) file_lat_north = np.max(file_lats) plot_crs = cartopy.crs.Mercator() data_crs = cartopy.crs.PlateCarree() # Define graph title figure_title = ' == Floods Scenario - Catchment: ' + scenario_name + ' Time: ' + scenario_timestamp + ' == ' # Create a Stamen Terrain instance. # map_background = cimgt.Stamen('terrain-background') map_background = cimgt.OSM() # map_background = cimgt.GoogleTiles() fig = plt.figure(figsize=(12, 10)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=plot_crs) ax.set_title(figure_title, size=14, color='black', weight='bold') # ax.coastlines(resolution='10m', color='black') ax.stock_img() ax.set_extent( [file_lon_west, file_lon_east, file_lat_south, file_lat_north]) gl = ax.gridlines(crs=data_crs, draw_labels=True, linewidth=2, color='gray', alpha=0.5, linestyle='--') gl.xlabels_bottom = True gl.xlabels_top = False gl.ylabels_left = True gl.ylabels_right = False gl.xformatter = LONGITUDE_FORMATTER gl.yformatter = LATITUDE_FORMATTER gl.xlabel_style = {'size': 8, 'color': 'gray', 'weight': 'bold'} gl.ylabel_style = {'size': 8, 'color': 'gray', 'weight': 'bold'} # Add the Stamen data at zoom level 8. ax.add_image(map_background, 14) sc = ax.pcolormesh(file_lons, file_lats, np.flipud(file_data), zorder=3, cmap=fig_color_map_obj, transform=data_crs) divider = make_axes_locatable(ax) ax_cb = divider.new_horizontal(size="5%", pad=0.1, axes_class=plt.Axes) fig.add_axes(ax_cb) cb1 = plt.colorbar(sc, cax=ax_cb, extend='both') cb1.set_label('water level [m]', size=12, color='gray', weight='normal') cb1.ax.tick_params(labelsize=10, labelcolor='gray') fig.savefig(file_name, dpi=fig_dpi) plt.close()
def plot_spat_interpol(self, time, figsize=(15, 15), OSMtile=False, out_file=None): """Plot spatial interpolation of rain rate Parameters ---------- time : str, optional Datetime string of desired timestamp (for example 'yyyy-mm-dd HH:MM') figsize : matplotlib parameter, optional Size of output figure in inches (default is (15,15)) OSMtile : bool, optional Use OpenStreetMap tile as background (slows down the plotting) out_file : str, optional file path of output image file (Default is None) """ fig = plt.figure(figsize=figsize) ax = plt.axes(projection=cartopy.crs.PlateCarree()) gl = ax.gridlines(crs=cartopy.crs.PlateCarree(), draw_labels=True, linewidth=2, color='gray', alpha=0.5, linestyle='--') gl.xlabels_top = False ax.set_extent( (self.set_info['area'][0] - .05, self.set_info['area'][1] + .05, self.set_info['area'][2] - .05, self.set_info['area'][3] + .05), crs=cartopy.crs.PlateCarree()) if OSMtile: gg_tiles = img_tiles.OSM() ax.add_image(gg_tiles, 11) nws_precip_colors = [ "#04e9e7", # 0.01 - 0.10 inches "#019ff4", # 0.10 - 0.25 inches "#0300f4", # 0.25 - 0.50 inches "#02fd02", # 0.50 - 0.75 inches "#01c501", # 0.75 - 1.00 inches "#008e00", # 1.00 - 1.50 inches "#fdf802", # 1.50 - 2.00 inches "#e5bc00", # 2.00 - 2.50 inches "#fd9500", # 2.50 - 3.00 inches "#fd0000", # 3.00 - 4.00 inches "#d40000", # 4.00 - 5.00 inches "#bc0000", # 5.00 - 6.00 inches "#f800fd", # 6.00 - 8.00 inches "#9854c6" # 10.00+ ] precip_colormap = matplotlib.colors.ListedColormap(nws_precip_colors) levels_rr = [ 0.01, 0.1, 0.25, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 5.0, 7.5, 10.0, 12.5, 15.0, 20.0 ] for cml in self.set: if 'site_A' in cml.metadata and 'site_B' in cml.metadata: if 'lat' in cml.metadata['site_A'] and \ 'lon' in cml.metadata['site_A'] and \ 'lat' in cml.metadata['site_B'] and \ 'lon' in cml.metadata['site_B']: plt.plot([ cml.metadata['site_A']['lon'], cml.metadata['site_B']['lon'] ], [ cml.metadata['site_A']['lat'], cml.metadata['site_B']['lat'] ], linewidth=1, color='k', transform=cartopy.crs.Geodetic()) interpolm = np.ma.masked_less( self.set_info['interpol'][( pd.Timestamp(time)).strftime('%Y-%m-%d %H:%M')], 0.01) norm = matplotlib.colors.BoundaryNorm(levels_rr, 14) cs = plt.pcolormesh(self.set_info['interpol_longrid'], self.set_info['interpol_latgrid'], interpolm, norm=norm, cmap=precip_colormap, alpha=0.4) cbar = plt.colorbar(cs, orientation='vertical', shrink=0.4) cbar.set_label('mm/h') plt.title((pd.Timestamp(time)).strftime('%Y-%m-%d %H:%M') + 'UTC', loc='right') plt.plot([self.set_info['area'][0], self.set_info['area'][0]], [self.set_info['area'][2], self.set_info['area'][3]], linewidth=2, color='k', alpha=0.6, transform=cartopy.crs.Geodetic()) plt.plot([self.set_info['area'][0], self.set_info['area'][1]], [self.set_info['area'][2], self.set_info['area'][2]], linewidth=2, color='k', alpha=0.6, transform=cartopy.crs.Geodetic()) plt.plot([self.set_info['area'][1], self.set_info['area'][1]], [self.set_info['area'][2], self.set_info['area'][3]], linewidth=2, color='k', alpha=0.6, transform=cartopy.crs.Geodetic()) plt.plot([self.set_info['area'][0], self.set_info['area'][1]], [self.set_info['area'][3], self.set_info['area'][3]], linewidth=2, color='k', alpha=0.6, transform=cartopy.crs.Geodetic()) if out_file is not None: plt.savefig(out_file, bbox_inches='tight', format='png')
def maprando(input_file, output_file, title=None): """ Create personalized maps from my Strava activities. Input: -input_file str -output_file str pdf -title str """ # read gpx file activity_date, activity_name, xmin, xmax, ymin, ymax, points = read_gpx( input_file) # get coordinates of points in meters (projected in EPSG 3857) projected_coords = ccrs.epsg(3857).transform_points( ccrs.PlateCarree(), np.asarray(points["lon"]), np.asarray(points["lat"])) # add velocity (in km/h) to points dataframe gradient = np.gradient( # compute gradient projected_coords[:, :2], points["time"], axis=0) gradient *= 3.6 # convert form m/s to km/h points["vel"] = np.array([norm(v) for v in gradient]) # add to dataframe # filter velocity b, a = signal.butter(3, 0.01) # get Butterworth filter coefficients points["vel"] = signal.filtfilt( b, a, points["vel"]) # apply forward and backward filter # create figure fig = plt.figure(figsize=(16, 12), dpi=100) # create geo axes geo_axes = plt.axes(projection=ccrs.PlateCarree()) # plot points plt.scatter( points["lon"], points["lat"], c=points["vel"], cmap="RdBu_r", linewidth=1, marker="o", transform=ccrs.PlateCarree(), ) # add colorbar cbar = plt.colorbar(shrink=0.4) cbar.set_label("Walking speed (km/h)") # add open street map background osm_background = cimgt.OSM() geo_axes.add_image(osm_background, 15) # add gridlines gridlines = geo_axes.gridlines(draw_labels=True, ) gridlines.top_labels = False gridlines.right_labels = False gridlines.xformatter = FormatStrFormatter("%.3f°E") gridlines.yformatter = FormatStrFormatter("%.4f°N") # add title if title is not None: plt.title(title) # save map plt.savefig(output_file, bbox_inches="tight")
# print idx for idx in range(2846, 3070): val = df.index[idx] print idx # In[103]: val # In[ ]: import matplotlib.pyplot as plt import cartopy.crs as ccrs from cartopy.io import img_tiles tiles = img_tiles.OSM() fig = plt.figure(figsize=(15, 14)) ax = plt.subplot(211, projection=ccrs.Mercator()) ax.set_extent([-4.2, -3, 50.3, 50.7]) ax.add_image(tiles, 9) ax.coastlines("10m") ax = plt.subplot(212, projection=ccrs.Mercator()) ax.set_extent([-4.2, -3, 50.3, 50.7]) ax.add_image(tiles, 10) ax.coastlines("10m") plt.show() # In[ ]:
class RainAlerter: """ Retrieves and plots data for city specified in the command line arguement """ tiler = cimgt.OSM() proj = tiler.crs trans = ccrs.PlateCarree() logo = mpimg.imread(os.path.join(HERE, 'routewx_logo.png')) def __init__(self, init_datestr): self.init_datestr = init_datestr self.total_img = None self.data_maximums = [] self.hourly_data = dict( (recipient, dict((point_label, []) for point_label in point)) for recipient, point in RECIPIENTS.items()) def start(self): """ Starts the loop over each hour """ fig = plt.figure(figsize=(10, 10)) for hour in range(1, 37): final_hour = hour == 36 hrrr_data_tuple = retrieve_hrrr_data(hour, total=final_hour) hrrr_data_inches, max_precip_inches = self._data_conversion_and_max( hour, hrrr_data_tuple) hour_datestr = generate_hour_datestr(hour) if max_precip_inches > 0.05 and hour < 36: precip_inches, precip_lats, precip_lons = hrrr_data_inches for recipient in self.hourly_data: for point in self.hourly_data[recipient]: point_lat = POINTS[point]['Lat'] point_lon = POINTS[point]['Lon'] point_precip = nearest_gridpoint( precip_lats, precip_lons, point_lat, point_lon, precip_inches) self.hourly_data[recipient][point].append( {hour_datestr: point_precip}) if final_hour: print(max_precip_inches) self.plot_total(hrrr_data_inches, hour_datestr, max_precip_inches) def _data_conversion_and_max(self, hour, hrrr_data): precip_mm, precip_lats, precip_lons = hrrr_data precip_inches = precip_mm * MM_TO_IN max_precip_inches = np.max(precip_inches) if hour < 36: self.data_maximums.append(max_precip_inches) hrrr_data_inches = (precip_inches, precip_lats, precip_lons) return (hrrr_data_inches, max_precip_inches) def _savefig_hourly(self, fig, precip_contour, plot_count): title_str = CITY_NAME + '\n1 Hr. Precip. (in.)' fig.suptitle(title_str) fig.tight_layout(rect=(0.00, 0.05, 0.95, 0.95)) fig.subplots_adjust(right=0.85) cbar_ax = fig.add_axes([0.8, 0.09, 0.025, 0.79]) fig.colorbar(precip_contour, cax=cbar_ax) logo_ax = fig.add_axes([0, 0, 0.2, 0.15]) logo_ax.axis('off') logo_ax.imshow(self.logo) plot_fname = 'accum_thumb_' + str(plot_count / 4) + '.png' buf = io.BytesIO() fig.savefig(buf, dpi=300) buf.seek(0) img = MIMEImage(buf.read()) img.add_header('Content-Disposition', "attachment; filename= %s" % plot_fname) self.msg.attach(img) buf.close() fig.clf() def plot_hourly(self, fig, hrrr_data, hour_datestr, plot_count): """ Plots hourly accumlated precipitation data @param {object} fig - hourly matplotlib.figure.Figure instance. @param {tuple} hrrr_data - tuple containing gridded model data, and corresponding lats, lons. @param {str} hour_datestr - human-friendly string representing the current hour. @param {int} plot_count - Current number of plots generated. @return {object, QuadContourSet} fig, precip_contour """ precip_inches, precip_lats, precip_lons = hrrr_data print(plot_count, 'plot_count') axes_idx = (plot_count + 1) % 4 if (plot_count + 1) % 4 > 0 else 1 print(axes_idx, 'axes_idx') current_ax = fig.add_subplot(2, 2, axes_idx, projection=self.proj) precip_contour = current_ax.contourf(precip_lons, precip_lats, precip_inches, transform=self.trans, cmap=plt.cm.get_cmap('ocean_r'), vmin=0) current_ax.set_title(hour_datestr) current_ax.set_xticks([], []) current_ax.set_yticks([], []) return fig, precip_contour def plot_total(self, hrrr_data, hour_datestr, max_precip_inches): """ Plots total accumulated precipitation """ precip_inches, precip_lats, precip_lons = hrrr_data fig = plt.figure(figsize=(10, 10)) total_ax = plt.axes(projection=self.proj) total_ax.set_extent([L_LON, R_LON, B_LAT, T_LAT], crs=self.trans) total_ax.add_image(self.tiler, ZOOM_LEVEL) precip_contour = total_ax.contourf(precip_lons, precip_lats, precip_inches, transform=self.trans, cmap=plt.get_cmap('ocean_r'), alpha=0.5) if False: for label, coords in POINTS.items(): point_lon = coords['Lon'] point_lat = coords['Lat'] total_ax.scatter(point_lon, point_lat, color='k', linewidth=2, marker='o', transform=self.trans) total_ax.text(point_lon - LABEL_OFFSET, point_lat - LABEL_OFFSET, label, transform=self.trans) grid_precip = nearest_gridpoint(precip_lats, precip_lons, point_lat, point_lon, precip_inches) total_ax.text(point_lon + LABEL_OFFSET, point_lat + LABEL_OFFSET, str(grid_precip) + ' inches', transform=self.trans) fig.colorbar(precip_contour, ax=total_ax) plt.title(AREA + '\nTotal Precip (in.) - ' + self.init_datestr + ' to ' + hour_datestr) logo_ax = fig.add_axes([0, 0, 0.2, 0.15]) logo_ax.axis('off') logo_ax.imshow(self.logo) if max_precip_inches > 0: self._savefig_total(fig) def _savefig_total(self, fig): buf = io.BytesIO() fig.savefig(buf, dpi=300) buf.seek(0) img = buf.read() self.total_img = img buf.close()
# You'll need cartopy for a pretty map import json import matplotlib.pyplot as plt import datetime import urllib2, urllib import pandas as pd import sys import cartopy.crs as ccrs import cartopy.io.img_tiles as cimgt import matplotlib.cm as cm db = pd.read_csv(sys.argv[1]) db['Date'] = db['Date'].apply(pd.to_datetime) bg = cimgt.OSM() src = ccrs.PlateCarree() f = plt.figure(figsize=(20, 30)) ax = plt.axes(projection=bg.crs) ax.add_image(bg, 9, alpha=0.5) x, y = db['lon'], db['lat'] extent = [y.min(), y.max(), x.min(), 34] extent = [34, 36, x.min(), x.max()] #Manually tweaked for d, day in db.set_index('Date').groupby(lambda x: x.day): y, x = day['lon'], day['lat'] c = cm.Set1(d/30.) s = plt.scatter(x, y, marker='^', color=c, label=str(d), s=40, \ transform=src) ax.set_extent(extent, crs=src) plt.legend(loc=2) plt.title('Spatial distribution of events by day')
axe = plt.axes(projection=tiler.crs) axe.plot(lons, lats, color='red', transform=ccrs.Geodetic(), **kwargs) if title: axe.set_title(title) zoom = 12 axe.add_image(tiler, zoom) plt.show() if title: plt.savefig(title + '.png') for provider in [ { 'tiler': cimgt.OSM(), 'title': 'OSM' }, { 'tiler': cimgt.GoogleTiles(), 'title': 'GoogleTiles' }, { 'tiler': cimgt.MapQuestOpenAerial(), 'title': 'MapQuestOpenAerial' }, #this last one raises an errot which is managed { 'tiler': cimgt.Stamen(), 'title': 'Stamen' },
def common_features( scale="110m", ax=None, crs=pc, *, figsize=None, dpi=None, counties_scale="20m", dark=False, verbose=False, COASTLINES=True, COASTLINES_kwargs={}, BORDERS=False, BORDERS_kwargs={}, STATES=False, STATES_kwargs={}, COUNTIES=False, COUNTIES_kwargs={}, OCEAN=False, OCEAN_kwargs={}, LAND=False, LAND_kwargs={}, RIVERS=False, RIVERS_kwargs={}, LAKES=False, LAKES_kwargs={}, ROADS=False, ROADS_kwargs={}, PLACES=False, PLACES_kwargs={}, STAMEN=False, STAMEN_kwargs={}, OSM=False, OSM_kwargs={}, **kwargs, ): """ Add common features to a cartopy axis. This completes about 95% of my cartopy needs. .. tip:: This is a great way to initialize a new cartopy axes. Parameters ---------- scale : {'10m', '50m' 110m'} The cartopy feature's level of detail. .. note:: The ``'10m'`` scale for OCEAN and LAND takes a *long* time. ax : plot axes The axis to add the feature to. If None, it will create a new cartopy axes with ``crs``. crs : cartopy.crs Coordinate reference system (aka "projection") to create new map if no cartopy axes is given. Default is ccrs.PlateCarree. dark : bool If True, use alternative "dark theme" colors for land and water. .. figure:: _static/BB_maps/common_features-1.png .. figure:: _static/BB_maps/common_features-2.png counties_scale: {'20m', '5m', '500k'} Counties are plotted via MetPy and have different resolutions available than other features. - 20m = 20,000,000 resolution (Ok if you show a large area) - 5m = 5,000,000 resolution (provides good detail) - 500k = 500,000 resolution (high resolution, plots very slow) figsize : tuple Set the figure size dpi : int Set the figure dpi FEATURES : bool Toggle on various features. By default, only COASTLINES is turned on. Each feature has a cooresponding ``FEATURE_kwargs={}`` dictionary to supply additional arguments to cartopy's add_feature method (e.g., change line color or width by feature type). ========== ========================================================= FEATURE Description ========== ========================================================= COASTLINES Coastlines, boundary between land and ocean. BORDERS Borders between countries. *Does not includes coast*. STATES US state borders. Includes coast. COUNTIES US Counties. Includes coast. OCEAN Colored ocean area LAND Colored land area RIVERS Lines where rivers exist LAKES Colored lake area ROADS All major roads. Can break filter by road type. PLACES Points and labels for major cities (filter by rank). ========== ========================================================= ========== ========================================================= MAP TILE Description ========== ========================================================= Stamen Specify type and zoom level. http://maps.stamen.com/ Style: ``terrain-background``, ``terrain``, ``toner-background``, ``toner``, `watercolor`` zoom: int [0-10] alpha: [0-1] alpha_color: an overlay color to put on top of map use 'k' to darken background use 'w' to lighten background OSM Open Street Maps zoom: int ========== ========================================================= .. note:: For ``ROADS_kwargs`` you may provide a key for 'type' to filter out the types of roads you want. The road type may be a single string or a list of road types. For example ``ROADS_kwargs=dict(type='Major Highway')`` or ``ROADS_kwargs=dict(type=['Secondary Highway', 'Major Highway']) Of course, the shapefile has many other road classifiers for each road, like "level" (Federal, State, Interstate), road "name", "length_km", etc. Filters for each of these could be added if I need them later. .. note:: When adding a tile product to a map, it might be better to add it to the map first, then set the map extent, then make a separate call to ``common_features`` to add other features like roads and counties. The reason is because, if you add a tile map to Methods ------- .adjust_extent .center_extent .copy_extent Examples -------- https://github.com/blaylockbk/Carpenter_Workshop/blob/main/notebooks/demo_cartopy_tools.ipynb Returns ------- The cartopy axes (obviously you don't need this if you gave an ax as an argument, but it is useful if you initialize a new map). """ ax = check_cartopy_axes(ax=ax, crs=crs, verbose=verbose) if (LAND or OCEAN) and scale in ["10m"]: if verbose: warnings.warn( "đ OCEAN or LAND features at 10m may take a long time (3+ mins) to display on large maps." ) kwargs.setdefault("linewidth", 0.75) COASTLINES_kwargs.setdefault("zorder", 100) COASTLINES_kwargs.setdefault("facecolor", "none") COUNTIES_kwargs.setdefault("linewidth", 0.5) STATES_kwargs.setdefault("alpha", 0.15) LAND_kwargs.setdefault("edgecolor", "none") LAND_kwargs.setdefault("linewidth", 0) OCEAN_kwargs.setdefault("edgecolor", "none") LAKES_kwargs.setdefault("linewidth", 0) # NOTE: I don't use the 'setdefault' method here because it doesn't # work as expect when switching between dark and normal themes. # The defaults would be set the first time the function is called, # but the next time it is called and `dark=True` the defaults do not # reset. I don't know why this is the behavior. if dark: land = "#060613" water = "#0f2b38" # https://github.com/SciTools/cartopy/issues/880 ax.set_facecolor(land) # requires cartopy >= 0.18 kwargs = {**{"edgecolor": ".5"}, **kwargs} LAND_kwargs = {**{"facecolor": land}, **LAND_kwargs} OCEAN_kwargs = {**{"facecolor": water}, **OCEAN_kwargs} RIVERS_kwargs = {**{"edgecolor": water}, **RIVERS_kwargs} LAKES_kwargs = {**{"facecolor": water}, **LAKES_kwargs} else: kwargs = {**{"edgecolor": ".15"}, **kwargs} RIVERS_kwargs = { **{ "edgecolor": feature.COLORS["water"] }, **RIVERS_kwargs } LAKES_kwargs = { **{ "edgecolor": feature.COLORS["water"] }, **LAKES_kwargs } ##------------------------------------------------------------------ ## Add each element to the plot ## When combining kwargs, ## - kwargs is the main value ## - FEATURE_kwargs is the overwrite for the feature ## For example: ## {**kwargs, **FEATURE_kwargs} ## the kwargs are overwritten by FEATURE_kwargs ##------------------------------------------------------------------ if COASTLINES: # ax.coastlines(scale, **kwargs) # Nah, use the crs.feature instead ax.add_feature(feature.COASTLINE.with_scale(scale), **{ **kwargs, **COASTLINES_kwargs }) if verbose == "debug": print("đ COASTLINES:", {**kwargs, **COASTLINES_kwargs}) if BORDERS: ax.add_feature(feature.BORDERS.with_scale(scale), **{ **kwargs, **BORDERS_kwargs }) if verbose == "debug": print("đ BORDERS:", {**kwargs, **BORDERS_kwargs}) if STATES: ax.add_feature(feature.STATES.with_scale(scale), **{ **kwargs, **STATES_kwargs }) if verbose == "debug": print("đ STATES:", {**kwargs, **STATES_kwargs}) if COUNTIES: _counties_scale = {"20m", "5m", "500k"} assert ( counties_scale in _counties_scale), f"counties_scale must be {_counties_scale}" ax.add_feature(USCOUNTIES.with_scale(counties_scale), **{ **kwargs, **COUNTIES_kwargs }) if verbose == "debug": print("đ COUNTIES:", {**kwargs, **COUNTIES_kwargs}) if OCEAN: ax.add_feature(feature.OCEAN.with_scale(scale), **{ **kwargs, **OCEAN_kwargs }) if verbose == "debug": print("đ OCEAN:", {**kwargs, **OCEAN_kwargs}) if LAND and not dark: # If `dark=True`, the face_color is the land color. ax.add_feature(feature.LAND.with_scale(scale), **{ **kwargs, **LAND_kwargs }) if verbose == "debug": print("đ LAND:", {**kwargs, **LAND_kwargs}) if RIVERS: ax.add_feature(feature.RIVERS.with_scale(scale), **{ **kwargs, **RIVERS_kwargs }) if verbose == "debug": print("đ RIVERS:", {**kwargs, **RIVERS_kwargs}) if LAKES: ax.add_feature(feature.LAKES.with_scale(scale), **{ **kwargs, **LAKES_kwargs }) if verbose == "debug": print("đ LAKES:", {**kwargs, **LAKES_kwargs}) if ROADS: ROADS_kwargs.setdefault("edgecolor", "#b30000") ROADS_kwargs.setdefault("facecolor", "none") ROADS_kwargs.setdefault("linewidth", 0.2) if "type" not in ROADS_kwargs: # Plot all roadways roads = feature.NaturalEarthFeature("cultural", "roads", "10m", **ROADS_kwargs) ax.add_feature(roads) else: # Specify the type of road to include in plot road_types = ROADS_kwargs.pop("type") if isinstance(road_types, str): road_types = [road_types] shpfilename = shapereader.natural_earth("10m", "cultural", "roads") df = geopandas.read_file(shpfilename) _types = df["type"].unique() assert np.all([ i in _types for i in road_types ]), f"`ROADS_kwargs['type']` must be a list of these: {_types}" road_geos = df.loc[df["type"].apply( lambda x: x in road_types)].geometry.values ax.add_geometries(road_geos, crs=pc, **ROADS_kwargs) if verbose == "debug": print("đ ROADS:", ROADS_kwargs) if PLACES: PLACES_kwargs.setdefault("country", "United States") PLACES_kwargs.setdefault("rank", 2) PLACES_kwargs.setdefault("scatter_kw", {"marker": "."}) PLACES_kwargs.setdefault("label_kw", dict(fontweight="bold", alpha=0.5)) country = PLACES_kwargs.pop("country") rank = PLACES_kwargs.pop("rank") scatter_kw = PLACES_kwargs.pop("scatter_kw") label_kw = PLACES_kwargs.pop("label_kw") places = shapereader.natural_earth("10m", "cultural", "populated_places") df = geopandas.read_file(places) df = df[df.SOV0NAME == country] df = df[df.SCALERANK <= rank] xs = df.geometry.values.x ys = df.geometry.values.y names = df.NAME if scatter_kw is not None: ax.scatter(xs, ys, transform=pc, **scatter_kw) if label_kw is not None: for x, y, name in zip(xs, ys, names): plt.text(x, y, name, clip_on=True, **label_kw) if STAMEN: if verbose: print( "đ Please use `ax.set_extent` before increasing Zoom level for faster plotting." ) STAMEN_kwargs.setdefault("style", "terrain-background") STAMEN_kwargs.setdefault("zoom", 3) stamen_terrain = cimgt.Stamen(STAMEN_kwargs["style"]) ax.add_image(stamen_terrain, STAMEN_kwargs["zoom"]) if "alpha" in STAMEN_kwargs: # Need to manually put a white layer over the STAMEN terrain if dark: STAMEN_kwargs.setdefault("alpha_color", "k") else: STAMEN_kwargs.setdefault("alpha_color", "w") poly = ax.projection.domain ax.add_feature( feature.ShapelyFeature([poly], ax.projection), color=STAMEN_kwargs["alpha_color"], alpha=1 - STAMEN_kwargs["alpha"], zorder=1, ) if verbose == "debug": print("đ STAMEN:", STAMEN_kwargs) if OSM: image = cimgt.OSM() OSM_kwargs.setdefault("zoom", 1) ax.add_image(image, OSM_kwargs["zoom"]) if "alpha" in OSM_kwargs: # Need to manually put a white layer over the STAMEN terrain if dark: OSM_kwargs.setdefault("alpha_color", "k") else: OSM_kwargs.setdefault("alpha_color", "w") poly = ax.projection.domain ax.add_feature( feature.ShapelyFeature([poly], ax.projection), color=OSM_kwargs["alpha_color"], alpha=1 - OSM_kwargs["alpha"], zorder=1, ) if verbose == "debug": print("đ OSM:", OSM_kwargs) if figsize is not None: plt.gcf().set_figwidth(figsize[0]) plt.gcf().set_figheight(figsize[1]) if dpi is not None: plt.gcf().set_dpi(dpi) # Add my custom methods ax.__class__.adjust_extent = _adjust_extent ax.__class__.center_extent = _center_extent ax.__class__.copy_extent = _copy_extent return ax
from urllib.request import urlopen, Request from PIL import Image def image_spoof(self, tile): # this function pretends not to be a Python script url = self._image_url(tile) # get the url of the street map API req = Request(url) # start request req.add_header('User-agent','Anaconda 3') # add user agent to request fh = urlopen(req) im_data = io.BytesIO(fh.read()) # get image fh.close() # close url img = Image.open(im_data) # open image with PIL img = img.convert(self.desired_tile_form) # set image format return img, self.tileextent(tile), 'lower' # reformat for cartopy cimgt.OSM.get_image = image_spoof # reformat web request for street map spoofing osm_img = cimgt.OSM() # spoofed, downloaded street map fig = plt.figure(figsize=(12,9)) # open matplotlib figure ax1 = plt.subplot(231, projection=osm_img.crs) # project using coordinate reference system (CRS) of street map #center_pt = [40.713, -74.0135] # lat/lon of One World Trade Center in NY center_pt = [50.7313, -3.5170] # lat/lon of nearby zoom = 0.00075 # for zooming out of center point #zoom = 0.00500 # for zooming out of center point extent = [center_pt[1]-(zoom*2.0),center_pt[1]+(zoom*2.0),center_pt[0]-zoom,center_pt[0]+zoom] # adjust to zoom ax1.set_extent(extent) # set extents scale = np.ceil(-np.sqrt(2)*np.log(np.divide(zoom,350.0))) # empirical solve for scale based on zoom