def draw_figures(self, problem, dataset, history): event = problem.base_source targets = problem.gnss_targets for target in targets: target.set_dataset(dataset) comp_weights = target.component_weights()[0] ws_n = comp_weights[:, 0::3] / comp_weights.max() ws_e = comp_weights[:, 1::3] / comp_weights.max() ws_u = comp_weights[:, 2::3] / comp_weights.max() ws_e = num.array(ws_e[0]).flatten() ws_n = num.array(ws_n[0]).flatten() ws_u = num.array(ws_u[0]).flatten() if ws_n.size == 0: continue distances = target.distance_to(event) azimuths = od.azibazi_numpy( num.array(event.effective_lat)[num.newaxis], num.array(event.effective_lon)[num.newaxis], target.get_latlon()[:, 0], target.get_latlon()[:, 1])[0] labels = target.station_names item = PlotItem(name='station_distribution-N-%s' % target.path) fig, ax, legend = self.plot_station_distribution( azimuths, distances, ws_n, labels, legend_title='Weight, N components') yield (item, fig) item = PlotItem(name='station_distribution-E-%s' % target.path) fig, ax, legend = self.plot_station_distribution( azimuths, distances, ws_e, labels, legend_title='Weight, E components') yield (item, fig) item = PlotItem(name='station_distribution-U-%s' % target.path) fig, ax, legend = self.plot_station_distribution( azimuths, distances, ws_u, labels, legend_title='Weight, U components') yield (item, fig)
def draw_figures(self, sources, targets, results_list): results_list = list(zip(*results_list)) for itarget, target, results in zip( range(len(targets)), targets, results_list): if isinstance(target, WaveformMisfitTarget) and results: item = PlotItem(name='t%i' % itarget) item.attributes['targets'] = [target.string_id()] fig = self.draw_figure(sources, target, results) if fig is not None: yield item, fig
def draw_figures(self, history): problem = history.problem by_cluster = history.imodels_by_cluster( self.cluster_attribute) for icluster, percentage, imodels in by_cluster: misfits = history.misfits[imodels] models = history.models[imodels] mts = [] for ix, x in enumerate(models): source = problem.get_source(x) mts.append(source.pyrocko_moment_tensor()) best_mt = stats.get_best_source( problem, models, misfits).pyrocko_moment_tensor() fig = plt.figure(figsize=self.size_inch) fig.subplots_adjust(left=0., right=1., bottom=0., top=1.) axes = fig.add_subplot(1, 1, 1, aspect=1.0) if self.cluster_attribute is not None: color = cluster_color(icluster) else: color = 'black' beachball.plot_fuzzy_beachball_mpl_pixmap( mts, axes, best_mt, beachball_type='full', size=8.*math.sqrt(percentage/100.), position=(5., 5.), color_t=color, edgecolor='black', best_color=mpl_color('scarletred2')) if self.cluster_attribute is not None: axes.annotate( cluster_label(icluster, percentage), xy=(5., 0.), xycoords='data', xytext=(0., self.font_size/2.), textcoords='offset points', ha='center', va='bottom', color='black', fontsize=self.font_size) axes.set_xlim(0., 10.) axes.set_ylim(0., 10.) axes.set_axis_off() item = PlotItem( name=( 'cluster_%i' % icluster if icluster >= 0 else 'unclustered')) yield [item, fig]
def draw_figures(self, history, optimiser): fig = plt.figure() imodels = num.arange(history.nmodels) gms = history.bootstrap_misfits[:, 0] gms_softclip = num.where(gms > 1.0, 0.1 * num.log10(gms) + 1.0, gms) axes = fig.add_subplot(1, 1, 1) ibests = [] for ibootstrap in range(history.nchains): # if ibootstrap ==0: # global, no-bootstrapping misfits, chain # gms = history.bootstrap_misfits[:, ibootstrap] # gms_softclip = num.where(gms > 1.0, # 0.1 * num.log10(gms) + 1.0, # gms) bms = history.bootstrap_misfits[:, ibootstrap] isort_bms = num.argsort(bms)[::-1] ibests.append(isort_bms[-1]) bms_softclip = num.where(bms > 1.0, 0.1 * num.log10(bms) + 1.0, bms) axes.plot(imodels, bms_softclip[isort_bms], color='red', alpha=0.2) isort = num.argsort(gms)[::-1] iorder = num.empty(isort.size) iorder[isort] = imodels axes.plot(iorder[ibests], gms_softclip[ibests], 'x', color='black') m = num.median(gms_softclip[ibests]) s = num.std(gms_softclip[ibests]) axes.axhline(m + s, color='black', alpha=0.5) axes.axhline(m, color='black') axes.axhline(m - s, color='black', alpha=0.5) axes.plot(imodels, gms_softclip[isort], color='black') axes.set_xlim(imodels[0], imodels[-1]) axes.set_xlabel( 'Tested model, sorted descending by global misfit value') return [(PlotItem(name='main'), fig)]
def draw_figures(self, history): problem = history.problem fig = plt.figure(figsize=self.size_inch) axes = fig.gca() gms = problem.combine_misfits(history.misfits) isort = num.argsort(gms)[::-1] gms = gms[isort] models = history.models[isort, :] kwargs = { 'beachball_type': 'full', 'size': 8, 'position': (5, 5), 'color_t': 'black', 'edgecolor': 'black' } mts = [] for ix, x in enumerate(models): if random.random() < 0.1: source = problem.get_source(x) mts.append(source.pyrocko_moment_tensor()) best_mt = mts[-1] beachball.plot_fuzzy_beachball_mpl_pixmap(mts, axes, best_mt, **kwargs) axes.set_xlim(0., 10.) axes.set_ylim(0., 10.) axes.set_axis_off() item = PlotItem( name='main', title='Fuzzy Moment Tensor', description='The opaqueness illustrates the propability' ' of all combined moment tensor solution.' 'The red lines indicate the global best solution.') return [[item, fig]]
def draw_figures(self, problem, dataset, history): event = problem.base_source targets = problem.gnss_targets for target in targets: target.set_dataset(dataset) ws = target.station_weights / target.station_weights.max() distances = target.distance_to(event) azimuths = od.azibazi_numpy( num.array(event.effective_lat)[num.newaxis], num.array(event.effective_lon)[num.newaxis], target.get_latlon()[:, 0], target.get_latlon()[:, 1])[0] labels = target.station_names item = PlotItem(name='station_distribution-%s' % target.path) fig, ax, legend = self.plot_station_distribution( azimuths, distances, ws, labels) legend.set_title('Weight') yield (item, fig)
def draw_figures(self, history): fontsize = self.font_size fig = plt.figure(figsize=self.size_inch) axes = fig.add_subplot(1, 1, 1, aspect=1.0) fig.subplots_adjust(left=0., right=1., bottom=0., top=1.) problem = history.problem models = history.models if models.size == 0: logger.warn('Empty models vector.') return [] # gms = problem.combine_misfits(history.misfits) # isort = num.argsort(gms) # iorder = num.empty_like(isort) # iorder[isort] = num.arange(iorder.size)[::-1] ref_source = problem.base_source mean_source = stats.get_mean_source( problem, history.models) best_source = history.get_best_source() nlines_max = int(round(self.size_cm[1] / 5. * 4. - 1.0)) if self.cluster_attribute: cluster_sources = history.mean_sources_by_cluster( self.cluster_attribute) else: cluster_sources = [] def get_deco(source): mt = source.pyrocko_moment_tensor() return mt.standard_decomposition() lines = [] lines.append( ('Ensemble best', get_deco(best_source), mpl_color('aluminium5'))) lines.append( ('Ensemble mean', get_deco(mean_source), mpl_color('aluminium5'))) for (icluster, perc, source) in cluster_sources: if len(lines) < nlines_max - int(self.show_reference): lines.append( (cluster_label(icluster, perc), get_deco(source), cluster_color(icluster))) else: logger.warn( 'Skipping display of cluster %i because figure height is ' 'too small. Figure height should be at least %g cm.' % ( icluster, (3 + len(cluster_sources) + int(self.show_reference)) * 5/4.)) if self.show_reference: lines.append( ('Reference', get_deco(ref_source), mpl_color('aluminium3'))) moment_full_max = max(deco[-1][0] for (_, deco, _) in lines) for xpos, label in [ (0., 'Full'), (2., 'Isotropic'), (4., 'Deviatoric'), (6., 'CLVD'), (8., 'DC')]: axes.annotate( label, xy=(1 + xpos, nlines_max), xycoords='data', xytext=(0., 0.), textcoords='offset points', ha='center', va='center', color='black', fontsize=fontsize) for i, (label, deco, color_t) in enumerate(lines): ypos = nlines_max - i - 1.0 [(moment_iso, ratio_iso, m_iso), (moment_dc, ratio_dc, m_dc), (moment_clvd, ratio_clvd, m_clvd), (moment_devi, ratio_devi, m_devi), (moment_full, ratio_full, m_full)] = deco size0 = moment_full / moment_full_max axes.annotate( label, xy=(-2., ypos), xycoords='data', xytext=(0., 0.), textcoords='offset points', ha='left', va='center', color='black', fontsize=fontsize) for xpos, mt_part, ratio, ops in [ (0., m_full, ratio_full, '-'), (2., m_iso, ratio_iso, '='), (4., m_devi, ratio_devi, '='), (6., m_clvd, ratio_clvd, '+'), (8., m_dc, ratio_dc, None)]: if ratio > 1e-4: try: beachball.plot_beachball_mpl( mt_part, axes, beachball_type='full', position=(1. + xpos, ypos), size=0.9 * size0 * math.sqrt(ratio), size_units='data', color_t=color_t, linewidth=1.0) except beachball.BeachballError as e: logger.warn(str(e)) axes.annotate( 'ERROR', xy=(1. + xpos, ypos), ha='center', va='center', color='red', fontsize=fontsize) else: axes.annotate( 'N/A', xy=(1. + xpos, ypos), ha='center', va='center', color='black', fontsize=fontsize) if ops is not None: axes.annotate( ops, xy=(2. + xpos, ypos), ha='center', va='center', color='black', fontsize=fontsize) axes.axison = False axes.set_xlim(-2.25, 9.75) axes.set_ylim(-0.5, nlines_max+0.5) item = PlotItem(name='main') return [[item, fig]]
def draw_figures(self, history): import scipy.stats from grond.core import make_stats exclude = self.exclude include = self.include figsize = self.size_inch fontsize = self.font_size method = self.method ref_color = mpl_color('aluminium6') stats_color = mpl_color('scarletred2') bar_color = mpl_color('scarletred1') stats_color3 = mpl_color('scarletred3') problem = history.problem models = history.models bounds = problem.get_combined_bounds() exclude = list(exclude) for ipar in range(problem.ncombined): par = problem.combined[ipar] vmin, vmax = bounds[ipar] if vmin == vmax: exclude.append(par.name) xref = problem.get_reference_model() smap = {} iselected = 0 for ipar in range(problem.ncombined): par = problem.combined[ipar] if exclude and par.name in exclude or \ include and par.name not in include: continue smap[iselected] = ipar iselected += 1 nselected = iselected del iselected pnames = [ problem.combined[smap[iselected]].name for iselected in range(nselected)] rstats = make_stats(problem, models, history.get_primary_chain_misfits(), pnames=pnames) for iselected in range(nselected): ipar = smap[iselected] par = problem.combined[ipar] vs = problem.extract(models, ipar) vmin, vmax = bounds[ipar] fig = plt.figure(figsize=figsize) labelpos = mpl_margins( fig, nw=1, nh=1, w=7., bottom=5., top=1, units=fontsize) axes = fig.add_subplot(1, 1, 1) labelpos(axes, 2.5, 2.0) axes.set_xlabel(par.get_label()) axes.set_ylabel('PDF') axes.set_xlim(*fixlim(*par.scaled((vmin, vmax)))) if method == 'gaussian_kde': try: kde = scipy.stats.gaussian_kde(vs) except Exception: logger.warn( 'Cannot create plot histogram with gaussian_kde: ' 'possibly all samples have the same value.') continue vps = num.linspace(vmin, vmax, 600) pps = kde(vps) axes.plot( par.scaled(vps), par.inv_scaled(pps), color=stats_color) elif method == 'histogram': pps, edges = num.histogram( vs, bins=num.linspace(vmin, vmax, num=40), density=True) vps = 0.5 * (edges[:-1] + edges[1:]) axes.bar(par.scaled(vps), par.inv_scaled(pps), par.scaled(2.*(vps - edges[:-1])), color=bar_color) pstats = rstats.parameter_stats_list[iselected] axes.axvspan( par.scaled(pstats.minimum), par.scaled(pstats.maximum), color=stats_color, alpha=0.1) axes.axvspan( par.scaled(pstats.percentile16), par.scaled(pstats.percentile84), color=stats_color, alpha=0.1) axes.axvspan( par.scaled(pstats.percentile5), par.scaled(pstats.percentile95), color=stats_color, alpha=0.1) axes.axvline( par.scaled(pstats.median), color=stats_color3, alpha=0.5) axes.axvline( par.scaled(pstats.mean), color=stats_color3, ls=':', alpha=0.5) if self.show_reference: axes.axvline( par.scaled(problem.extract(xref, ipar)), color=ref_color) item = PlotItem(name=par.name) item.attributes['parameters'] = [par.name] yield item, fig
def draw_figures(self, environ): nwindow = 200 show_raw_acceptance_rates = False optimiser = environ.get_optimiser() problem = environ.get_problem() history = environ.get_history() chains = optimiser.chains(problem, history) chains.load() acceptance = chains.acceptance_history nmodels_rate = history.nmodels - (nwindow - 1) if nmodels_rate < 1: logger.warning( 'Cannot create plot acceptance: insufficient number of tested ' 'models.') return acceptance_rate = num.zeros((history.nchains, nmodels_rate)) for ichain in range(history.nchains): acceptance_rate[ichain, :] = trace.moving_sum( acceptance[ichain, :], nwindow, mode='valid') / float(nwindow) acceptance_n = num.sum(acceptance, axis=0) acceptance_any = num.minimum(acceptance_n, 1) acceptance_any_rate = trace.moving_sum( acceptance_any, nwindow, mode='valid') / float(nwindow) acceptance_p = acceptance_n / float(history.nchains) popularity = trace.moving_sum( acceptance_p, nwindow, mode='valid') \ / float(nwindow) / acceptance_any_rate mpl_init(fontsize=self.font_size) fig = plt.figure(figsize=self.size_inch) labelpos = mpl_margins(fig, w=7., h=5., units=self.font_size) axes = fig.add_subplot(1, 1, 1) labelpos(axes, 2.5, 2.0) imodels = num.arange(history.nmodels) imodels_rate = imodels[nwindow - 1:] axes.plot(acceptance_n / history.nchains * 100., '.', ms=2.0, color=mpl_color('skyblue2'), label='Popularity of Accepted Models', alpha=0.3) if show_raw_acceptance_rates: for ichain in range(chains.nchains): axes.plot(imodels_rate, acceptance_rate[ichain, :] * 100., color=mpl_color('scarletred2'), alpha=0.2) axes.plot(imodels_rate, popularity * 100., color=mpl_color('skyblue2'), label='Popularity (moving average)') axes.plot(imodels_rate, acceptance_any_rate * 100., color='black', label='Acceptance Rate (any chain)') axes.legend() axes.set_xlabel('Iteration') axes.set_ylabel('Acceptance Rate, Model Popularity') axes.set_ylim(0., 100.) axes.set_xlim(0., history.nmodels - 1) axes.grid(alpha=.2) axes.yaxis.set_major_formatter(FuncFormatter(lambda v, p: '%d%%' % v)) iiter = 0 bgcolors = [mpl_color('aluminium1'), mpl_color('aluminium2')] for iphase, phase in enumerate(optimiser.sampler_phases): axes.axvspan(iiter, iiter + phase.niterations, color=bgcolors[iphase % len(bgcolors)]) iiter += phase.niterations yield (PlotItem(name='acceptance', description=u''' Acceptance rate (black line) within a moving window of %d iterations. A model is considered accepted, if it is accepted in at least one chain. The popularity of accepted models is shown as blue dots. Popularity is defined as the percentage of chains accepting the model (100%% meaning acceptance in all chains). A moving average of the popularities is shown as blue line (same averaging interval as for the acceptance rate). Different background colors represent different sampler phases. ''' % nwindow), fig) mpl_init(fontsize=self.font_size) fig = plt.figure(figsize=self.size_inch) labelpos = mpl_margins(fig, w=7., h=5., units=self.font_size) axes = fig.add_subplot(1, 1, 1) labelpos(axes, 2.5, 2.0) nwindow2 = max(1, int(history.nmodels / (self.size_inch[1] * 100))) nmodels_rate2 = history.nmodels - (nwindow2 - 1) acceptance_rate2 = num.zeros((history.nchains, nmodels_rate2)) for ichain in range(history.nchains): acceptance_rate2[ichain, :] = trace.moving_sum( acceptance[ichain, :], nwindow2, mode='valid') \ / float(nwindow2) imodels_rate2 = imodels[nwindow2 - 1:] axes.pcolormesh(imodels_rate2, num.arange(history.nchains), num.log(0.01 + acceptance_rate2), cmap='GnBu') if history.sampler_contexts is not None: axes.plot(imodels, history.sampler_contexts[:, 1], '.', ms=2.0, color='black', label='Breeding Chain', alpha=0.3) axes.set_xlabel('Iteration') axes.set_ylabel('Bootstrap Chain') axes.set_xlim(0, history.nmodels - 1) axes.set_ylim(0, history.nchains - 1) axes.xaxis.grid(alpha=.4) yield (PlotItem(name='acceptance_img', description=u''' Model acceptance per bootstrap chain averaged over %d models (background color, low to high acceptance as light to dark colors). Black dots mark the base chains used when sampling new models (directed sampler phases only). ''' % nwindow2), fig)
def generate_plot(sat_target, result, ifig): scene = sat_target.scene fig = plt.figure() fig.set_size_inches(*self.size_inch) gs = gridspec.GridSpec( 2, 3, wspace=.15, hspace=.2, left=.1, right=.975, top=.95, height_ratios=[12, 1]) item = PlotItem( name='fig_%i' % ifig, attributes={'targets': [sat_target.path]}, title=u'Satellite Surface Displacements - %s' % scene.meta.scene_title, description=u''' Surface displacements derived from satellite data. (Left) the input data, (center) the modelled data and (right) the model residual. ''') stat_obs = result.statics_obs['displacement.los'] stat_syn = result.statics_syn['displacement.los'] res = stat_obs - stat_syn if scene.frame.isMeter(): offset_n, offset_e = map(float, latlon_to_ne_numpy( scene.frame.llLat, scene.frame.llLon, source.effective_lat, source.effective_lon)) elif scene.frame.isDegree(): offset_n = source.effective_lat - scene.frame.llLat offset_e = source.effective_lon - scene.frame.llLon im_extent = ( scene.frame.E.min() - offset_e, scene.frame.E.max() - offset_e, scene.frame.N.min() - offset_n, scene.frame.N.max() - offset_n) if self.displacement_unit == 'rad': wavelength = scene.meta.wavelength if wavelength is None: raise AttributeError( 'The satellite\'s wavelength is not set') stat_obs = displ2rad(stat_obs, wavelength) stat_syn = displ2rad(stat_syn, wavelength) res = displ2rad(res, wavelength) self.colormap = 'hsv' data_range = (0., num.pi) else: abs_displ = num.abs([stat_obs.min(), stat_obs.max(), stat_syn.min(), stat_syn.max(), res.min(), res.max()]).max() data_range = (-abs_displ, abs_displ) cmw = cm.ScalarMappable(cmap=self.colormap) cmw.set_clim(*data_range) cmw.set_array(stat_obs) axes = [fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[0, 1]), fig.add_subplot(gs[0, 2])] ax = axes[0] ax.imshow( get_displacement_rgba(stat_obs, scene, cmw), extent=im_extent, origin='lower') draw_leaves(ax, scene, offset_e, offset_n) draw_source(ax, scene) add_arrow(ax, scene) init_axes(ax, scene, 'Observed') ax.text(.025, .025, 'Scene ID: %s' % scene.meta.scene_id, fontsize=8, alpha=.7, va='bottom', transform=ax.transAxes) if scene.frame.isMeter(): ax.set_ylabel('Northing [km]', fontsize=self.font_size) ax = axes[1] ax.imshow( get_displacement_rgba(stat_syn, scene, cmw), extent=im_extent, origin='lower') draw_leaves(ax, scene, offset_e, offset_n) draw_source(ax, scene) add_arrow(ax, scene) init_axes(ax, scene, 'Model') ax.get_yaxis().set_visible(False) ax = axes[2] ax.imshow( get_displacement_rgba(res, scene, cmw), extent=im_extent, origin='lower') draw_leaves(ax, scene, offset_e, offset_n) draw_source(ax, scene) add_arrow(ax, scene) init_axes(ax, scene, 'Residual', last_axes=True) ax.get_yaxis().set_visible(False) for ax in axes: ax.set_xlim(*im_extent[:2]) ax.set_ylim(*im_extent[2:]) if closeup: if scene.frame.isMeter(): fn, fe = source.outline(cs='xy').T elif scene.frame.isDegree(): fn, fe = source.outline(cs='latlon').T fn -= source.effective_lat fe -= source.effective_lon if fn.size > 1: off_n = (fn[0] + fn[1]) / 2 off_e = (fe[0] + fe[1]) / 2 else: off_n = fn[0] off_e = fe[0] fault_size = 2*num.sqrt(max(abs(fn-off_n))**2 + max(abs(fe-off_e))**2) fault_size *= self.map_scale if fault_size == 0.0: extent = (scene.frame.N[-1] + scene.frame.E[-1]) / 2 fault_size = extent * .25 for ax in axes: ax.set_xlim(-fault_size/2 + off_e, fault_size/2 + off_e) ax.set_ylim(-fault_size/2 + off_n, fault_size/2 + off_n) if self.map_limits is not None: xmin, xmax, ymin, ymax = self.map_limits assert xmin < xmax, 'bad map_limits xmin > xmax' assert ymin < ymax, 'bad map_limits ymin > ymax' for ax in axes: ax.set_xlim( xmin/ax.scale_x['scale'] - ax.scale_x['offset'], xmax/ax.scale_x['scale'] - ax.scale_x['offset'],) ax.set_ylim( ymin/ax.scale_y['scale'] - ax.scale_y['offset'], ymax/ax.scale_y['scale'] - ax.scale_y['offset']) if self.displacement_unit == 'm': def cfmt(x, p): return '%.2f' % x elif self.displacement_unit == 'cm': def cfmt(x, p): return '%.1f' % (x * 1e2) elif self.displacement_unit == 'mm': def cfmt(x, p): return '%.0f' % (x * 1e3) elif self.displacement_unit == 'rad': def cfmt(x, p): return '%.2f' % x else: raise AttributeError( 'unknown displacement unit %s' % self.displacement_unit) cbar_args = dict( orientation='horizontal', format=FuncFormatter(cfmt), use_gridspec=True) cbar_label = 'LOS Displacement [%s]' % self.displacement_unit if self.common_color_scale: cax = fig.add_subplot(gs[1, 1]) cax.set_aspect(.05) cbar = fig.colorbar(cmw, cax=cax, **cbar_args) cbar.set_label(cbar_label) else: for idata, data in enumerate((stat_syn, stat_obs, res)): cax = fig.add_subplot(gs[1, idata]) cax.set_aspect(.05) if not self.displacement_unit == 'rad': abs_displ = num.abs(data).max() cmw.set_clim(-abs_displ, abs_displ) cbar = fig.colorbar(cmw, cax=cax, **cbar_args) cbar.set_label(cbar_label) return (item, fig)
def plot_gnss(gnss_target, result, ifig, vertical=False): campaign = gnss_target.campaign item = PlotItem( name='fig_%i' % ifig, attributes={'targets': gnss_target.path}, title=u'Static GNSS Surface Displacements - Campaign %s' % campaign.name, description=u'Static surface displacement from GNSS campaign ' u'%s (black vectors) and displacements derived ' u'from best rupture model (red).' % campaign.name) lat, lon = campaign.get_center_latlon() if self.radius is None: radius = campaign.get_radius() if radius == 0.: logger.warn('Radius of GNSS campaign %s too small, defaulting' ' to 30 km' % campaign.name) radius = 30 * km model_camp = gnss.GNSSCampaign(stations=copy.deepcopy( campaign.stations), name='grond model') for ista, sta in enumerate(model_camp.stations): sta.north.shift = result.statics_syn['displacement.n'][ista] sta.north.sigma = 0. sta.east.shift = result.statics_syn['displacement.e'][ista] sta.east.sigma = 0. sta.up.shift = -result.statics_syn['displacement.d'][ista] sta.up.sigma = 0. m = automap.Map(width=self.size_cm[0], height=self.size_cm[1], lat=lat, lon=lon, radius=radius, show_topo=self.show_topo, show_grid=self.show_grid, show_rivers=self.show_rivers, color_wet=(216, 242, 254), color_dry=(238, 236, 230)) if vertical: m.add_gnss_campaign(campaign, psxy_style={ 'G': 'black', 'W': '0.8p,black', }, vertical=True) m.add_gnss_campaign(model_camp, psxy_style={ 'G': 'red', 'W': '0.8p,red', 't': 30, }, vertical=True, labels=False) else: m.add_gnss_campaign(campaign, psxy_style={ 'G': 'black', 'W': '0.8p,black', }) m.add_gnss_campaign(model_camp, psxy_style={ 'G': 'red', 'W': '0.8p,red', 't': 30, }, labels=False) if isinstance(problem, CMTProblem): from pyrocko import moment_tensor from pyrocko.plot import gmtpy event = source.pyrocko_event() mt = event.moment_tensor.m_up_south_east() xx = num.trace(mt) / 3. mc = num.matrix([[xx, 0., 0.], [0., xx, 0.], [0., 0., xx]]) mc = mt - mc mc = mc / event.moment_tensor.scalar_moment() * \ moment_tensor.magnitude_to_moment(5.0) m6 = tuple(moment_tensor.to6(mc)) symbol_size = 20. m.gmt.psmeca(S='%s%g' % ('d', symbol_size / gmtpy.cm), in_rows=[ (source.lon, source.lat, 10) + m6 + (1, 0, 0) ], M=True, *m.jxyr) elif isinstance(problem, RectangularProblem): m.gmt.psxy(in_rows=source.outline(cs='lonlat'), L='+p2p,black', W='1p,black', G='black', t=60, *m.jxyr) return (item, m)
def draw_figures(self, ds, history, optimiser): fontsize = self.font_size fontsize_title = self.font_size_title nxmax = self.nx nymax = self.ny problem = history.problem for target in problem.targets: target.set_dataset(ds) target_index = {} i = 0 for target in problem.targets: target_index[target] = i, i+target.nmisfits i += target.nmisfits xbest = history.get_best_model() misfits = history.misfits[history.get_sorted_misfits_idx(chain=0), ...] ws = problem.get_target_weights() gcms = problem.combine_misfits( misfits[:1, :, :], extra_correlated_weights=optimiser.get_correlated_weights(problem), get_contributions=True)[0, :] w_max = num.nanmax(ws) gcm_max = num.nanmax(gcms) source = problem.get_source(xbest) target_to_result = {} all_syn_trs = [] all_syn_specs = [] results = problem.evaluate(xbest) dtraces = [] for target, result in zip(problem.targets, results): if not isinstance(result, WaveformMisfitResult): dtraces.extend([None] * target.nmisfits) continue itarget, itarget_end = target_index[target] assert itarget_end == itarget + 1 w = target.get_combined_weight() if target.misfit_config.domain == 'cc_max_norm': tref = ( result.filtered_obs.tmin + result.filtered_obs.tmax) * 0.5 for tr_filt, tr_proc, tshift in ( (result.filtered_obs, result.processed_obs, 0.), (result.filtered_syn, result.processed_syn, result.tshift)): norm = num.sum(num.abs(tr_proc.ydata)) / tr_proc.data_len() tr_filt.ydata /= norm tr_proc.ydata /= norm tr_filt.shift(tshift) tr_proc.shift(tshift) ctr = result.cc ctr.shift(tref) dtrace = ctr else: for tr in ( result.filtered_obs, result.filtered_syn, result.processed_obs, result.processed_syn): tr.ydata *= w for spec in ( result.spectrum_obs, result.spectrum_syn): if spec is not None: spec.ydata *= w if result.tshift is not None and result.tshift != 0.0: # result.filtered_syn.shift(result.tshift) result.processed_syn.shift(result.tshift) dtrace = make_norm_trace( result.processed_syn, result.processed_obs, problem.norm_exponent) target_to_result[target] = result dtrace.meta = dict( normalisation_family=target.normalisation_family, path=target.path) dtraces.append(dtrace) result.processed_syn.meta = dict( normalisation_family=target.normalisation_family, path=target.path) all_syn_trs.append(result.processed_syn) if result.spectrum_syn: result.spectrum_syn.meta = dict( normalisation_family=target.normalisation_family, path=target.path) all_syn_specs.append(result.spectrum_syn) if not all_syn_trs: logger.warn('No traces to show!') return def skey(tr): return tr.meta['normalisation_family'], tr.meta['path'] trace_minmaxs = trace.minmax(all_syn_trs, skey) amp_spec_maxs = amp_spec_max(all_syn_specs, skey) dminmaxs = trace.minmax([x for x in dtraces if x is not None], skey) for tr in dtraces: if tr: dmin, dmax = dminmaxs[skey(tr)] tr.ydata /= max(abs(dmin), abs(dmax)) cg_to_targets = meta.gather( problem.waveform_targets, lambda t: (t.path, t.codes[3]), filter=lambda t: t in target_to_result) cgs = sorted(cg_to_targets.keys()) for cg in cgs: targets = cg_to_targets[cg] frame_to_target, nx, ny, nxx, nyy = layout( source, targets, nxmax, nymax) figures = {} for iy in range(ny): for ix in range(nx): if (iy, ix) not in frame_to_target: continue ixx = ix // nxmax iyy = iy // nymax if (iyy, ixx) not in figures: title = '_'.join(x for x in cg if x) item = PlotItem( name='fig_%s_%i_%i' % (title, ixx, iyy)) item.attributes['targets'] = [] figures[iyy, ixx] = ( item, plt.figure(figsize=self.size_inch)) figures[iyy, ixx][1].subplots_adjust( left=0.03, right=1.0 - 0.03, bottom=0.03, top=1.0 - 0.06, wspace=0.2, hspace=0.2) item, fig = figures[iyy, ixx] target = frame_to_target[iy, ix] item.attributes['targets'].append(target.string_id()) amin, amax = trace_minmaxs[ target.normalisation_family, target.path] absmax = max(abs(amin), abs(amax)) ny_this = nymax # min(ny, nymax) nx_this = nxmax # min(nx, nxmax) i_this = (iy % ny_this) * nx_this + (ix % nx_this) + 1 axes2 = fig.add_subplot(ny_this, nx_this, i_this) space = 0.5 space_factor = 1.0 + space axes2.set_axis_off() axes2.set_ylim(-1.05 * space_factor, 1.05) axes = axes2.twinx() axes.set_axis_off() if target.misfit_config.domain == 'cc_max_norm': axes.set_ylim(-10. * space_factor, 10.) else: axes.set_ylim( -absmax * 1.33 * space_factor, absmax * 1.33) itarget, itarget_end = target_index[target] assert itarget_end == itarget + 1 result = target_to_result[target] dtrace = dtraces[itarget] tap_color_annot = (0.35, 0.35, 0.25) tap_color_edge = (0.85, 0.85, 0.80) tap_color_fill = (0.95, 0.95, 0.90) plot_taper( axes2, result.processed_obs.get_xdata(), result.taper, fc=tap_color_fill, ec=tap_color_edge) obs_color = mpl_color('aluminium5') obs_color_light = light(obs_color, 0.5) syn_color = mpl_color('scarletred2') syn_color_light = light(syn_color, 0.5) misfit_color = mpl_color('scarletred2') weight_color = mpl_color('chocolate2') cc_color = mpl_color('aluminium5') if target.misfit_config.domain == 'cc_max_norm': tref = (result.filtered_obs.tmin + result.filtered_obs.tmax) * 0.5 plot_dtrace( axes2, dtrace, space, -1., 1., fc=light(cc_color, 0.5), ec=cc_color) plot_dtrace_vline( axes2, tref, space, color=tap_color_annot) elif target.misfit_config.domain == 'frequency_domain': asmax = amp_spec_maxs[ target.normalisation_family, target.path] fmin, fmax = \ target.misfit_config.get_full_frequency_range() plot_spectrum( axes2, result.spectrum_syn, result.spectrum_obs, fmin, fmax, space, 0., asmax, syn_color=syn_color, obs_color=obs_color, syn_lw=1.0, obs_lw=0.75, color_vline=tap_color_annot, fontsize=fontsize) else: plot_dtrace( axes2, dtrace, space, 0., 1., fc=light(misfit_color, 0.3), ec=misfit_color) plot_trace( axes, result.filtered_syn, color=syn_color_light, lw=1.0) plot_trace( axes, result.filtered_obs, color=obs_color_light, lw=0.75) plot_trace( axes, result.processed_syn, color=syn_color, lw=1.0) plot_trace( axes, result.processed_obs, color=obs_color, lw=0.75) # xdata = result.filtered_obs.get_xdata() tmarks = [ result.processed_obs.tmin, result.processed_obs.tmax] for tmark in tmarks: axes2.plot( [tmark, tmark], [-0.9, 0.1], color=tap_color_annot) dur = tmarks[1] - tmarks[0] for tmark, text, ha in [ (tmarks[0], '$\\,$ ' + meta.str_duration( tmarks[0] - source.time), 'left'), (tmarks[1], '$\\Delta$ ' + meta.str_duration(dur), 'right')]: axes2.annotate( text, xy=(tmark, -0.9), xycoords='data', xytext=( fontsize * 0.4 * [-1, 1][ha == 'left'], fontsize * 0.2), textcoords='offset points', ha=ha, va='bottom', color=tap_color_annot, fontsize=fontsize) axes2.set_xlim(tmarks[0] - dur*0.1, tmarks[1] + dur*0.1) rel_w = ws[itarget] / w_max rel_c = gcms[itarget] / gcm_max sw = 0.25 sh = 0.1 ph = 0.01 for (ih, rw, facecolor, edgecolor) in [ (0, rel_w, light(weight_color, 0.5), weight_color), (1, rel_c, light(misfit_color, 0.5), misfit_color)]: bar = patches.Rectangle( (1.0 - rw * sw, 1.0 - (ih + 1) * sh + ph), rw * sw, sh - 2 * ph, facecolor=facecolor, edgecolor=edgecolor, zorder=10, transform=axes.transAxes, clip_on=False) axes.add_patch(bar) scale_string = None if target.misfit_config.domain == 'cc_max_norm': scale_string = 'Syn/obs scales differ!' infos = [] if scale_string: infos.append(scale_string) if self.nx == 1 and self.ny == 1: infos.append(target.string_id()) else: infos.append('.'.join(x for x in target.codes if x)) dist = source.distance_to(target) azi = source.azibazi_to(target)[0] infos.append(meta.str_dist(dist)) infos.append('%.0f\u00B0' % azi) infos.append('%.3g' % ws[itarget]) infos.append('%.3g' % gcms[itarget]) axes2.annotate( '\n'.join(infos), xy=(0., 1.), xycoords='axes fraction', xytext=(2., 2.), textcoords='offset points', ha='left', va='top', fontsize=fontsize, fontstyle='normal') if (self.nx == 1 and self.ny == 1): yield item, fig del figures[iyy, ixx] if not (self.nx == 1 and self.ny == 1): for (iyy, ixx), (_, fig) in figures.items(): title = '.'.join(x for x in cg if x) if len(figures) > 1: title += ' (%i/%i, %i/%i)' % ( iyy + 1, nyy, ixx + 1, nxx) fig.suptitle(title, fontsize=fontsize_title) for item, fig in figures.values(): yield item, fig
def generate_plot(sat_target, result, ifig): scene = sat_target.scene fig = plt.figure() fig.set_size_inches(*self.size_inch) gs = gridspec.GridSpec(2, 3, wspace=.15, hspace=.2, left=.1, right=.975, top=.95, height_ratios=[12, 1]) item = PlotItem(name='fig_%i' % ifig, attributes={'targets': [sat_target.path]}, title=u'Satellite Surface Displacements - %s' % scene.meta.scene_title, description=u''' Surface displacements derived from satellite data. (Left) the input data, (center) the modelled data and (right) the model residual. '''.format(meta=scene.meta)) stat_obs = result.statics_obs stat_syn = result.statics_syn['displacement.los'] res = stat_obs - stat_syn if scene.frame.isMeter(): offset_n, offset_e = map( float, latlon_to_ne_numpy(scene.frame.llLat, scene.frame.llLon, source.effective_lat, source.effective_lon)) elif scene.frame.isDegree(): offset_n = source.effective_lat - scene.frame.llLat offset_e = source.effective_lon - scene.frame.llLon im_extent = (scene.frame.E.min() - offset_e, scene.frame.E.max() - offset_e, scene.frame.N.min() - offset_n, scene.frame.N.max() - offset_n) abs_displ = num.abs([ stat_obs.min(), stat_obs.max(), stat_syn.min(), stat_syn.max(), res.min(), res.max() ]).max() cmw = cm.ScalarMappable(cmap=self.colormap) cmw.set_clim(vmin=-abs_displ, vmax=abs_displ) cmw.set_array(stat_obs) axes = [ fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[0, 1]), fig.add_subplot(gs[0, 2]) ] ax = axes[0] ax.imshow(mapDisplacementGrid(stat_obs, scene), extent=im_extent, cmap=self.colormap, vmin=-abs_displ, vmax=abs_displ, origin='lower') drawLeaves(ax, scene, offset_e, offset_n) drawSource(ax, scene) addArrow(ax, scene) initAxes(ax, scene, 'Observed') ax.text(.025, .025, 'Scene ID: %s' % scene.meta.scene_id, fontsize=8, alpha=.7, va='bottom', transform=ax.transAxes) if scene.frame.isDegree(): ax.set_ylabel('Lat [°]') elif scene.frame.isMeter(): ax.set_ylabel('Northing [km]') ax = axes[1] ax.imshow(mapDisplacementGrid(stat_syn, scene), extent=im_extent, cmap=self.colormap, vmin=-abs_displ, vmax=abs_displ, origin='lower') drawLeaves(ax, scene, offset_e, offset_n) drawSource(ax, scene) addArrow(ax, scene) initAxes(ax, scene, 'Model') ax.get_yaxis().set_visible(False) ax = axes[2] ax.imshow(mapDisplacementGrid(res, scene), extent=im_extent, cmap=self.colormap, vmin=-abs_displ, vmax=abs_displ, origin='lower') drawLeaves(ax, scene, offset_e, offset_n) drawSource(ax, scene) addArrow(ax, scene) initAxes(ax, scene, 'Residual', last_axes=True) ax.get_yaxis().set_visible(False) for ax in axes: ax.set_xlim(llE, urE) ax.set_ylim(llN, urN) if closeup: if scene.frame.isMeter(): fn, fe = source.outline(cs='xy').T elif scene.frame.isDegree(): fn, fe = source.outline(cs='latlon').T fn -= source.effective_lat fe -= source.effective_lon if fn.size > 1: off_n = (fn[0] + fn[1]) / 2 off_e = (fe[0] + fe[1]) / 2 else: off_n = fn[0] off_e = fe[0] fault_size = 2 * num.sqrt( max(abs(fn - off_n))**2 + max(abs(fe - off_e))**2) fault_size *= self.map_scale if fault_size == 0.0: extent = (scene.frame.N[-1] + scene.frame.E[-1]) / 2 fault_size = extent * .25 for ax in axes: ax.set_xlim(-fault_size / 2 + off_e, fault_size / 2 + off_e) ax.set_ylim(-fault_size / 2 + off_n, fault_size / 2 + off_n) cax = fig.add_subplot(gs[1, :]) cbar = fig.colorbar(cmw, cax=cax, orientation='horizontal', use_gridspec=True) cbar.set_label('LOS Displacement [m]') return (item, fig)
def draw_figures(self, history, optimiser): color_parameter = self.color_parameter exclude = self.exclude include = self.include nsubplots = self.nsubplots figsize = self.size_inch ibootstrap = 0 if self.ibootstrap is None else self.ibootstrap misfit_cutoff = self.misfit_cutoff show_ellipses = self.show_ellipses msize = 1.5 cmap = 'coolwarm' problem = history.problem if not problem: return [] models = history.models exclude = list(exclude) bounds = problem.get_combined_bounds() for ipar in range(problem.ncombined): par = problem.combined[ipar] lo, hi = bounds[ipar] if lo == hi: exclude.append(par.name) xref = problem.get_reference_model() isort = history.get_sorted_misfits_idx(chain=ibootstrap)[::-1] models = history.get_sorted_models(chain=ibootstrap)[::-1] nmodels = history.nmodels gms = history.get_sorted_misfits(chain=ibootstrap)[::-1] if misfit_cutoff is not None: ibest = gms < misfit_cutoff gms = gms[ibest] models = models[ibest] kwargs = {} if color_parameter == 'dist': mx = num.mean(models, axis=0) cov = num.cov(models.T) mdists = core.mahalanobis_distance(models, mx, cov) icolor = meta.ordersort(mdists) elif color_parameter == 'misfit': iorder = num.arange(nmodels) icolor = iorder elif color_parameter in problem.parameter_names: ind = problem.name_to_index(color_parameter) icolor = problem.extract(models, ind) elif color_parameter in history.attribute_names: icolor = history.get_attribute(color_parameter)[isort] icolor_need = num.unique(icolor) colors = [] for i in range(icolor_need[-1]+1): colors.append(mpl_graph_color(i)) cmap = mcolors.ListedColormap(colors) cmap.set_under(mpl_color('aluminium3')) kwargs.update(dict(vmin=0, vmax=icolor_need[-1])) else: raise meta.GrondError( 'Invalid color_parameter: %s' % color_parameter) smap = {} iselected = 0 for ipar in range(problem.ncombined): par = problem.combined[ipar] if exclude and par.name in exclude or \ include and par.name not in include: continue smap[iselected] = ipar iselected += 1 nselected = iselected if nselected < 2: logger.warn('Cannot draw joinpar figures with less than two ' 'parameters selected.') return [] nfig = (nselected - 2) // nsubplots + 1 figs = [] for ifig in range(nfig): figs_row = [] for jfig in range(nfig): if ifig >= jfig: item = PlotItem(name='fig_%i_%i' % (ifig, jfig)) item.attributes['parameters'] = [] figs_row.append((item, plt.figure(figsize=figsize))) else: figs_row.append(None) figs.append(figs_row) for iselected in range(nselected): ipar = smap[iselected] ypar = problem.combined[ipar] for jselected in range(iselected): jpar = smap[jselected] xpar = problem.combined[jpar] ixg = (iselected - 1) iyg = jselected ix = ixg % nsubplots iy = iyg % nsubplots ifig = ixg // nsubplots jfig = iyg // nsubplots aind = (nsubplots, nsubplots, (ix * nsubplots) + iy + 1) item, fig = figs[ifig][jfig] tlist = item.attributes['parameters'] if xpar.name not in tlist: tlist.append(xpar.name) if ypar.name not in tlist: tlist.append(ypar.name) axes = fig.add_subplot(*aind) axes.axvline(0., color=mpl_color('aluminium3'), lw=0.5) axes.axhline(0., color=mpl_color('aluminium3'), lw=0.5) for spine in axes.spines.values(): spine.set_edgecolor(mpl_color('aluminium5')) spine.set_linewidth(0.5) xmin, xmax = fixlim(*xpar.scaled(bounds[jpar])) ymin, ymax = fixlim(*ypar.scaled(bounds[ipar])) if ix == 0 or jselected + 1 == iselected: for (xpos, xoff, x) in [ (0.0, 10., xmin), (1.0, -10., xmax)]: axes.annotate( '%.3g%s' % (x, xpar.get_unit_suffix()), xy=(xpos, 1.05), xycoords='axes fraction', xytext=(xoff, 5.), textcoords='offset points', verticalalignment='bottom', horizontalalignment='left', rotation=45.) if iy == nsubplots - 1 or jselected + 1 == iselected: for (ypos, yoff, y) in [ (0., 10., ymin), (1.0, -10., ymax)]: axes.annotate( '%.3g%s' % (y, ypar.get_unit_suffix()), xy=(1.0, ypos), xycoords='axes fraction', xytext=(5., yoff), textcoords='offset points', verticalalignment='bottom', horizontalalignment='left', rotation=45.) axes.set_xlim(xmin, xmax) axes.set_ylim(ymin, ymax) if not self.show_ticks: axes.get_xaxis().set_ticks([]) axes.get_yaxis().set_ticks([]) else: axes.tick_params(length=4, which='both') axes.get_yaxis().set_ticklabels([]) axes.get_xaxis().set_ticklabels([]) if iselected == nselected - 1 or ix == nsubplots - 1: axes.annotate( xpar.get_label(with_unit=False), xy=(0.5, -0.05), xycoords='axes fraction', verticalalignment='top', horizontalalignment='right', rotation=45.) if iy == 0: axes.annotate( ypar.get_label(with_unit=False), xy=(-0.05, 0.5), xycoords='axes fraction', verticalalignment='top', horizontalalignment='right', rotation=45.) fx = problem.extract(models, jpar) fy = problem.extract(models, ipar) axes.scatter( xpar.scaled(fx), ypar.scaled(fy), c=icolor, s=msize, alpha=0.5, cmap=cmap, edgecolors='none', **kwargs) if show_ellipses: cov = num.cov((xpar.scaled(fx), ypar.scaled(fy))) evals, evecs = eigh_sorted(cov) evals = num.sqrt(evals) ell = patches.Ellipse( xy=( num.mean(xpar.scaled(fx)), num.mean(ypar.scaled(fy))), width=evals[0] * 2, height=evals[1] * 2, angle=num.rad2deg( num.arctan2(evecs[1][0], evecs[0][0]))) ell.set_facecolor('none') axes.add_artist(ell) if self.show_reference: fx = problem.extract(xref, jpar) fy = problem.extract(xref, ipar) ref_color = mpl_color('aluminium6') ref_color_light = 'none' axes.plot( xpar.scaled(fx), ypar.scaled(fy), 's', mew=1.5, ms=5, mfc=ref_color_light, mec=ref_color) figs_flat = [] for figs_row in figs: figs_flat.extend( item_fig for item_fig in figs_row if item_fig is not None) return figs_flat
def draw_figure(self, ds, history, tpath): problem = history.problem color_parameter = self.color_parameter misfit_cutoff = self.misfit_cutoff fontsize = self.font_size targets = [ t for t in problem.targets if isinstance(t, PhaseRatioTarget) and t.path == tpath ] gms = problem.combine_misfits(history.misfits) isort = num.argsort(gms)[::-1] gms = gms[isort] models = history.models[isort, :] if misfit_cutoff is not None: ibest = gms < misfit_cutoff gms = gms[ibest] models = models[ibest] gms = gms[::self.istride_ensemble] models = models[::self.istride_ensemble] nmodels = models.shape[0] if color_parameter == 'dist': mx = num.mean(models, axis=0) cov = num.cov(models.T) mdists = core.mahalanobis_distance(models, mx, cov) icolor = meta.ordersort(mdists) elif color_parameter == 'misfit': iorder = num.arange(nmodels) icolor = iorder elif color_parameter in problem.parameter_names: ind = problem.name_to_index(color_parameter) icolor = problem.extract(models, ind) from matplotlib import colors cmap = cm.ScalarMappable(norm=colors.Normalize(vmin=num.min(icolor), vmax=num.max(icolor)), cmap=plt.get_cmap('coolwarm')) imodel_to_color = [] for imodel in range(nmodels): imodel_to_color.append(cmap.to_rgba(icolor[imodel])) data = [] for imodel in range(nmodels): model = models[imodel, :] # source = problem.get_source(model) results = problem.evaluate(model, targets=targets) for target, result in zip(targets, results): if isinstance(result, gf.SeismosizerError): continue if not isinstance(target, PhaseRatioTarget): continue a_obs = result.a_obs b_obs = result.b_obs a_syn = result.a_syn b_syn = result.b_syn r_obs = a_obs / (a_obs + b_obs) r_syn = a_syn / (a_syn + b_syn) data.append(('.'.join(target.codes), imodel, r_obs, r_syn)) fontsize = self.font_size item = PlotItem(name='fig_%s' % tpath) item.attributes['targets'] = [t.string_id() for t in targets] fig = plt.figure(figsize=self.size_inch) labelpos = mpl_margins(fig, nw=1, nh=1, left=7., right=1., bottom=10., top=3, units=fontsize) axes = fig.add_subplot(1, 1, 1) labelpos(axes, 2.5, 2.0) labels = sorted(set(x[0] for x in data)) ntargets = len(labels) string_id_to_itarget = dict((x, i) for (i, x) in enumerate(labels)) itargets = num.array([string_id_to_itarget[x[0]] for x in data]) imodels = num.array([x[1] for x in data], dtype=num.int).T r_obs, r_syn = num.array([x[2:] for x in data]).T r_obs_median = num.zeros(ntargets) for itarget in range(ntargets): r_obs_median[itarget] = num.median(r_obs[itargets == itarget]) iorder = meta.ordersort(r_obs_median) for imodel in range(nmodels): mask = imodels == imodel axes.plot(iorder[itargets[mask]], r_obs[mask], '_', ms=20., zorder=-10, alpha=0.5, color='black') axes.plot(iorder[itargets[mask]], r_syn[mask], '_', ms=10., alpha=0.5, color=imodel_to_color[imodel]) axes.set_yscale('log') axes.set_ylabel('Ratio') axes.set_xticks(iorder[num.arange(ntargets)]) axes.set_xticklabels(labels, rotation='vertical') fig.suptitle(tpath, fontsize=self.font_size_title) yield item, fig
def draw_figures(self, history): from matplotlib import colors color = 'black' fontsize = self.font_size markersize = fontsize * 1.5 beachballsize_small = markersize * 0.5 beachball_type = self.beachball_type problem = history.problem sp = SectionPlot(config=self) self._to_be_closed.append(sp) fig = sp.fig axes_en = sp.axes_xy axes_dn = sp.axes_zy axes_ed = sp.axes_xz bounds = problem.get_combined_bounds() gms = problem.combine_misfits(history.misfits) isort = num.argsort(gms)[::-1] gms = gms[isort] models = history.models[isort, :] iorder = num.arange(history.nmodels) for parname, set_label, set_lim in [[ 'east_shift', sp.set_xlabel, sp.set_xlim ], ['north_shift', sp.set_ylabel, sp.set_ylim], ['depth', sp.set_zlabel, sp.set_zlim]]: ipar = problem.name_to_index(parname) par = problem.combined[ipar] set_label(par.get_label()) xmin, xmax = fixlim(*par.scaled(bounds[ipar])) set_lim(xmin, xmax) for axes, xparname, yparname in [(axes_en, 'east_shift', 'north_shift'), (axes_dn, 'depth', 'north_shift'), (axes_ed, 'east_shift', 'depth')]: ixpar = problem.name_to_index(xparname) iypar = problem.name_to_index(yparname) xpar = problem.combined[ixpar] ypar = problem.combined[iypar] xmin, xmax = fixlim(*xpar.scaled(bounds[ixpar])) ymin, ymax = fixlim(*ypar.scaled(bounds[iypar])) try: axes.set_facecolor(mpl_color('aluminium1')) except AttributeError: axes.patch.set_facecolor(mpl_color('aluminium1')) rect = patches.Rectangle((xmin, ymin), xmax - xmin, ymax - ymin, facecolor=mpl_color('white'), edgecolor=mpl_color('aluminium2')) axes.add_patch(rect) # fxs = xpar.scaled(problem.extract(models, ixpar)) # fys = ypar.scaled(problem.extract(models, iypar)) # axes.set_xlim(*fixlim(num.min(fxs), num.max(fxs))) # axes.set_ylim(*fixlim(num.min(fys), num.max(fys))) cmap = cm.ScalarMappable(norm=colors.Normalize( vmin=num.min(iorder), vmax=num.max(iorder)), cmap=plt.get_cmap('coolwarm')) for ix, x in enumerate(models): source = problem.get_source(x) mt = source.pyrocko_moment_tensor(store=problem.get_gf_store( problem.targets[0]), target=problem.targets[0]) fx = problem.extract(x, ixpar) fy = problem.extract(x, iypar) sx, sy = xpar.scaled(fx), ypar.scaled(fy) color = cmap.to_rgba(iorder[ix]) alpha = (iorder[ix] - num.min(iorder)) / \ float(num.max(iorder) - num.min(iorder)) try: beachball.plot_beachball_mpl(mt, axes, beachball_type=beachball_type, position=(sx, sy), size=beachballsize_small, color_t=color, alpha=alpha, zorder=1, linewidth=0.25) except beachball.BeachballError as e: logger.warn(str(e)) item = PlotItem(name='main') return [[item, fig]]
def draw_figures(self, history): fontsize = self.font_size fig = plt.figure(figsize=self.size_inch) labelpos = mpl_margins(fig, nw=2, nh=2, w=7., h=5., wspace=2., hspace=5., units=fontsize) problem = history.problem if not problem: logger.warn('problem not set') return [] models = history.models if models.size == 0: logger.warn('empty models vector') return [] imodels = num.arange(history.nmodels) gms = problem.combine_misfits(history.misfits)**problem.norm_exponent isort = num.argsort(gms)[::-1] gms = gms[isort] gms_softclip = num.where(gms > 1.0, 0.1 * num.log10(gms) + 1.0, gms) gcms = problem.combine_misfits(history.misfits, get_contributions=True) gcms = gcms[isort, :] jsort = num.argsort(gcms[-1, :])[::-1] # ncols = 4 # nrows = ((problem.ntargets + 1) - 1) / ncols + 1 axes = fig.add_subplot(2, 2, 1) labelpos(axes, 2.5, 2.0) axes.set_ylabel('Relative contribution (smoothed)') axes.set_ylim(0.0, 1.0) axes2 = fig.add_subplot(2, 2, 3, sharex=axes) labelpos(axes2, 2.5, 2.0) axes2.set_xlabel( 'Tested model, sorted descending by global misfit value') axes2.set_ylabel('Square of misfit') axes2.set_ylim(0., 1.5) axes2.axhspan(1.0, 1.5, color=(0.8, 0.8, 0.8)) axes2.set_yticks( [0., 0.2, 0.4, 0.6, 0.8, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5]) axes2.set_yticklabels([ '0.0', '0.2', '0.4', '0.6', '0.8', '1', '10', '100', '1000', '10000', '100000' ]) axes2.set_xlim(imodels[0], imodels[-1]) rel_ms_sum = num.zeros(history.nmodels) rel_ms_smooth_sum = num.zeros(history.nmodels) ms_smooth_sum = num.zeros(history.nmodels) b = num.hanning(min(100, history.nmodels // 3)) b /= num.sum(b) a = [1] ii = 0 target_idx = [ str(it) * t.nmisfits for it, t in enumerate(problem.targets) ] target_idx = num.fromiter(map(float, ''.join(target_idx)), dtype=int) for idx in jsort: target = problem.targets[target_idx[idx]] ms = gcms[:, idx] ms = num.where(num.isfinite(ms), ms, 0.0) if num.all(ms == 0.0): continue rel_ms = ms / gms rel_ms_smooth = signal.filtfilt(b, a, rel_ms) ms_smooth = rel_ms_smooth * gms_softclip rel_poly_y = num.concatenate( [rel_ms_smooth_sum[::-1], rel_ms_smooth_sum + rel_ms_smooth]) poly_x = num.concatenate([imodels[::-1], imodels]) add_args = {} if ii < 20: add_args['label'] = '%s (%.2g)' % (target.string_id(), num.mean(rel_ms[-1])) axes.fill(poly_x, rel_poly_y, alpha=0.5, color=mpl_graph_color(ii), **add_args) poly_y = num.concatenate( [ms_smooth_sum[::-1], ms_smooth_sum + ms_smooth]) axes2.fill(poly_x, poly_y, alpha=0.5, color=mpl_graph_color(ii)) rel_ms_sum += rel_ms # axes.plot( # imodels, rel_ms_sum, color='black', alpha=0.1, zorder=-1) ms_smooth_sum += ms_smooth rel_ms_smooth_sum += rel_ms_smooth ii += 1 axes.legend(title='Contributions (top twenty)', bbox_to_anchor=(1.05, 0.0, 1.0, 1.0), loc='upper left', ncol=1, borderaxespad=0., prop={'size': 9}) axes2.plot(imodels, gms_softclip, color='black') axes2.axhline(1.0, color=(0.5, 0.5, 0.5)) return [[PlotItem(name='main'), fig]]
def draw_figures(self, history): fontsize = self.font_size fig = plt.figure(figsize=self.size_inch) axes = fig.add_subplot(1, 1, 1, aspect=1.0) fig.subplots_adjust(left=0., right=1., bottom=0., top=1.) problem = history.problem models = history.models if models.size == 0: logger.warn('empty models vector') return [] gms = problem.combine_misfits(history.misfits) isort = num.argsort(gms) iorder = num.empty_like(isort) iorder[isort] = num.arange(iorder.size)[::-1] mean_source = core.get_mean_source(problem, history.models) best_source = core.get_best_source(problem, history.models, history.misfits) ref_source = problem.base_source for xpos, label in [(0., 'Full'), (2., 'Isotropic'), (4., 'Deviatoric'), (6., 'CLVD'), (8., 'DC')]: axes.annotate(label, xy=(1 + xpos, 3), xycoords='data', xytext=(0., 0.), textcoords='offset points', ha='center', va='center', color='black', fontsize=fontsize) decos = [] for source in [best_source, mean_source, ref_source]: mt = source.pyrocko_moment_tensor() deco = mt.standard_decomposition() decos.append(deco) moment_full_max = max(deco[-1][0] for deco in decos) for ypos, label, deco, color_t in [ (2., 'Ensemble best', decos[0], mpl_color('aluminium5')), (1., 'Ensemble mean', decos[1], mpl_color('scarletred1')), (0., 'Reference', decos[2], mpl_color('aluminium3')) ]: [(moment_iso, ratio_iso, m_iso), (moment_dc, ratio_dc, m_dc), (moment_clvd, ratio_clvd, m_clvd), (moment_devi, ratio_devi, m_devi), (moment_full, ratio_full, m_full)] = deco size0 = moment_full / moment_full_max axes.annotate(label, xy=(-2., ypos), xycoords='data', xytext=(0., 0.), textcoords='offset points', ha='left', va='center', color='black', fontsize=fontsize) for xpos, mt_part, ratio, ops in [(0., m_full, ratio_full, '-'), (2., m_iso, ratio_iso, '='), (4., m_devi, ratio_devi, '='), (6., m_clvd, ratio_clvd, '+'), (8., m_dc, ratio_dc, None)]: if ratio > 1e-4: try: beachball.plot_beachball_mpl( mt_part, axes, beachball_type='full', position=(1. + xpos, ypos), size=0.9 * size0 * math.sqrt(ratio), size_units='data', color_t=color_t, linewidth=1.0) except beachball.BeachballError as e: logger.warn(str(e)) axes.annotate('ERROR', xy=(1. + xpos, ypos), ha='center', va='center', color='red', fontsize=fontsize) else: axes.annotate('N/A', xy=(1. + xpos, ypos), ha='center', va='center', color='black', fontsize=fontsize) if ops is not None: axes.annotate(ops, xy=(2. + xpos, ypos), ha='center', va='center', color='black', fontsize=fontsize) axes.axison = False axes.set_xlim(-2.25, 9.75) axes.set_ylim(-0.5, 3.5) item = PlotItem(name='main') return [[item, fig]]
def draw_figures(self, history, color_p_axis=False): from matplotlib import colors color = 'black' fontsize = self.font_size markersize = fontsize * 1.5 beachballsize_small = markersize * 0.5 beachball_type = self.beachball_type problem = history.problem sp = SectionPlot(config=self) self._to_be_closed.append(sp) fig = sp.fig axes_en = sp.axes_xy axes_dn = sp.axes_zy axes_ed = sp.axes_xz bounds = problem.get_combined_bounds() models = history.get_sorted_primary_models()[::-1] iorder = num.arange(history.nmodels) for parname, set_label, set_lim in [ ['east_shift', sp.set_xlabel, sp.set_xlim], ['north_shift', sp.set_ylabel, sp.set_ylim], ['depth', sp.set_zlabel, sp.set_zlim]]: ipar = problem.name_to_index(parname) par = problem.combined[ipar] set_label(par.get_label()) xmin, xmax = fixlim(*par.scaled(bounds[ipar])) set_lim(xmin, xmax) if 'volume_change' in problem.parameter_names: volumes = models[:, problem.name_to_index('volume_change')] volume_max = volumes.max() volume_min = volumes.min() def scale_size(source): if not hasattr(source, 'volume_change'): return beachballsize_small volume_change = source.volume_change fac = (volume_change - volume_min) / (volume_max - volume_min) return markersize * .25 + markersize * .5 * fac for axes, xparname, yparname in [ (axes_en, 'east_shift', 'north_shift'), (axes_dn, 'depth', 'north_shift'), (axes_ed, 'east_shift', 'depth')]: ixpar = problem.name_to_index(xparname) iypar = problem.name_to_index(yparname) xpar = problem.combined[ixpar] ypar = problem.combined[iypar] xmin, xmax = fixlim(*xpar.scaled(bounds[ixpar])) ymin, ymax = fixlim(*ypar.scaled(bounds[iypar])) try: axes.set_facecolor(mpl_color('aluminium1')) except AttributeError: axes.patch.set_facecolor(mpl_color('aluminium1')) rect = patches.Rectangle( (xmin, ymin), xmax-xmin, ymax-ymin, facecolor=mpl_color('white'), edgecolor=mpl_color('aluminium2')) axes.add_patch(rect) # fxs = xpar.scaled(problem.extract(models, ixpar)) # fys = ypar.scaled(problem.extract(models, iypar)) # axes.set_xlim(*fixlim(num.min(fxs), num.max(fxs))) # axes.set_ylim(*fixlim(num.min(fys), num.max(fys))) cmap = cm.ScalarMappable( norm=colors.PowerNorm( gamma=self.normalisation_gamma, vmin=iorder.min(), vmax=iorder.max()), cmap=plt.get_cmap('coolwarm')) for ix, x in enumerate(models): source = problem.get_source(x) mt = source.pyrocko_moment_tensor( store=problem.get_gf_store(problem.targets[0]), target=problem.targets[0]) fx = problem.extract(x, ixpar) fy = problem.extract(x, iypar) sx, sy = xpar.scaled(fx), ypar.scaled(fy) # TODO: Add rotation in cross-sections color = cmap.to_rgba(iorder[ix]) alpha = (iorder[ix] - iorder.min()) / \ float(iorder.max() - iorder.min()) alpha = alpha**self.normalisation_gamma try: beachball.plot_beachball_mpl( mt, axes, beachball_type=beachball_type, position=(sx, sy), size=scale_size(source), color_t=color, color_p=color if color_p_axis else 'white', alpha=alpha, zorder=1, linewidth=0.25) except beachball.BeachballError as e: logger.warn(str(e)) item = PlotItem(name='main') return [[item, fig]]
def draw_figures(self): item = PlotItem(name='gf_shakemap') return [[item]]
def draw_figures(self, problem, dataset, history): target_index = {} i = 0 for target in problem.targets: target_index[target] = i, i + target.nmisfits i += target.nmisfits misfits = history.misfits[history.get_sorted_misfits_idx(), ...] gcms = problem.combine_misfits(misfits[:1, :, :], get_contributions=True)[0, :] models = history.get_sorted_primary_models()[::-1] origin = problem.base_source targets = [ t for t in problem.targets if isinstance(t, PhasePickTarget) ] ntargets = len(targets) nmodels = history.nmodels tts = num.zeros((nmodels, ntargets, 2)) sdata = [] for imodel in range(nmodels): model = models[imodel, :] source = problem.get_source(model) sdata.append( (origin.distance_to(source), origin.azibazi_to(source)[0])) results = problem.evaluate(model, targets=targets) for itarget, result in enumerate(results): result = results[itarget] tts[imodel, itarget, :] = result.tobs, result.tsyn ok = num.all(num.isfinite(tts), axis=2) ok = num.all(ok, axis=0) targets_ok = [ target for (itarget, target) in enumerate(targets) if ok[itarget] ] tts = tts[:, ok, :] residuals = tts[:, :, 0] - tts[:, :, 1] mean_residuals = num.mean(residuals, axis=0) rlo, rhi = num.percentile(mean_residuals, [10., 90.]) residual_amax = max(abs(rlo), abs(rhi)) target_to_residual = dict( (target, residual) for (target, residual) in zip(targets_ok, mean_residuals)) cg_to_targets = meta.gather(targets, lambda t: (t.path, )) cgs = sorted(cg_to_targets.keys()) for cg in cgs: cg_str = '.'.join(cg) targets = cg_to_targets[cg] if len(targets) == 0: continue assert all(target_index[target][0] == target_index[target][1] - 1 for target in targets) itargets = num.array( [target_index[target][0] for target in targets]) labels = ['.'.join(x for x in t.codes[:3] if x) for t in targets] azimuths = num.array([origin.azibazi_to(t)[0] for t in targets]) distances = num.array([t.distance_to(origin) for t in targets]) residuals = num.array( [target_to_residual.get(t, num.nan) for t in targets]) item = PlotItem( name='picks_contributions_%s' % cg_str, title=u'Pick residuals and contributions (%s)' % cg_str, description=u'\n\nMarkers are scaled according to their ' u'misfit contribution for the globally best ' u'source model.') fig, axes, legend = self.plot_station_distribution( azimuths, distances, gcms[itargets], labels, colors=residuals, cnorm=(-residual_amax, residual_amax), cmap='RdYlBu', clabel='$T_{obs} - T_{syn}$ [s]', scatter_kwargs=dict(alpha=1.0), legend_title='Contribution') sources = [problem.get_source(x) for x in models[::10]] azimuths = num.array([origin.azibazi_to(s)[0] for s in sources]) distances = num.array([s.distance_to(origin) for s in sources]) axes.plot(azimuths * d2r, distances, 'o', ms=2.0, color='black', alpha=0.3) yield (item, fig)
def draw_figures(self, history): from matplotlib import colors color = 'black' fontsize = self.font_size markersize = fontsize * 1.5 beachballsize_small = markersize * 0.5 beachball_type = self.beachball_type problem = history.problem fig = plt.figure(figsize=self.size_inch) axes_en = fig.add_subplot(2, 2, 1) axes_dn = fig.add_subplot(2, 2, 2) axes_ed = fig.add_subplot(2, 2, 3) bounds = problem.get_combined_bounds() gms = problem.combine_misfits(history.misfits) isort = num.argsort(gms)[::-1] gms = gms[isort] models = history.models[isort, :] iorder = num.arange(history.nmodels) for axes, xparname, yparname in [(axes_en, 'east_shift', 'north_shift'), (axes_dn, 'depth', 'north_shift'), (axes_ed, 'east_shift', 'depth')]: ixpar = problem.name_to_index(xparname) iypar = problem.name_to_index(yparname) xpar = problem.combined[ixpar] ypar = problem.combined[iypar] axes.set_xlabel(xpar.get_label()) axes.set_ylabel(ypar.get_label()) xmin, xmax = fixlim(*xpar.scaled(bounds[ixpar])) ymin, ymax = fixlim(*ypar.scaled(bounds[iypar])) axes.set_aspect(1.0) axes.set_xlim(xmin, xmax) axes.set_ylim(ymin, ymax) # fxs = xpar.scaled(problem.extract(models, ixpar)) # fys = ypar.scaled(problem.extract(models, iypar)) # axes.set_xlim(*fixlim(num.min(fxs), num.max(fxs))) # axes.set_ylim(*fixlim(num.min(fys), num.max(fys))) cmap = cm.ScalarMappable(norm=colors.Normalize( vmin=num.min(iorder), vmax=num.max(iorder)), cmap=plt.get_cmap('coolwarm')) for ix, x in enumerate(models): source = problem.get_source(x) mt = source.pyrocko_moment_tensor() fx = problem.extract(x, ixpar) fy = problem.extract(x, iypar) sx, sy = xpar.scaled(fx), ypar.scaled(fy) color = cmap.to_rgba(iorder[ix]) alpha = (iorder[ix] - num.min(iorder)) / \ float(num.max(iorder) - num.min(iorder)) try: beachball.plot_beachball_mpl(mt, axes, beachball_type=beachball_type, position=(sx, sy), size=beachballsize_small, color_t=color, alpha=alpha, zorder=1, linewidth=0.25) except beachball.BeachballError as e: logger.warn(str(e)) item = PlotItem(name='main', title='Moment Tensor Location') return [[item, fig]]
def draw_figures(self, history): color = 'black' fontsize = self.font_size markersize = fontsize * 1.5 markersize_small = markersize * 0.2 beachballsize = markersize beachballsize_small = beachballsize * 0.5 beachball_type = self.beachball_type problem = history.problem best_source = history.get_best_source() mean_source = history.get_mean_source() fig = plt.figure(figsize=self.size_inch) axes = fig.add_subplot(1, 1, 1) data = [] for ix, x in enumerate(history.models): source = problem.get_source(x) mt = source.pyrocko_moment_tensor() u, v = hudson.project(mt) if random.random() < 0.1: try: beachball.plot_beachball_mpl( mt, axes, beachball_type=beachball_type, position=(u, v), size=beachballsize_small, color_t=color, alpha=0.5, zorder=1, linewidth=0.25) except beachball.BeachballError as e: logger.warn(str(e)) else: data.append((u, v)) if data: u, v = num.array(data).T axes.plot( u, v, 'o', color=color, ms=markersize_small, mec='none', mew=0, alpha=0.25, zorder=0) hudson.draw_axes(axes) mt = mean_source.pyrocko_moment_tensor() u, v = hudson.project(mt) try: beachball.plot_beachball_mpl( mt, axes, beachball_type=beachball_type, position=(u, v), size=beachballsize, color_t=color, zorder=2, linewidth=0.5) except beachball.BeachballError as e: logger.warn(str(e)) mt = best_source.pyrocko_moment_tensor() u, v = hudson.project(mt) axes.plot( u, v, 's', markersize=markersize, mew=1, mec='black', mfc='none', zorder=-2) if self.show_reference: mt = problem.base_source.pyrocko_moment_tensor() u, v = hudson.project(mt) try: beachball.plot_beachball_mpl( mt, axes, beachball_type=beachball_type, position=(u, v), size=beachballsize, color_t='red', zorder=2, linewidth=0.5) except beachball.BeachballError as e: logger.warn(str(e)) item = PlotItem( name='main') return [[item, fig]]
def draw_figures(self, ds, history, optimiser): show_mean_residuals = False # gms = history.get_sorted_primary_misfits()[::-1] models = history.get_sorted_primary_models()[::-1] problem = history.problem targets = [ t for t in problem.targets if isinstance(t, PhasePickTarget) ] # targets.sort(key=lambda t: t.distance_to(problem.base_source)) # tpaths = sorted(set(t.path for t in targets)) ntargets = len(targets) nmodels = history.nmodels tts = num.zeros((nmodels, ntargets, 2)) distances = num.zeros((nmodels, ntargets)) azimuths = num.zeros((nmodels, ntargets)) for imodel in range(nmodels): model = models[imodel, :] source = problem.get_source(model) results = problem.evaluate(model, targets=targets) for itarget, result in enumerate(results): result = results[itarget] tts[imodel, itarget, :] = result.tobs, result.tsyn distances[imodel, itarget] = source.distance_to(targets[itarget]) azimuths[imodel, itarget] = source.azibazi_to(targets[itarget])[0] ok = num.all(num.isfinite(tts), axis=2) ok = num.all(ok, axis=0) targets = [ target for (itarget, target) in enumerate(targets) if ok[itarget] ] tts = tts[:, ok, :] distances = distances[:, ok] azimuths = azimuths[:, ok] residuals = tts[:, :, 0] - tts[:, :, 1] residual_amax = num.max(num.abs(residuals)) mean_residuals = num.mean(residuals, axis=0) mean_distances = num.mean(distances, axis=0) isort = num.array([ x[2] for x in sorted(zip(targets, mean_distances, range(len(targets))), key=lambda x: (x[0].path, x[1])) ], dtype=num.int) distances = distances[:, isort] distance_min = num.min(distances) distance_max = num.max(distances) azimuths = azimuths[:, isort] targets = [targets[i] for i in isort] ntargets = len(targets) residuals = residuals[:, isort] mean_residuals = mean_residuals[isort] icolor = num.arange(nmodels) norm = mcolors.Normalize(vmin=num.min(icolor), vmax=num.max(icolor)) cmap = plt.get_cmap('coolwarm') napprox = max(1, int(round( (self.size_points[1] / self.font_size - 7)))) npages = (ntargets - 1) // napprox + 1 ntargets_page = (ntargets - 1) // npages + 1 for ipage in range(npages): ilo, ihi = ipage * ntargets_page, (ipage + 1) * ntargets_page ihi = min(len(targets), ihi) targets_page = targets[ilo:ihi] item = PlotItem(name='fig_%02i' % ipage) item.attributes['targets'] = [t.string_id() for t in targets_page] fig = plt.figure(figsize=self.size_inch) labelpos = mpl_margins(fig, nw=2, nh=1, left=12., right=1., bottom=5., top=1., wspace=1., units=self.font_size) axes1 = fig.add_subplot(1, 3, 1) axes2 = fig.add_subplot(1, 3, 2) axes3 = fig.add_subplot(1, 3, 3) for axes in (axes1, axes2, axes3): axes.set_ylim(-0.5, len(targets_page) - 0.5) axes.invert_yaxis() labelpos(axes, 2.5, 2.0) axes1.axvline(0.0, color='black') labels = [] lastpath = None for ipos, t in enumerate(targets_page): scodes = '.'.join(t.codes) if lastpath is None or lastpath != t.path: labels.append(t.path + '.' + scodes) if lastpath is not None: for axes in (axes1, axes2, axes3): axes.axhline(ipos - 0.5, color='black') else: labels.append(scodes) lastpath = t.path for ipos, itarget in enumerate(range(ilo, ihi)): axes1.plot(residuals[-1, itarget], ipos, '|', ms=self.font_size, color='black') if show_mean_residuals: axes1.plot(mean_residuals[itarget], ipos, 's', ms=self.font_size, color='none', mec='black') axes1.scatter(residuals[::10, itarget], util.num_full(icolor[::10].size, ipos, dtype=num.float), c=icolor[::10], cmap=cmap, norm=norm, alpha=0.5) axes2.scatter(distances[::10, itarget] / km, util.num_full(icolor[::10].size, ipos, dtype=num.float), c=icolor[::10], cmap=cmap, norm=norm, alpha=0.5) axes3.scatter(azimuths[::10, itarget], util.num_full(icolor[::10].size, ipos, dtype=num.float), c=icolor[::10], cmap=cmap, norm=norm, alpha=0.5) axes1.set_yticks(num.arange(len(labels))) axes1.set_yticklabels(labels) axes1.set_xlabel('$T_{obs} - T_{syn}$ [s]') axes1.set_xlim(-residual_amax, residual_amax) axes2.set_xlabel('Distance [km]') axes2.set_xlim(distance_min / km, distance_max / km) axes3.set_xlabel('Azimuth [deg]') axes3.set_xlim(-180., 180.) axes2.get_yaxis().set_ticks([]) axes2.get_yaxis().set_ticks([]) axes3.get_yaxis().set_ticks([]) axes3.get_yaxis().set_ticks([]) yield item, fig
def draw_figures(self, problem, dataset, history): target_index = {} i = 0 for target in problem.targets: target_index[target] = i, i+target.nmisfits i += target.nmisfits ws = problem.get_target_weights() if history: misfits = history.misfits[history.get_sorted_misfits_idx(), ...] gcms = problem.combine_misfits( misfits[:1, :, :], get_contributions=True)[0, :] event = problem.base_source cg_to_targets = meta.gather( problem.waveform_targets, lambda t: (t.path, t.codes[3])) cgs = sorted(cg_to_targets.keys()) for cg in cgs: cg_str = '.'.join(cg) targets = cg_to_targets[cg] if len(targets) == 0: continue assert all(target_index[target][0] == target_index[target][1] - 1 for target in targets) itargets = num.array( [target_index[target][0] for target in targets]) labels = ['.'.join(x for x in t.codes[:3] if x) for t in targets] azimuths = num.array([event.azibazi_to(t)[0] for t in targets]) distances = num.array([t.distance_to(event) for t in targets]) item = PlotItem( name='seismic_stations_weights_%s' % cg_str, title=u'Station weights (%s)' % cg_str, description=u'\n\nMarkers are scaled according to the ' u'weighting factor of the corresponding target\'s ' u'contribution in the misfit function.') fig, ax, legend = self.plot_station_distribution( azimuths, distances, ws[itargets], labels) legend.set_title( 'Weight', prop=dict(size=self.font_size)) yield (item, fig) if history: item = PlotItem( name='seismic_stations_contributions_%s' % cg_str, title=u'Station misfit contributions (%s)' % cg_str, description=u'\n\nMarkers are scaled according to their ' u'misfit contribution for the globally best ' u'source model.') fig, ax, legend = self.plot_station_distribution( azimuths, distances, gcms[itargets], labels) legend.set_title( 'Contribution', prop=dict(size=self.font_size)) yield (item, fig)
def draw_figures(self, dataset, history, optimiser): fontsize = self.font_size fig = plt.figure(figsize=self.size_inch) labelpos = mpl_margins(fig, nw=2, nh=2, w=7., h=5., wspace=2., hspace=5., units=fontsize) problem = history.problem if not problem: logger.warn('Problem not set.') return [] models = history.models if models.size == 0: logger.warn('Empty models vector.') return [] for target in problem.targets: target.set_dataset(dataset) imodels = num.arange(history.nmodels) gms = history.get_sorted_primary_misfits()[::-1] isort = history.get_sorted_misfits_idx(chain=0)[::-1] gms **= problem.norm_exponent gms_softclip = num.where(gms > 1.0, 0.1 * num.log10(gms) + 1.0, gms) gcms = problem.combine_misfits( history.misfits, extra_correlated_weights=optimiser.get_correlated_weights(problem), get_contributions=True) gcms = gcms[isort, :] nmisfits = gcms.shape[1] # noqa ncontributions = sum([ 1 if t.plot_misfits_cumulative else t.nmisfits for t in problem.targets ]) cum_gcms = num.zeros((history.nmodels, ncontributions)) # Squash matrix and sum large targets.nmisifts, eg SatelliteTarget plot_target_labels = [] idx = 0 idx_cum = 0 for itarget, target in enumerate(problem.targets): target_gcms = gcms[:, idx:idx + target.nmisfits] if target.plot_misfits_cumulative: cum_gcms[:, idx_cum] = target_gcms.sum(axis=1) plot_target_labels.append(target.string_id()) idx_cum += 1 else: cum_gcms[:, idx_cum:idx_cum + target.nmisfits] = target_gcms plot_target_labels.extend(target.misfits_string_ids()) idx_cum += target.nmisfits idx += target.nmisfits jsort = num.argsort(cum_gcms[-1, :])[::-1] # ncols = 4 # nrows = ((problem.ntargets + 1) - 1) / ncols + 1 axes = fig.add_subplot(2, 2, 1) labelpos(axes, 2.5, 2.0) axes.set_ylabel('Relative contribution (smoothed)') axes.set_ylim(0.0, 1.0) axes2 = fig.add_subplot(2, 2, 3, sharex=axes) labelpos(axes2, 2.5, 2.0) axes2.set_xlabel( 'Tested model, sorted descending by global misfit value') axes2.set_ylabel('Square of misfit') axes2.set_ylim(0., 1.5) axes2.axhspan(1.0, 1.5, color=(0.8, 0.8, 0.8)) axes2.set_yticks( [0., 0.2, 0.4, 0.6, 0.8, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5]) axes2.set_yticklabels([ '0.0', '0.2', '0.4', '0.6', '0.8', '1', '10', '100', '1000', '10000', '100000' ]) axes2.set_xlim(imodels[0], imodels[-1]) rel_ms_sum = num.zeros(history.nmodels) rel_ms_smooth_sum = num.zeros(history.nmodels) ms_smooth_sum = num.zeros(history.nmodels) b = num.hanning(min(100, history.nmodels // 5)) b /= num.sum(b) a = [1] ii = 0 for idx in jsort: target_label = plot_target_labels[idx] ms = cum_gcms[:, idx] ms = num.where(num.isfinite(ms), ms, 0.0) if num.all(ms == 0.0): continue rel_ms = ms / gms if b.shape[0] > 5: rel_ms_smooth = signal.filtfilt(b, a, rel_ms) else: rel_ms_smooth = rel_ms ms_smooth = rel_ms_smooth * gms_softclip rel_poly_y = num.concatenate( [rel_ms_smooth_sum[::-1], rel_ms_smooth_sum + rel_ms_smooth]) poly_x = num.concatenate([imodels[::-1], imodels]) add_args = {} if ii < 20: add_args['label'] = '%s (%.2g)' % (target_label, num.mean(rel_ms[-1])) axes.fill(poly_x, rel_poly_y, alpha=0.5, color=mpl_graph_color(ii), **add_args) poly_y = num.concatenate( [ms_smooth_sum[::-1], ms_smooth_sum + ms_smooth]) axes2.fill(poly_x, poly_y, alpha=0.5, color=mpl_graph_color(ii)) rel_ms_sum += rel_ms # axes.plot( # imodels, rel_ms_sum, color='black', alpha=0.1, zorder=-1) ms_smooth_sum += ms_smooth rel_ms_smooth_sum += rel_ms_smooth ii += 1 axes.legend(title='Contributions (top twenty)', bbox_to_anchor=(1.05, 0.0, 1.0, 1.0), loc='upper left', ncol=1, borderaxespad=0., prop={'size': 9}) axes2.plot(imodels, gms_softclip, color='black') axes2.axhline(1.0, color=(0.5, 0.5, 0.5)) return [[PlotItem(name='main'), fig]]
def draw_figures(self, ds, history, optimiser): color_parameter = self.color_parameter misfit_cutoff = self.misfit_cutoff fontsize = self.font_size fontsize_title = self.font_size_title nxmax = self.nx nymax = self.ny problem = history.problem for target in problem.targets: target.set_dataset(ds) target_index = {} i = 0 for target in problem.targets: target_index[target] = i, i+target.nmisfits i += target.nmisfits gms = history.get_sorted_primary_misfits()[::-1] models = history.get_sorted_primary_models()[::-1] if misfit_cutoff is not None: ibest = gms < misfit_cutoff gms = gms[ibest] models = models[ibest] gms = gms[::10] models = models[::10] nmodels = models.shape[0] if color_parameter == 'dist': mx = num.mean(models, axis=0) cov = num.cov(models.T) mdists = core.mahalanobis_distance(models, mx, cov) icolor = meta.ordersort(mdists) elif color_parameter == 'misfit': iorder = num.arange(nmodels) icolor = iorder elif color_parameter in problem.parameter_names: ind = problem.name_to_index(color_parameter) icolor = problem.extract(models, ind) target_to_results = defaultdict(list) all_syn_trs = [] dtraces = [] for imodel in range(nmodels): model = models[imodel, :] source = problem.get_source(model) results = problem.evaluate(model) dtraces.append([]) for target, result in zip(problem.targets, results): w = target.get_combined_weight() if isinstance(result, gf.SeismosizerError) or \ not isinstance(target, WaveformMisfitTarget) or \ not num.all(num.isfinite(w)): dtraces[-1].extend([None] * target.nmisfits) continue itarget, itarget_end = target_index[target] assert itarget_end == itarget + 1 if target.misfit_config.domain == 'cc_max_norm': tref = ( result.filtered_obs.tmin + result.filtered_obs.tmax) \ * 0.5 for tr_filt, tr_proc, tshift in ( (result.filtered_obs, result.processed_obs, 0.), (result.filtered_syn, result.processed_syn, result.tshift)): norm = num.sum(num.abs(tr_proc.ydata)) \ / tr_proc.data_len() tr_filt.ydata /= norm tr_proc.ydata /= norm tr_filt.shift(tshift) tr_proc.shift(tshift) ctr = result.cc ctr.shift(tref) dtrace = ctr else: for tr in ( result.filtered_obs, result.filtered_syn, result.processed_obs, result.processed_syn): tr.ydata *= w if result.tshift is not None and result.tshift != 0.0: # result.filtered_syn.shift(result.tshift) result.processed_syn.shift(result.tshift) dtrace = make_norm_trace( result.processed_syn, result.processed_obs, problem.norm_exponent) target_to_results[target].append(result) dtrace.meta = dict( normalisation_family=target.normalisation_family, path=target.path) dtraces[-1].append(dtrace) result.processed_syn.meta = dict( normalisation_family=target.normalisation_family, path=target.path) all_syn_trs.append(result.processed_syn) if not all_syn_trs: logger.warn('No traces to show!') return def skey(tr): return tr.meta['normalisation_family'], tr.meta['path'] trace_minmaxs = trace.minmax(all_syn_trs, skey) dtraces_all = [] for dtraces_group in dtraces: dtraces_all.extend(dtraces_group) dminmaxs = trace.minmax([ dtrace_ for dtrace_ in dtraces_all if dtrace_ is not None], skey) for tr in dtraces_all: if tr: dmin, dmax = dminmaxs[skey(tr)] tr.ydata /= max(abs(dmin), abs(dmax)) cg_to_targets = meta.gather( problem.waveform_targets, lambda t: (t.path, t.codes[3]), filter=lambda t: t in target_to_results) cgs = sorted(cg_to_targets.keys()) from matplotlib import colors cmap = cm.ScalarMappable( norm=colors.Normalize(vmin=num.min(icolor), vmax=num.max(icolor)), cmap=plt.get_cmap('coolwarm')) imodel_to_color = [] for imodel in range(nmodels): imodel_to_color.append(cmap.to_rgba(icolor[imodel])) for cg in cgs: targets = cg_to_targets[cg] frame_to_target, nx, ny, nxx, nyy = layout( source, targets, nxmax, nymax) figures = {} for iy in range(ny): for ix in range(nx): if (iy, ix) not in frame_to_target: continue ixx = ix // nxmax iyy = iy // nymax if (iyy, ixx) not in figures: title = '_'.join(x for x in cg if x) item = PlotItem( name='fig_%s_%i_%i' % (title, ixx, iyy)) item.attributes['targets'] = [] figures[iyy, ixx] = ( item, plt.figure(figsize=self.size_inch)) figures[iyy, ixx][1].subplots_adjust( left=0.03, right=1.0 - 0.03, bottom=0.03, top=1.0 - 0.06, wspace=0.2, hspace=0.2) item, fig = figures[iyy, ixx] target = frame_to_target[iy, ix] item.attributes['targets'].append(target.string_id()) amin, amax = trace_minmaxs[ target.normalisation_family, target.path] absmax = max(abs(amin), abs(amax)) ny_this = nymax # min(ny, nymax) nx_this = nxmax # min(nx, nxmax) i_this = (iy % ny_this) * nx_this + (ix % nx_this) + 1 axes2 = fig.add_subplot(ny_this, nx_this, i_this) space = 0.5 space_factor = 1.0 + space axes2.set_axis_off() axes2.set_ylim(-1.05 * space_factor, 1.05) axes = axes2.twinx() axes.set_axis_off() if target.misfit_config.domain == 'cc_max_norm': axes.set_ylim(-10. * space_factor, 10.) else: axes.set_ylim(-absmax*1.33 * space_factor, absmax*1.33) itarget, itarget_end = target_index[target] assert itarget_end == itarget + 1 for imodel, result in enumerate(target_to_results[target]): syn_color = imodel_to_color[imodel] dtrace = dtraces[imodel][itarget] tap_color_annot = (0.35, 0.35, 0.25) tap_color_edge = (0.85, 0.85, 0.80) tap_color_fill = (0.95, 0.95, 0.90) plot_taper( axes2, result.processed_obs.get_xdata(), result.taper, fc=tap_color_fill, ec=tap_color_edge, alpha=0.2) obs_color = mpl_color('aluminium5') obs_color_light = light(obs_color, 0.5) plot_dtrace( axes2, dtrace, space, 0., 1., fc='none', ec=syn_color) # plot_trace( # axes, result.filtered_syn, # color=syn_color_light, lw=1.0) if imodel == 0: plot_trace( axes, result.filtered_obs, color=obs_color_light, lw=0.75) plot_trace( axes, result.processed_syn, color=syn_color, lw=1.0, alpha=0.3) plot_trace( axes, result.processed_obs, color=obs_color, lw=0.75, alpha=0.3) if imodel != 0: continue xdata = result.filtered_obs.get_xdata() axes.set_xlim(xdata[0], xdata[-1]) tmarks = [ result.processed_obs.tmin, result.processed_obs.tmax] for tmark in tmarks: axes2.plot( [tmark, tmark], [-0.9, 0.1], color=tap_color_annot) dur = tmarks[1] - tmarks[0] for tmark, text, ha in [ (tmarks[0], '$\\,$ ' + meta.str_duration( tmarks[0] - source.time), 'left'), (tmarks[1], '$\\Delta$ ' + meta.str_duration( dur), 'right')]: axes2.annotate( text, xy=(tmark, -0.9), xycoords='data', xytext=( fontsize*0.4 * [-1, 1][ha == 'left'], fontsize*0.2), textcoords='offset points', ha=ha, va='bottom', color=tap_color_annot, fontsize=fontsize) axes2.set_xlim( tmarks[0] - dur*0.1, tmarks[1] + dur*0.1) scale_string = None if target.misfit_config.domain == 'cc_max_norm': scale_string = 'Syn/obs scales differ!' infos = [] if scale_string: infos.append(scale_string) if self.nx == 1 and self.ny == 1: infos.append(target.string_id()) else: infos.append('.'.join(x for x in target.codes if x)) dist = source.distance_to(target) azi = source.azibazi_to(target)[0] infos.append(meta.str_dist(dist)) infos.append(u'%.0f\u00B0' % azi) axes2.annotate( '\n'.join(infos), xy=(0., 1.), xycoords='axes fraction', xytext=(2., 2.), textcoords='offset points', ha='left', va='top', fontsize=fontsize, fontstyle='normal') if (self.nx == 1 and self.ny == 1): yield item, fig del figures[iyy, ixx] if not (self.nx == 1 and self.ny == 1): for (iyy, ixx), (_, fig) in figures.items(): title = '.'.join(x for x in cg if x) if len(figures) > 1: title += ' (%i/%i, %i/%i)' % (iyy+1, nyy, ixx+1, nxx) fig.suptitle(title, fontsize=fontsize_title) for item, fig in figures.values(): yield item, fig
def draw_figures(self, history, optimiser): misfit_cutoff = self.misfit_cutoff sort_by = self.sort_by problem = history.problem models = history.models npar = problem.nparameters ndep = problem.ndependants fontsize = self.font_size nfx, nfy = self.subplot_layout imodels = num.arange(history.nmodels) bounds = problem.get_combined_bounds() xref = problem.get_reference_model() gms = history.get_primary_chain_misfits() gms_softclip = num.where(gms > 1.0, 0.2 * num.log10(gms) + 1.0, gms) isort = num.argsort(gms)[::-1] if sort_by == 'iteration': imodels = imodels[isort] elif sort_by == 'misfit': imodels = num.arange(imodels.size) else: assert False gms = gms[isort] gms_softclip = gms_softclip[isort] models = models[isort, :] iorder = num.empty_like(isort) iorder = num.arange(iorder.size) if misfit_cutoff is None: ibest = num.ones(gms.size, dtype=num.bool) else: ibest = gms < misfit_cutoff def config_axes(axes, nfx, nfy, impl, iplot, nplots): if (impl - 1) % nfx != nfx - 1: axes.get_yaxis().tick_left() if (impl - 1) >= (nfx * (nfy - 1)) or iplot >= nplots - nfx: axes.set_xlabel('Iteration') if not (impl - 1) // nfx == 0: axes.get_xaxis().tick_bottom() elif (impl - 1) // nfx == 0: axes.get_xaxis().tick_top() axes.set_xticklabels([]) else: axes.get_xaxis().set_visible(False) # nfz = (npar + ndep + 1 - 1) / (nfx*nfy) + 1 cmap = cm.YlOrRd cmap = cm.jet msize = self.marker_size axes = None fig = None item_fig = None nfigs = 0 alpha = 0.5 for ipar in range(npar): impl = ipar % (nfx * nfy) + 1 if impl == 1: if item_fig: yield item_fig nfigs += 1 fig = plt.figure(figsize=self.size_inch) labelpos = mpl_margins(fig, nw=nfx, nh=nfy, left=7., right=2., top=1., bottom=5., wspace=7., hspace=2., units=fontsize) item = PlotItem(name='fig_%i' % (nfigs + 1)) item.attributes['parameters'] = [] item_fig = (item, fig) par = problem.parameters[ipar] item_fig[0].attributes['parameters'].append(par.name) axes = fig.add_subplot(nfy, nfx, impl) labelpos(axes, 2.5, 2.0) axes.set_ylabel(par.get_label()) axes.get_yaxis().set_major_locator(plt.MaxNLocator(4)) config_axes(axes, nfx, nfy, impl, ipar, npar + ndep + 1) axes.set_ylim(*fixlim(*par.scaled(bounds[ipar]))) axes.set_xlim(0, history.nmodels) axes.scatter(imodels[ibest], par.scaled(models[ibest, ipar]), s=msize, c=iorder[ibest], edgecolors='none', cmap=cmap, alpha=alpha, rasterized=True) if self.show_reference: axes.axhline(par.scaled(xref[ipar]), color='black', alpha=0.3) for idep in range(ndep): # ifz, ify, ifx = num.unravel_index(ipar, (nfz, nfy, nfx)) impl = (npar + idep) % (nfx * nfy) + 1 if impl == 1: if item_fig: yield item_fig nfigs += 1 fig = plt.figure(figsize=self.size_inch) labelpos = mpl_margins(fig, nw=nfx, nh=nfy, left=7., right=2., top=1., bottom=5., wspace=7., hspace=2., units=fontsize) item = PlotItem(name='fig_%i' % (nfigs + 1)) item.attributes['parameters'] = [] item_fig = (item, fig) par = problem.dependants[idep] item_fig[0].attributes['parameters'].append(par.name) axes = fig.add_subplot(nfy, nfx, impl) labelpos(axes, 2.5, 2.0) axes.set_ylabel(par.get_label()) axes.get_yaxis().set_major_locator(plt.MaxNLocator(4)) config_axes(axes, nfx, nfy, impl, npar + idep, npar + ndep + 1) axes.set_ylim(*fixlim(*par.scaled(bounds[npar + idep]))) axes.set_xlim(0, history.nmodels) ys = problem.make_dependant(models[ibest, :], par.name) axes.scatter(imodels[ibest], par.scaled(ys), s=msize, c=iorder[ibest], edgecolors='none', cmap=cmap, alpha=alpha, rasterized=True) if self.show_reference: y = problem.make_dependant(xref, par.name) axes.axhline(par.scaled(y), color='black', alpha=0.3) impl = (npar + ndep) % (nfx * nfy) + 1 if impl == 1: if item_fig: yield item_fig nfigs += 1 fig = plt.figure(figsize=self.size_inch) labelpos = mpl_margins(fig, nw=nfx, nh=nfy, left=7., right=2., top=1., bottom=5., wspace=7., hspace=2., units=fontsize) item = PlotItem(name='fig_%i' % (nfigs + 1)) item.attributes['parameters'] = [] item_fig = (item, fig) axes = fig.add_subplot(nfy, nfx, impl) labelpos(axes, 2.5, 2.0) config_axes(axes, nfx, nfy, impl, npar + ndep, npar + ndep + 1) axes.set_ylim(0., 1.5) axes.set_yticks([0., 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4]) axes.set_yticklabels( ['0.0', '0.2', '0.4', '0.6', '0.8', '1', '10', '100']) axes.scatter(imodels[ibest], gms_softclip[ibest], c=iorder[ibest], s=msize, edgecolors='none', cmap=cmap, alpha=alpha) axes.axhspan(1.0, 1.5, color=(0.8, 0.8, 0.8), alpha=0.2) axes.axhline(1.0, color=(0.5, 0.5, 0.5), zorder=2) axes.set_xlim(0, history.nmodels) axes.set_xlabel('Iteration') axes.set_ylabel('Misfit') yield item_fig nfigs += 1
def plot_gnss(gnss_target, result, ifig, vertical=False): campaign = gnss_target.campaign item = PlotItem( name='fig_%i' % ifig, attributes={'targets': gnss_target.path}, title=u'Static GNSS Surface Displacements - Campaign %s' % campaign.name, description=u''' Static surface displacement from GNSS campaign %s (black vectors) and displacements derived from best model (red). ''' % campaign.name) event = source.pyrocko_event() locations = campaign.stations + [event] lat, lon = od.geographic_midpoint_locations(locations) if self.radius is None: coords = num.array([loc.effective_latlon for loc in locations]) radius = od.distance_accurate50m_numpy(lat[num.newaxis], lon[num.newaxis], coords[:, 0].max(), coords[:, 1]).max() radius *= 1.1 if radius < 30. * km: logger.warn('Radius of GNSS campaign %s too small, defaulting' ' to 30 km' % campaign.name) radius = 30 * km model_camp = gnss.GNSSCampaign(stations=copy.deepcopy( campaign.stations), name='grond model') for ista, sta in enumerate(model_camp.stations): sta.north.shift = result.statics_syn['displacement.n'][ista] sta.north.sigma = 0. sta.east.shift = result.statics_syn['displacement.e'][ista] sta.east.sigma = 0. if sta.up: sta.up.shift = -result.statics_syn['displacement.d'][ista] sta.up.sigma = 0. m = automap.Map(width=self.size_cm[0], height=self.size_cm[1], lat=lat, lon=lon, radius=radius, show_topo=self.show_topo, show_grid=self.show_grid, show_rivers=self.show_rivers, color_wet=(216, 242, 254), color_dry=(238, 236, 230)) all_stations = campaign.stations + model_camp.stations offset_scale = num.zeros(len(all_stations)) for ista, sta in enumerate(all_stations): for comp in sta.components.values(): offset_scale[ista] += comp.shift offset_scale = num.sqrt(offset_scale**2).max() m.add_gnss_campaign(campaign, psxy_style={ 'G': 'black', 'W': '0.8p,black', }, offset_scale=offset_scale, vertical=vertical) m.add_gnss_campaign(model_camp, psxy_style={ 'G': 'red', 'W': '0.8p,red', 't': 30, }, offset_scale=offset_scale, vertical=vertical, labels=False) if isinstance(problem, CMTProblem) \ or isinstance(problem, VLVDProblem): from pyrocko import moment_tensor from pyrocko.plot import gmtpy mt = event.moment_tensor.m_up_south_east() ev_lat, ev_lon = event.effective_latlon xx = num.trace(mt) / 3. mc = num.matrix([[xx, 0., 0.], [0., xx, 0.], [0., 0., xx]]) mc = mt - mc mc = mc / event.moment_tensor.scalar_moment() * \ moment_tensor.magnitude_to_moment(5.0) m6 = tuple(moment_tensor.to6(mc)) symbol_size = 20. m.gmt.psmeca(S='%s%g' % ('d', symbol_size / gmtpy.cm), in_rows=[(ev_lon, ev_lat, 10) + m6 + (1, 0, 0)], M=True, *m.jxyr) elif isinstance(problem, RectangularProblem): m.gmt.psxy(in_rows=source.outline(cs='lonlat'), L='+p2p,black', W='1p,black', G='black', t=60, *m.jxyr) elif isinstance(problem, VolumePointProblem): ev_lat, ev_lon = event.effective_latlon dV = abs(source.volume_change) sphere_radius = num.cbrt(dV / (4. / 3. * num.pi)) volcanic_circle = [ev_lon, ev_lat, '%fe' % sphere_radius] m.gmt.psxy(S='E-', in_rows=[volcanic_circle], W='1p,black', G='orange3', *m.jxyr) return (item, m)
def draw_figures(self, ds, history): fontsize = self.font_size fontsize_title = self.font_size_title problem = history.problem for target in problem.targets: target.set_dataset(ds) target_index = dict( (target, i) for (i, target) in enumerate(problem.targets)) gms = problem.combine_misfits(history.misfits) isort = num.argsort(gms) gms = gms[isort] models = history.models[isort, :] misfits = history.misfits[isort, :] xbest = models[0, :] ws = problem.get_target_weights() gcms = problem.combine_misfits(misfits[:1, :, :], get_contributions=True)[0, :] w_max = num.nanmax(ws) gcm_max = num.nanmax(gcms) source = problem.get_source(xbest) target_to_result = {} all_syn_trs = [] all_syn_specs = [] results = problem.evaluate(xbest) dtraces = [] for target, result in zip(problem.targets, results): if not isinstance(result, WaveformMisfitResult): dtraces.append(None) continue itarget = target_index[target] w = target.get_combined_weight() if target.misfit_config.domain == 'cc_max_norm': tref = (result.filtered_obs.tmin + result.filtered_obs.tmax) * 0.5 for tr_filt, tr_proc, tshift in ((result.filtered_obs, result.processed_obs, 0.), (result.filtered_syn, result.processed_syn, result.tshift)): norm = num.sum(num.abs(tr_proc.ydata)) / tr_proc.data_len() tr_filt.ydata /= norm tr_proc.ydata /= norm tr_filt.shift(tshift) tr_proc.shift(tshift) ctr = result.cc ctr.shift(tref) dtrace = ctr else: for tr in (result.filtered_obs, result.filtered_syn, result.processed_obs, result.processed_syn): tr.ydata *= w for spec in (result.spectrum_obs, result.spectrum_syn): if spec is not None: spec.ydata *= w if result.tshift is not None and result.tshift != 0.0: # result.filtered_syn.shift(result.tshift) result.processed_syn.shift(result.tshift) dtrace = make_norm_trace(result.processed_syn, result.processed_obs, problem.norm_exponent) target_to_result[target] = result dtrace.meta = dict( normalisation_family=target.normalisation_family, path=target.path) dtraces.append(dtrace) result.processed_syn.meta = dict( normalisation_family=target.normalisation_family, path=target.path) all_syn_trs.append(result.processed_syn) if result.spectrum_syn: result.spectrum_syn.meta = dict( normalisation_family=target.normalisation_family, path=target.path) all_syn_specs.append(result.spectrum_syn) if not all_syn_trs: logger.warn('no traces to show') return [] def skey(tr): return tr.meta['normalisation_family'], tr.meta['path'] trace_minmaxs = trace.minmax(all_syn_trs, skey) amp_spec_maxs = amp_spec_max(all_syn_specs, skey) dminmaxs = trace.minmax([x for x in dtraces if x is not None], skey) for tr in dtraces: if tr: dmin, dmax = dminmaxs[skey(tr)] tr.ydata /= max(abs(dmin), abs(dmax)) cg_to_targets = meta.gather(problem.waveform_targets, lambda t: (t.path, t.codes[3]), filter=lambda t: t in target_to_result) cgs = sorted(cg_to_targets.keys()) figs = [] for cg in cgs: targets = cg_to_targets[cg] nframes = len(targets) nx = int(math.ceil(math.sqrt(nframes))) ny = (nframes - 1) // nx + 1 nxmax = 4 nymax = 4 nxx = (nx - 1) // nxmax + 1 nyy = (ny - 1) // nymax + 1 # nz = nxx * nyy xs = num.arange(nx) // ((max(2, nx) - 1.0) / 2.) ys = num.arange(ny) // ((max(2, ny) - 1.0) / 2.) xs -= num.mean(xs) ys -= num.mean(ys) fxs = num.tile(xs, ny) fys = num.repeat(ys, nx) data = [] for target in targets: azi = source.azibazi_to(target)[0] dist = source.distance_to(target) x = dist * num.sin(num.deg2rad(azi)) y = dist * num.cos(num.deg2rad(azi)) data.append((x, y, dist)) gxs, gys, dists = num.array(data, dtype=num.float).T iorder = num.argsort(dists) gxs = gxs[iorder] gys = gys[iorder] targets_sorted = [targets[ii] for ii in iorder] gxs -= num.mean(gxs) gys -= num.mean(gys) gmax = max(num.max(num.abs(gys)), num.max(num.abs(gxs))) if gmax == 0.: gmax = 1. gxs /= gmax gys /= gmax dists = num.sqrt((fxs[num.newaxis, :] - gxs[:, num.newaxis])**2 + (fys[num.newaxis, :] - gys[:, num.newaxis])**2) distmax = num.max(dists) availmask = num.ones(dists.shape[1], dtype=num.bool) frame_to_target = {} for itarget, target in enumerate(targets_sorted): iframe = num.argmin( num.where(availmask, dists[itarget], distmax + 1.)) availmask[iframe] = False iy, ix = num.unravel_index(iframe, (ny, nx)) frame_to_target[iy, ix] = target figures = {} for iy in range(ny): for ix in range(nx): if (iy, ix) not in frame_to_target: continue ixx = ix // nxmax iyy = iy // nymax if (iyy, ixx) not in figures: title = '_'.join(x for x in cg if x) item = PlotItem(name='fig_%s_%i_%i' % (title, ixx, iyy)) item.attributes['targets'] = [] figures[iyy, ixx] = (item, plt.figure(figsize=self.size_inch)) figures[iyy, ixx][1].subplots_adjust(left=0.03, right=1.0 - 0.03, bottom=0.03, top=1.0 - 0.06, wspace=0.2, hspace=0.2) figs.append(figures[iyy, ixx]) item, fig = figures[iyy, ixx] target = frame_to_target[iy, ix] item.attributes['targets'].append(target.string_id()) amin, amax = trace_minmaxs[target.normalisation_family, target.path] absmax = max(abs(amin), abs(amax)) ny_this = nymax # min(ny, nymax) nx_this = nxmax # min(nx, nxmax) i_this = (iy % ny_this) * nx_this + (ix % nx_this) + 1 axes2 = fig.add_subplot(ny_this, nx_this, i_this) space = 0.5 space_factor = 1.0 + space axes2.set_axis_off() axes2.set_ylim(-1.05 * space_factor, 1.05) axes = axes2.twinx() axes.set_axis_off() if target.misfit_config.domain == 'cc_max_norm': axes.set_ylim(-10. * space_factor, 10.) else: axes.set_ylim(-absmax * 1.33 * space_factor, absmax * 1.33) itarget = target_index[target] result = target_to_result[target] dtrace = dtraces[itarget] tap_color_annot = (0.35, 0.35, 0.25) tap_color_edge = (0.85, 0.85, 0.80) tap_color_fill = (0.95, 0.95, 0.90) plot_taper(axes2, result.processed_obs.get_xdata(), result.taper, fc=tap_color_fill, ec=tap_color_edge) obs_color = mpl_color('aluminium5') obs_color_light = light(obs_color, 0.5) syn_color = mpl_color('scarletred2') syn_color_light = light(syn_color, 0.5) misfit_color = mpl_color('scarletred2') weight_color = mpl_color('chocolate2') cc_color = mpl_color('aluminium5') if target.misfit_config.domain == 'cc_max_norm': tref = (result.filtered_obs.tmin + result.filtered_obs.tmax) * 0.5 plot_dtrace(axes2, dtrace, space, -1., 1., fc=light(cc_color, 0.5), ec=cc_color) plot_dtrace_vline(axes2, tref, space, color=tap_color_annot) elif target.misfit_config.domain == 'frequency_domain': asmax = amp_spec_maxs[target.normalisation_family, target.path] fmin, fmax = \ target.misfit_config.get_full_frequency_range() plot_spectrum(axes2, result.spectrum_syn, result.spectrum_obs, fmin, fmax, space, 0., asmax, syn_color=syn_color, obs_color=obs_color, syn_lw=1.0, obs_lw=0.75, color_vline=tap_color_annot, fontsize=fontsize) else: plot_dtrace(axes2, dtrace, space, 0., 1., fc=light(misfit_color, 0.3), ec=misfit_color) plot_trace(axes, result.filtered_syn, color=syn_color_light, lw=1.0) plot_trace(axes, result.filtered_obs, color=obs_color_light, lw=0.75) plot_trace(axes, result.processed_syn, color=syn_color, lw=1.0) plot_trace(axes, result.processed_obs, color=obs_color, lw=0.75) xdata = result.filtered_obs.get_xdata() axes.set_xlim(xdata[0], xdata[-1]) tmarks = [ result.processed_obs.tmin, result.processed_obs.tmax ] for tmark in tmarks: axes2.plot([tmark, tmark], [-0.9, 0.1], color=tap_color_annot) for tmark, text, ha in [ (tmarks[0], '$\\,$ ' + meta.str_duration(tmarks[0] - source.time), 'right'), (tmarks[1], '$\\Delta$ ' + meta.str_duration(tmarks[1] - tmarks[0]), 'left') ]: axes2.annotate( text, xy=(tmark, -0.9), xycoords='data', xytext=(fontsize * 0.4 * [-1, 1][ha == 'left'], fontsize * 0.2), textcoords='offset points', ha=ha, va='bottom', color=tap_color_annot, fontsize=fontsize) rel_w = ws[itarget] / w_max rel_c = gcms[itarget] / gcm_max sw = 0.25 sh = 0.1 ph = 0.01 for (ih, rw, facecolor, edgecolor) in [ (0, rel_w, light(weight_color, 0.5), weight_color), (1, rel_c, light(misfit_color, 0.5), misfit_color) ]: bar = patches.Rectangle( (1.0 - rw * sw, 1.0 - (ih + 1) * sh + ph), rw * sw, sh - 2 * ph, facecolor=facecolor, edgecolor=edgecolor, zorder=10, transform=axes.transAxes, clip_on=False) axes.add_patch(bar) scale_string = None if target.misfit_config.domain == 'cc_max_norm': scale_string = 'Syn/obs scales differ!' infos = [] if scale_string: infos.append(scale_string) infos.append('.'.join(x for x in target.codes if x)) dist = source.distance_to(target) azi = source.azibazi_to(target)[0] infos.append(meta.str_dist(dist)) infos.append('%.0f\u00B0' % azi) infos.append('%.3g' % ws[itarget]) infos.append('%.3g' % gcms[itarget]) axes2.annotate('\n'.join(infos), xy=(0., 1.), xycoords='axes fraction', xytext=(2., 2.), textcoords='offset points', ha='left', va='top', fontsize=fontsize, fontstyle='normal') for (iyy, ixx), (_, fig) in figures.items(): title = '.'.join(x for x in cg if x) if len(figures) > 1: title += ' (%i/%i, %i/%i)' % (iyy + 1, nyy, ixx + 1, nxx) fig.suptitle(title, fontsize=fontsize_title) return figs