Example #1
0
def plot_scatter(options, data_obs, kelly_scaled_fit, mantz_scaled_fit, x_piv,
                 x_min, x_max):
    ''' Plot data '''
    (x_obs, y_obs, x_err_obs, y_err_obs) = data_obs

    # Plot data
    plt.errorbar(x_obs, y_obs, xerr=x_err_obs, yerr=y_err_obs, fmt='o', markeredgecolor='k')

    for method in METHODS:
        if method == 'kelly':
            scaled_fit = kelly_scaled_fit
            color = 'r'

        elif method == 'mantz':
            scaled_fit = mantz_scaled_fit
            color = 'm'

        (fit_int, fit_slope, fit_sig) = scaled_fit
        data_fit = scaled_fit_to_data(x_min, x_max, x_piv, scaled_fit)
        (x_fit, y_fit, _, _) = data_fit

        print (
            'mean b, m, sig: {}, {}, {}'
            .format(np.mean(fit_int), np.mean(fit_slope), np.mean(fit_sig))
        )

        # plot fit
        if PARAMETERS['show_method_name'] is True or len(METHODS) > 1:
            # Prints method name in legend (default if more than 1 method)
            plt.loglog(
                x_fit, y_fit, color, linewidth=2.0,
                label=(
                    '{0}:'
                    r'$({1:0.2g} \pm {2:0.2g}) '
                    r'(x/x_{{piv}})^{{{3:0.2g} \pm {4:0.2g}}} '
                    r'(\sigma^2 = {5:0.2g} \pm {6:0.2g})$'
                ).format(
                    method.capitalize(),
                    np.exp(np.mean(fit_int)),
                    np.exp(np.mean(fit_int)) * np.std(fit_int),
                    np.mean(fit_slope),
                    np.std(fit_slope),
                    np.mean(fit_sig),
                    np.std(fit_sig)
                )
            )

        else:
            # Doesn't print method label
            plt.loglog(
                x_fit, y_fit, color, linewidth=2.0,
                label=(
                    r'$({0:0.2g} \pm {1:0.2g}) '
                    r'(x/x_{{piv}})^{{{2:0.2f} \pm {3:0.2f}}} '
                    r'(\sigma = {4:0.2f} \pm {5:0.2f})$'
                ).format(
                    np.exp(np.mean(fit_int)),
                    np.exp(np.mean(fit_int)) * np.std(fit_int),
                    np.mean(fit_slope),
                    np.std(fit_slope),
                    np.mean(fit_sig),
                    np.std(fit_sig)
                )
            )

    plt.xlabel(axis_label(options.x), fontsize=16)
    plt.ylabel(axis_label(options.y), fontsize=16)
    plt.xlim([0.8*np.min(x_obs), 1.2*np.max(x_obs)])
    plt.ylim([0.8*np.min(y_obs), 1.2*np.max(y_obs)])

    plt.legend(loc=2)

    plt.savefig(
        'Scatter-{}{}-{}.pdf'
        .format(options.prefix, fits_label(options.y), fits_label(options.x)),
        bbox_inches='tight'
    )

    return
Example #2
0
def make_plots(options, parameters, methods, data_obs, kelly_scaled_fit,
               mantz_scaled_fit, piv, x_min, x_max):
    '''
    Calls both plotting functions and then combines all outputs into a single
    PDF.
    '''

    # pylint: disable=global-statement

    # OLD: now uses METHODS
    # Retreive methods list

    # Sets module parameters to those set in clustr.py
    global PARAMETERS
    global METHODS
    PARAMETERS = parameters
    METHODS = methods

    # Initialize pdf list
    pdfs = []

    if PARAMETERS['scatter'] is True:
        plot_scatter(options, data_obs, kelly_scaled_fit, mantz_scaled_fit,
                     piv, x_min, x_max)
        # Add scatter/fit plot
        pdfs.append(
            'Scatter-{}{}-{}.pdf'
            .format(
                options.prefix,
                fits_label(options.y),
                fits_label(options.x)
            )
        )

    if PARAMETERS['residuals'] is True:
        plot_residuals(options, data_obs, kelly_scaled_fit, mantz_scaled_fit)
        # Add residual plot(s)
        for method in METHODS:
            pdfs.append(
                'Residuals-{}-{}{}-{}.pdf'.format(
                    method,
                    options.prefix, fits_label(options.y),
                    fits_label(options.x)
                )
            )

    if PARAMETERS['corner'] is True:
        plot_corners(options, kelly_scaled_fit, mantz_scaled_fit)
        # Add corner plot(s)
        for method in METHODS:
            pdfs.append(
                'Corner-{}-{}{}-{}.pdf'
                .format(
                    method,
                    options.prefix,
                    fits_label(options.y),
                    fits_label(options.x)
                )
            )

    if PARAMETERS['chains'] is True:
        plot_chains(options, kelly_scaled_fit, mantz_scaled_fit)
        # Add chain plot(s)
        for method in METHODS:
            pdfs.append(
                'Chains-{}-{}{}-{}.pdf'
                .format(
                    method,
                    options.prefix,
                    fits_label(options.y),
                    fits_label(options.x)
                )
            )

    merger = PyPDF2.PdfFileMerger()

    for pdf in pdfs:
        merger.append(pdf)

    # Save combined output file
    merger.write(
        '{}{}-{}.pdf'
        .format(options.prefix, fits_label(options.y), fits_label(options.x))
    )

    # Unless otherwise specified, delete individual plots
    if parameters['save_all_plots'] is False:
        for pdf in pdfs:
            os.remove(pdf)

    return
Example #3
0
def plot_corners(options, kelly_scaled_fit, mantz_scaled_fit):
    '''
    Makes corner plots for the desired Kelly and/or Mantz method parameter
    posteriors. Burn is the burn in period parameter.
    '''

    burn = PARAMETERS['burn']

    # FIX: Is this still being used?
    N = np.size(METHODS)  # Number of subplots
    n = 1  # Subplot counter

    for method in METHODS:
        if method == 'kelly':
            scaled_fit = kelly_scaled_fit
        elif method == 'mantz':
            scaled_fit = mantz_scaled_fit
        else:
            print (
                'WARNNG: Only `kelly`, `mantz`, or `both` are valid method '
                'options. Will use Kelly method instead.'
            )
            scaled_fit = kelly_scaled_fit

        # Set up subplot
        plt.subplot(N, 1, n)

        (B, M, S) = scaled_fit

        # Paramter Limits
        blo, bhi = min(B[burn:]), max(B[burn:])
        mlo, mhi = min(M[burn:]), max(M[burn:])
        slo, shi = min(S[burn:]), max(S[burn:])

        # FIX: maybe use lo = -hi for symmetry?? Can cause issues for small min

        sf = 0.25  # scale factor
        db = sf*abs(bhi - blo)
        dm = sf*abs(mhi - mlo)
        ds = sf*abs(shi - slo)
        blo, bhi = blo-db, bhi+db
        mlo, mhi = mlo-db, mhi+dm
        slo, shi = slo-ds, shi+ds
        # blo, bhi = blo-abs(blo)*sf, bhi+abs(bhi)*sf
        # mlo, mhi = mlo-abs(mlo)*sf, mhi+abs(mhi)*sf
        # slo, shi = slo-abs(slo)*sf, shi+abs(shi)*sf

        data = np.transpose((B, M, S))

        fig = corner.corner(
            data,
            labels=['b', 'm', 's'],
            range=[(blo, bhi), (mlo, mhi), (slo, shi)],
            quantiles=[0.16, 0.5, 0.84],
            show_titles=True,
            title_args={"fontsize": 18},
            plot_datapoints=True,
            fill_contours=True,
            levels=[0.68, 0.95],
            color='b',
            bins=40,
            smooth=1.0
        )

        if PARAMETERS['show_method_name'] is True or len(METHODS) > 1:
            fig.suptitle('Posterior for {} Method'.format(method.capitalize()),
                         fontsize=16)
        else:
            fig.suptitle('Posterior',
                         fontsize=16)

        plt.savefig(
            'Corner-{}-{}{}-{}.pdf'
            .format(
                method,
                options.prefix,
                fits_label(options.y),
                fits_label(options.x)
            )
        )

        n += 1  # Iterate counter

    return
Example #4
0
def plot_chains(options, kelly_scaled_fit, mantz_scaled_fit):
    '''
    Use this to examine chain convergence. May implement convergence tests in
    future.
    '''

    burn = PARAMETERS['burn']

    # OLD: now uses MEHTODS
    # methods = clustr.return_methods_list(options.method)

    for method in METHODS:
        if method == 'kelly':
            scaled_fit = kelly_scaled_fit
        elif method == 'mantz':
            scaled_fit = mantz_scaled_fit
        else:
            print (
                'WARNNG: Only `kelly`, `mantz`, or `both` are valid method '
                'options. Will use Kelly method instead.'
            )
            scaled_fit = kelly_scaled_fit

        # Initialize
        B, M, S = None, None, None

        # Unpack fit parameters
        (B, M, S) = scaled_fit
        # Remove burn-in period
        B, M, S = B[burn:], M[burn:], S[burn:]
        # Take averages
        b, m, s = np.mean(B), np.mean(M), np.mean(S)

        # Length of chain
        nmc = np.size(B)

        fig = plt.figure()

        plt.subplot(311)

        plt.plot(M, 'o', markerfacecolor="None")
        plt.plot((0, nmc), (m, m), 'r--')
        plt.xlabel('Chain Number')
        plt.ylabel('Slope')

        plt.subplot(312)

        plt.plot(B, 'o', markerfacecolor="None")
        plt.plot((0, nmc), (b, b), 'r--')
        plt.xlabel('Chain Number')
        plt.ylabel('Intercept')

        plt.subplot(313)

        plt.plot(S, 'o', markerfacecolor="None")
        plt.plot((0, nmc), (s, s), 'r--')
        plt.xlabel('Chain Number')
        plt.ylabel(r'$\sigma^2$')

        fig.suptitle(
            'Markov Chains for {} Method'.format(method.capitalize()),
            fontsize=16
        )

        fig.set_size_inches(10, 10)

        plt.savefig(
            'Chains-{}-{}{}-{}.pdf'
            .format(method, options.prefix, fits_label(options.y),
                    fits_label(options.x))
        )

        plt.clf()

    return
Example #5
0
def plot_residuals(options, data_obs, kelly_scaled_fit, mantz_scaled_fit):
    '''
    FIX: Description
    '''

    # (x_obs, y_obs, x_err_obs, y_err_obs) = data_obs
    (lx_obs, ly_obs, _lx_err_obs, _ly_err_obs, _x_piv) = scale(*data_obs)

    for method in METHODS:
        if method == 'kelly':
            scaled_fit = kelly_scaled_fit
        elif method == 'mantz':
            scaled_fit = mantz_scaled_fit
        else:
            print (
                'WARNNG: Only `kelly`, `mantz`, or `both` are valid method '
                'options. Will use Kelly method instead.'
            )
            scaled_fit = kelly_scaled_fit

        (B, M, _S) = scaled_fit

        b, m = np.mean(B), np.mean(M)

        # Calculate residuals
        x_fit = lx_obs
        y_fit = m*x_fit+b
        # FIX: Find out which normalization to use!
        # residuals = (ly_obs - y_fit) / ly_err_obs
        residuals = (ly_obs - y_fit) / np.std(ly_obs)

        '''
        # Make residual plot fig1 = plt.figure(1) #Plot Data-model frame1 =
        fig1.add_axes((.1,.3,.8,.6)) #xstart, ystart, xend, yend [units are
        fraction of the image frame, from bottom left corner]
        plt.errorbar(lx_obs, ly_obs, xerr=lx_err_obs, yerr=ly_err_obs, c='r',
        fmt='o') plt.plot(x_fit,y_fit,'b') #Best fit model
        frame1.set_xticklabels([]) #Remove x-tic labels for the first frame

        #Residual plot frame2 = fig1.add_axes((.1,.1,.8,.2))
        plt.plot(lx_obs,residuals,'ob')
        plt.plot([np.min(lx_obs),np.max(lx_obs)],[0,0],'k--',linewidth=2)

        plt.title('{} Method'.format(method.capitalize()),fontsize=14)
        '''

        # Bin number
        # FIX: make bins automatically consistent with Michigan group
        nbin = 18

        plt.hist(residuals, nbin)
        plt.xlabel(r'$\Delta(\ln X)/\sigma_{\ln X}$', fontsize=16)
        plt.ylabel('Count', fontsize=16)

        if PARAMETERS['show_method_name'] is True or len(METHODS) > 1:
            plt.title(
                '{} Residuals for {} Method'
                .format(fits_label(options.y), method.capitalize()),
                fontsize=16
            )
        else:
            plt.title(
                '{} Residuals'.format(fits_label(options.y)),
                fontsize=16
            )

        plt.savefig(
            'Residuals-{}-{}{}-{}.pdf'
            .format(
                method,
                options.prefix,
                fits_label(options.y),
                fits_label(options.x)
            )
        )

    return