def plot_tri_res(fname=None, work_dir=None, inv_data=None, plt_opts={}, nheader=0, mesh_dict=None, inv_col=3, keep_log=False, xylims=[None, None, None, None]): '''Plot inversion results on triangular mesh.''' if inv_data is None: # load data if fname is None and work_dir is not None: inv_data = load_inv_output(work_dir=work_dir, nheader=nheader) elif os.path.dirname(fname) in ['']: inv_data = load_inv_output(fname=os.path.join(work_dir, fname), nheader=nheader) else: inv_data = load_inv_output(fname=fname, nheader=nheader) print(inv_data.shape) tri_dict = { 'mesh_dict': mesh_dict, 'inv_data': inv_data, 'inv_col': inv_col, 'plt_dict': plt_opts, 'keep_log': keep_log } fig, ax, tri_obj = plot_tri_mesh(**tri_dict) if xylims[0] is not None: ax.set_xlim(xylims[:2]) ax.set_ylim(xylims[2:]) return fig, ax
def plot_outnodes(fname=None,work_dir=None,fwd_transfer_bool=False): '''Plot model nodes.''' if fwd_transfer_bool==True: nheader=1 else: nheader=0 if fname is None and work_dir is not None: inv_data = load_inv_output(work_dir=work_dir,nheader=nheader) elif os.path.dirname(fname) in ['']: inv_data = load_inv_output(fname=os.path.join(work_dir,fname),nheader=nheader) else: inv_data = load_inv_output(fname=fname,nheader=nheader) fig,ax = plt.subplots() # ax.plot(inv_data[:,0],inv_data[:,1],'.') ax.scatter(inv_data[:,0],inv_data[:,1],c=inv_data[:,3],edgecolor='none') ax.set_xlabel('Distance') ax.set_ylabel('Depth or Elevation')
def plot_final_res(fname=None, work_dir=None, region_xyz=None, topo_xyz=None, method='constant', nxny=[1e2, 1e2], inv_col=3, plt_opts={}, miny=None, plt_opts2={}, region_plot=False, plot_buffer=1., cmap=plt.cm.inferno_r, save_dict=None, fwd_transfer_bool=False, invert_y=False): if fwd_transfer_bool == True: nheader = 1 else: nheader = 0 if isinstance(cmap, str): cmap = plt.get_cmap(cmap) if fname is None and work_dir is not None: inv_data = load_inv_output(work_dir=work_dir, nheader=nheader) elif os.path.dirname(fname) in ['']: inv_data = load_inv_output(fname=os.path.join(work_dir, fname), nheader=nheader) else: inv_data = load_inv_output(fname=fname, nheader=nheader) # Make regular grid for plotting surface x = np.linspace(np.min(inv_data[:, 0]), np.max(inv_data[:, 0]), nxny[0]) if miny is None: miny = np.min(inv_data[:, 1]) y = np.linspace(0., miny, nxny[1]) X, Y = np.meshgrid(x, y) if 'vmin' in plt_opts.keys(): vmin = 10.**plt_opts['vmin'] _ = plt_opts.pop('vmin', None) else: vmin = 10. if 'vmax' in plt_opts.keys(): vmax = 10.**plt_opts['vmax'] _ = plt_opts.pop('vmax', None) else: vmax = 1e3 if 'cmap' not in plt_opts.keys(): plt_opts['cmap'] = cmap formatter = LogFormatter(10, labelOnlyBase=False) ticks = log_steps([vmin, vmax]) if region_xyz is not None and topo_xyz is not None and region_plot: # Use region data to separate plotting zones # 1) Find elevation of divider (originally depth) div_y = extrap(region_xyz[:, 0], topo_xyz[:, 0], topo_xyz[:, 2], method) + region_xyz[:, 1] # 2) Find y locations above region divider div_y_all = extrap(X, region_xyz[:, 0], div_y, method) # 3) Find y shift for topography yshift = extrap(X, topo_xyz[:, 0], topo_xyz[:, 2], method) Y = Y + yshift lower_mask = (Y > div_y_all) | ((X > region_xyz[:, 0].max()) | (X < region_xyz[:, 0].min())) upper_mask = (Y < div_y_all) | ((X > region_xyz[:, 0].max()) | (X < region_xyz[:, 0].min())) all_ER = griddata(inv_data[:, :2], inv_data[:, inv_col], (X, Y), method='linear') if inv_col == 3: # Log transform already applied, change to untransformed all_ER = 10.**(all_ER) upper_ER = np.ma.masked_array(all_ER, mask=upper_mask) fig, ax = plt.subplots() s1 = ax.pcolormesh(X, Y, upper_ER, norm=LogNorm(vmin, vmax), **plt_opts) # ax.plot(X,Y,'g.') ax.plot(topo_xyz[:, 0], topo_xyz[:, 2], 'k-') ax.plot(region_xyz[:, 0], div_y, '-o', color='lightgrey') ax.set_xlim([ region_xyz[:, 0].min() - plot_buffer, region_xyz[:, 0].max() + plot_buffer ]) ax.set_ylim([miny - plot_buffer, np.max(Y) + plot_buffer]) plt.colorbar(s1, ax=ax, ticks=ticks, extend='both', format=formatter) ax2 = ax.twinx() lower_ER = np.ma.masked_array(all_ER, mask=lower_mask) s2 = ax.pcolormesh(X, Y, lower_ER, norm=LogNorm(vmin, vmax), **plt_opts2) ax2.set_xlim([ region_xyz[:, 0].min() - plot_buffer, region_xyz[:, 0].max() + plot_buffer ]) ax2.set_ylim([miny - plot_buffer, np.max(Y) + plot_buffer]) plt.colorbar(s2, ax=ax2, ticks=ticks, extend='both', format=formatter) elif topo_xyz is not None and region_xyz is not None: # 1) Find elevation of divider (originally depth) div_y = extrap(region_xyz[:, 0], topo_xyz[:, 0], topo_xyz[:, 2], method) + region_xyz[:, 1] # Find y shift for topography yshift = extrap(X, topo_xyz[:, 0], topo_xyz[:, 2], method) Y = Y + yshift upper_mask = (X > topo_xyz[:, 0].max()) | (X < topo_xyz[:, 0].min()) all_ER = griddata(inv_data[:, :2], inv_data[:, inv_col], (X, Y), method='linear') if inv_col == 3: # Log transform already applied, change to untransformed all_ER = 10.**(all_ER) upper_ER = np.ma.masked_array(all_ER, mask=upper_mask) fig, ax = plt.subplots() s1 = ax.pcolormesh(X, Y, upper_ER, norm=LogNorm(vmin, vmax), **plt_opts) # ax.plot(X,Y,'g.') ax.plot(topo_xyz[:, 0], topo_xyz[:, 2], 'k-') ax.plot(region_xyz[:, 0], div_y, '-o', color='lightgrey') ax.set_xlim([ topo_xyz[:, 0].min() - plot_buffer, topo_xyz[:, 0].max() + plot_buffer ]) ax.set_ylim([miny - plot_buffer, np.max(Y) + plot_buffer]) plt.colorbar(s1, ax=ax, ticks=ticks, extend='both', format=formatter) else: if topo_xyz is None: # Copy inv data output y coordinates topo_xyz = np.zeros_like(inv_data) topo_xyz[:, :2] = inv_data[:, :2] # Find y shift for topography yshift = extrap(X, topo_xyz[:, 0], topo_xyz[:, 2], method) Y = Y + yshift all_ER = griddata(inv_data[:, :2], inv_data[:, inv_col], (X, Y), method='linear') if inv_col == 3: # Log transform already applied, change to untransformed all_ER = 10.**(all_ER) upper_ER = np.ma.masked_invalid(all_ER) fig, ax = plt.subplots() s1 = ax.pcolormesh(X, Y, upper_ER, norm=LogNorm(vmin, vmax), **plt_opts) # ax.plot(X,Y,'g.') ax.plot(topo_xyz[:, 0], topo_xyz[:, 2], 'k-') ax.set_xlim([ topo_xyz[:, 0].min() - plot_buffer, topo_xyz[:, 0].max() + plot_buffer ]) ax.set_ylim([miny - plot_buffer, np.max(Y) + plot_buffer]) plt.colorbar(s1, ax=ax, ticks=ticks, extend='both', format=formatter) if invert_y: ax.set_ylim(ax.get_ylim()[::-1]) # put back in dictionary plt_opts['vmin'] = np.log10(vmin) plt_opts['vmax'] = np.log10(vmax) if save_dict is not None: fig.savefig(save_dict['fig_fname'], **save_dict['fig_opts']) plt.close('all') else: return fig, ax
def plot_res(fname=None, work_dir=None, topog_xy=None, region_xyz=None, method='force_grid', nxny=[1e2, 1e2], inv_col=3, plt_opts={}, miny=None, maxy=0, plot_buffer=1., cmap=plt.cm.inferno_r, save_dict=None, fwd_transfer_bool=False, invert_y=False, interp='bicubic', aspect=1, keep_log=False, nticks=8): '''Simple inverse output plot. interp: str str defining interpolation method for imshow options: https://matplotlib.org/examples/images_contours_and_fields/interpolation_methods.html ''' if fwd_transfer_bool == True: nheader = 1 else: nheader = 0 if isinstance(cmap, str): cmap = plt.get_cmap(cmap) if 'cmap' not in plt_opts.keys(): plt_opts['cmap'] = cmap if 'aspect' not in plt_opts.keys() and topog_xy is None: plt_opts['aspect'] = aspect if fname is None and work_dir is not None: inv_data = load_inv_output(work_dir=work_dir, nheader=nheader) elif os.path.dirname(fname) in ['']: inv_data = load_inv_output(fname=os.path.join(work_dir, fname), nheader=nheader) else: inv_data = load_inv_output(fname=fname, nheader=nheader) if 'vmin' not in plt_opts.keys(): plt_opts['vmin'] = np.min(inv_data[:, inv_col]) if 'vmax' not in plt_opts.keys(): plt_opts['vmax'] = np.max(inv_data[:, inv_col]) # Make regular grid for plotting surface grid_dict = { 'inv_data': inv_data, 'nxny': nxny, 'maxy': maxy, 'miny': miny, 'interp_method': method, 'inv_col': inv_col } X, Y, all_ER = grid_inv_data(**grid_dict) minx, maxx = np.nanmin(X), np.nanmax(X) if topog_xy is not None: ydif = extrap(X[0, :], topog_xy[:, 0], topog_xy[:, 1]) - Y[0, :] else: ydif = 0 if 'ticks' in list(plt_opts.keys()): ticks = plt_opts['ticks'] _ = plt_opts.pop('ticks') elif inv_col == 3 and not keep_log: # Log transform already applied, change to untransformed ticks = log_steps([plt_opts['vmin'], plt_opts['vmax']]) elif inv_col == 3 and keep_log: plt_opts['vmin'] = np.log10(plt_opts['vmin']) plt_opts['vmax'] = np.log10(plt_opts['vmax']) ticks = np.linspace(plt_opts['vmin'], plt_opts['vmax'], nticks) else: ticks = np.linspace(plt_opts['vmin'], plt_opts['vmax'], nticks) if not keep_log: all_ER = 10.**(all_ER) upper_ER = np.ma.masked_invalid(all_ER) if miny is None: miny = np.nanmin(Y) fig, ax = plt.subplots() if topog_xy is not None: Y = Y + ydif miny = np.nanmin(Y) maxy = np.nanmax(Y) im = ax.pcolormesh(X, Y, upper_ER, **plt_opts) else: im = ax.imshow(upper_ER, interpolation=interp, extent=(minx, maxx, miny, maxy), **plt_opts) ax.set_ylabel('Elevation') ax.set_xlabel('Distance') ax.set_xlim(minx, maxx) ax.set_ylim(miny, maxy) if 'aspect' in plt_opts.keys(): ax.set_title('Aspect = {}:1'.format(plt_opts['aspect'])) plt.colorbar(im, ax=ax, ticks=ticks, extend='both', shrink=0.5) if invert_y: ax.set_ylim(ax.get_ylim()[::-1]) ax.set_ylabel('Depth') if save_dict is not None: fig.savefig(save_dict['fig_fname'], **save_dict['fig_opts']) plt.close('all') else: return fig, ax, [X, Y, upper_ER]
catch_warnings=[itemp.strip() for itemp in output if 'WARNING' in itemp] if len(catch_warnings)>0: iwarn = catch_warnings[-1] else: iwarn = None icatch_warnings.append(iwarn) rms1 = [float(i.split()[-1]) for i in output if 'Final RMS' in i][-1] convg_status = 1 if iwarn is not None: if 'not converged' in iwarn: convg_status = -1 # Post process runs inv_data = pyres_utils.load_inv_output(work_dir=inv_work_dir) X,Y,ER = pyres_utils.grid_inv_data(inv_data,inv_col=2) # use non-log-transformed data obs_array = main_res*np.ones_like(ER) topo_y = pyres_utils.extrap(txy[:,0],xx_mesh,topog) target_bool = (X>=txy[0,0]) & (X<=txy[1,0]) &\ (Y<=(topo_y[0]-txy[0,1])) & (Y>=(topo_y[2]-txy[2,1])) obs_array[target_bool] = target_res err_array = errfunc(obs_array,ER) target_err = err_array[target_bool] # Integrate error over target weighted by areas # Use area weighting of errors, only for quad meshes x2,y2 = np.meshgrid(xx_mesh,yy_mesh) xdiff = np.hstack([np.diff(x2,axis=1),np.zeros((x2.shape[0],1))])