def plot_val_vs_pred_mt(pred_mt, val_mt): for pred_m, real_m in zip(pred_mt, val_mt): omega = omega_angle(real_m.m6(), pred_m.m6()) kagan = mtm.kagan_angle(real_m, pred_m) fig = plt.figure() axes = fig.add_subplot(1, 1, 1) axes.set_xlim(-2., 4.) axes.set_ylim(-2., 2.) axes.set_axis_off() plot.beachball.plot_beachball_mpl( real_m, axes, beachball_type='deviatoric', size=60., position=(0, 1), color_t=plot.mpl_color('scarletred2'), linewidth=1.0) plot.beachball.plot_beachball_mpl( pred_m, axes, beachball_type='deviatoric', size=60., position=(1.5, 1), color_t=plot.mpl_color('scarletred2'), linewidth=1.0) plt.show() print("Omega Angle:", omega, "Kagan Angle:", kagan)
def update(iframe): if iframe is not None: frame = frames[:, iframe] if not progress_artists: progress_artists[:] = [ axes2.axvline(tmin_frames - t0 + deltat_cf * iframe, color=plot.mpl_color('scarletred3'), alpha=0.5, lw=2.) ] else: progress_artists[0].set_xdata(tmin_frames - t0 + deltat_cf * iframe) else: frame = num.max(frames[:, iframe_min:iframe_max + 1], axis=1) frame_artists[:] = grid.plot(axes, frame, amin=0.0, amax=amax, cmap=cmap, system=system, artists=frame_artists, units=dist_units, shading='gouraud') return frame_artists + progress_artists + static_artists
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 plot_polygons(polygons, ax, **kwargs): from matplotlib.patches import Polygon import numpy as num import cartopy.crs as ccrs from pyrocko.plot import mpl_color args = { 'edgecolor': 'red', } args.update(kwargs) colormap = [ mpl_color('aluminium2'), mpl_color('skyblue1'), mpl_color('aluminium4'), mpl_color('skyblue2'), mpl_color('white'), mpl_color('aluminium1') ] map(ax.add_patch, [ Polygon(num.fliplr(p.points), transform=ccrs.Geodetic(), facecolor=colormap[p.level_no - 1], **args) for p in polygons ])
def plot_pred_mt(pred_mt): for pred_m in pred_mt: fig = plt.figure() axes = fig.add_subplot(1, 1, 1) axes.set_xlim(-2., 4.) axes.set_ylim(-2., 2.) axes.set_axis_off() plot.beachball.plot_beachball_mpl( pred_m, axes, beachball_type='full', size=60., position=(0, 1), color_t=plot.mpl_color('scarletred2'), linewidth=1.0) plt.show()
def plot_polygons(polygons, ax, **kwargs): # from matplotlib.patches import Polygon from pyrocko.plot import mpl_color args = { 'edgecolor': 'red', } args.update(kwargs) colormap = [ mpl_color('aluminium2'), mpl_color('skyblue1'), mpl_color('aluminium4'), mpl_color('skyblue2'), mpl_color('white'), mpl_color('aluminium1') ] for p in polygons: ax.plot(p.points[:, 1], p.points[:, 0], color=colormap[p.level_no - 1])
def plot_polygons(polygons, ax, **kwargs): from matplotlib.patches import Polygon import numpy as num import cartopy.crs as ccrs from pyrocko.plot import mpl_color args = { 'edgecolor': 'red', } args.update(kwargs) colormap = [ mpl_color('aluminium2'), mpl_color('skyblue1'), mpl_color('aluminium4'), mpl_color('skyblue2'), mpl_color('white'), mpl_color('aluminium1')] map(ax.add_patch, [Polygon(num.fliplr(p.points), transform=ccrs.Geodetic(), facecolor=colormap[p.level_no-1], **args) for p in polygons])
def cluster_color(icluster): if icluster == -1: return mpl_color('aluminium3') else: return mpl_graph_color(icluster)
mpl_init(fontsize=fontsize) width = 7. figsize = (width, width / (4. / 3.)) fig = plt.figure(figsize=figsize) axes = fig.add_subplot(1, 1, 1) fig.subplots_adjust(left=0.03, right=0.97, bottom=0.03, top=0.97) # draw focal sphere diagrams for the random MTs for mt in moment_tensors: u, v = hudson.project(mt) try: beachball.plot_beachball_mpl( mt, axes, beachball_type='full', position=(u, v), size=markersize, color_t=mpl_color('skyblue3'), color_p=mpl_color('skyblue1'), alpha=1.0, # < 1 for transparency zorder=1, linewidth=0.25) except beachball.BeachballError as e: print(str(e), file=sys.stderr) # draw the axes and annotations of the hudson plot hudson.draw_axes(axes) fig.savefig('hudson_diagram.png', dpi=150) # plt.show()
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
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 plot_station_distribution(self, azimuths, distances, weights, labels=None, colors=None, cmap=None, cnorm=None, clabel=None, scatter_kwargs=dict(), annotate_kwargs=dict(), maxsize=10**2, legend_title=''): invalid_color = plot.mpl_color('aluminium3') scatter_default = { 'alpha': .5, 'zorder': 10, 'c': plot.mpl_color('skyblue2'), } annotate_default = { 'alpha': .8, 'color': 'k', 'fontsize': self.font_size_labels, 'ha': 'right', 'va': 'top', 'xytext': (-5, -5), 'textcoords': 'offset points' } scatter_default.update(scatter_kwargs) annotate_default.update(annotate_kwargs) fig = plt.figure(figsize=self.size_inch) plot.mpl_margins(fig, nw=1, nh=1, left=3., right=10., top=3., bottom=3., units=self.font_size) ax = fig.add_subplot(111, projection='polar') valid = num.isfinite(weights) valid[valid] = num.logical_and(valid[valid], weights[valid] > 0.0) weights = weights.copy() if num.sum(valid) == 0: weights[:] = 1.0 weights_ref = 1.0 else: weights[~valid] = weights[valid].min() weights_ref = plot.nice_value(weights[valid].max()) if weights_ref == 0.: weights_ref = 1.0 if colors is None: scolors = [ scatter_default['c'] if s else invalid_color for s in valid ] else: if cnorm is None: cnorm = mcolors.Normalize() elif isinstance(cnorm, tuple): cnorm = mcolors.Normalize(vmin=cnorm[0], vmax=cnorm[1]) if cmap is None: cmap = plt.get_cmap('viridis') elif isinstance(cmap, str): cmap = plt.get_cmap(cmap) sm = mcm.ScalarMappable(norm=cnorm, cmap=cmap) sm.set_array(colors) scolors = [sm.to_rgba(value) for value in colors] scolors = num.array(scolors) scatter_default.pop('c') weights_scaled = (weights / weights_ref) * maxsize ws, exp, fmt = make_scale(0., weights_ref) ws = ws[1:] weight_clip_min = ws[0] weight_clip_min_scaled = (weight_clip_min / weights_ref) * maxsize weights_scaled = num.maximum(weight_clip_min_scaled, weights_scaled) stations = ax.scatter(azimuths * d2r, distances, s=weights_scaled, c=scolors, edgecolors=darken(0.5, scolors), linewidths=1.0, **scatter_default) if len(labels) < 30: # TODO: remove after impl. of collision detection if labels is not None: for ilbl, label in enumerate(labels): ax.annotate(label, (azimuths[ilbl] * d2r, distances[ilbl]), **annotate_default) ax.set_theta_zero_location('N') ax.set_theta_direction(-1) ax.tick_params('y', labelsize=self.font_size, labelcolor='gray') ax.grid(alpha=.2) ax.set_ylim(0, distances.max() * 1.1) ax.yaxis.set_major_locator(plt.MaxNLocator(4)) ax.yaxis.set_major_formatter( FuncFormatter(lambda x, pos: '%d km' % (x / km) if x != 0.0 else '')) # Legend valid_marker = num.argmax(valid) ecl = stations.get_edgecolor() fc = tuple(stations.get_facecolor()[valid_marker]) ec = tuple(ecl[min(valid_marker, len(ecl) - 1)]) legend_data = [] for w in ws[::-1]: legend_data.append( (lines.Line2D([0], [0], ls='none', marker='o', ms=num.sqrt(w / weights_ref * maxsize), mfc=fc, mec=ec), fmt % (w / 10**exp) + ('$\\times 10^{%i}$' % exp if exp != 0 else ''))) if not num.all(valid): legend_data.append((lines.Line2D([0], [0], marker='o', ms=num.sqrt(maxsize), mfc=invalid_color, mec=darken(0.5, invalid_color), mew=1.0), 'Excluded')) legend = fig.legend(*zip(*legend_data), fontsize=self.font_size, loc='upper left', bbox_to_anchor=(0.77, 0.4), markerscale=1, numpoints=1, frameon=False) legend.set_title(legend_title, prop=dict(size=self.font_size)) cb_axes = fig.add_axes([0.8, 0.6, 0.02, 0.3]) if clabel is not None: fig.colorbar(sm, cax=cb_axes, label=clabel, extend='both') return fig, ax, legend
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 plot_map_basemap(stations=None, east_min=-119.2, east_max=-116, north_min=34.5, north_max=37.501, events=None, savename=None, preds=None, best_mts=None, pred_events=None, rect_lats=None, rect_lons=None, ticks=0.01, kmscale=5, add_grid=True, overview=False): try: from mpl_toolkits.basemap import Basemap use_basemap = True except: import cartopy.crs as ccrs import cartopy import cartopy.geodesic as cgeo from cartopy.io import srtm from cartopy.io import PostprocessedRasterSource, LocatedImage from cartopy.io.srtm import SRTM3Source, SRTM1Source use_basemap = False from matplotlib import pyplot as plt from pyrocko.plot import beachball from pyrocko import plot from obspy.imaging.beachball import beach fig, ax = plt.subplots(figsize=(12, 12)) map = Basemap(projection='merc', llcrnrlon=east_min, llcrnrlat=north_min, urcrnrlon=east_max, urcrnrlat=north_max, resolution='h', epsg=3395, ax=ax) xpixels = 1000 map.arcgisimage(service='World_Shaded_Relief', xpixels=xpixels, verbose=False, zorder=-3, colormap="gray", cmap="gray") if overview is True: map.drawmapscale(east_min + 0.35, north_min + 0.31, east_min + 0.65, north_min + 0.5, kmscale) else: map.drawmapscale(east_min + 0.05, north_min + 0.01, east_min + 0.55, north_min + 0.2, kmscale) parallels = np.arange(north_min, north_max, ticks) meridians = np.arange(east_min, east_max, ticks) if overview is True: map.drawparallels(np.round(parallels, 1), labels=[1, 0, 0, 0], fontsize=12) map.drawmeridians(np.round(meridians, 1), labels=[1, 1, 0, 1], fontsize=12, rotation=45) else: map.drawparallels(parallels, labels=[1, 0, 0, 0], fontsize=12) map.drawmeridians(meridians, labels=[1, 1, 0, 1], fontsize=12, rotation=45) if events is not None: for event in events: mt = event.moment_tensor if overview is False: if event.lat > 35.845: x, y = map(event.lon, event.lat) else: x, y = map(event.lon, event.lat) if overview is True: size = 12 else: size = 20 beachball.plot_beachball_mpl(mt, ax, beachball_type='full', size=size, position=(x, y), color_t=plot.mpl_color('scarletred2'), linewidth=1.0, zorder=1) if stations is not None: lats = [s.lat for s in stations] lons = [s.lon for s in stations] labels = ['.'.join(s.nsl()) for s in stations] x_station, y_station = map(lons, lats) map.scatter(x_station, y_station, marker="^", s=36, c="g", zorder=8) for k, label in enumerate(labels): plt.text(x_station[k], y_station[k], str(label), fontsize=12) if rect_lats is not None: import matplotlib.patches as patches if add_grid is True: for lat in rect_lats: for lon in rect_lons: x, y = map(lon, lat) rect = patches.Rectangle((x, y), 1800, 2200, linewidth=1, edgecolor='r', facecolor='none') # Add the patch to the Axes ax.add_patch(rect) max_lat_rect = np.max(rect_lats) min_lat_rect = np.min(rect_lats) max_lon_rect = np.max(rect_lons) min_lon_rect = np.min(rect_lons) xmin, ymin = map(min_lon_rect, max_lat_rect) xmax, ymax = map(max_lon_rect, min_lat_rect) width = xmax - xmin length = ymin - ymax if overview is True: rect = patches.Rectangle( (xmin, ymax), width, length, linewidth=5, edgecolor='k', facecolor='none', zorder=7, ) # Add the patch to the Axes ax.add_patch(rect) if preds is None and best_mts is not None: k = 1 for best_mt, ev in zip(best_mts, pred_events): mt = ev.moment_tensor x, y = map(ev.lon, ev.lat) plt.text(x, y + 0.02, str(k), fontsize=42, zorder=9, color="k") k = k + 1 beachball.plot_beachball_mpl(mt, ax, beachball_type='full', size=22., position=(x, y), color_t=plot.mpl_color('blue'), linewidth=1.0, zorder=3) if preds is not None: for pred_mts, best_mt, ev in zip(preds, best_mts, pred_events): x, y = map(ev.lon, ev.lat) plot_kwargs = { 'beachball_type': 'full', 'size': 500, 'position': (x, y), 'color_t': 'black', 'edgecolor': 'black', 'zorder': 3, } beachball.plot_fuzzy_beachball_mpl_pixmap(pred_mts, ax, best_mt, **plot_kwargs) plt.show()
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 plot_station_distribution(self, azimuths, distances, weights, labels=None, scatter_kwargs=dict(), annotate_kwargs=dict(), maxsize=10**2): invalid_color = plot.mpl_color('aluminium3') scatter_default = { 'alpha': .5, 'zorder': 10, 'c': plot.mpl_color('skyblue2'), } annotate_default = { 'alpha': .8, 'color': 'k', 'fontsize': self.font_size_labels, 'ha': 'right', 'va': 'top', 'xytext': (-5, -5), 'textcoords': 'offset points' } scatter_default.update(scatter_kwargs) annotate_default.update(annotate_kwargs) fig = plt.figure(figsize=self.size_inch) plot.mpl_margins(fig, nw=1, nh=1, left=3., right=10., top=3., bottom=3., units=self.font_size) ax = fig.add_subplot(111, projection='polar') valid = ~num.isnan(weights) weights = weights.copy() weights[~valid] = weights[valid].min() colors = [scatter_default['c'] if s else invalid_color for s in valid] scatter_default.pop('c') weights_ref = plot.nice_value(weights[valid].max()) weights_scaled = (weights / weights_ref) * maxsize stations = ax.scatter(azimuths * d2r, distances, s=weights_scaled, c=colors, **scatter_default) if len(labels) < 30: # TODO: remove after impl. of collision detection if labels is not None: for ilbl, label in enumerate(labels): ax.annotate(label, (azimuths[ilbl] * d2r, distances[ilbl]), **annotate_default) ax.set_theta_zero_location('N') ax.set_theta_direction(-1) ax.tick_params('y', labelsize=self.font_size, labelcolor='gray') ax.grid(alpha=.3) ax.set_ylim(0, distances.max() * 1.1) ax.yaxis.set_major_locator(plt.MaxNLocator(4)) ax.yaxis.set_major_formatter( FuncFormatter(lambda x, pos: '%d km' % (x / km))) # Legend entries = 4 valid_marker = num.argmax(valid) fc = stations.get_facecolor()[valid_marker] ec = stations.get_edgecolor()[valid_marker] def get_min_precision(values): sig_prec = num.floor(num.isfinite(num.log10(weights))) return int(abs(sig_prec.min())) + 1 legend_artists = [ lines.Line2D([0], [0], ls='none', marker='o', ms=num.sqrt(rad), mfc=fc, mec=ec) for rad in num.linspace(maxsize, .1 * maxsize, entries) ] sig_prec = get_min_precision(weights) legend_annot = [ '{value:.{prec}f}'.format(value=val, prec=sig_prec) for val in num.linspace(weights_ref, .1 * weights_ref, entries) ] if not num.all(valid): legend_artists.append( lines.Line2D([0], [0], ls='none', marker='o', ms=num.sqrt(maxsize), mfc=invalid_color, mec=invalid_color)) legend_annot.append('Excluded') legend = fig.legend(legend_artists, legend_annot, fontsize=self.font_size, loc=4, markerscale=1, numpoints=1, frameon=False) return fig, ax, legend
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, 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_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]]
from matplotlib import pyplot as plt from pyrocko import moment_tensor as pmt from pyrocko import plot fig = plt.figure(figsize=(4., 2.)) fig.subplots_adjust(left=0., right=1., bottom=0., top=1.) axes = fig.add_subplot(1, 1, 1) axes.set_xlim(0., 4.) axes.set_ylim(0., 2.) axes.set_axis_off() for i, beachball_type in enumerate(['full', 'deviatoric', 'dc']): plot.beachball.plot_beachball_mpl( pmt.as_mt((124654616., 370943136., -6965434.0, 553316224., -307467264., 84703760.0)), axes, beachball_type=beachball_type, size=60., position=(i+1, 1), color_t=plot.mpl_color('scarletred2'), linewidth=1.0) fig.savefig('beachball-example03.pdf') plt.show()
def call(self): self.cleanup() viewer = self.get_viewer() event = viewer.get_active_event() stations = self.get_stations() for s in stations: print(s.nsl()) nsl_to_station = dict((s.nsl(), s) for s in stations) if event is None: self.error('No active event set.') markers = self.get_selected_markers() if len(markers) != 1: self.error('Exactly one marker must be selected.') marker = markers[0] try: nslc = marker.one_nslc() except pmarker.MarkerOneNSLCRequired: self.error('Marker must be picked on a single trace.') marker_station = nsl_to_station[nslc[:3]] mod = cake.load_model() def traveltime(station): dist = event.distance_to(station) arrivals = mod.arrivals(zstart=event.depth, zstop=0., distances=[dist * cake.m2d], phases=[cake.PhaseDef(self.phasename)]) if not arrivals: raise NoArrival() return arrivals[0].t try: tt_marker_station = traveltime(marker_station) except NoArrival: self.error('Selected phase does not arrive at station.') nsl_to_delay = {} for station in stations: nsl_to_delay[station.nsl()] = \ traveltime(station) - tt_marker_station pile = self.get_pile() nsl_to_traces = {} nsl_to_tspan = {} fs = [f for f in [viewer.lowpass, viewer.highpass] if f is not None] if fs: tpad = 2.0 / min(fs) else: tpad = 0.0 deltats = set() for nsl in nsl_to_delay.keys(): delay = nsl_to_delay[nsl] tmin = marker.tmin + delay tmax = marker.tmax + delay nsl_to_tspan[nsl] = (tmin, tmax) trs = pile.all(tmin=tmin, tmax=tmax, tpad=tpad, trace_selector=lambda tr: tr.nslc_id[:3] == nsl, want_incomplete=False) for tr in trs: if viewer.lowpass is not None: tr.lowpass(4, viewer.lowpass) if viewer.highpass is not None: tr.highpass(4, viewer.highpass) tr.chop(tr.wmin, tr.wmax) deltats.add(tr.deltat) if trs: nsl_to_traces[nsl] = trs if len(deltats) != 1: self.error('All traces must have same sampling rate.') # add markers for nsl in nsl_to_traces.keys(): tmin, tmax = nsl_to_tspan[nsl] for tr in nsl_to_traces[nsl]: mark = PhaseMarker([tr.nslc_id], tmin=tmin, tmax=tmax, kind=1, phasename=self.phasename) self.add_marker(mark) # cross correlations nsls = sorted(list(nsl_to_traces.keys())) pair_corrs = [] for nsl_a in nsls: trs_a = nsl_to_traces[nsl_a] if self.channels_relamp == 'All': comps = sorted(set([tr.channel[-1] for tr in trs_a])) else: comps = [c.strip() for c in self.channels_relamp.split(',')] for nsl_b in nsls: trs_b = nsl_to_traces[nsl_b] for comp in comps: try: tr_a = get_trace(trs_a, lambda tr: tr.channel.endswith(comp)) tr_b = get_trace(trs_b, lambda tr: tr.channel.endswith(comp)) except NotFound: continue if tr_a is tr_b: continue tr_cor = trace.correlate(tr_a, tr_b, mode='full', normalization='normal') delaymax, ccmax = tr_cor.max() delaymin, ccmin = tr_cor.min() delay_syn = nsl_to_delay[nsl_b] - nsl_to_delay[nsl_a] if abs(ccmin) < abs(ccmax): delay = delaymax ccabsmax = abs(ccmax) ccsignedmax = ccmax else: delay = delaymin ccabsmax = abs(ccmin) ccsignedmax = ccmin tr_b_shifted = tr_b.copy() tr_b_shifted.shift(-delay) tmin_com = max(tr_b_shifted.tmin, tr_a.tmin) tmax_com = min(tr_b_shifted.tmax, tr_a.tmax) tr_a_chopped = tr_a.chop(tmin_com, tmax_com, inplace=False) tr_b_chopped = tr_b_shifted.chop(tmin_com, tmax_com, inplace=False) ya = tr_a_chopped.ydata yb = tr_b_chopped.ydata relamp1 = num.sum(ya * yb) / num.sum(yb**2) relamp2 = num.sum(ya * yb) / num.sum(ya**2) if nsl_a[1] == 'LYKK': print(ccabsmax, relamp1, relamp2, abs((relamp1 / (1.0 / relamp2) - 1.0))) if ccabsmax < self.cc_min: continue if abs((relamp1 / (1.0 / relamp2) - 1.0)) > 0.2: continue relamp = (relamp1 + 1. / relamp2) * 0.5 pair_corrs.append((tr_a.nslc_id, tr_b.nslc_id, ccsignedmax, relamp, delay, delay_syn)) nslc_to_relamp = invert_relative_amplitudes(pair_corrs) self._nslc_to_relamp = nslc_to_relamp nsl_to_xy = {} for nsl in nsl_to_traces.keys(): trs = nsl_to_traces[nsl] try: cc = [c.strip() for c in self.channels_polar.split(',')] tr_y, tr_x = [ get_trace(trs, lambda tr: tr.channel.endswith(c)) for c in cc ] x = tr_x.get_ydata() y = tr_y.get_ydata() nsl_to_xy[nsl] = (x, y) except NotFound: pass nsls = sorted(list(nsl_to_xy.keys())) n = len(nsls) xs_l = [nsl_to_xy[nsl][0] for nsl in nsls] ys_l = [nsl_to_xy[nsl][1] for nsl in nsls] nsamp = min(min(x.size for x in xs_l), min(y.size for y in ys_l)) xs = num.vstack(x[:nsamp] for x in xs_l) ys = num.vstack(y[:nsamp] for y in ys_l) amps = num.sqrt(xs**2 + ys**2) amp_maxs = num.max(amps, axis=1) xs = xs / amp_maxs[:, num.newaxis] ys = ys / amp_maxs[:, num.newaxis] nphi = 73 phis = num.linspace(-180., 180., nphi) d = num.zeros((n, n, nphi)) for ia in range(n): for iphi, phi in enumerate(phis): x = xs[ia, :] y = ys[ia, :] xrot = num.cos(phi * d2r) * x + num.sin(phi * d2r) * y yrot = -num.sin(phi * d2r) * x + num.cos(phi * d2r) * y d[ia, :, iphi] = num.sqrt( num.sum((xrot[num.newaxis, :] - xs)**2 + (yrot[num.newaxis, :] - ys)**2, axis=1)) imins = num.argmin(d, axis=2) dmins = num.min(d, axis=2) dmin_median = num.median(dmins) phimins = phis[imins] nsl_to_rot = {} for nsl in nsls: nsl_to_rot[nsl] = 0. failed = set() for i in range(n): mean_min_error = num.mean(dmins[i, :] / dmin_median) print(mean_min_error, nsls[i]) if mean_min_error > 3.0: failed.add(nsls[i]) while True: ia_worst = num.argmax(num.mean(num.abs(phimins), axis=1)) phimod = ((phis[num.newaxis, :] + phimins[ia_worst, :, num.newaxis] + 180.) % 360.) - 180. phirot = phis[num.argmin(num.mean(num.abs(phimod), axis=0))] if abs(phirot) < 10.: break nsl = nsls[ia_worst] mean_min_error = num.mean(dmins[ia_worst, :] / dmin_median) phimins[ia_worst, :] = ( (phimins[ia_worst, :] + phirot) + 180.) % 360. - 180. phimins[:, ia_worst] = ( (phimins[:, ia_worst] - phirot) + 180.) % 360. - 180. if nsl not in failed: print('%-20s %8.0f' % ('.'.join(nsl), phirot)) nsl_to_rot[nsl] += phirot fframe = self.figure_frame() fig = fframe.gcf() fig.clf() if n == 0: self.error('No matching traces found.') ncols = 1 while ncols**2 < n: ncols += 1 nrows = ncols axes = fig.add_subplot(1, 2, 1, aspect=1.0) axes.axison = False axes.set_xlim(-0.05 - ncols, ncols + 0.05) axes.set_ylim(-0.05 - nrows, nrows + 0.05) axes.set_title('Event: %s, Phase: %s' % (event.name, self.phasename)) for insl, nsl in enumerate(nsls): irow = insl // ncols icol = insl % ncols trs = nsl_to_traces[nsl] try: x, y = nsl_to_xy[nsl] cc = [c.strip() for c in self.channels_polar.split(',')] tr_y, tr_x = [ get_trace(trs, lambda tr: tr.channel.endswith(c)) for c in cc ] xpos = icol * 2 - ncols + 1 ypos = -irow * 2 + nrows - 1 x = tr_x.get_ydata() y = tr_y.get_ydata() a = num.sqrt(x**2 + y**2) amax = num.max(a) phi = nsl_to_rot[nsl] color = 'black' if num.abs(phi) > 0: color = mpl_color('chocolate2') if num.abs(phi) > 30: color = mpl_color('orange2') if nsl in failed: color = mpl_color('scarletred2') axes.plot(x / amax + xpos, y / amax + ypos, color=color, alpha=0.7) if nsl not in failed: xrot = num.cos(phi * d2r) * x - num.sin(phi * d2r) * y yrot = num.sin(phi * d2r) * x + num.cos(phi * d2r) * y axes.plot(xrot / amax + xpos, yrot / amax + ypos, color='black', alpha=0.5) # axes.plot( # [xpos, num.sin(phi*d2r) + xpos], # [ypos, num.cos(phi*d2r) + ypos], # color=color, alpha=0.5) axes.annotate('.'.join(_ for _ in nsl if _), xy=(icol * 2 - ncols + 1, -irow * 2 + nrows - 2), xycoords='data', xytext=(0, 0), textcoords='offset points', verticalalignment='center', horizontalalignment='center', rotation=0.) except NotFound: pass axes = fig.add_subplot(1, 2, 2) nslcs = sorted(nslc_to_relamp.keys()) pdata = [] for inslc, nslc in enumerate(nslcs): nsl = nslc[:3] cha = nslc[3] tr = get_trace(nsl_to_traces[nsl], lambda tr: tr.channel == cha).copy() tr.shift(-(event.time + tt_marker_station + nsl_to_delay[nsl])) relamp = nslc_to_relamp[nslc] tr.ydata /= relamp color = 'black' if abs(num.log10(relamp)) > num.log10(1.1): color = mpl_color('chocolate2') if abs(num.log10(relamp)) > num.log10(2.0): color = mpl_color('orange2') if abs(num.log10(relamp)) > num.log10(10.0): color = mpl_color('scarletred2') pdata.append((tr, relamp, color, inslc, nslc)) ranges = trace.minmax([aa[0] for aa in pdata], lambda tr: None) ymin, ymax = ranges[None] yabsmax = max(abs(ymin), abs(ymax)) for (tr, relamp, color, inslc, nslc) in pdata: axes.plot(tr.get_xdata(), inslc + tr.get_ydata() / yabsmax, color=color) axes.annotate('.'.join(_ for _ in nslc if _), xy=(0, inslc), xycoords=('axes fraction', 'data'), xytext=(-5, 0), textcoords='offset points', verticalalignment='center', horizontalalignment='right', rotation=0., color=color) axes.annotate('x %g' % (1.0 / relamp), xy=(1., inslc), xycoords=('axes fraction', 'data'), xytext=(+5, 0), textcoords='offset points', verticalalignment='center', horizontalalignment='left', rotation=0., color=color) axes.get_yaxis().set_visible(False) for which in ['top', 'right', 'left']: axes.spines[which].set_visible(False) axes.set_xlabel('Time [s]') fframe.draw()
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]]
figsize = (width, width / (4. / 3.)) fig = plt.figure(figsize=figsize) axes = fig.add_subplot(1, 1, 1) fig.subplots_adjust(left=0.03, right=0.97, bottom=0.03, top=0.97) # draw focal sphere diagrams for the random MT u, v = hudson.project(m) print(u, v) try: beachball.plot_beachball_mpl( m, axes, beachball_type='full', position=(u, v), size=30, color_t=mpl_color('skyblue3'), color_p=mpl_color('skyblue1'), alpha=1.0, # < 1 for transparency zorder=1, linewidth=0.25) except beachball.BeachballError as e: print(str(e), file=sys.stderr) # draw the axes and annotations of the hudson plot hudson.draw_axes(axes) #fig.savefig('hudson_diagram.png', dpi=250) plt.show()
def plot_detection(grid, receivers, frames, tmin_frames, deltat_cf, imax, iframe, xpeak, ypeak, zpeak, tr_stackmax, tpeaks, apeaks, detector_threshold, wmin, wmax, pdata, trs_raw, fmin, fmax, idetection, tpeaksearch, movie=False, save_filename=None, show=True, event=None): from matplotlib import pyplot as plt from matplotlib import cm from matplotlib.animation import FuncAnimation nsls = set(tr.nslc_id[:3] for tr in trs_raw) receivers_on = [r for r in receivers if r.codes in nsls] receivers_off = [r for r in receivers if r.codes not in nsls] distances = grid.distances(receivers) plot.mpl_init(fontsize=9) fig = plt.figure(figsize=plot.mpl_papersize('a4', 'landscape')) axes = plt.subplot2grid((2, 3), (0, 2), aspect=1.0) plot.mpl_labelspace(axes) axes2 = plt.subplot2grid((2, 3), (1, 2)) plot.mpl_labelspace(axes2) axes3 = plt.subplot2grid((2, 3), (0, 1), rowspan=2) axes4 = plt.subplot2grid((2, 3), (0, 0), rowspan=2) if grid.distance_max() > km: dist_units = km axes.set_xlabel('Easting [km]') axes.set_ylabel('Northing [km]') axes4.set_ylabel('Distance [km]') else: dist_units = 1.0 axes.set_xlabel('Easting [m]') axes.set_ylabel('Northing [m]') axes4.set_ylabel('Distance [m]') axes.locator_params(nbins=6, tight=True) axes2.set_xlabel('Time [s]') axes2.set_ylabel('Detector level') axes3.set_xlabel('Time [s]') for el in axes3.get_yticklabels(): el.set_visible(False) axes4.set_xlabel('Time [s]') tpeak_current = tmin_frames + deltat_cf * iframe t0 = tpeak_current tduration = 2.0 * tpeaksearch axes2.axvspan(tr_stackmax.tmin - t0, wmin - t0, color=plot.mpl_color('aluminium2')) axes2.axvspan(wmax - t0, tr_stackmax.tmax - t0, color=plot.mpl_color('aluminium2')) axes2.axvspan(tpeak_current - 0.5 * tduration - t0, tpeak_current + 0.5 * tduration - t0, color=plot.mpl_color('scarletred2'), alpha=0.3, lw=0.) axes2.set_xlim(tr_stackmax.tmin - t0, tr_stackmax.tmax - t0) axes2.axhline(detector_threshold, color=plot.mpl_color('aluminium6'), lw=2.) t = tr_stackmax.get_xdata() amp = tr_stackmax.get_ydata() axes2.plot(t - t0, amp, color=plot.mpl_color('scarletred2'), lw=1.) for tpeak, apeak in zip(tpeaks, apeaks): axes2.plot(tpeak - t0, apeak, '*', ms=20., mfc='white', mec='black') station_index = dict((rec.codes, i) for (i, rec) in enumerate(receivers)) dists_all = [] amps = [] shifts = [] pdata2 = [] for trs, shift_table, shifter in pdata: trs = [tr.copy() for tr in trs] dists = [] for tr in trs: istation = station_index[tr.nslc_id[:3]] shift = shift_table[imax, istation] tr2 = tr.chop(tpeak_current - 0.5 * tduration + shift, tpeak_current + 0.5 * tduration + shift, inplace=False) dists.append(distances[imax, istation]) amp = tr2.get_ydata() * shifter.weight amps.append(num.max(num.abs(amp))) shifts.append(shift) pdata2.append((trs, dists, shift_table, shifter)) dists_all.extend(dists) dist_min = min(dists_all) dist_max = max(dists_all) shift_min = min(shifts) shift_max = max(shifts) amp_max = max(amps) scalefactor = (dist_max - dist_min) / len(trs) * 0.5 axes3.set_xlim(-0.5 * tduration + shift_min, 0.5 * tduration + shift_max) axes3.set_ylim((dist_min - scalefactor) / dist_units, (dist_max + scalefactor) / dist_units) axes4.set_xlim(-0.5 * tduration + shift_min, 0.5 * tduration + shift_max) axes4.set_ylim((dist_min - scalefactor) / dist_units, (dist_max + scalefactor) / dist_units) axes3.axvline(0., color=plot.mpl_color('aluminium3'), lw=2.) nsl_have = set() phase_markers = [] picks = [] for ishifter, (trs, dists, shift_table, shifter) in enumerate(pdata2): color = plot.mpl_graph_color(ishifter) for tr, dist in zip(trs, dists): tmint = tr.tmin tr = tr.chop(tpeak_current - 0.5 * tduration + shift_min, tpeak_current + 0.5 * tduration + shift_max, inplace=False) nsl = tr.nslc_id[:3] istation = station_index[nsl] shift = shift_table[imax, istation] phase_markers.append( PhaseMarker([(nsl[0], nsl[1], "", nsl[2])], tmin=tmint + shift, tmax=tmint + shift, phasename=shifter.name, event_time=t0, event_hash=idetection)) p = Pick(time=UTCDateTime(tmint + shift), waveform_id=WaveformStreamID(network_code=nsl[0], station_code=nsl[1]), phase_hint=shifter.name, method_id="lassie") picks.append(p) axes3.plot(shift, dist / dist_units, '|', mew=2, mec=color, ms=10, zorder=2) t = tr.get_xdata() amp = tr.get_ydata() * shifter.weight amp /= amp_max axes3.plot( t - t0, (dist + scalefactor * amp + ishifter * scalefactor * 0.1) / dist_units, color=color, zorder=1) if nsl not in nsl_have: axes3.annotate('.'.join(nsl), xy=(t[0] - t0, dist / dist_units), xytext=(10., 0.), textcoords='offset points', verticalalignment='top') nsl_have.add(nsl) for tr in trs_raw: istation = station_index[tr.nslc_id[:3]] dist = distances[imax, istation] shift = shift_table[imax, istation] tr = tr.copy() tr.highpass(4, fmin, demean=True) tr.lowpass(4, fmax, demean=False) tr.chop(tpeak_current - 0.5 * tduration + shift_min, tpeak_current + 0.5 * tduration + shift_max) t = tr.get_xdata() amp = tr.get_ydata().astype(num.float) amp = amp / num.max(num.abs(amp)) axes4.plot(t - t0, (dist + scalefactor * amp) / dist_units, color='black', alpha=0.5, zorder=1) axes4.plot(shift, dist / dist_units, '|', mew=2, mec=color, ms=10, zorder=2) PhaseMarker.save_markers(phase_markers, "%s.pym" % (save_filename[:-4]), fdigits=3) event_obspy = Event() origin = Origin(time=UTCDateTime(t0), longitude=event.lon, latitude=event.lat, method="lassie") event_obspy.origins.append(origin) event_obspy.picks = picks cat = Catalog() cat.append(event_obspy) cat.write(save_filename[:-4] + ".qml", format="QUAKEML") nframes = frames.shape[1] iframe_min = max(0, int(round(iframe - 0.5 * tduration / deltat_cf))) iframe_max = min(nframes - 1, int(round(iframe + 0.5 * tduration / deltat_cf))) amax = frames[imax, iframe] axes.set_xlim(grid.ymin / dist_units, grid.ymax / dist_units) axes.set_ylim(grid.xmin / dist_units, grid.xmax / dist_units) cmap = cm.YlOrBr system = ('ne', grid.lat, grid.lon) static_artists = [] static_artists.extend( plot_receivers(axes, receivers_on, system=system, units=dist_units, style=dict(mfc='black', ms=5.0))) static_artists.extend( plot_receivers(axes, receivers_off, system=system, units=dist_units, style=dict(mfc='none', ms=5.0))) static_artists.extend( axes.plot(ypeak / dist_units, xpeak / dist_units, '*', ms=20., mec='black', mfc='white')) static_artists.append( fig.suptitle('%06i - %s' % (idetection, util.time_to_str(t0)))) frame_artists = [] progress_artists = [] def update(iframe): if iframe is not None: frame = frames[:, iframe] if not progress_artists: progress_artists[:] = [ axes2.axvline(tmin_frames - t0 + deltat_cf * iframe, color=plot.mpl_color('scarletred3'), alpha=0.5, lw=2.) ] else: progress_artists[0].set_xdata(tmin_frames - t0 + deltat_cf * iframe) else: frame = num.max(frames[:, iframe_min:iframe_max + 1], axis=1) frame_artists[:] = grid.plot(axes, frame, amin=0.0, amax=amax, cmap=cmap, system=system, artists=frame_artists, units=dist_units, shading='gouraud') return frame_artists + progress_artists + static_artists if movie: ani = FuncAnimation( fig, update, frames=list(range(iframe_min, iframe_max + 1))[::10] + [None], interval=20., repeat=False, blit=True) else: ani = None update(None) if save_filename: fig.savefig(save_filename) if show: plt.show() else: plt.close() del ani
from matplotlib import pyplot as plt from pyrocko import moment_tensor as pmt from pyrocko import plot fig = plt.figure(figsize=(4., 2.)) fig.subplots_adjust(left=0., right=1., bottom=0., top=1.) axes = fig.add_subplot(1, 1, 1) axes.set_xlim(0., 4.) axes.set_ylim(0., 2.) axes.set_axis_off() for i, beachball_type in enumerate(['full', 'deviatoric', 'dc']): plot.beachball.plot_beachball_mpl(pmt.as_mt( (124654616., 370943136., -6965434.0, 553316224., -307467264., 84703760.0)), axes, beachball_type=beachball_type, size=60., position=(i + 1, 1), color_t=plot.mpl_color('scarletred2'), linewidth=1.0) fig.savefig('beachball-example03.pdf') plt.show()
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 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 draw_figures(self, ds, history): color_parameter = self.color_parameter misfit_cutoff = self.misfit_cutoff 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)[::-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[::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): if isinstance(result, gf.SeismosizerError): dtraces[-1].append(None) continue if not isinstance(target, WaveformMisfitTarget): dtraces[-1].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 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])) 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] 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) 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) 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(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') 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