Exemplo n.º 1
0
    def plot_triangle(self, ID, 
            params_to_plot=None, 
            suffix=None, 
            replot=False, 
            M_star=False, 
            show=False):
        """ 
        Draw a "triangle plot" with the 1D and 2D posterior probability

        Parameters
        ----------
        ID : str or int
            Object ID


        M_star : bool, optional
            If set, the routine will plot the mass currenly locked into stars
            instead of the mass of star formed (i.e., the plotted mass will
            accout for the return fraction)

        """ 
        # NB: you changed the getdist/plot.py _set_locator function
        # replacing line 1172-1176
        #if x and (abs(xmax - xmin) < 0.01 or max(abs(xmin), abs(xmax)) >= 1000):
        #    axis.set_major_locator(plt.MaxNLocator(self.settings.subplot_size_inch / 2 + 3, prune=prune))
        #else:
        #    axis.set_major_locator(plt.MaxNLocator(self.settings.subplot_size_inch / 2 + 4, prune=prune))
        # with
        #if x and (abs(xmax - xmin) < 0.01 or max(abs(xmin), abs(xmax)) >= 1000):
        #    axis.set_major_locator(plt.MaxNLocator(self.settings.subplot_size_inch / 2 + 2, prune=prune))
        #else:
        #    axis.set_major_locator(plt.MaxNLocator(self.settings.subplot_size_inch / 2 + 3, prune=prune))
        # to have a fewer number of tick marks, and hence less crowded triangle plots

        # for "cosmetics" reasons you also changed the getdist/plot.py setWithSubplotSize function
        # replacing line 166-167
        # self.lab_fontsize = 7 + 2 * self.subplot_size_inch
        # self.axes_fontsize = 4 + 2 * self.subplot_size_inch
        # with
        # self.lab_fontsize = 7 + 4 * self.subplot_size_inch
        # self.axes_fontsize = 4 + 4 * self.subplot_size_inch
        # to have larger, hence more readable, label and axes font sizes
    
        # Name of the output plot
        if suffix is None:
            plot_name = str(ID)+'_BEAGLE_triangle.pdf'
        else:
            plot_name = str(ID)+'_BEAGLE_triangle_' + suffix + '.pdf'

        # Check if the plot already exists
        if plot_exists(plot_name) and not replot and not show:
            logging.warning('The plot "' + plot_name + '" already exists. \n Exiting the function.')
            return

        fits_file = os.path.join(BeagleDirectories.results_dir,
                str(ID) + '_' + BeagleDirectories.suffix + '.fits.gz')

        hdulist = fits.open(fits_file)

        param_values = OrderedDict()
        for key, value in six.iteritems(self.adjust_params):
            extName = "POSTERIOR PDF"
            if "extName" in value:
                extName = value["extName"]

            colName = key
            if "colName" in value:
                colName = value["colName"]

            param_values[key] = hdulist[extName].data[colName]

        probability = hdulist['posterior pdf'].data['probability']

        n_rows = probability.size

       # ParamsToPlot = ['mass', 'redshift', 'tauV_eff', 'metallicity', 'specific_sfr', 'tau']

        # By default you plot all parameters
        if params_to_plot is None:
            _params_to_plot = list()
            for key, value in six.iteritems(self.adjust_params):
                _params_to_plot.append(key)
        else: 
            _params_to_plot = params_to_plot

        # Here you check whether you want to plot the mass currently locked
        # into stars or not (i.e. accounting for the return fraction as well)
        if M_star and 'mass' in _params_to_plot:
            param_values['mass'][:] = np.log10(hdulist['galaxy properties'].data['M_star'][:])

        nParamsToPlot = len(_params_to_plot)

        names = list()
        labels = list()
        ranges = dict()
        samps = np.zeros((n_rows, nParamsToPlot))
        keys = list()

        j = 0
        for key, par in six.iteritems(self.adjust_params):
            keys.append(key)
            for par_name in _params_to_plot:
                if key == par_name:
                    names.append(key)
                    label = par['label'].replace("$","")
                    labels.append(label)

                    samps[:,j] = param_values[key]
                    ranges.update({key:par['range']})
                    if 'log' in par:
                        if par["log"]:
                            samps[:,j] = np.log10(param_values[key])
                            ranges.update({key:np.log10(par['range'])})
                    j += 1
                    break

        settings = {
                    "contours":[0.68, 0.95, 0.99], 
                    "range_ND_contour":1, 
                    "range_confidence":0.001,
                    "fine_bins":200,
                    "fine_bins_2d":80,
                    "smooth_scale_1D":0.3,
                    "smooth_scale_2D":0.5,
                    "tight_gap_fraction":0.15
                    }

        samples = MCSamples(samples=samps, names=names, ranges=ranges, \
                weights=probability, labels=labels, settings=settings )

        g = plots.getSubplotPlotter()
        g.settings.num_plot_contours = 3
        g.settings.prob_y_ticks = True

        # Change the size of the labels 
        if self.triangle_font_size is None:
            g.settings.lab_fontsize = 7 + 4 * g.settings.subplot_size_inch
            g.settings.axes_fontsize = 4 + 4 * g.settings.subplot_size_inch
        else:
            g.settings.lab_fontsize = self.triangle_font_size
            g.settings.axes_fontsize = self.triangle_font_size

        line_args = {"lw":2, "color":colorConverter.to_rgb("#006FED") } 

        g.triangle_plot(samples, filled=True, line_args=line_args)

        g.fig.subplots_adjust(wspace=0.1, hspace=0.1)

        prune  = 'both'

        #for i, ax in enumerate([g.subplots[i,i] for i in range(nParamsToPlot)]):
        #    ax.set_autoscalex_on(True)

        for i in range(len(names)):
            for i2 in range(i, len(names)):
                _ax = g._subplot(i, i2)
                _ax.xaxis.set_major_locator(plt.MaxNLocator(3, prune=prune))
                _ax.yaxis.set_major_locator(plt.MaxNLocator(3, prune=prune))

        # Add tick labels at top of diagonal panels
        for i, ax in enumerate([g.subplots[i,i] for i in range(nParamsToPlot)]):
            par_name = keys[i]

            if i < nParamsToPlot-1: 
                ax.tick_params(which='both', labelbottom=False, 
                        top=True, labeltop=True, left=False, labelleft=False)
            else:
                ax.tick_params(which='both', labelbottom=True, 
                        top=True, labeltop=False, left=False, labelleft=False)

            # Add shaded region showing 1D 68% credible interval
            y0, y1 = ax.get_ylim()
            lev = samples.get1DDensity(par_name).getLimits(settings['contours'][0])

            ax.add_patch(
                    Rectangle((lev[0], y0), 
                    lev[1]-lev[0], 
                    y1-y0, 
                    facecolor="grey", 
                    alpha=0.5)
                    )

            # Indicate the value of the "true" parameter
            if self.mock_catalogue is not None:
                name = names[i]
                value = self.mock_catalogue.get_param_values(ID, (name,))
                if "log" in self.adjust_params[name]:
                    if self.adjust_params[name]["log"]:
                        value = np.log10(value)

                ax.plot(value,
                        y0+(y1-y0)*0.05,
                        marker="D",
                        ms=8,
                        color="green") 

        if self.single_solutions is not None:
            row =  self.single_solutions['row'][self.single_solutions['ID']==ID]

            for i in range(nParamsToPlot):
                parX = keys[i]
                valueX = param_values[parX][row]

                if "log" in self.adjust_params[parX]:
                    if self.adjust_params[parX]["log"]:
                        valueX = np.log10(valueX)

                for j in range(nParamsToPlot):
                    ax = g.subplots[i,j]
                    if ax is None:
                        continue

                    if i == j:

                        ax.plot(valueX,
                                y0+(y1-y0)*0.05,
                                marker="*",
                                ms=12,
                                color="darkorange") 
                    else:

                        parY = keys[j]
                        valueY = param_values[parY][row]

                        if "log" in self.adjust_params[parY]:
                            if self.adjust_params[parY]["log"]:
                                valueY = np.log10(valueY)

                        ax.plot(valueY,
                                valueX,
                                marker="*",
                                ms=12,
                                color="darkorange") 

        if show:
            plt.show()
        else:
            # Now save the plot
            name = prepare_plot_saving(plot_name)
            g.export(name)

        plt.close()
        hdulist.close()
Exemplo n.º 2
0
def plot_triangle(sim_samples,
                  gp_samples,
                  burnin_frac=0.1,
                  emulator=True,
                  gp_error=False):

    if gp_error and emulator:
        label_gp = 'GP (Error)'

    elif emulator and not gp_error:
        label_gp = 'GP (Mean)'

    else:
        label_gp = 'Simulator (MOPED)'

    ndim = sim_samples.shape[-1]

    names = ["x%s" % i for i in range(ndim)]

    labels = [
        r"\Omega_{m}", r"w_{0}", r"M_{B}", r"\delta M", r"\alpha", r"\beta"
    ]

    # for the simulator
    burnin = int(burnin_frac * sim_samples.shape[1])
    samples_exact = sim_samples[:, burnin:, :].reshape((-1, ndim))
    cut_samps = samples_exact[samples_exact[:, 0] >= 0.0, :]
    samples1 = MCSamples(samples=cut_samps,
                         names=names,
                         labels=labels,
                         ranges={'x0': (0.0, None)})

    # for the emulator
    burnin = int(burnin_frac * gp_samples.chain.shape[1])
    samples_emu = gp_samples.chain[:, burnin:, :].reshape((-1, ndim))
    cut_samps = samples_emu[samples_emu[:, 0] >= 0.0, :]
    samples2 = MCSamples(samples=cut_samps,
                         names=names,
                         labels=labels,
                         ranges={'x0': (0.0, None)})

    # setups for plotting
    sim_color = '#EEC591'
    gp_color = 'Blue'
    alpha_tri = 0.1
    red_patch = mpatches.Patch(color=sim_color,
                               label='Simulator',
                               alpha=alpha_tri)
    gp_line = Line2D([0], [0],
                     color=gp_color,
                     linewidth=3,
                     linestyle='--',
                     label=label_gp)
    rec_leg = [red_patch, gp_line]

    contours = np.array([0.68, 0.95])

    G = plots.getSubplotPlotter(subplot_size=3.5)
    samples1.updateSettings({'contours': [0.68, 0.95]})

    G.triangle_plot([samples1],
                    filled=True,
                    line_args={
                        'lw': 3,
                        'color': sim_color
                    },
                    contour_colors=[sim_color])
    G.settings.num_plot_contours = 2
    plt.legend(handles=rec_leg,
               loc='best',
               prop={'size': 25},
               bbox_to_anchor=(0.7, 6.0),
               borderaxespad=0.)
    G.settings.alpha_filled_add = alpha_tri
    for i in range(0, 6):
        for j in range(0, i + 1):
            if i != j:
                ax = G.subplots[i, j]

                a, b = G.get_param_array(samples2,
                                         ['x' + str(j), 'x' + str(i)])
                density = G.sample_analyser.get_density_grid(samples2, a, b)
                density.contours = density.getContourLevels(contours)
                contour_levels = density.contours
                ax.contour(density.x,
                           density.y,
                           density.P,
                           sorted(contour_levels),
                           colors=gp_color,
                           linewidths=3,
                           linestyles='--')

                ax.tick_params(labelsize=20)
                ax.yaxis.label.set_size(20)
                ax.xaxis.label.set_size(20)
            else:
                ax = G.subplots[i, j]

                dense = samples2.get1DDensity('x' + str(i))
                dense.normalize(by='max')
                ax.plot(dense.x, dense.P, lw=3, c=gp_color, linestyle='--')

                ax.tick_params(labelsize=20)
                ax.yaxis.label.set_size(20)
                ax.xaxis.label.set_size(20)
    plt.savefig('images/triangle_plot.jpg',
                bbox_inches='tight',
                transparent=False)
    plt.close()