Beispiel #1
0
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)
Beispiel #2
0
    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
Beispiel #3
0
    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]
Beispiel #4
0
    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
        ])
Beispiel #5
0
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()
Beispiel #6
0
    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])
Beispiel #8
0
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()
Beispiel #10
0
    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
Beispiel #11
0
    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
Beispiel #12
0
    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
Beispiel #13
0
    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]]
Beispiel #14
0
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()
Beispiel #15
0
    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]]
Beispiel #16
0
    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
Beispiel #17
0
    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
Beispiel #18
0
    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
Beispiel #19
0
    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()
Beispiel #21
0
    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()
Beispiel #22
0
    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]]
Beispiel #23
0
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()
Beispiel #24
0
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()
Beispiel #26
0
    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)
Beispiel #27
0
    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
Beispiel #28
0
    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