Ejemplo n.º 1
0
    def test_gradient(self):
        """
        Should test if the gradient calculation returns the same result when using 'along_wiggle' as for single layer
        :return:
        """
        rho = RpTestCase.w.block['Logs'].logs['den'].data
        vp = cnvrt(RpTestCase.w.block['Logs'].logs['ac'].data, 'us/ft', 'm/s')
        vs = cnvrt(RpTestCase.w.block['Logs'].logs['acs'].data, 'us/ft', 'm/s')
        grad2 = rp.gradient(vp, None, vs, None, rho, None, along_wiggle=True)
        i = 10637
        grad1 = rp.gradient(vp[i], vp[i + 1], vs[i], vs[i + 1], rho[i],
                            rho[i + 1])
        grad1_2 = rp.gradient(vp[i + 1], vp[i + 2], vs[i + 1], vs[i + 2],
                              rho[i + 1], rho[i + 2])

        with self.subTest():
            print('Layer based gradient at i {}: {}'.format(i, grad1))
            print('Layer based gradient at i {}: {}'.format(i + 1, grad1_2))
            print('Wiggle based gradient at i {}: {}'.format(
                i, grad2[i:i + 2]))
            self.assertTrue(True)
Ejemplo n.º 2
0
    def test_step(self):
        i = 5
        theta = 10.  # degrees
        x1 = np.linspace(1, 10, 10)
        x2 = np.linspace(2, 11, 10)
        x3 = np.linspace(3, 12, 10)
        d1 = rp.step(x1[i], x1[i + 1])
        d2 = rp.step(x1, None, along_wiggle=True)
        incept1 = rp.intercept(x1[i], x1[i + 1], x3[i], x3[i + 1])
        incept2 = rp.intercept(x1, None, x3, None, along_wiggle=True)
        grad1 = rp.gradient(x1[i], x1[i + 1], x2[i], x2[i + 1], x3[i],
                            x3[i + 1])
        grad2 = rp.gradient(x1, None, x2, None, x3, None, along_wiggle=True)
        func1 = rp.reflectivity(x1[i], x1[i + 1], x2[i], x2[i + 1], x3[i],
                                x3[i + 1])
        func2 = rp.reflectivity(x1,
                                None,
                                x2,
                                None,
                                x3,
                                None,
                                along_wiggle=True)

        with self.subTest():
            print('Layer based step at i {}: {}'.format(i, d1))
            print('Wiggle based step at i {}: {}'.format(i, d2[i]))
            print('Layer based intercept at i {}: {}'.format(i, incept1))
            print('Wiggle based intercept at i {}: {}'.format(i, incept2[i]))
            print('Layer based gradient at i {}: {}'.format(i, grad1))
            print('Wiggle based gradient at i {}: {}'.format(i, grad2[i]))
            print('Layer based refl. coeff. at i {} at {} deg.: {}'.format(
                i, theta, func1(theta)))
            print('Wiggle based refl. coeff. at i {} at {} deg.: {}'.format(
                i, theta,
                func2(theta)[i]))
            self.assertTrue(True)
Ejemplo n.º 3
0
def rpt_phi_sw(_phi, _sw, **kwargs):
    plot_type = kwargs.pop('plot_type', 'AI-VpVs')
    ref_val = kwargs.pop(
        'ref_val', [3500., 1700., 2.6
                    ])  # ref values of Vp, Vs and rho for calculating I x G
    model = kwargs.pop('model', 'stiff')
    phic = kwargs.pop('phic', 0.4)  # critical porosity
    cn = kwargs.pop(
        'cn', 8)  # coordination number, average number of contacts per grain
    p = kwargs.pop('p', 10)  # Confining pressure in MPa (effective pressure?)
    f = kwargs.pop(
        'f', 0.3
    )  # shear modulus correction factor  (1=dry pack with perfect adhesion, 0=dry frictionless pack)
    rho_b = kwargs.pop('rho_b', 1.1)  # Brine density  g/cm3
    k_b = kwargs.pop('k_b', 2.8)  # Brine bulk modulus  GPa
    rho_hc = kwargs.pop('rho_hc', 0.2)  # HC density
    k_hc = kwargs.pop('k_hc', 0.06)  # HC bulk modulus
    rho_min = kwargs.pop('rho_min', 2.7)  # Density [g/cm3] of mineral mix
    k_min = kwargs.pop('k_min', 30.)  # Bulk modulus GPa of mineral mix
    mu_min = kwargs.pop('mu_min', 20.)  # Shear modulus of mineral mix

    # Apply the rock physics model to modify the mineral properties
    if model == 'stiff':
        k_dry, mu_dry = rp.stiffsand(k_min, mu_min, _phi, phic, cn, p, f)
    else:
        k_dry, mu_dry = rp.softsand(k_min, mu_min, _phi, phic, cn, p, f)

    # Calculate the final fluid properties for the given water saturation
    k_f2 = rp.vrh_bounds([_sw, 1. - _sw], [k_b, k_hc])[1]  # K_f
    rho_f2 = rp.vrh_bounds([_sw, 1. - _sw], [rho_b, rho_hc])[0]  #RHO_f

    # Use Gassman to calculate the final elastic properties
    vp_2, vs_2, rho_2, k_2 = rp.vels(k_dry, mu_dry, k_min, rho_min, k_f2,
                                     rho_f2, _phi)

    if plot_type == 'AI-VpVs':
        xx = rho_2 * vp_2
        yy = vp_2 / vs_2
    elif plot_type == 'Phi-Vp':
        xx = _phi
        yy = vp_2
    elif plot_type == 'I-G':
        xx = rp.intercept(ref_val[0], vp_2, ref_val[2], rho_2)
        yy = rp.gradient(ref_val[0], vp_2, ref_val[1], vs_2, ref_val[2], rho_2)
    else:
        raise IOError('No valid plot_type selected')

    return xx, yy
Ejemplo n.º 4
0
def plot_one_interface(sums,
                       name1,
                       name2,
                       color,
                       fig_ig,
                       ax_ig,
                       fig_refl,
                       ax_refl,
                       n_samps=1000):

    # elastics_from_stats calculates the normally distributed variables, with correlations, given
    # the mean, std and correlation, using a multivariate function
    vp1, vs1, rho1 = elastics_from_stats(sums[name1], n_samps)
    vp2, vs2, rho2 = elastics_from_stats(sums[name2], n_samps)

    # Calculate statistics of the reflection coefficient, assuming 50 samples from 0 to 40 deg incidence angle
    theta = np.linspace(0, 40, 50)
    refs = np.full((n_samps, 50), np.nan)
    # calculate the reflectivity as a function of theta for all variations of the elastic properties
    for i, params in enumerate(zip(vp1, vp2, vs1, vs2, rho1, rho2)):
        refs[i, :] = rp.reflectivity(*params)(theta)

    refl_stds = np.std(refs, 0)

    # Calculate the mean reflectivity curve
    mean_refl = rp.reflectivity(
        sums[name1]['VpMean'],
        sums[name2]['VpMean'],
        sums[name1]['VsMean'],
        sums[name2]['VsMean'],
        sums[name1]['RhoMean'],
        sums[name2]['RhoMean'],
    )

    # plot the mean reflectivity curve together with the uncertainty
    mypr.plot(theta,
              mean_refl(theta),
              c=color,
              yerror=refl_stds,
              yerr_style='fill',
              fig=fig_refl,
              ax=ax_refl)

    intercept = rp.intercept(vp1, vp2, rho1, rho2)
    gradient = rp.gradient(vp1, vp2, vs1, vs2, rho1, rho2)

    #res = least_squares(
    #        mycf.residuals,
    #        [1.,1.],
    #        args=(intercept, gradient),
    #        kwargs={'target_function': straight_line}
    #)
    #print('{} on {}: WS = {:.4f}*I {:.4f} - G'.format(name1, name2, *res.x))
    #print(res.status)
    #print(res.message)
    #print(res.success)

    myxp.plot(intercept,
              gradient,
              cdata=color,
              fig=fig_ig,
              ax=ax_ig,
              edge_color=None,
              alpha=0.2)
    #x_new = np.linspace(-0.75, 0.75, 50)
    #ax_ig.plot(x_new, straight_line(x_new, *res.x), c=color, label='_nolegend_')

    # Do AVO classification
    c1 = len(gradient[(intercept > 0.) & (gradient > -4 * intercept) &
                      (gradient < 0.)])
    c2p = len(gradient[(intercept > 0.) & (gradient < -4 * intercept)])
    c2 = len(gradient[(intercept > -0.02) & (intercept < 0.) &
                      (gradient < 0.)])
    c3 = len(gradient[(intercept < -0.02) & (gradient < 0.)])
    c4 = len(gradient[(intercept < 0.) & (gradient > 0.)])
    rest = len(gradient[(intercept > 0.) & (gradient > 0.)])
    print(
        'Class I: {:.0f}% \nClass IIp: {:.0f}% \nClass II: {:.0f}% \nClass III: {:.0f}% \nClass IV: {:.0f}%'
        .format(100. * c1 / n_samps, 100. * c2p / n_samps, 100. * c2 / n_samps,
                100. * c3 / n_samps, 100. * c4 / n_samps))
    print('Rest:  {:.0f}%'.format(100. * rest / n_samps))
Ejemplo n.º 5
0
def twolayer(vp0, vs0, rho0, vp1, vs1, rho1, angels=None):
    #from bruges.reflection import shuey2
    #from bruges.filters import ricker
    from rp.rp_core import reflectivity, intercept, gradient
    if angels is None:
        angels = [5, 15, 30]

    n_samples = 500
    interface = int(n_samples / 2)
    ang = np.arange(31)
    wavelet = ricker(.25, 0.001, 25)

    model_ip, model_vpvs, rc0, rc1, rc2 = (np.zeros(n_samples)
                                           for _ in range(5))
    model_z = np.arange(n_samples)
    model_ip[:interface] = vp0 * rho0
    model_ip[interface:] = vp1 * rho1
    model_vpvs[:interface] = np.true_divide(vp0, vs0)
    model_vpvs[interface:] = np.true_divide(vp1, vs1)

    #avo = shuey2(vp0, vs0, rho0, vp1, vs1, rho1, ang)
    _avo = reflectivity(vp0, vp1, vs0, vs1, rho0, rho1, version='ShueyAkiRich')
    avo = _avo(ang)
    rc0[interface] = avo[angels[0]]
    rc1[interface] = avo[angels[1]]
    rc2[interface] = avo[angels[2]]
    synt0 = np.convolve(rc0, wavelet, mode='same')
    synt1 = np.convolve(rc1, wavelet, mode='same')
    synt2 = np.convolve(rc2, wavelet, mode='same')
    clip = np.max(np.abs([synt0, synt1, synt2]))
    clip += clip * .2

    ic = intercept(vp0, vp1, rho0, rho1)
    gr = gradient(vp0, vp1, vs0, vs1, rho0, rho1)

    opz0 = {'color': 'b', 'linewidth': 4}
    opz1 = {'color': 'k', 'linewidth': 2}
    opz2 = {'linewidth': 0, 'alpha': 0.5}
    opz3 = {'color': 'tab:red', 'linewidth': 0, 'markersize': 8, 'marker': 'o'}
    opz4 = {
        'color': 'tab:blue',
        'linewidth': 0,
        'markersize': 8,
        'marker': 'o'
    }

    f = plt.subplots(figsize=(12, 10))
    ax0 = plt.subplot2grid((2, 12), (0, 0), colspan=3)  # ip
    ax1 = plt.subplot2grid((2, 12), (0, 3), colspan=3)  # vp/vs
    ax2 = plt.subplot2grid((2, 12), (0, 6), colspan=2)  # synthetic @ 0 deg
    ax3 = plt.subplot2grid((2, 12), (0, 8), colspan=2)  # synthetic @ 30 deg
    ax35 = plt.subplot2grid((2, 12), (0, 10), colspan=2)  # synthetic @ 30 deg
    ax4 = plt.subplot2grid((2, 12), (1, 0), colspan=5)  # avo curve
    ax6 = plt.subplot2grid((2, 12), (1, 7), colspan=5)  # avo curve

    ax0.plot(model_ip, model_z, **opz0)
    ax0.set_xlabel('IP')
    ax0.locator_params(axis='x', nbins=2)

    ax1.plot(model_vpvs, model_z, **opz0)
    ax1.set_xlabel('VP/VS')
    ax1.locator_params(axis='x', nbins=2)

    ax2.plot(synt0, model_z, **opz1)
    ax2.plot(synt0[interface], model_z[interface], **opz3)
    ax2.fill_betweenx(model_z,
                      0,
                      synt0,
                      where=synt0 > 0,
                      facecolor='black',
                      **opz2)
    ax2.set_xlim(-clip, clip)
    ax2.set_xlabel('angle={:.0f}'.format(angels[0]))
    ax2.locator_params(axis='x', nbins=2)

    ax3.plot(synt1, model_z, **opz1)
    ax3.plot(synt1[interface], model_z[interface], **opz3)
    ax3.fill_betweenx(model_z,
                      0,
                      synt1,
                      where=synt1 > 0,
                      facecolor='black',
                      **opz2)
    ax3.set_xlim(-clip, clip)
    ax3.set_xlabel('angle={:.0f}'.format(angels[1]))
    ax3.locator_params(axis='x', nbins=2)

    ax35.plot(synt2, model_z, **opz1)
    ax35.plot(synt2[interface], model_z[interface], **opz3)
    ax35.fill_betweenx(model_z,
                       0,
                       synt2,
                       where=synt2 > 0,
                       facecolor='black',
                       **opz2)
    ax35.set_xlim(-clip, clip)
    ax35.set_xlabel('angle={:.0f}'.format(angels[2]))
    ax35.locator_params(axis='x', nbins=2)

    ax4.plot(ang, avo, **opz0)
    ax4.axhline(0, color='k', lw=2)
    ax4.set_xlabel('angle of incidence')
    ax4.tick_params(which='major', labelsize=8)

    ax5 = ax4.twinx()
    color = 'tab:red'
    ax5.plot(angels, [s[interface] for s in [synt0, synt1, synt2]], **opz3)
    ax5.set_ylabel('Seismic amplitude')
    ax5.tick_params(axis='y', labelcolor=color, labelsize=8)

    # Calculate intercept & gradient based on the three "angle stacks"1G
    res = least_squares(
        mycf.residuals, [1., 1.],
        args=(np.array(angels),
              np.array([s[interface] for s in [synt0, synt1, synt2]])),
        kwargs={'target_function': straight_line})
    print('amp = {:.4f}*theta + {:.4f}'.format(*res.x))
    print(res.status)
    print(res.message)
    print(res.success)
    ax5.plot(ang, straight_line(ang, *res.x), c='tab:red')

    res2 = least_squares(
        mycf.residuals, [1., 1.],
        args=(np.sin(np.array(angels) * np.pi / 180.)**2,
              np.array([s[interface] for s in [synt0, synt1, synt2]])),
        kwargs={'target_function': straight_line})
    print('amp = {:.4f}*theta + {:.4f}'.format(*res2.x))
    print(res2.status)
    print(res2.message)
    print(res2.success)

    ax6.plot(ic, gr, **opz4)
    ax6.plot(*res2.x[::-1], **opz3)
    ax6.set_xlabel('Intercept')
    ax6.set_ylabel('Gradient')

    for aa in [ax0, ax1, ax2, ax3, ax35]:
        aa.set_ylim(350, 150)
        aa.tick_params(which='major', labelsize=8)
        aa.set_yticklabels([])

    plt.subplots_adjust(wspace=.8, left=0.05, right=0.95)
Ejemplo n.º 6
0
def plot_rp(wells,
            log_table,
            wis,
            wi_name,
            cutoffs=None,
            templates=None,
            legend_items=None,
            plot_type=None,
            ref_val=None,
            fig=None,
            ax=None,
            block_name=None,
            savefig=None,
            **kwargs):
    """
    Plots some standard rock physics crossplots for the given wells

    :param wells:
        dict
        dictionary with well names as keys, and core.well.Well object as values
        As returned from core.well.Project.load_all_wells()
    :param log_table:
        dict
        Dictionary of log type: log name key: value pairs which decides which log, under each log type, to plot
        E.G.
            log_table = {
               'P velocity': 'vp',
               'S velocity': 'vs',
               'Density': 'rhob',
               'Porosity': 'phie',
               'Volume': 'vcl'}
    :param wis:
        dict
        working intervals, as defined in the "Working intervals" sheet of the project table, and
        loaded through:
        wp = Project()
        wis = rp_utils.io.project_working_intervals(wp.project_table)
    :param wi_name:
        str
        name of working interval to plot
    :param cutoffs:
        dict
        Dictionary with log types as keys, and list with mask definition as value
        E.G.
            {'Volume': ['<', 0.5], 'Porosity': ['>', 0.1]}
    :param templates:
        dict
        templates dictionary as returned from rp_utils.io.project_templates()
    :param legend_items:
        list
        list of Line2D objects that are used in the legends.
        if None, the well names will be used
    :param plot_type:
        str
        plot_type =
            'AI-VpVs': AI versus Vp/Vs plot
            'Phi-Vp': Porosity versus Vp plot
            'I-G': Intercept versus Gradient plot
    :param ref_val:
        list
        List of reference Vp [m/s], Vs [m/s], and rho [g/cm3] that are used
        when calculating the Intercept and gradient
    :param fig:

    :param ax:

    :param block_name:
        str
        Name of the log block from where the logs are picked
    :param savefig
        str
        full pathname of file to save the plot to
    :param **kwargs:
        keyword arguments passed on to crossplot.plot()
    :return:
    """
    #
    # some initial setups
    log_table = small_log_table(log_table)
    if block_name is None:
        block_name = cw.def_lb_name

    _savefig = False
    if plot_type is None:
        plot_type = 'AI-VpVs'
    elif plot_type == 'I-G' and ref_val is None:
        ref_val = [3500., 1700., 2.6]
    logs = [n.lower() for n in list(log_table.values())]
    if savefig is not None:
        _savefig = True

    #
    # set up plotting environment
    if fig is None:
        if ax is None:
            fig = plt.figure(figsize=(10, 10))
            ax = fig.subplots()
        else:  # Only ax is set, but not fig. Which means all functionality calling fig must be turned off
            _savefig = False
    elif ax is None:
        ax = fig.subplots()

    # load
    well_names = []
    desc = ''
    for wname, _well in wells.items():
        print('Plotting well {}'.format(wname))
        # create a deep copy of the well so that the original is not altered
        well = deepcopy(_well)
        these_wis = wis[wname]
        if wi_name.upper() not in [
                _x.upper() for _x in list(these_wis.keys())
        ]:
            warn_txt = 'Working interval {} does not exist in well {}'.format(
                wi_name, wname)
            print('WARNING: {}'.format(warn_txt))
            logger.warning(warn_txt)
            continue  # this working interval does not exist in current well
        # test if necessary logs are in the well
        skip = False
        for _log in logs:
            if _log not in list(well.block[block_name].logs.keys()):
                warn_txt = '{} log is lacking in {}'.format(_log, wname)
                print('WARNING: {}'.format(warn_txt))
                logger.warning(warn_txt)
                skip = True
        if skip:
            continue
        # create mask based on working interval
        well.calc_mask({}, name='XXX', wis=wis, wi_name=wi_name)
        # apply mask (which also deletes the mask itself)
        well.apply_mask('XXX')
        # create mask based on cutoffs
        if cutoffs is not None:
            well.calc_mask(cutoffs,
                           name='cmask',
                           log_type_input=True,
                           log_table=log_table)
            mask = well.block[block_name].masks['cmask'].data
            desc = well.block[block_name].masks['cmask'].header.desc
        else:
            mask = None

        # collect data for plot
        if plot_type == 'AI-VpVs':
            if 'P velocity' in list(log_table.keys()):
                # Calculating Vp / Vs using vp and vs
                x_data = well.block[block_name].logs[log_table['P velocity'].lower()].data * \
                         well.block[block_name].logs[log_table['Density'].lower()].data
                x_unit = '{} {}'.format(
                    well.block[block_name].logs[
                        log_table['P velocity'].lower()].header.unit,
                    well.block[block_name].logs[
                        log_table['Density'].lower()].header.unit)
                y_data = well.block[block_name].logs[log_table['P velocity'].lower()].data / \
                         well.block[block_name].logs[log_table['S velocity'].lower()].data
            else:
                # Assume we are calculating Vp / Vs using sonic logs
                x_data = well.block[block_name].logs[log_table['Density'].lower()].data / \
                         well.block[block_name].logs[log_table['Sonic'].lower()].data
                x_unit = '{}/{}'.format(
                    well.block[block_name].logs[
                        log_table['Density'].lower()].header.unit,
                    well.block[block_name].logs[
                        log_table['Sonic'].lower()].header.unit)
                y_data = well.block[block_name].logs[log_table['Shear sonic'].lower()].data / \
                         well.block[block_name].logs[log_table['Sonic'].lower()].data

            y_unit = '-'
            xtempl = {'full_name': 'AI', 'unit': x_unit}
            ytempl = {'full_name': 'Vp/Vs', 'unit': y_unit}

        elif (plot_type == 'Vp-bd') or (plot_type == 'Vp-tvd'):
            if 'P velocity' in list(log_table.keys()):
                x_data = well.block[block_name].logs[
                    log_table['P velocity'].lower()].data
                x_unit = '{}'.format(well.block[block_name].logs[
                    log_table['P velocity'].lower()].header.unit)
                xtempl = {'full_name': log_table['P velocity'], 'unit': x_unit}
            else:
                x_data = 1. / well.block[block_name].logs[
                    log_table['Sonic'].lower()].data
                x_unit = '1/{}'.format(well.block[block_name].logs[
                    log_table['Sonic'].lower()].header.unit)
                xtempl = {'full_name': '1/Sonic', 'unit': x_unit}
            if plot_type == 'Vp-bd':
                y_data = well.get_burial_depth(templates, block_name)
                ytempl = {'full_name': 'Burial depth', 'unit': 'm'}
            else:
                y_data = well.block[block_name].get_tvd()
                ytempl = {'full_name': 'TVD', 'unit': 'm'}

        elif (plot_type == 'VpVs-bd') or (plot_type == 'VpVs-tvd'):
            x_data = well.block[block_name].logs[log_table['P velocity'].lower()].data / \
                     well.block[block_name].logs[log_table['S velocity'].lower()].data
            xtempl = {'full_name': 'Vp/Vs', 'unit': '-'}
            if plot_type == 'VpVs-bd':
                y_data = well.get_burial_depth(templates, block_name)
                ytempl = {'full_name': 'Burial depth', 'unit': 'm'}
            else:
                y_data = well.block[block_name].get_tvd()
                ytempl = {'full_name': 'TVD', 'unit': 'm'}

        elif (plot_type == 'AI-bd') or (plot_type == 'AI-tvd'):
            x_data = well.block[block_name].logs[log_table['P velocity'].lower()].data * \
                     well.block[block_name].logs[log_table['Density'].lower()].data
            x_unit = '{} {}'.format(
                well.block[block_name].logs[
                    log_table['P velocity'].lower()].header.unit,
                well.block[block_name].logs[
                    log_table['Density'].lower()].header.unit)
            xtempl = {'full_name': 'AI', 'unit': x_unit}
            if plot_type == 'AI-bd':
                y_data = well.get_burial_depth(templates, block_name)
                ytempl = {'full_name': 'Burial depth', 'unit': 'm'}
            else:
                y_data = well.block[block_name].get_tvd()
                ytempl = {'full_name': 'TVD', 'unit': 'm'}

        elif (plot_type == 'Rho-bd') or (plot_type == 'Rho-tvd'):
            x_data = well.block[block_name].logs[
                log_table['Density'].lower()].data
            x_unit = '{}'.format(well.block[block_name].logs[
                log_table['Density'].lower()].header.unit)
            xtempl = {'full_name': log_table['Density'], 'unit': x_unit}
            if plot_type == 'Rho-bd':
                y_data = well.get_burial_depth(templates, block_name)
                ytempl = {'full_name': 'Burial depth', 'unit': 'm'}
            else:
                y_data = well.block[block_name].get_tvd()
                ytempl = {'full_name': 'TVD', 'unit': 'm'}

        elif plot_type == 'Phi-Vp':
            x_data = well.block[block_name].logs[
                log_table['Porosity'].lower()].data
            x_unit = '{}'.format(well.block[block_name].logs[
                log_table['Porosity'].lower()].header.unit)
            if 'P velocity' in list(log_table.keys()):
                # Calculating Vp using vp
                y_data = well.block[block_name].logs[
                    log_table['P velocity'].lower()].data
                y_unit = '{}'.format(well.block[block_name].logs[
                    log_table['P velocity'].lower()].header.unit)
            else:
                # Assume we are calculating Vp using sonic logs
                y_data = cnvrt(
                    well.block[block_name].logs[
                        log_table['P velocity'].lower()].data, 'us/ft', 'm/s')
                y_unit = 'm/s'
            xtempl = {'full_name': 'Porosity', 'unit': x_unit}
            ytempl = {'full_name': 'Vp', 'unit': y_unit}
        elif plot_type == 'I-G':
            x_data = rp.intercept(
                ref_val[0], well.block[block_name].logs[
                    log_table['P velocity'].lower()].data, ref_val[2],
                well.block[block_name].logs[log_table['Density'].lower()].data)
            x_unit = '-'
            y_data = rp.gradient(
                ref_val[0], well.block[block_name].logs[
                    log_table['P velocity'].lower()].data, ref_val[1],
                well.block[block_name].logs[
                    log_table['S velocity'].lower()].data, ref_val[2],
                well.block[block_name].logs[log_table['Density'].lower()].data)
            y_unit = '-'
            xtempl = {'full_name': 'Intercept', 'unit': x_unit}
            ytempl = {'full_name': 'Gradient', 'unit': y_unit}
        else:
            raise IOError('No known plot type selected')

        well_names.append(wname)
        # start plotting

        xp.plot(x_data,
                y_data,
                cdata=templates[wname]['color'],
                mdata=templates[wname]['symbol'],
                xtempl=xtempl,
                ytempl=ytempl,
                mask=mask,
                fig=fig,
                ax=ax,
                **kwargs)
    ax.autoscale(True, axis='both')
    if ('tvd' in plot_type) or ('bd' in plot_type):
        ax.set_ylim(ax.get_ylim()[::-1])
    ax.set_title('{}, {}'.format(wi_name, desc))
    #
    if legend_items is None:
        legend_items = []
        for wname in well_names:
            legend_items.append(
                Line2D([0], [0],
                       color=templates[wname]['color'],
                       lw=0,
                       marker=templates[wname]['symbol'],
                       label=wname))

    legend_names = [x._label for x in legend_items]
    this_legend = ax.legend(legend_items,
                            legend_names,
                            prop=FontProperties(size='smaller'),
                            scatterpoints=1,
                            markerscale=2,
                            loc=1)

    if _savefig:
        fig.savefig(savefig)