def summary_figure(self, num=3): fig = plt.figure(num) fig.clf() ax_map = fig.add_subplot(1, 2, 1) ax_A = fig.add_subplot(1, 2, 2) # pnts = self.section_ls L = 5 * self.section_s.max() clip = [ pnts[:, 0].min() - L, pnts[:, 0].max() + L, pnts[:, 1].min() - L, pnts[:, 1].max() ] plot_wkb.plot_wkb(hyp.g_poly, fc='0.8', ec='none', ax=ax_map, zorder=-4) # hyp.g.plot_cells(mask=self.region_cells,ax=ax_map,color='orange') ax_map.plot(self.section_ls[:, 0], self.section_ls[:, 1], 'b-') # Show the location of the reference station ax_map.plot([ self.hyp.his.station_x_coordinate.isel( stations=self.section_station) ], [ self.hyp.his.station_y_coordinate.isel( stations=self.section_station) ], 'go') ax_map.text(self.section_ls[0, 0], self.section_ls[0, 1], self.section_name) ax_map.axis('equal') ax_map.axis(clip) order = np.argsort(self.eta) ax_A.plot(self.eta[order], self.areas[order], label="model") dem_xas = np.array([self.dem_eta_to_xA(eta) for eta in self.eta]) ax_A.plot(self.eta[order], dem_xas[order], label='DEM', color='k', lw=0.6) ax_A.set_ylabel('area') ax_A.set_xlabel('eta') ax_A.legend() return fig
def make_summary_map(model,mr): poly=model.grid.boundary_polygon() his_file=model.his_output() fig=plt.figure(10) fig.set_size_inches((6,9),forward=True) fig.clf() ax=fig.add_axes([0,0,1,1]) ax.xaxis.set_visible(0) ax.yaxis.set_visible(0) plot_wkb.plot_wkb(poly,ax=ax,fc='0.75',ec='0.75',lw=0.8) ax.axis('equal') for station in stations: args = station[1] args['ID'] = station[0] for key in defaults: args.setdefault(key, defaults[key]) # append default parameters if missing p = MyPlotter(mr, args) if not p.valid: continue if args['ID']=='TSL' and args['var']=='flow' and 'grid100_13' in his_file: print("Monkey patch sign on TSL flow") p.pred *= -1 metrics=p.calculate_metrics() if metrics['ratio']<-1000: continue # probably no data xy=p.xy if xy.ndim==2: xy=xy.mean(axis=0) # a little tricky with flow+stage if args['var']=='flow': kw=dict(va='top') else: kw=dict(va='bottom') kw['clip_on']=True kw['fontsize']=8 ax.text(xy[0],xy[1],"%s %s: %.2f/%.1fmin"%(args['ID'],args['var'], metrics['ratio'], 24*60*metrics['lag']) , **kw) ax.axis( (605686., 639321., 4211471, 4267529)) plot_utils.reduce_text_overlap(ax) fig.savefig(os.path.join(plot_dir,'amp_phase_map.png'),dpi=120) return fig
def make_phase_figure(model,mr): poly=model.grid.boundary_polygon() period_s=12.4206*3600 results=calc_phases(model,period_s=period_s) fig=plt.figure(11) fig.clf() fig.set_size_inches((10,10),forward=True) fig,axs=plt.subplots(1,2,sharex=True,sharey=True,num=11) axs[0].set_position([0,0,0.5,1.0]) axs[1].set_position([0.5,0,0.5,1.0]) caxs=[ fig.add_axes([0.05,0.5,0.03,0.45]), fig.add_axes([0.55,0.5,0.03,0.45]) ] ccolls=[] for proc in range(model.num_procs): proc_data=results[proc] for ax,cax,ph,name in zip(axs,caxs, [proc_data['eta_phases']-results['ref_eta_phase'], proc_data['uf_phases']-results['ref_uf_phase']], ['eta','u']): gsub=proc_data['grid'] phase_relative=(ph + 180)%360 - 180 phase_minutes=-phase_relative/360. * (period_s/60.) period_minutes=period_s/60. ccoll=gsub.plot_cells(values=phase_minutes%period_minutes, clim=[0,period_minutes],ax=ax) if 0: # contours are messy ecoll=gsub.scalar_contour(phase_minutes,V=np.arange(-30,500,15)) ax.add_collection(ecoll) ccoll.set_cmap('hsv') if proc==0: ax.xaxis.set_visible(0) ax.yaxis.set_visible(0) plot_wkb.plot_wkb(poly,ax=ax,fc='none',ec='0.5',lw=0.8,zorder=-10) plt.colorbar(ccoll,orientation='vertical',cax=cax, label='%s phase (minutes)'%name) ax.axis('equal') fig.savefig(os.path.join(plot_dir,"phases.png"))
def setup_figure(num=1): plt.figure(num).clf() fig, ax = plt.subplots(num=num) fig.set_size_inches([6.4, 4.8], forward=True) ax.set_position([0, 0, 1, 1]) ax.xaxis.set_visible(0) ax.yaxis.set_visible(0) ax.set_facecolor('0.7') lcoll = collections.LineCollection(lin_segs, lw=0.8, color='k') ax.add_collection(lcoll) plot_wkb.plot_wkb(domain_poly, facecolor='none', lw=0.8, ax=ax) plot_wkb.plot_wkb(domain_poly, edgecolor='none', facecolor='w', lw=0.8, ax=ax, zorder=-.5) cax = fig.add_axes([0.08, 0.2, 0.3, 0.03]) return fig, ax, cax
noise[:winsize] = 0 # so the ends still match up noise[-winsize:] = 0 noise_lp = filters.lowpass_fir(noise, winsize) noise_lp *= noise_w / np.sqrt(np.mean(noise_lp**2)) # domain boundary including the random noise ring_noise = ring + noise_lp[:, None] * ring_norm # Create the curvilinear section thalweg = centerline[50:110] plt.figure(1).clf() plt.plot(centerline[:, 0], centerline[:, 1], 'k-', zorder=2) plt.axis('equal') plot_wkb.plot_wkb(channel, zorder=-2) plt.plot(ring_noise[:, 0], ring_noise[:, 1], 'm-') plt.plot(thalweg[:, 0], thalweg[:, 1], 'r--', lw=3) ## # First, just the curvilinear section: g = unstructured_grid.UnstructuredGrid(max_sides=4) thalweg_resamp = linestring_utils.resample_linearring(thalweg, 50, closed_ring=0) g.add_rectilinear_on_line( thalweg_resamp,
for j in cdt.valid_edge_iter(): c1, c2 = cdt.edges['cells'][j] if c1 < 0 or c2 < 0: continue if not (cell_sub[c1] and cell_sub[c2]): continue for c in [c1, c2]: if c not in cell_to_node: cell_to_node[c] = ma.add_node(x=cc[c]) ma.add_edge(nodes=[cell_to_node[c1], cell_to_node[c2]]) ## # That gets to a reasonable MA - but still a lot of work to do... ## plt.figure(21).clf() fig, ax = plt.subplots(num=21) x, y = dem2.xy() X, Y = np.meshgrid(x, y) plot_wkb.plot_wkb(poly, ax=ax, fc='none') ma.plot_edges(ax=ax, color='m', lw=2) ax.axis('equal') plt.pause(0.01) ##
if l1 > l2: l1, l2 = l2, l1 zs = xyz[l1:l2 + 1, 2] if closed: # allow for possibility that the levee is a closed ring # and this grid edge actually straddles the end, dist_fwd = dists[l2] - dists[l1] dist_rev = dists[-1] - dist_fwd if dist_rev < dist_fwd: print("wraparound") zs = np.concatenate([xyz[l2:, 2], xyz[:l1, 2]]) z = zs.min() levee_de[j] = z return levee_de ## if 0: zoom = (585813.9075730171, 586152.9743682485, 4146296.412810114, 4146567.6036336995) plt.figure(1).clf() ecoll = g.plot_edges(values=levee_de, mask=np.isfinite(levee_de), lw=2.5) plot_wkb.plot_wkb(poly, fc="0.8", zorder=-3) plt.axis('equal') plt.axis(zoom)
from stompy.plot import plot_wkb buffers = [geometry.Point(x).buffer(L, 8) for x in cutoff_xyz[:, :2]] total_poly = cascaded_union(buffers) assert total_poly.type == 'Polygon' total_poly = total_poly.simplify(Lres / 2.) ## plt.figure(3).clf() fig, ax = plt.subplots(1, 1, num=3) scat = ax.scatter(cutoff_xyz[:, 0], cutoff_xyz[:, 1], 20, cutoff_xyz[:, 2]) plot_wkb.plot_wkb(total_poly, zorder=-2) ax.axis('equal') ## from stompy.spatial import field from stompy.grid import paver six.moves.reload_module(paver) p = paver.Paving(geom=total_poly, density=field.ConstantField(Lres)) p.verbose = 1 p.pave_all() ## # But better to just use a subset of the existing grid.
seed_point = no_mans_land.representative_point() # [500870., 4170787.] seed_point = np.array(seed_point) # 5000 ought to be plenty of nodes to get around this loop nodes = g_merge.enclosing_nodestring(seed_point, 5000) ## xy_shore = g_merge.nodes['x'][nodes] if 1: plt.figure(2).clf() fig, ax = plt.subplots(num=2) g_merge.plot_edges(ax=ax, color='k', lw=0.8) plot_wkb.plot_wkb(no_mans_land, facecolor='r', alpha=0.3) ax.plot(xy_shore[:, 0], xy_shore[:, 1], 'r-') ## # Construct a scale based on existing spacing # But only do this for edges that are part of one of the original grids g_merge.edge_to_cells() # update edges['cells'] sample_xy = [] sample_scale = [] ec = g_merge.edges_center() for na, nb in utils.circular_pairs(nodes): j = g_merge.nodes_to_edge([na, nb]) if np.any(g_merge.edges['cells'][j] >= 0): sample_xy.append(ec[j])
grp_poly = ops.cascaded_union([model.grid.cell_polygon(i) for i in grp]) assert grp_poly.type == 'Polygon', "Hmm - add code to deal with multipolygons" polys.append(grp_poly) agg_shp_fn = "dwaq_aggregation.shp" wkb2shp.wkb2shp(agg_shp_fn, polys, overwrite=True) ## import matplotlib.pyplot as plt plt.figure(1).clf() ax = plt.gca() model.grid.plot_cells(values=permute[labels], ax=ax) ax.axis('equal') for poly in polys: plot_wkb.plot_wkb(poly, ax=ax, fc='none', lw=3) ## hyd_path = os.path.join(model.run_dir, "DFM_DELWAQ_%s" % model.mdu.name, "%s.hyd" % model.mdu.name) assert os.path.exists(hyd_path) ## from stompy.model.delft import waq_hydro_editor, waq_scenario six.moves.reload_module(waq_scenario) six.moves.reload_module(waq_hydro_editor) ##
tekno_clip=tekno[ (tekno.Epoch_Sec>=t_min) & (tekno.Epoch_Sec<=t_max) ] ## yaps_in=yaps3_clip.in_poly.sum() yaps_tot=len(yaps3_clip) print(f"{yaps_in}/{yaps_tot} ({100.0*yaps_in/yaps_tot:.2f}% 3+ rx yaps solutions are within the domain") print(f"{yaps_tot-yaps_in}/{yaps_tot} ({100.0*(1.0-yaps_in/yaps_tot):.2f}% 3+ rx yaps solutions are outside the domain") tek_in=tekno_clip.in_poly.sum() tek_tot=len(tekno_clip) print(f"{tek_in}/{tek_tot} ({100.0*tek_in/tek_tot:.2f}% Teknologic solutions are within the domain") print(f"{tek_tot-tek_in}/{tek_tot} ({100.0*(1.0-tek_in/tek_tot):.2f}% Teknologic solutions are outside the domain") ## plt.figure(1).clf() fig,ax=plt.subplots(num=1) sel=tekno_clip.in_poly ax.plot(tekno_clip.loc[sel,'X_UTM'],tekno_clip.loc[sel,'Y_UTM'],'k.') sel=~sel ax.plot(tekno_clip.loc[sel,'X_UTM'],tekno_clip.loc[sel,'Y_UTM'],'k+') sel=yaps3_clip.in_poly ax.plot(yaps3_clip.loc[sel,'x'],yaps3_clip.loc[sel,'y'],'r.') sel=~sel ax.plot(yaps3_clip.loc[sel,'x'],yaps3_clip.loc[sel,'y'],'r+') plot_wkb.plot_wkb(g_poly,ax=ax,zorder=-2,alpha=0.3) ax.axis('equal')
(levee_bounds[:, 3] >= dem_xxyy[2])) levee_clip = levees[sel] # 23k ## plt.figure(1).clf() fig, ax = plt.subplots(num=1) dem.downsample(4).plot(cmap='gray', vmin=-1, vmax=5, ax=ax, zorder=-2) ax.axis('off') from stompy.plot import plot_wkb for l in levee_clip['geom'][:1000]: plot_wkb.plot_wkb(l, ax=ax, color='m', lw=2, zorder=2) ax.axis('equal') ## # Would like to burn in the Z_Min from the levees to the DEM, but only # where higher than existing values. levee_burn_fn = "levee_burn.tif" if not os.path.exists(levee_burn_fn): levee_burn = dem.copy() levee_burn.F[:, :] = np.nan levee_burn.write_gdal(levee_burn_fn) cmd = (
img = dem_clip.plot(ax=ax, cmap=cm_topobathy) img.set_clim([-8, 4]) ac = aerial.crop(clip).plot(ax=ax, zorder=-2) grid_coll = grid.plot_edges(lw=0.5, color='k', alpha=0.3, ax=ax) cbar = plt.colorbar(img, cax=cax, label='Bathymetry (m NAVD88)', orientation='horizontal') cbar.set_ticks([-8, -5, -2, 1, 4]) plot_wkb.plot_wkb(grid_poly, edgecolor='k', lw=1., zorder=3, ax=ax, facecolor='none') ax.plot(rx_locs['yap_x'], rx_locs['yap_y'], 'yo', label='Hydrophone', mew=1, mec='k') ax.axis(zoom) leg_ax.legend(loc='upper left', frameon=False, bbox_to_anchor=[0, 0.95], handles=ax.lines)
def add_mouth_as_bathy(self, crest=0.5, width=50.0, plot=True): """ Update bed elevation in the grid to reflect the QCM geometry at a specific time (run_start). Uses the 'mouth_centerline' feature in the shapefile inputs to define the centerline and which nodes will be updated. Bed is static, though. """ center = self.match_gazetteer(name='mouth_centerline')[0]['geom'] node_sel, node_long, node_lat = self.centerline_to_node_coordinates( center) # Make a copy of original depth data and update self.grid.add_node_field('node_z_bed_orig', self.grid.nodes['node_z_bed'], on_exists='pass') def channel(n, c_long, c_lat): # from mouth_as_structure: # Trapezoid, but the flat part is the full width from the QCM lat_slope = 1.0 / 10 # outside the width rise with 1:10 slope lat_shape = (c_lat - width / 2).clip(0) * lat_slope # And a trapezoidal longitudinal shape, flat in the middle. # sloping down up/downstream. rise = 1.0 run = (c_long.max() - c_long.min()) / 2 lon_mid = np.median(c_long) # or the lon coord nearest the middle lon_slope = rise / run lon_flat = 10.0 # half-width of flat length along channel print("Longitudinal slope is %.3f (%.2f:%.2f)" % (lon_slope, rise, run)) # additional ad hoc adjustment to qcm_z_thalweg of -0.10, and # slope down away from the middle-ish point. lon_shape = -lon_slope * (abs(c_long - lon_mid) - lon_flat).clip(0) z_node = crest + lon_shape + lat_shape z_orig = self.grid.nodes['node_z_bed_orig'][n] return np.maximum(z_orig, z_node) self.grid.nodes['node_z_bed'][node_sel] = channel( node_sel, node_long, node_lat) if plot: fig = plt.figure(1) fig.clf() self.grid.plot_edges(color='k', lw=0.4) self.grid.plot_nodes(mask=node_sel) plot_wkb.plot_wkb(center, color='orange') #plt.scatter(pnts[:,0],pnts[:,1],30,node_lat,cmap=turbo) self.grid.contourf_node_values(self.grid.nodes['node_z_bed'], np.linspace(0, 2.5, 30), cmap=turbo) plt.axis('tight') plt.axis('equal') plt.axis('off') plt.axis((552070., 552178., 4124574., 4124708.))
cf=CompositeField(shp_fn='sources_v03.shp', factory=factory, priority_field='priority', data_mode='data_mode', alpha_mode='alpha_mode') bounds=[590000,591000,4142000,4143000] dem=cf.to_grid(dx=2,dy=2,bounds=bounds) ## plt.figure(1).clf() fig,ax=plt.subplots(num=1) img=dem.plot(ax=ax,interpolation='nearest',vmin=-5,vmax=4) plot_utils.cbar(img,ax=ax) for src_i in range(len(cf.sources)): if cf.sources['priority'][src_i]<0: continue plot_wkb.plot_wkb( cf.sources['geom'][src_i], ax=ax, fc='none',ec='k',lw=0.5) ## # looking pretty good, about ready to scale it up... # The test tile took 10.8s, with all the time in mask_outside. # So far so good - last thing is to bring in the holey USGS 2m, so it can sit # on top of the pond bathy.
plt.figure(1).clf() fig,ax=plt.subplots(num=1) blend.plot(interpolation='nearest',ax=ax,vmin=-10,vmax=5) blend.plot_hillshade(ax=ax) ## # this does require that someone drew the bounding polygons to basically # follow the areas with actual data. ## from stompy.plot import plot_wkb plt.figure(2).clf() fig,ax=plt.subplots(num=2) # it's not taking... for g in mbf.bfs[0].ic.shp_data['geom']: plot_wkb.plot_wkb(g,ax=ax,alpha=0.3) ax.axis('equal') ## merged_old=field.GdalGrid('tiles_5m_20170501/merged_5m.tif')
ac = aerial.crop(clip).plot(ax=ax, zorder=-2) grid_coll = grid.plot_edges(lw=0.5, color='k', alpha=0.3, ax=ax) cbar = plt.colorbar(img, cax=cax, label='Bathymetry (m NAVD88)', orientation='horizontal') cbar.set_ticks([-8, -5, -2, 1, 4]) plt.setp(cax.get_xticklabels(), fontsize=9) plt.setp(cax.xaxis.label, fontsize=9) plot_wkb.plot_wkb(grid_poly, edgecolor='k', lw=1., zorder=3, ax=ax, facecolor='none') ax.plot(rx_locs['yap_x'], rx_locs['yap_y'], 'yo', label='Hydrophone', mew=1, mec='k') ax.axis(zoom) leg_ax.legend(loc='upper left', frameon=False, bbox_to_anchor=[0, 0.90], fontsize=9,
def summary_figure(self, num=3): fig = plt.figure(num) fig.clf() ax_map = fig.add_subplot(1, 2, 1) ax_V = fig.add_subplot(1, 2, 2) xyxy = self.region_poly.bounds clip = [xyxy[0], xyxy[2], xyxy[1], xyxy[3]] hyp = self.hyp # hyp.g.plot_edges(clip=clip,ax=ax_map,color='k',lw=0.4,alpha=0.4) plot_wkb.plot_wkb(hyp.g_poly, fc='0.8', ec='none', ax=ax_map, zorder=-4) hyp.g.plot_cells(mask=self.region_cells, ax=ax_map, color='orange') # Show the location of the reference station ax_map.plot([ self.hyp.his.station_x_coordinate.isel( stations=self.region_station) ], [ self.hyp.his.station_y_coordinate.isel( stations=self.region_station) ], 'go') # bound_xs=self.bounding_cross_sections() xys = [] uvs = [] for k in self.bound_xs.keys(): sgn = self.bound_xs[k] sec_x = self.hyp.his.cross_section_x_coordinate.isel( cross_section=k).values sec_y = self.hyp.his.cross_section_y_coordinate.isel( cross_section=k).values sec_xy = np.c_[sec_x, sec_y] sec_xy = sec_xy[sec_xy[:, 0] < 1e10] ax_map.plot(sec_xy[:, 0], sec_xy[:, 1], 'r-') uvs.append(sgn * (sec_xy[-1] - sec_xy[0])) xys.append(sec_xy.mean(axis=0)) xys = np.array(xys) uvs = np.array(uvs) uvs = utils.rot(-np.pi / 2, utils.to_unit(uvs)) ax_map.quiver(xys[:, 0], xys[:, 1], uvs[:, 0], uvs[:, 1]) ax_map.axis('equal') order = np.argsort(self.eta) ax_V.plot(self.eta[order], self.vol_and_Q[order], label="model") ax_V.plot(self.dem_etas, self.dem_volumes, label='DEM', color='k', lw=0.6) # and what we expect from the model, assuming nonlin2d=0 cell_etas, cell_vols = self.calculate_cell_volumes() ax_V.plot(cell_etas, cell_vols, label='Cell depth', color='r', lw=0.6) ax_V.set_ylabel('Vol') ax_V.set_xlabel('eta') ax_V.legend() return fig
] ] g = grids[0].copy() for other in grids[1:]: g.add_grid(other) # fig = plt.figure(1) fig.clf() fig, axs = plt.subplots(2, 1, sharex=True, sharey=True, num=1) ax = axs[0] for centerline in centerlines['geom']: plot_wkb.plot_wkb(centerline, color='r', ax=ax) for bound in bounds['geom']: plot_wkb.plot_wkb(bound, color='0.8', zorder=-2, ax=ax) g.plot_edges(color='k', ax=ax) ax.axis('equal') ## from stompy.grid import orthogonalize tweaker = orthogonalize.Tweaker(g) n_iters = 20 angle_thresh_deg = 1.0 angles = g.angle_errors()
edge_mask = self.g.edges['sign'] != 0 plt.figure(1).clf() fig, ax = plt.subplots(num=1) self.g.plot_cells(color='0.7', lw=0.5, mask=self.visited < 0, ax=ax) ccoll = self.g.plot_cells(values=self.visited, lw=0.5, mask=self.visited >= 0, ax=ax, alpha=0.3) ccoll.set_edgecolors('k') ccoll.set_cmap('jet') [plot_wkb.plot_wkb(geo, color='k', ax=ax) for geo in self.flow_lines['geom']] fluxes = self.fluxes areas = self.fluxareas(t=0).clip(1, np.inf) self.g.plot_edges(labeler=lambda j, r: "%.1f (%.2fm/s)" % (self.g.edges[ 'sign'][j] * fluxes[j], self.g.edges['sign'][j] * fluxes[j] / areas[j]), mask=edge_mask, ax=ax) p_xy = np.zeros((len(self.particles), 2), np.float64) for p_i, loc in enumerate(self.particles): p_xy[p_i, :] = router.bary_to_xy(loc) ax.plot(p_xy[:, 0], p_xy[:, 1], 'bo')