Пример #1
0
def plot_correlation_hist(data):
    """ Plot histogram of all correlations
    """
    # gather data
    corrs = []
    for raw_res, enh_list in data:
        _, raw_mat, _ = raw_res

        if not raw_mat is None:
            raw_vec = extract_sig_entries(raw_mat)
            corrs.extend(raw_vec)

        for enh_res in enh_list:
            _, enh_mat, _ = enh_res

            if not enh_mat is None:
                enh_vec = extract_sig_entries(enh_mat)
                corrs.extend(enh_vec)

    # plot result
    fig = plt.figure()

    plot_histogram(corrs, plt.gca())
    plt.xlabel('simulated correlations')

    fig.savefig('images/all_sim_corrs.pdf')
Пример #2
0
def plot_correlation_hist(data):
    """ Plot histogram of all correlations
    """
    # gather data
    corrs = []
    for raw_res, enh_list in data:
        _, raw_mat, _ = raw_res

        if not raw_mat is None:
            raw_vec = extract_sig_entries(raw_mat)
            corrs.extend(raw_vec)

        for enh_res in enh_list:
            _, enh_mat, _ = enh_res

            if not enh_mat is None:
                enh_vec = extract_sig_entries(enh_mat)
                corrs.extend(enh_vec)

    # plot result
    fig = plt.figure()

    plot_histogram(corrs, plt.gca())
    plt.xlabel('simulated correlations')

    fig.savefig('images/all_sim_corrs.pdf')
Пример #3
0
    def do(syst, ax):
        # data
        single_run_matrices = []
        for _ in trange(reps):
            sol = solve_system(syst)

            sol_extract = sol.T[int(len(sol.T)*3/4):]
            single_run_mat = compute_correlation_matrix(np.array([sol_extract]))

            if single_run_mat.shape == (4, 4):
                single_run_mat = single_run_mat[:-1,:-1]
            assert single_run_mat.shape == (3, 3)

            single_run_matrices.append(single_run_mat)
        single_run_matrices = np.asarray(single_run_matrices)

        # plotting
        cols = cycle(['b', 'r', 'g', 'c', 'm', 'y', 'k'])
        for i, row in enumerate(single_run_matrices.T):
            for j, series in enumerate(row):
                if i == j: break
                plot_histogram(
                    series[series!=1], ax,
                    label=r'$c_{{{},{}}}$'.format(i,j),
                    facecolor=next(cols), alpha=0.5,
                    bins=100)
Пример #4
0
def plot_correlation_histogram(motifs, data):
    """ Plot histogram of all observed intensity correlations
    """
    colors = itertools.cycle(['b', 'r', 'g', 'c', 'm', 'y', 'k'])

    plt.figure()
    for (m, lbl) in motifs:
        # compute correlations
        corrs = []
        for cs in tqdm(m):
            for c1 in cs:
                for c2 in cs:
                    if c1 == c2: break
                    # compute correlations
                    for i, int1 in enumerate(data[c1]['intensities']):
                        for j, int2 in enumerate(data[c2]['intensities']):
                            cc, _ = scis.pearsonr(int1, int2)
                            corrs.append(cc)

        # plot
        plotter.plot_histogram(
            corrs, plt.gca(),
            facecolor=next(colors), alpha=0.5,
            label=lbl)

    plt.title('Comparison of intensity correlation distributions')
    plt.xlabel('intensity vector correlation')

    plt.legend(loc='best')
    plt.tight_layout()
    plotter.save_figure('images/rl_corr_hist.pdf', bbox_inches='tight')
Пример #5
0
def plot_all_correlations(cs, data, ax):
    """ Plot correlations between all intensity combinations
    """
    col_list = ['red', 'blue', 'green']

    tmp = collections.defaultdict(lambda: collections.defaultdict(list))
    for c1 in cs:
        for c2 in cs:
            if c1 == c2: break
            corrs = {}

            # compute correlations
            for i, int1 in enumerate(data[c1]['intensities']):
                for j, int2 in enumerate(data[c2]['intensities']):
                    cc, _ = scis.pearsonr(int1, int2)
                    corrs[(i,j)] = cc

            c1_idx, c2_idx = max(corrs.keys(), key=lambda k: corrs[k])
            tmp[c1][c1_idx].append(corrs[(c1_idx, c2_idx)])
            tmp[c2][c2_idx].append(corrs[(c1_idx, c2_idx)])

            # plot histogram
            if not ax is None:
                plotter.plot_histogram(
                    list(corrs.values()), ax,
                    alpha=0.5, facecolor=col_list.pop())

    # choose final selection
    sel = {}
    for c, maps in tmp.items():
        choice = max(maps.keys(), key=lambda k: sum(maps[k]))
        sel[c] = choice

    return sel, corrs.values()
Пример #6
0
def parse_XML(doc):

	cards = doc.getroot()

	# Create general transition matrix (Model 3)
	# (general_mtx,row_code,col_code) = model3.create_transition_matrix(extract_history(cards), 1)

	# Updating global variable for progress measuring purposes
	global total
	total = len(cards)

	global counter
	counter = Value('i', 0)

	# Executes card history evaluation in parallel
	pool = Pool(processes=8, initializer = init, initargs = (counter, ))
	rs = pool.map_async(exec_task, extract_history(cards), chunksize = 1)

	while(True):
		if (rs.ready()): 
		    break
		remaining = rs._number_left
		sys.stdout.write("\tCurrent progress: %.2f %% of cards analyzed\r" % (100*(total-remaining)/total) )
		sys.stdout.flush()

		time.sleep(0.1)

	rs.wait()
	
	results = rs.get()

	# Configurations for evaluation matrix
	m_min_history = 0
	m_max_history = 500
	delta = 25
	levels = int(math.floor((m_max_history-m_min_history)/delta))
	mtx = np.zeros((levels,levels), dtype=np.float) - 1
	counts = np.zeros((levels,levels), dtype=np.float)
	min_range = range(m_min_history,delta*levels+m_min_history,delta)
	max_range = range(m_min_history+delta,delta*levels+m_min_history+delta,delta)

	###

	mtx = update_evaluation_matrix(mtx,counts,results,min_range,min_range)

	sys.stdout.write("\tCurrent progress: %.2f %% of cards analyzed\r\n" % (100.00) )
	sys.stdout.flush()

	precision = [float(i[0]) for i in results]

	print "Average precision: " , sum(precision)/len(precision) , " ( min-history = " , min(1,m_min_history) , ", max-history = " , m_max_history, " )"

	plotter.plot_matrix(mtx,max_range,min_range,"Model " + modelName + " precision","../results/model_"+modelName+"_matrix.png")
	plotter.plot_histogram(np.asarray(precision),"Model " + modelName + " precision","../results/model_"+modelName+"_histogram.png")

	print "Evaluation completed!"
Пример #7
0
def plot_result(motifs, data, fname_app='', sub_num=10):
    """ Create result plot
    """
    mpl.style.use('default')
    sub_num = min(sub_num, len(motifs))
    print(' > Plotting results ({})'.format(fname_app[1:]))

    # overview plots
    plt.figure(figsize=(30, 4 * sub_num))
    gs = mpl.gridspec.GridSpec(sub_num, 3, width_ratios=[1, 2, 1])

    idx = map(int,
        np.linspace(0, len(motifs), num=sub_num, endpoint=False))

    corrs = []
    for ai, i in tqdm(enumerate(idx), total=sub_num):
        c1, c2, c3 = motifs[i]

        # plot all possible correlations and select optimal one
        sel, all_corrs = plot_all_correlations(
            (c1, c2, c3), data,
            plt.subplot(gs[ai, 2]) if ai < sub_num else None)

        # get intensities
        sols = []
        for foo in [c1, c2, c3]:
            sols.append(data[foo]['intensities'][sel[foo]])

        # compute correlation matrix
        corr_mat = get_correlation_matrix(sols)
        corrs.extend(all_corrs)

        # plot rest
        plotter.plot_corr_mat(corr_mat, plt.subplot(gs[ai, 0]))

        series_ax = plt.subplot(gs[ai, 1])
        plotter.plot_system_evolution(
            sols, series_ax,
            xlabel='sample')
        series_ax.set_title('{}\n{}\n{}'.format(c1, c2, c3))

    plt.tight_layout()
    plotter.save_figure('images/rl_motifs{}.pdf'.format(fname_app), bbox_inches='tight')

    # correlation histogram
    plt.figure()

    plotter.plot_histogram(corrs, plt.gca())

    plt.tight_layout()
    plotter.save_figure('images/rl_corr_hist{}.pdf'.format(fname_app), bbox_inches='tight')
Пример #8
0
def compute_overview_histogram(corrs):
    """ Compute histogram of all possible correlations
    """
    flat_corrs = list(itertools.chain.from_iterable(corrs))

    plt.figure()
    plot_histogram(flat_corrs, plt.gca())

    plt.xlabel('molecule intensity correlation')
    plt.title('Overview over all correlations')

    plt.savefig('images/all_corrs_hist.pdf')
    plt.close()

    return flat_corrs
Пример #9
0
def movement_monte_carlo_plot_movenents():
    start_time = time.perf_counter()

    height = 20
    width = 20
    iterations = 10000
    min_moves = 10
    max_moves = 20

    success = 0
    wrong = 0
    fail = 0
    required_moves = np.zeros(max_moves + 1, dtype=int)

    for i in range(iterations):
        if i % 100 == 0:
            log.debug("Running iteration", i)

        m = mapgrid.generate_map(width=width, height=height)
        v = vehicle.Vehicle(m, 10)
        num_matches, x, y, possible_loc, movements = \
            locator.locate_with_movement_and_error_fallback(m, v, max_moves, min_moves=min_moves)

        if num_matches == 1:
            correct_x, correct_y, direction = v.location()
            if x == correct_x and y == correct_y:
                success += 1
                required_moves[movements] += 1
            else:
                wrong += 1
        else:
            fail += 1

    #print("Success:", success)
    #print("Wrong:", wrong)
    #print("Fail", fail)
    #print("Required moves", required_moves)
    #print("Total time", time.perf_counter() - start_time)

    x_axis = np.arange(1, 8)
    y_axis = (required_moves / iterations)[10:17]

    plotter.plot_histogram(x_axis,
                           y_axis,
                           xlabel="lisäaskelten lukumäärä",
                           ylim=None,
                           savename="lisa-askelten_lkm")
Пример #10
0
    def do_hist(name1, ints1, name2, ints2):
        corrs = []
        for i1, i2 in itertools.product(ints1, ints2):
            corr, p = scits.pearsonr(i1, i2)
            corrs.append(corr)

        if plot:
            plt.figure()
            plot_histogram(corrs, plt.gca())

            plt.title('"{} ({})" vs "{} ({})"'.format(
                name2, len(ints2), name1, len(ints1)))
            plt.xlabel('correlation')

            plt.savefig('corr_hists/corr_hist_{}_{}.pdf'.format(name1, name2))
            plt.close()

        return corrs
Пример #11
0
def compute_correlation_matrix(data, plot_hist=False, save_stdev=None):
    """ Compute correlation matrix of given data points
    """
    dim = data.shape[2]

    mats = []
    for rep_slice in data:
        mat = np.empty((dim, dim))
        for i in range(dim):
            for j in range(dim):
                xs, ys = extract(i, j, rep_slice)
                cc = get_correlation(xs, ys)
                mat[i, j] = cc
        mats.append(mat)
    mats = np.array(mats)

    if plot_hist:
        plt.figure(figsize=(6, 14))
        gs = mpl.gridspec.GridSpec(int((dim**2-dim)/2), 1)

        axc = 0
        for i in range(dim):
            for j in range(dim):
                if i == j: break

                ax = plt.subplot(gs[axc])
                plotter.plot_histogram(mats[:,i,j], ax)
                ax.set_title('Nodes {}, {}'.format(i, j))
                ax.set_xlabel('correlation')

                axc += 1

        plt.tight_layout()
        plt.savefig('images/simulated_corrs_hist.pdf')
        plt.close()

    if save_stdev is not None:
        std = np.std(mats, axis=0)
        np.save(save_stdev, std)

    res_mat = np.mean(mats, axis=0)
    return res_mat
Пример #12
0
def compute_correlation_matrix(data, plot_hist=False, save_stdev=None):
    """ Compute correlation matrix of given data points
    """
    dim = data.shape[2]

    mats = []
    for rep_slice in data:
        mat = np.empty((dim, dim))
        for i in range(dim):
            for j in range(dim):
                xs, ys = extract(i, j, rep_slice)
                cc = get_correlation(xs, ys)
                mat[i, j] = cc
        mats.append(mat)
    mats = np.array(mats)

    if plot_hist:
        plt.figure(figsize=(6, 14))
        gs = mpl.gridspec.GridSpec(int((dim**2 - dim) / 2), 1)

        axc = 0
        for i in range(dim):
            for j in range(dim):
                if i == j: break

                ax = plt.subplot(gs[axc])
                plotter.plot_histogram(mats[:, i, j], ax)
                ax.set_title('Nodes {}, {}'.format(i, j))
                ax.set_xlabel('correlation')

                axc += 1

        plt.tight_layout()
        plt.savefig('images/simulated_corrs_hist.pdf')
        plt.close()

    if save_stdev is not None:
        std = np.std(mats, axis=0)
        np.save(save_stdev, std)

    res_mat = np.mean(mats, axis=0)
    return res_mat
Пример #13
0
def main(target, cfg):
    """
    Puts everything together.
    """
    t0 = time.time()

    #####################################################################
    #
    # READ SEGY
    #
    #####################################################################
    if cfg['segy_library'].lower() == 'obspy':
        s = Seismic.from_segy_with_obspy(target, params={'ndim': cfg['ndim']})
    else:
        s = Seismic.from_segy(target, params={'ndim': cfg['ndim']})

    # Set the line and/or xline number.
    try:
        n, xl = cfg['number']
    except:
        n, xl = cfg['number'], 0.5

    # Set the direction.
    if (s.ndim) == 2:
        direction = ['inline']
    elif cfg['direction'].lower()[0] == 'i':
        direction = ['inline']
    elif cfg['direction'].lower()[0] in ['x', 'c']:  # Allow 'crossline' too.
        direction = ['xline']
    elif cfg['direction'].lower()[0] == 't':
        direction = ['tslice']
    else:
        direction = ['xline', 'inline']

    # Get the data.
    try:
        ss = [
            Seismic.from_seismic(s, n=n, direction=d)
            for n, d in zip((n, xl), direction)
        ]
    except IndexError:
        # Perhaps misinterpreted 2D as 3D
        s = Seismic.from_segy(target, params={'ndim': 2})
        direction = ['inline']
        ss = [
            Seismic.from_seismic(s, n=n, direction=d)
            for n, d in zip((n, xl), direction)
        ]

    clip_val = np.percentile(s.data, cfg['percentile'])

    if clip_val < 10:
        fstr = '{:.3f}'
    elif clip_val < 100:
        fstr = '{:.2f}'
    elif clip_val < 1000:
        fstr = '{:.1f}'
    else:
        fstr = '{:.0f}'

    # Notify user of parameters.
    Notice.info("n_traces   {}".format(s.ntraces))
    Notice.info("n_samples  {}".format(s.nsamples))
    Notice.info("dt         {}".format(s.dt))
    Notice.info("t_start    {}".format(s.tstart))
    Notice.info("t_end      {}".format(s.tend))
    Notice.info("max_val    " + fstr.format(np.amax(s.data)))
    Notice.info("min_val    " + fstr.format(np.amin(s.data)))
    Notice.info("clip_val   " + fstr.format(clip_val))

    t1 = time.time()
    Notice.ok("Read data in {:.1f} s".format(t1 - t0))

    #####################################################################
    #
    # MAKE PLOT
    #
    #####################################################################
    Notice.hr_header("Plotting")

    # Plot size parameters.
    wsl = 6  # Width of sidelabel, inches
    mih = 11  # Minimum plot height, inches
    fhh = 5  # File header box height, inches
    m = 0.75  # basic unit of margins, inches

    # Margins, CSS like: top, right, bottom, left.
    mt, mr, mb, ml = m, 1.5 * m, m, 1.5 * m
    mm = 2 * m  # padded margin between seismic and label

    # Determine plot dimensions. Kind of laborious and repetitive (see below).
    if cfg['plot_width']:
        seismic_width = cfg['plot_width'] - wsl - mm - ml - mr
        tpi = max([s.ntraces for s in ss]) / seismic_width
    else:
        tpi = cfg['tpi']

    if cfg['plot_height']:
        seismic_height = max(
            mih, cfg['plot_height']) - mb - 0.75 * (len(ss) - 1) - mt
        seismic_height_raw = seismic_height / len(ss)
        ips = seismic_height_raw / (s.tbasis[-1] - s.tbasis[0])
    else:
        ips = cfg['ips']

    # Width is determined by seismic width, plus sidelabel, plus margins.
    # Height is given by ips, but with a minimum of mih inches.
    if 'tslice' in direction:
        seismic_width = [s.ntraces / tpi for s in ss]
        seismic_height_raw = max([s.nxlines for s in ss]) / tpi
    else:
        seismic_width = [s.ntraces / tpi for s in ss]
        seismic_height_raw = ips * (s.tbasis[-1] - s.tbasis[0])

    w = ml + max(seismic_width) + mm + wsl + mr  # inches
    seismic_height = len(ss) * seismic_height_raw
    h_reqd = mb + seismic_height + 0.75 * (len(ss) - 1) + mt  # inches
    h = max(mih, h_reqd)

    # Calculate where to start sidelabel and seismic data.
    # Depends on whether sidelabel is on the left or right.
    if cfg['sidelabel'] == 'right':
        ssl = (ml + max(seismic_width) + mm) / w  # Start of side label (ratio)
        seismic_left = ml / w
    else:
        ssl = ml / w
        seismic_left = (ml + wsl + mm) / w

    adj = max(0, h - h_reqd) / 2
    seismic_bottom = (mb / h) + adj / h
    seismic_width_fraction = [sw / w for sw in seismic_width]
    seismic_height_fraction = seismic_height_raw / h

    # Publish some notices so user knows plot size.
    Notice.info("plot width   {:.2f} in".format(w))
    Notice.info("plot height  {:.2f} in".format(h))

    # Make the figure.
    fig = plt.figure(figsize=(w, h), facecolor='w')

    # Set the tickformat.
    tickfmt = mtick.FormatStrFormatter('%.0f')

    # Could definitely do better for default fontsize than 10.
    # Ideally would be adaptive to plot size.
    cfg['fontsize'] = cfg['fontsize'] or 10

    # Plot title.
    if cfg['title']:
        # Deal with Windows paths: \1 gets interpreted as a group by regex.
        newt = re.sub(r'\\', '@@@@@', target)
        temp = re.sub(r'_filename', newt, cfg['title'])
        title = re.sub(r'@@@', r'\\', temp)
        title_ax = fig.add_axes([ssl, 1 - mt / h, wsl / w, mt / h])
        title_ax = plotter.plot_title(title_ax,
                                      title,
                                      fs=1.4 * cfg['fontsize'],
                                      cfg=cfg)

    # Plot title.
    if cfg['subtitle']:
        date = str(datetime.date.today())
        subtitle = re.sub(r'_date', date, cfg['subtitle'])
        subtitle_ax = fig.add_axes([ssl, 1 - mt / h, wsl / w, mt / h],
                                   label='subtitle')
        title_ax = plotter.plot_subtitle(subtitle_ax,
                                         subtitle,
                                         fs=0.75 * cfg['fontsize'],
                                         cfg=cfg)

    # Plot text header.
    start = (h - 1.5 * mt - fhh) / h
    head_ax = fig.add_axes([ssl, start, wsl / w, fhh / h])
    head_ax = plotter.plot_header(head_ax,
                                  s.header,
                                  fs=9,
                                  cfg=cfg,
                                  version=__version__)

    # Plot histogram.
    # Params for histogram plot.
    pady = 0.75 / h  # 0.75 inch
    padx = 0.75 / w  # 0.75 inch
    cstrip = 0.3 / h  # color_strip height = 0.3 in
    charth = 1.25 / h  # height of charts = 1.25 in
    chartw = wsl / w - mr / w - padx  # or ml/w for left-hand sidelabel; same thing
    chartx = (ssl + padx)
    histy = 1.5 * mb / h + charth + pady
    # Plot colourbar under histogram.
    clrbar_ax = fig.add_axes([chartx, histy - cstrip, chartw, cstrip])
    clrbar_ax = plotter.plot_colourbar(clrbar_ax, cmap=cfg['cmap'])
    # Plot histogram itself.
    hist_ax = fig.add_axes([chartx, histy, chartw, charth])
    hist_ax = plotter.plot_histogram(hist_ax, s.data, tickfmt, cfg)

    # Plot spectrum.
    specy = 1.5 * mb / h
    spec_ax = fig.add_axes([chartx, specy, chartw, charth])

    try:
        colour = utils.rgb_to_hex(cfg['highlight_colour'])
        spec_ax = s.plot_spectrum(
            ax=spec_ax,
            tickfmt=tickfmt,
            ntraces=20,
            fontsize=cfg['fontsize'],
            colour=colour,
        )
    except:
        pass  # No spectrum, oh well.

    for i, line in enumerate(ss):
        # Add the seismic axis.
        ax = fig.add_axes([
            seismic_left,
            seismic_bottom + i * seismic_height_fraction + i * pady,
            seismic_width_fraction[i], seismic_height_fraction
        ])

        # Plot seismic data.
        if cfg['display'].lower() in ['vd', 'varden', 'variable', 'both']:
            im = ax.imshow(line.data.T,
                           cmap=cfg['cmap'],
                           clim=[-clip_val, clip_val],
                           extent=[
                               line.olineidx[0], line.olineidx[-1],
                               1000 * line.tbasis[-1], line.tbasis[0]
                           ],
                           aspect='auto',
                           interpolation=cfg['interpolation'])

            if np.argmin(seismic_width) == i:
                cax = utils.add_subplot_axes(ax, [1.01, 0.02, 0.01, 0.2])
                _ = plt.colorbar(im, cax=cax)

        if cfg['display'].lower() in ['wiggle', 'both']:
            ax = line.wiggle_plot(
                cfg['number'],
                direction,
                ax=ax,
                skip=cfg['skip'],
                gain=cfg['gain'],
                rgb=cfg['colour'],
                alpha=cfg['opacity'],
                lw=cfg['lineweight'],
            )

        valid = ['vd', 'varden', 'variable', 'wiggle', 'both']
        if cfg['display'].lower() not in valid:
            Notice.fail("You must specify the display: wiggle, vd, both.")
            return

        # Seismic axis annotations.
        ax.set_ylabel(utils.LABELS[line.ylabel], fontsize=cfg['fontsize'])
        ax.set_xlabel(utils.LABELS[line.xlabel],
                      fontsize=cfg['fontsize'],
                      ha='center')
        ax.tick_params(axis='both', labelsize=cfg['fontsize'] - 2)

        ax.xaxis.set_major_formatter(tickfmt)
        ax.yaxis.set_major_formatter(tickfmt)
        if ('tslice' not in direction):
            ax.set_ylim(1000 * cfg['trange'][1] or 1000 * line.tbasis[-1],
                        1000 * cfg['trange'][0])

        # Crossing point. Will only work for non-arb lines.
        try:
            ax.axvline(ss[i - 1].slineidx[0],
                       c=utils.rgb_to_hex(cfg['highlight_colour']),
                       alpha=0.5)
        except IndexError:
            pass  # Nevermind.

        # Grid, optional.
        if cfg['grid_time'] or cfg['grid_traces']:
            ax.grid()
            for l in ax.get_xgridlines():
                l.set_color(utils.rgb_to_hex(cfg['grid_colour']))
                l.set_linestyle('-')
                if cfg['grid_traces']:
                    l.set_linewidth(1)
                else:
                    l.set_linewidth(0)
                l.set_alpha(min(1, cfg['grid_alpha']))
            for l in ax.get_ygridlines():
                l.set_color(utils.rgb_to_hex(cfg['grid_colour']))
                l.set_linestyle('-')
                if cfg['grid_time']:
                    if 'tslice' in direction:
                        l.set_linewidth(1)
                    else:
                        l.set_linewidth(1.4)
                else:
                    l.set_linewidth(0)
                l.set_alpha(min(1, 2 * cfg['grid_alpha']))

        # Watermark.
        if cfg['watermark_text']:
            ax = plotter.watermark_seismic(ax, cfg)

        # Make parasitic (top) axis for labeling CDP number.
        if (s.data.ndim > 2) and ('tslice' not in direction):
            ylim = ax.get_ylim()
            par1 = ax.twiny()
            par1.spines["top"].set_position(("axes", 1.0))
            par1.plot(line.slineidx, np.zeros_like(line.slineidx), alpha=0)
            par1.set_xlabel(utils.LABELS[line.slabel],
                            fontsize=cfg['fontsize'])
            par1.set_ylim(ylim)

            # Adjust ticks
            tx = par1.get_xticks()
            newtx = [
                line.slineidx[len(line.slineidx) * (i // len(tx))]
                for i, _ in enumerate(tx)
            ]
            par1.set_xticklabels(newtx, fontsize=cfg['fontsize'] - 2)

    t2 = time.time()
    Notice.ok("Built plot in {:.1f} s".format(t2 - t1))

    #####################################################################
    #
    # SAVE FILE
    #
    #####################################################################
    Notice.hr_header("Saving")

    dname, fname, ext = utils.path_bits(target)
    outfile = cfg['outfile'] or ''
    if not os.path.splitext(outfile)[1]:
        outfile = os.path.join(cfg['outfile'] or dname, fname + '.png')

    fig.savefig(outfile)

    t3 = time.time()
    Notice.info("output file {}".format(outfile))
    Notice.ok("Saved output in {:.1f} s".format(t3 - t2))

    if cfg['stain_paper'] or cfg['coffee_rings'] or cfg['distort'] or cfg[
            'scribble']:
        fname = os.path.splitext(outfile)[0] + ".stupid.png"
        fig.savefig(fname)
    else:
        return

    #####################################################################
    #
    # SAVE STUPID FILE
    #
    #####################################################################
    Notice.hr_header("Applying the stupidity")

    stupid_image = Image.open(fname)
    if cfg['stain_paper']:
        utils.stain_paper(stupid_image)
    utils.add_rings(stupid_image, cfg['coffee_rings'])
    if cfg['scribble']:
        utils.add_scribble(stupid_image)

    # Trick to remove remaining semi-transparent pixels.
    result = Image.new("RGB", stupid_image.size, (255, 255, 255))
    result.paste(stupid_image)

    result.save(fname)

    t4 = time.time()
    Notice.info("output file {}".format(fname))
    Notice.ok("Saved stupidity in {:.1f} s".format(t4 - t3))

    return
Пример #14
0
def check_ergodicity(reps=500):
    """ Check whether simulated systems are ergodic
    """
    def get_matrices(syst, entry_num=100):
        """ Get correlation matrices for both cases
        """
        # multiple entries from single run
        single_run_matrices = []
        for _ in range(entry_num):
            sol = solve_system(syst)

            extract = sol.T[-entry_num:]
            single_run_mat = compute_correlation_matrix(np.array([extract]))

            single_run_matrices.append(single_run_mat)
        avg_single_mat = np.mean(single_run_matrices, axis=0)

        # one entry from multiple runs
        multiple_runs = []
        for _ in range(entry_num):
            sol = solve_system(syst)

            extract = sol.T[-1].T
            multiple_runs.append(extract)
        multiple_mat = compute_correlation_matrix(np.array([multiple_runs]))

        return avg_single_mat, multiple_mat

    syst = generate_basic_system()

    single_runs = []
    multiple_runs = []
    for _ in trange(reps):
        sm, rm = get_matrices(syst)

        single_runs.append(sm)
        multiple_runs.append(rm)
    single_runs = np.array(single_runs)
    multiple_runs = np.array(multiple_runs)

    # plot result
    dim = syst.jacobian.shape[1]

    plt.figure(figsize=(6, 14))
    gs = mpl.gridspec.GridSpec(int((dim**2-dim)/2), 1)

    axc = 0
    for i in range(dim):
        for j in range(dim):
            if i == j: break
            ax = plt.subplot(gs[axc])

            plot_histogram(
                single_runs[:,i,j], ax,
                alpha=0.5,
                label='Multiple entries from single run')
            plot_histogram(multiple_runs[:,i,j], ax,
                facecolor='mediumturquoise', alpha=0.5,
                label='One entry from multiple runs')

            ax.set_title('Nodes {}, {}'.format(i, j))
            ax.set_xlabel('correlation')
            ax.legend(loc='best')

            axc += 1

    plt.tight_layout()
    plt.savefig('images/ergodicity_check.pdf')
Пример #15
0
def main(target, cfg):
    """
    Puts everything together.
    """
    t0 = time.time()

    #####################################################################
    #
    # READ SEGY
    #
    #####################################################################
    s = Seismic.from_segy(target, params={'ndim': cfg['ndim']})

    # Set the line and/or xline number.
    try:
        n, xl = cfg['number']
    except:
        n, xl = cfg['number'], 0.5

    # Set the direction.
    if (s.ndim) == 2:
        direction = ['inline']
    elif cfg['direction'].lower()[0] == 'i':
        direction = ['inline']
    elif cfg['direction'].lower()[0] == 'x':
        direction = ['xline']
    elif cfg['direction'].lower()[0] == 't':
        direction = ['tslice']
    else:
        direction = ['inline', 'xline']

    # Get the data.
    ss = [Seismic.from_seismic(s, n=n, direction=d) for n, d in zip((n, xl), direction)]
    data = [s.data for s in ss]

    clip_val = np.percentile(s.data, cfg['percentile'])

    # Notify user of parameters.
    Notice.info("n_traces   {}".format(s.ntraces))
    Notice.info("n_samples  {}".format(s.nsamples))
    Notice.info("dt         {}".format(s.dt))
    Notice.info("t_start    {}".format(s.tstart))
    Notice.info("t_end      {}".format(s.tend))
    Notice.info("max_val    {:.3f}".format(np.amax(s.data)))
    Notice.info("min_val    {:.3f}".format(np.amin(s.data)))
    Notice.info("clip_val   {:.3f}".format(clip_val))

    t1 = time.time()
    Notice.ok("Read data in {:.1f} s".format(t1-t0))

    #####################################################################
    #
    # MAKE PLOT
    #
    #####################################################################
    Notice.hr_header("Plotting")

    # Plot size parameters.
    fs = cfg['fontsize']
    wsl = 6  # Width of sidelabel, inches
    mih = 12  # Minimum plot height, inches
    fhh = 5  # File header box height, inches
    m = 0.5  # basic unit of margins, inches

    # Margins, CSS like: top, right, bottom, left.
    mt, mr, mb, ml = m, 2 * m, m, 2 * m
    mm = m  # padded margin between seismic and label

    # Width is determined by seismic width, plus sidelabel, plus margins.
    # Height is given by ips, but with a minimum of mih inches.
    if 'tslice' in direction:
        print('doing tslice')
        seismic_width = max([s.ninlines for s in ss]) / cfg['tpi']
        seismic_height_raw = max([s.nxlines for s in ss]) / cfg['tpi']
        print(seismic_width, seismic_height_raw)
    else:
        seismic_width = max([s.ntraces for s in ss]) / cfg['tpi']
        seismic_height_raw = cfg['ips'] * (s.tbasis[-1] - s.tbasis[0])

    w = ml + seismic_width + mm + wsl + mr  # inches
    seismic_height = len(ss) * seismic_height_raw
    h_reqd = mb + seismic_height + 0.75*(len(ss)-1) + mt  # inches
    h = max(mih, h_reqd)

    # Calculate where to start sidelabel and seismic data.
    # Depends on whether sidelabel is on the left or right.
    if cfg['sidelabel'] == 'right':
        ssl = (ml + seismic_width + mm) / w  # Start of side label (ratio)
        seismic_left = ml / w
    else:
        ssl = ml / w
        seismic_left = (ml + wsl + mm) / w

    adj = max(0, h - h_reqd) / 2
    seismic_bottom = (mb / h) + adj / h
    seismic_width_fraction = seismic_width / w
    seismic_height_fraction = seismic_height_raw / h

    # Publish some notices so user knows plot size.
    Notice.info("Width of plot   {} in".format(w))
    Notice.info("Height of plot  {} in".format(h))

    # Make the figure.
    fig = plt.figure(figsize=(w, h), facecolor='w')

    # Set the tickformat.
    tickfmt = mtick.FormatStrFormatter('%.0f')

    # Plot title.
    if cfg['filename']:
        title_ax = fig.add_axes([ssl, 1-mt/h, wsl/w, mt/h])
        title_ax = plotter.plot_title(title_ax, target, fs=1.5*fs, cfg=cfg)

    # Plot text header.
    start = (h - 1.5*mt - fhh) / h
    head_ax = fig.add_axes([ssl, start, wsl/w, fhh/h])
    head_ax = plotter.plot_header(head_ax, s.header, fs=fs-1, cfg=cfg)

    # Plot histogram.
    # Params for histogram plot.
    pady = 0.75 / h  # 0.75 inch
    padx = 0.75 / w   # 0.75 inch
    cstrip = 0.3/h   # color_strip height = 0.3 in
    charth = 1.5/h   # height of charts = 1.5 in
    chartw = wsl/w - mr/w - padx  # or ml/w for left-hand sidelabel; same thing
    chartx = (ssl + padx)
    histy = 1.5 * mb/h + charth + pady
    # Plot colourbar under histogram.
    clrbar_ax = fig.add_axes([chartx, histy - cstrip, chartw, cstrip])
    clrbar_ax = plotter.plot_colourbar(clrbar_ax, cmap=cfg['cmap'])
    # Plot histogram itself.
    hist_ax = fig.add_axes([chartx, histy, chartw, charth])
    hist_ax = plotter.plot_histogram(hist_ax,
                                     s.data,
                                     tickfmt,
                                     percentile=cfg['percentile'],
                                     fs=fs)

    # Plot spectrum.
    specy = 1.5 * mb/h
    spec_ax = fig.add_axes([chartx, specy, chartw, charth])

    try:
        spec_ax = s.plot_spectrum(ax=spec_ax,
                                  tickfmt=tickfmt,
                                  ntraces=20,
                                  fontsize=fs)
    except:
        pass

    for i, line in enumerate(ss):
        # Add the seismic axis.
        ax = fig.add_axes([seismic_left,
                           seismic_bottom + i*seismic_height_fraction + i*pady,
                           seismic_width_fraction,
                           seismic_height_fraction
                           ])

        # Plot seismic data.
        if cfg['display'].lower() in ['vd', 'varden', 'variable', 'both']:
            _ = ax.imshow(line.data.T,
                          cmap=cfg['cmap'],
                          clim=[-clip_val, clip_val],
                          extent=[0, 
                                  line.ntraces,
                                  1000*line.tbasis[-1],
                                  line.tbasis[0]],
                          aspect='auto'
                          )

            # This does not work: should cut off line at cfg['tmax']
            # ax.set_ylim(1000*cfg['tmax'] or 1000*line.tbasis[-1], line.tbasis[0])

        if cfg['display'].lower() in ['wiggle', 'both']:
            ax = line.wiggle_plot(cfg['number'], direction,
                               ax=ax,
                               skip=cfg['skip'],
                               gain=cfg['gain'],
                               rgb=cfg['colour'],
                               alpha=cfg['opacity'],
                               lw=cfg['lineweight'],
                               tmax=cfg['tmax'],
                               )

        if cfg['display'].lower() not in ['vd', 'varden', 'variable', 'wiggle', 'both']:
            Notice.fail("You must specify the type of display: wiggle, vd, both.")
            return

        # Seismic axis annotations.
        fs = cfg['fontsize'] - 2
        ax.set_xlim([0, line.data.shape[0]])
        ax.set_ylabel(line.ylabel, fontsize=fs)
        ax.set_xlabel(line.xlabel, fontsize=fs, horizontalalignment='center')
        ax.set_xticklabels(ax.get_xticks(), fontsize=fs)
        ax.set_yticklabels(ax.get_yticks(), fontsize=fs)
        ax.xaxis.set_major_formatter(tickfmt)
        ax.yaxis.set_major_formatter(tickfmt)


        # Watermark.
        if cfg['watermark_text']:
            ax = plotter.watermark_seismic(ax, cfg)

        # Make parasitic axes for labeling CDP number.
        par1 = ax.twiny()
        par1.spines["top"].set_position(("axes", 1.0))
        par1.plot(s.xlines, np.zeros_like(s.xlines))
        par1.set_xlabel(line.xlabel, fontsize=fs)
        par1.set_xticklabels(par1.get_xticks(), fontsize=fs)
        par1.xaxis.set_major_formatter(tickfmt)

    t2 = time.time()
    Notice.ok("Built plot in {:.1f} s".format(t2-t1))

    #####################################################################
    #
    # SAVE FILE
    #
    #####################################################################
    Notice.hr_header("Saving")

    dname, fname, ext = utils.path_bits(target)
    outfile = cfg['outfile'] or ''
    if not os.path.splitext(outfile)[1]:
        outfile = os.path.join(cfg['outfile'] or dname, fname + '.png')

    fig.savefig(outfile)

    t3 = time.time()
    Notice.ok("Saved image file {} in {:.1f} s".format(outfile, t3-t2))

    if cfg['stain_paper'] or cfg['coffee_rings'] or cfg['distort'] or cfg['scribble']:
        fname = os.path.splitext(outfile)[0] + ".stupid.png"
        fig.savefig(fname)
    else:
        return

    #####################################################################
    #
    # SAVE STUPID FILE
    #
    #####################################################################
    Notice.hr_header("Applying the stupidity")

    stupid_image = Image.open(fname)
    if cfg['stain_paper']: utils.stain_paper(stupid_image)
    utils.add_rings(stupid_image, cfg['coffee_rings'])
    if cfg['scribble']: utils.add_scribble(stupid_image)
    stupid_image.save(fname)

    t4 = time.time()
    Notice.ok("Saved stupid file {} in {:.1f} s".format(fname, t4-t3))

    return
Пример #16
0
def check_ergodicity(reps=500):
    """ Check whether simulated systems are ergodic
    """
    def get_matrices(syst, entry_num=100):
        """ Get correlation matrices for both cases
        """
        # multiple entries from single run
        single_run_matrices = []
        for _ in range(entry_num):
            sol = solve_system(syst)

            extract = sol.T[-entry_num:]
            single_run_mat = compute_correlation_matrix(np.array([extract]))

            single_run_matrices.append(single_run_mat)
        avg_single_mat = np.mean(single_run_matrices, axis=0)

        # one entry from multiple runs
        multiple_runs = []
        for _ in range(entry_num):
            sol = solve_system(syst)

            extract = sol.T[-1].T
            multiple_runs.append(extract)
        multiple_mat = compute_correlation_matrix(np.array([multiple_runs]))

        return avg_single_mat, multiple_mat

    syst = generate_basic_system()

    single_runs = []
    multiple_runs = []
    for _ in trange(reps):
        sm, rm = get_matrices(syst)

        single_runs.append(sm)
        multiple_runs.append(rm)
    single_runs = np.array(single_runs)
    multiple_runs = np.array(multiple_runs)

    # plot result
    dim = syst.jacobian.shape[1]

    plt.figure(figsize=(6, 14))
    gs = mpl.gridspec.GridSpec(int((dim**2-dim)/2), 1)

    axc = 0
    for i in range(dim):
        for j in range(dim):
            if i == j: break
            ax = plt.subplot(gs[axc])

            plot_histogram(
                single_runs[:,i,j], ax,
                alpha=0.5,
                label='Multiple entries from single run')
            plot_histogram(multiple_runs[:,i,j], ax,
                facecolor='mediumturquoise', alpha=0.5,
                label='One entry from multiple runs')

            ax.set_title('Nodes {}, {}'.format(i, j))
            ax.set_xlabel('correlation')
            ax.legend(loc='best')

            axc += 1

    plt.tight_layout()
    plt.savefig('images/ergodicity_check.pdf')
Пример #17
0
	if progress%1000==0:
		sys.stdout.write("\tCurrent progress: %d cards grouped\r" % (progress) )
		sys.stdout.flush()


frequencies = np.asarray(frequencies)
amounts = np.asarray(amounts)

frequencies = frequencies[frequencies<=500]
amounts = amounts[amounts<=25000]

sys.stdout.write("\tCurrent progress: %d cards grouped\r\n" % (len(frequencies)) )
sys.stdout.flush()

plotter.plot_histogram(frequencies,"History length","../results/history_length_histogram.png",50)

plotter.plot_histogram(amounts,"Mean purchase amount","../results/mean_amounts_histogram.png",50)

print "Mean purchase amount: " , np.mean(amounts)

print "Median purchase amount: " , np.median(amounts)

print "Number of cards: " , len(frequencies)

############################################################




Пример #18
0
def main(target, cfg):
    """
    Puts everything together.
    """
    t0 = time.time()

    # Read the file.
    section = readSEGY(target, unpack_headers=True)

    # Calculate some things.
    # NB Getting nsamples and dt from the first trace assumes that all
    # traces are the same length, which is not a safe assumption in SEGY v2.
    ninlines = section.traces[-1].header.trace_sequence_number_within_line
    last_tr = section.traces[-1].header.trace_sequence_number_within_segy_file
    nxlines = last_tr / ninlines

    nsamples = section.traces[0].header.number_of_samples_in_this_trace
    dt = section.traces[0].header.sample_interval_in_ms_for_this_trace
    ntraces = len(section.traces)
    tbase = 0.001 * np.arange(0, nsamples * dt, dt)
    tstart = 0
    tend = np.amax(tbase)

    # Make the data array.
    data = np.vstack([t.data for t in section.traces]).T

    threed = False
    if nxlines > 1:  # Then it's a 3D and `data` is an ensemble.
        threed = True
        cube = np.reshape(data.T, (ninlines, nxlines, nsamples))
        l = cfg['number']
        if cfg['direction'].lower()[0] == 'i':
            direction = 'inline'
            ntraces = nxlines
            l *= ninlines if (l < 1) else 1
            data = cube[l, :, :].T
        else:
            direction = 'xline'
            ntraces = ninlines
            l *= nxlines if (l < 1) else 1
            data = cube[:, l, :].T

    # Collect some other data. Use a for loop because there are several.
    elev, esp, ens, tsq = [], [], [], []
    for i, trace in enumerate(section.traces):
        elev.append(trace.header.receiver_group_elevation)
        esp.append(trace.header.energy_source_point_number)
        tsq.append(trace.header.trace_sequence_number_within_line)

        if threed:
            trs = []
            if direction == 'inline':
                cdp_label_text = 'Crossline number'
                trace_label_text = 'Trace number'
                ens.append(trace.header.for_3d_poststack_data_this_field_is_for_cross_line_number)
                trs.append(trace.header.for_3d_poststack_data_this_field_is_for_in_line_number)
            else:
                cdp_label_text = 'Inline number'
                trace_label_text = 'Trace number'
                ens.append(trace.header.for_3d_poststack_data_this_field_is_for_in_line_number)
                trs.append(trace.header.for_3d_poststack_data_this_field_is_for_cross_line_number)
            line_no = min(trs)
        else:
            cdp_label_text = 'CDP number'
            trace_label_text = 'Trace number'
            ens.append(trace.header.ensemble_number)
        min_tr, max_tr = 0, ntraces

    traces = (min_tr, max_tr)

    clip_val = np.percentile(data, cfg['percentile'])

    # Notify user of parameters
    Notice.info("n_traces   {}".format(ntraces))
    Notice.info("n_samples  {}".format(nsamples))
    Notice.info("dt         {}".format(dt))
    Notice.info("t_start    {}".format(tstart))
    Notice.info("t_end      {}".format(tend))
    Notice.info("max_val    {}".format(np.amax(data)))
    Notice.info("min_val    {}".format(np.amin(data)))
    Notice.info("clip_val   {}".format(clip_val))

    t1 = time.time()
    Notice.ok("Read data in {:.1f} s".format(t1-t0))

    #####################################################################
    #
    # MAKE PLOT
    #
    #####################################################################
    Notice.hr_header("Plotting")

    ##################################
    # Plot size parameters
    # Some constants
    fs = cfg['fontsize']
    wsl = 6  # Width of sidelabel, inches
    mih = 12  # Minimum plot height, inches
    fhh = 5  # File header box height, inches
    m = 0.5  # basic unit of margins, inches

    # Margins, CSS like: top, right, bottom, left.
    mt, mr, mb, ml = m,  2 * m, m, 2 * m
    mm = m  # padded margin between seismic and label

    # Width is determined by seismic width, plus sidelabel, plus margins.
    seismic_width = ntraces / cfg['tpi']
    w = ml + seismic_width + mm + wsl + mr  # inches

    # Height is given by ips, but with a minimum of mih inches
    seismic_height = cfg['ips'] * (tbase[-1] - tbase[0]) / 1000
    h_reqd = mb + seismic_height + mt  # inches
    h = max(mih, h_reqd)

    # Calculate where to start sidelabel and seismic data.
    # Depends on whether sidelabel is on the left or right.
    if cfg['sidelabel'] == 'right':
        ssl = (ml + seismic_width + mm) / w  # Start of side label (ratio)
        seismic_left = ml / w
    else:
        ssl = ml / w
        seismic_left = (ml + wsl + mm) / w

    adj = max(0, h - h_reqd) / 2
    seismic_bottom = (mb / h) + adj / h
    seismic_width_fraction = seismic_width / w
    seismic_height_fraction = seismic_height / h

    # Publish some notices so user knows plot size.
    Notice.info("Width of plot   {} in".format(w))
    Notice.info("Height of plot  {} in".format(h))

    ##################################
    # Make the figure.
    fig = plt.figure(figsize=(w, h), facecolor='w')

    # Add the main seismic axis.
    ax = fig.add_axes([seismic_left,
                       seismic_bottom,
                       seismic_width_fraction,
                       seismic_height_fraction
                       ])

    # make parasitic axes for labeling CDP number
    par1 = ax.twiny()
    par1.spines["top"].set_position(("axes", 1.0))
    tickfmt = mtick.FormatStrFormatter('%.0f')
    par1.plot(ens, np.zeros_like(ens))
    par1.set_xlabel(cdp_label_text, fontsize=fs-2)
    par1.set_xticklabels(par1.get_xticks(), fontsize=fs-2)
    par1.xaxis.set_major_formatter(tickfmt)

    # Plot title
    title_ax = fig.add_axes([ssl, 1-mt/h, wsl/w, mt/(h)])
    title_ax = plotter.plot_title(title_ax, target, fs=1.5*fs, cfg=cfg)
    if threed:
        title_ax.text(0.0, 0.0, '{} {}'.format(direction.title(), line_no))

    # Plot text header.
    s = section.textual_file_header.decode()
    start = (h - 1.5*mt - fhh) / h
    head_ax = fig.add_axes([ssl, start, wsl/w, fhh/h])
    head_ax = plotter.plot_header(head_ax, s, fs=fs-1, cfg=cfg)

    # Plot histogram.
    # Params for histogram plot
    pady = 0.75 / h  # 0.75 inch
    padx = 0.75 / w   # 0.75 inch
    cstrip = 0.3/h   # color_strip height = 0.3 in
    charth = 1.5/h   # height of charts = 1.5 in
    chartw = wsl/w - mr/w - padx  # or ml/w for left-hand sidelabel; same thing
    chartx = (ssl + padx)
    histy = 1.5 * mb/h + charth + pady
    # Plot colourbar under histogram
    clrbar_ax = fig.add_axes([chartx, histy - cstrip, chartw, cstrip])
    clrbar_ax = plotter.plot_colourbar(clrbar_ax, cmap=cfg['cmap'])
    # Plot histogram itself
    hist_ax = fig.add_axes([chartx, histy, chartw, charth])
    hist_ax = plotter.plot_histogram(hist_ax,
                                     data,
                                     tickfmt,
                                     percentile=cfg['percentile'],
                                     fs=fs)

    # Plot spectrum.
    specy = 1.5 * mb/h
    spec_ax = fig.add_axes([chartx, specy, chartw, charth])

    try:
        spec_ax = plotter.plot_spectrum(spec_ax,
                                        data,
                                        dt,
                                        tickfmt,
                                        ntraces=20,
                                        fontsize=fs)
    except:
        pass

    # Plot seismic data.
    if cfg['display'].lower() in ['vd', 'varden', 'variable']:
        _ = ax.imshow(data,
                      cmap=cfg['cmap'],
                      clim=[-clip_val, clip_val],
                      extent=[0, ntraces, tbase[-1], tbase[0]],
                      aspect='auto'
                      )

    elif cfg['display'].lower() == 'wiggle':
        ax = plotter.wiggle_plot(ax,
                                 data,
                                 tbase,
                                 ntraces,
                                 skip=cfg['skip'],
                                 gain=cfg['gain'],
                                 rgb=cfg['colour'],
                                 alpha=cfg['opacity'],
                                 lw=cfg['lineweight']
                                 )
        ax.set_ylim(ax.get_ylim()[::-1])

    elif cfg['display'].lower() == 'both':
        # variable density goes on first
        _ = ax.imshow(data,
                      cmap=cfg['cmap'],
                      clim=[-clip_val, clip_val],
                      extent=[0, ntraces, tbase[-1], tbase[0]],
                      aspect='auto'
                      )

        # wiggle plots go on top
        ax = plotter.wiggle_plot(ax,
                                 data,
                                 tbase,
                                 ntraces,
                                 skip=cfg['skip'],
                                 gain=cfg['gain'],
                                 rgb=cfg['colour'],
                                 alpha=cfg['opacity'],
                                 lw=cfg['lineweight']
                                 )
        # ax.set_ylim(ax.get_ylim()[::-1])

    else:
        Notice.fail("You need to specify the type of display: wiggle or vd")

    # Seismic axis annotations.
    ax = plotter.decorate_seismic(ax, traces, trace_label_text, tickfmt, cfg)

    # Watermark.
    if cfg['watermark_text']:
        Notice.info("Adding watermark")
        ax = plotter.watermark_seismic(ax, cfg)

    t2 = time.time()
    Notice.ok("Built plot in {:.1f} s".format(t2-t1))

    #####################################################################
    #
    # SAVE FILE
    #
    #####################################################################
    Notice.hr_header("Saving")

    if cfg['stain_paper'] or cfg['coffee_rings'] or cfg['distort'] or cfg['scribble']:
        stupid = True
    else:
        stupid = False

    s = "Saved image file {} in {:.1f} s"
    if cfg['outfile']:

        if os.path.isfile(cfg['outfile']):
            outfile = cfg['outfile']
        else:  # is directory
            stem, ext = os.path.splitext(os.path.split(target)[1])
            outfile = os.path.join(cfg['outfile'], stem + '.png')

        stem, _ = os.path.splitext(outfile)  # Needed for stupidity.
        fig.savefig(outfile)
        t3 = time.time()
        Notice.ok(s.format(outfile, t3-t2))
    else:  # Do the default: save a PNG in the same dir as the target.
        stem, _ = os.path.splitext(target)
        fig.savefig(stem)
        t3 = time.time()
        Notice.ok(s.format(stem+'.png', t3-t2))

    if stupid:
        fig.savefig(stem + ".stupid.png")
    else:
        return

    #####################################################################
    #
    # SAVE STUPID FILE
    #
    #####################################################################
    Notice.hr_header("Applying the stupidity")

    stupid_image = Image.open(stem + ".stupid.png")
    if cfg['stain_paper']:
        utils.stain_paper(stupid_image)
    utils.add_rings(stupid_image, cfg['coffee_rings'])
    if cfg['scribble']:
        utils.add_scribble(stupid_image)
    stupid_image.save(stem + ".stupid.png")

    s = "Saved stupid file stupid.png in {:.1f} s"
    t4 = time.time()
    Notice.ok(s.format(t4-t3))

    return