def param_logx_diagram(run_list, **kwargs):
    """Creates diagrams of a nested sampling run's evolution as it iterates
    towards higher likelihoods, expressed as a function of log X, where X(L) is
    the fraction of the prior volume with likelihood greater than some value L.

    For a more detailed description and some example use cases, see 'nestcheck:
    diagnostic tests for nested sampling calculations" (Higson et al. 2019).

    Parameters
    ----------
    run_list: dict or list of dicts
        Nested sampling run(s) to plot.
    fthetas: list of functions, optional
        Quantities to plot. Each must map a 2d theta array to 1d ftheta array -
        i.e. map every sample's theta vector (every row) to a scalar quantity.
        E.g. use lambda x: x[:, 0] to plot the first parameter.
    labels: list of strs, optional
        Labels for each ftheta.
    ftheta_lims: dict, optional
        Plot limits for each ftheta.
    plot_means: bool, optional
        Should the mean value of each ftheta be plotted?
    n_simulate: int, optional
        Number of bootstrap replications to use for the fgivenx distributions.
    random_seed: int, optional
        Seed to make sure results are consistent and fgivenx caching can be
        used.
    logx_min: float, optional
        Lower limit of logx axis.
    figsize: tuple, optional
        Matplotlib figure size (in inches).
    colors: list of strs, optional
        Colors to plot run scatter plots with.
    colormaps: list of strs, optional
        Colormaps to plot run fgivenx plots with.
    npoints: int, optional
        How many points to have in the logx array used to calculate and plot
        analytical weights.
    cache: str or None
        Root for fgivenx caching (no caching if None).
    parallel: bool, optional
        fgivenx parallel optional
    point_size: float, optional
        size of markers on scatter plot (in pts)
    thin: float, optional
        factor by which to reduce the number of samples before plotting the
        scatter plot. Must be in half-closed interval (0, 1].
    rasterize_contours: bool, optional
        fgivenx rasterize_contours option.
    tqdm_kwargs: dict, optional
        Keyword arguments to pass to the tqdm progress bar when it is used in
        fgivenx while plotting contours.

    Returns
    -------
    fig: matplotlib figure
    """
    fthetas = kwargs.pop('fthetas', [lambda theta: theta[:, 0],
                                     lambda theta: theta[:, 1]])
    labels = kwargs.pop('labels', [r'$\theta_' + str(i + 1) + '$' for i in
                                   range(len(fthetas))])
    ftheta_lims = kwargs.pop('ftheta_lims', [[-1, 1]] * len(fthetas))
    threads_to_plot = kwargs.pop('threads_to_plot', [0])
    plot_means = kwargs.pop('plot_means', True)
    n_simulate = kwargs.pop('n_simulate', 100)
    random_seed = kwargs.pop('random_seed', 0)
    logx_min = kwargs.pop('logx_min', None)
    figsize = kwargs.pop('figsize', (6.4, 2 * (1 + len(fthetas))))
    colors = kwargs.pop('colors', ['red', 'blue', 'grey', 'green', 'orange'])
    colormaps = kwargs.pop('colormaps', ['Reds_r', 'Blues_r', 'Greys_r',
                                         'Greens_r', 'Oranges_r'])
    # Options for fgivenx
    cache_in = kwargs.pop('cache', None)
    parallel = kwargs.pop('parallel', True)
    rasterize_contours = kwargs.pop('rasterize_contours', True)
    point_size = kwargs.pop('point_size', 0.2)
    thin = kwargs.pop('thin', 1)
    npoints = kwargs.pop('npoints', 100)
    tqdm_kwargs = kwargs.pop('tqdm_kwargs', {'disable': True})
    if kwargs:
        raise TypeError('Unexpected **kwargs: {0}'.format(kwargs))
    if not isinstance(run_list, list):
        run_list = [run_list]
    # Use random seed to make samples consistent and allow caching.
    # To avoid fixing seed use random_seed=None
    state = np.random.get_state()  # save initial random state
    np.random.seed(random_seed)
    if not plot_means:
        mean_colors = [None] * len(colors)
    else:
        mean_colors = ['dark' + col for col in colors]
    nlogx = npoints
    ny_posterior = npoints
    assert len(fthetas) == len(labels)
    assert len(fthetas) == len(ftheta_lims)
    thread_linestyles = ['-', '-.', ':']
    # make figure
    # -----------
    fig, axes = plt.subplots(nrows=1 + len(fthetas), ncols=2, figsize=figsize,
                             gridspec_kw={'wspace': 0,
                                          'hspace': 0,
                                          'width_ratios': [15, 40]})
    # make colorbar axes in top left corner
    axes[0, 0].set_visible(False)
    divider = mpl_toolkits.axes_grid1.make_axes_locatable(axes[0, 0])
    colorbar_ax_list = []
    for i in range(len(run_list)):
        colorbar_ax_list.append(divider.append_axes("left", size=0.05,
                                                    pad=0.05))
    # Reverse color bar axis order so when an extra run is added the other
    # colorbars stay in the same place
    colorbar_ax_list = list(reversed(colorbar_ax_list))
    # plot runs in reverse order to put the first run on top
    for nrun, run in reversed(list(enumerate(run_list))):
        # Weight Plot
        # -----------
        ax_weight = axes[0, 1]
        ax_weight.set_ylabel('posterior\nmass')
        samples = np.zeros((n_simulate, run['nlive_array'].shape[0] * 2))
        for i in range(n_simulate):
            logx_temp = nestcheck.ns_run_utils.get_logx(
                run['nlive_array'], simulate=True)[::-1]
            logw_rel = logx_temp + run['logl'][::-1]
            w_rel = np.exp(logw_rel - logw_rel.max())
            w_rel /= np.trapz(w_rel, x=logx_temp)
            samples[i, ::2] = logx_temp
            samples[i, 1::2] = w_rel
        if logx_min is None:
            logx_min = samples[:, 0].min()
        logx_sup = np.linspace(logx_min, 0, nlogx)
        try:
            cache = cache_in + '_' + str(nrun) + '_weights'
        except TypeError:
            cache = None
        interp_alt = functools.partial(alternate_helper, func=np.interp)
        y, pmf = fgivenx.drivers.compute_pmf(
            interp_alt, logx_sup, samples, cache=cache, ny=npoints,
            parallel=parallel, tqdm_kwargs=tqdm_kwargs)
        cbar = fgivenx.plot.plot(
            logx_sup, y, pmf, ax_weight, rasterize_contours=rasterize_contours,
            colors=plt.get_cmap(colormaps[nrun]))
        ax_weight.set_xlim([logx_min, 0])
        ax_weight.set_ylim(bottom=0)
        ax_weight.set_yticks([])
        ax_weight.set_xticklabels([])
        # color bar plot
        # --------------
        colorbar_plot = plt.colorbar(cbar, cax=colorbar_ax_list[nrun],
                                     ticks=[1, 2, 3])
        colorbar_ax_list[nrun].yaxis.set_ticks_position('left')
        colorbar_plot.solids.set_edgecolor('face')
        colorbar_plot.ax.set_yticklabels([])
        if nrun == 0:
            colorbar_plot.ax.set_yticklabels(
                [r'$1\sigma$', r'$2\sigma$', r'$3\sigma$'])
        # samples plot
        # ------------
        logx = nestcheck.ns_run_utils.get_logx(run['nlive_array'],
                                               simulate=False)
        scatter_x = logx
        scatter_theta = run['theta']
        if thin != 1:
            assert 0 < thin <= 1, (
                'thin={} should be in the half-closed interval(0, 1]'
                .format(thin))
            state = np.random.get_state()  # save initial random state
            np.random.seed(random_seed)
            inds = np.where(np.random.random(logx.shape) <= thin)[0]
            np.random.set_state(state)  # return to original random state
            scatter_x = logx[inds]
            scatter_theta = run['theta'][inds, :]
        for nf, ftheta in enumerate(fthetas):
            ax_samples = axes[1 + nf, 1]
            ax_samples.scatter(scatter_x, ftheta(scatter_theta),
                               s=point_size, color=colors[nrun])
            if threads_to_plot is not None:
                for i in threads_to_plot:
                    thread_inds = np.where(run['thread_labels'] == i)[0]
                    ax_samples.plot(logx[thread_inds],
                                    ftheta(run['theta'][thread_inds]),
                                    linestyle=thread_linestyles[nrun],
                                    color='black', lw=1)
            ax_samples.set_xlim([logx_min, 0])
            ax_samples.set_ylim(ftheta_lims[nf])
        # Plot posteriors
        # ---------------
        posterior_axes = [axes[i + 1, 0] for i in range(len(fthetas))]
        _ = plot_bs_dists(run, fthetas, posterior_axes,
                          ftheta_lims=ftheta_lims,
                          flip_axes=True, n_simulate=n_simulate,
                          rasterize_contours=rasterize_contours,
                          cache=cache_in, nx=npoints, ny=ny_posterior,
                          colormap=colormaps[nrun],
                          mean_color=mean_colors[nrun],
                          parallel=parallel, tqdm_kwargs=tqdm_kwargs)
        # Plot means onto scatter plot
        # ----------------------------
        if plot_means:
            w_rel = nestcheck.ns_run_utils.get_w_rel(run, simulate=False)
            w_rel /= np.sum(w_rel)
            means = [np.sum(w_rel * f(run['theta'])) for f in fthetas]
            for nf, mean in enumerate(means):
                axes[nf + 1, 1].axhline(y=mean, lw=1, linestyle='--',
                                        color=mean_colors[nrun])
    # Format axes
    for nf, ax in enumerate(posterior_axes):
        ax.set_ylim(ftheta_lims[nf])
        ax.invert_xaxis()  # only invert each axis once, not for every run!
    axes[-1, 1].set_xlabel(r'$\log X$')
    # Add labels
    for i, label in enumerate(labels):
        axes[i + 1, 0].set_ylabel(label)
        # Prune final ytick label so it doesn't overlap with next plot
        prune = 'upper' if i != 0 else None
        axes[i + 1, 0].yaxis.set_major_locator(
            matplotlib.ticker.MaxNLocator(nbins=3, prune=prune))
    for _, ax in np.ndenumerate(axes):
        if not ax.is_first_col():
            ax.set_yticklabels([])
        if not (ax.is_last_row() and ax.is_last_col()):
            ax.set_xticks([])
    np.random.set_state(state)  # return to original random state
    return fig
def param_logx_diagram ( run_list , ** kwargs ) : fthetas = kwargs . pop ( 'fthetas' , [ lambda theta : theta [ : , 0 ] , lambda theta : theta [ : , 1 ] ] ) labels = kwargs . pop ( 'labels' , [ r'$\theta_' + str ( i + 1 ) + '$' for i in range ( len ( fthetas ) ) ] ) ftheta_lims = kwargs . pop ( 'ftheta_lims' , [ [ - 1 , 1 ] ] * len ( fthetas ) ) threads_to_plot = kwargs . pop ( 'threads_to_plot' , [ 0 ] ) plot_means = kwargs . pop ( 'plot_means' , True ) n_simulate = kwargs . pop ( 'n_simulate' , 100 ) random_seed = kwargs . pop ( 'random_seed' , 0 ) logx_min = kwargs . pop ( 'logx_min' , None ) figsize = kwargs . pop ( 'figsize' , ( 6.4 , 2 * ( 1 + len ( fthetas ) ) ) ) colors = kwargs . pop ( 'colors' , [ 'red' , 'blue' , 'grey' , 'green' , 'orange' ] ) colormaps = kwargs . pop ( 'colormaps' , [ 'Reds_r' , 'Blues_r' , 'Greys_r' , 'Greens_r' , 'Oranges_r' ] ) cache_in = kwargs . pop ( 'cache' , None ) parallel = kwargs . pop ( 'parallel' , True ) rasterize_contours = kwargs . pop ( 'rasterize_contours' , True ) point_size = kwargs . pop ( 'point_size' , 0.2 ) thin = kwargs . pop ( 'thin' , 1 ) npoints = kwargs . pop ( 'npoints' , 100 ) tqdm_kwargs = kwargs . pop ( 'tqdm_kwargs' , { 'disable' : True } ) if kwargs : raise TypeError ( 'Unexpected **kwargs: {0}' . format ( kwargs ) ) if not isinstance ( run_list , list ) : run_list = [ run_list ] state = np . random . get_state ( ) np . random . seed ( random_seed ) if not plot_means : mean_colors = [ None ] * len ( colors ) else : mean_colors = [ 'dark' + col for col in colors ] nlogx = npoints ny_posterior = npoints assert len ( fthetas ) == len ( labels ) assert len ( fthetas ) == len ( ftheta_lims ) thread_linestyles = [ '-' , '-.' , ':' ] fig , axes = plt . subplots ( nrows = 1 + len ( fthetas ) , ncols = 2 , figsize = figsize , gridspec_kw = { 'wspace' : 0 , 'hspace' : 0 , 'width_ratios' : [ 15 , 40 ] } ) axes [ 0 , 0 ] . set_visible ( False ) divider = mpl_toolkits . axes_grid1 . make_axes_locatable ( axes [ 0 , 0 ] ) colorbar_ax_list = [ ] for i in range ( len ( run_list ) ) : colorbar_ax_list . append ( divider . append_axes ( "left" , size = 0.05 , pad = 0.05 ) ) colorbar_ax_list = list ( reversed ( colorbar_ax_list ) ) for nrun , run in reversed ( list ( enumerate ( run_list ) ) ) : ax_weight = axes [ 0 , 1 ] ax_weight . set_ylabel ( 'posterior\nmass' ) samples = np . zeros ( ( n_simulate , run [ 'nlive_array' ] . shape [ 0 ] * 2 ) ) for i in range ( n_simulate ) : logx_temp = nestcheck . ns_run_utils . get_logx ( run [ 'nlive_array' ] , simulate = True ) [ : : - 1 ] logw_rel = logx_temp + run [ 'logl' ] [ : : - 1 ] w_rel = np . exp ( logw_rel - logw_rel . max ( ) ) w_rel /= np . trapz ( w_rel , x = logx_temp ) samples [ i , : : 2 ] = logx_temp samples [ i , 1 : : 2 ] = w_rel if logx_min is None : logx_min = samples [ : , 0 ] . min ( ) logx_sup = np . linspace ( logx_min , 0 , nlogx ) try : cache = cache_in + '_' + str ( nrun ) + '_weights' except TypeError : cache = None interp_alt = functools . partial ( alternate_helper , func = np . interp ) y , pmf = fgivenx . drivers . compute_pmf ( interp_alt , logx_sup , samples , cache = cache , ny = npoints , parallel = parallel , tqdm_kwargs = tqdm_kwargs ) cbar = fgivenx . plot . plot ( logx_sup , y , pmf , ax_weight , rasterize_contours = rasterize_contours , colors = plt . get_cmap ( colormaps [ nrun ] ) ) ax_weight . set_xlim ( [ logx_min , 0 ] ) ax_weight . set_ylim ( bottom = 0 ) ax_weight . set_yticks ( [ ] ) ax_weight . set_xticklabels ( [ ] ) colorbar_plot = plt . colorbar ( cbar , cax = colorbar_ax_list [ nrun ] , ticks = [ 1 , 2 , 3 ] ) colorbar_ax_list [ nrun ] . yaxis . set_ticks_position ( 'left' ) colorbar_plot . solids . set_edgecolor ( 'face' ) colorbar_plot . ax . set_yticklabels ( [ ] ) if nrun == 0 : colorbar_plot . ax . set_yticklabels ( [ r'$1\sigma$' , r'$2\sigma$' , r'$3\sigma$' ] ) logx = nestcheck . ns_run_utils . get_logx ( run [ 'nlive_array' ] , simulate = False ) scatter_x = logx scatter_theta = run [ 'theta' ] if thin != 1 : assert 0 < thin <= 1 , ( 'thin={} should be in the half-closed interval(0, 1]' . format ( thin ) ) state = np . random . get_state ( ) np . random . seed ( random_seed ) inds = np . where ( np . random . random ( logx . shape ) <= thin ) [ 0 ] np . random . set_state ( state ) scatter_x = logx [ inds ] scatter_theta = run [ 'theta' ] [ inds , : ] for nf , ftheta in enumerate ( fthetas ) : ax_samples = axes [ 1 + nf , 1 ] ax_samples . scatter ( scatter_x , ftheta ( scatter_theta ) , s = point_size , color = colors [ nrun ] ) if threads_to_plot is not None : for i in threads_to_plot : thread_inds = np . where ( run [ 'thread_labels' ] == i ) [ 0 ] ax_samples . plot ( logx [ thread_inds ] , ftheta ( run [ 'theta' ] [ thread_inds ] ) , linestyle = thread_linestyles [ nrun ] , color = 'black' , lw = 1 ) ax_samples . set_xlim ( [ logx_min , 0 ] ) ax_samples . set_ylim ( ftheta_lims [ nf ] ) posterior_axes = [ axes [ i + 1 , 0 ] for i in range ( len ( fthetas ) ) ] _ = plot_bs_dists ( run , fthetas , posterior_axes , ftheta_lims = ftheta_lims , flip_axes = True , n_simulate = n_simulate , rasterize_contours = rasterize_contours , cache = cache_in , nx = npoints , ny = ny_posterior , colormap = colormaps [ nrun ] , mean_color = mean_colors [ nrun ] , parallel = parallel , tqdm_kwargs = tqdm_kwargs ) if plot_means : w_rel = nestcheck . ns_run_utils . get_w_rel ( run , simulate = False ) w_rel /= np . sum ( w_rel ) means = [ np . sum ( w_rel * f ( run [ 'theta' ] ) ) for f in fthetas ] for nf , mean in enumerate ( means ) : axes [ nf + 1 , 1 ] . axhline ( y = mean , lw = 1 , linestyle = '--' , color = mean_colors [ nrun ] ) for nf , ax in enumerate ( posterior_axes ) : ax . set_ylim ( ftheta_lims [ nf ] ) ax . invert_xaxis ( ) axes [ - 1 , 1 ] . set_xlabel ( r'$\log X$' ) for i , label in enumerate ( labels ) : axes [ i + 1 , 0 ] . set_ylabel ( label ) prune = 'upper' if i != 0 else None axes [ i + 1 , 0 ] . yaxis . set_major_locator ( matplotlib . ticker . MaxNLocator ( nbins = 3 , prune = prune ) ) for _ , ax in np . ndenumerate ( axes ) : if not ax . is_first_col ( ) : ax . set_yticklabels ( [ ] ) if not ( ax . is_last_row ( ) and ax . is_last_col ( ) ) : ax . set_xticks ( [ ] ) np . random . set_state ( state ) return fig
Creates diagrams of a nested sampling run's evolution as it iterates
    towards higher likelihoods, expressed as a function of log X, where X(L) is
    the fraction of the prior volume with likelihood greater than some value L.

    For a more detailed description and some example use cases, see 'nestcheck:
    diagnostic tests for nested sampling calculations" (Higson et al. 2019).

    Parameters
    ----------
    run_list: dict or list of dicts
        Nested sampling run(s) to plot.
    fthetas: list of functions, optional
        Quantities to plot. Each must map a 2d theta array to 1d ftheta array -
        i.e. map every sample's theta vector (every row) to a scalar quantity.
        E.g. use lambda x: x[:, 0] to plot the first parameter.
    labels: list of strs, optional
        Labels for each ftheta.
    ftheta_lims: dict, optional
        Plot limits for each ftheta.
    plot_means: bool, optional
        Should the mean value of each ftheta be plotted?
    n_simulate: int, optional
        Number of bootstrap replications to use for the fgivenx distributions.
    random_seed: int, optional
        Seed to make sure results are consistent and fgivenx caching can be
        used.
    logx_min: float, optional
        Lower limit of logx axis.
    figsize: tuple, optional
        Matplotlib figure size (in inches).
    colors: list of strs, optional
        Colors to plot run scatter plots with.
    colormaps: list of strs, optional
        Colormaps to plot run fgivenx plots with.
    npoints: int, optional
        How many points to have in the logx array used to calculate and plot
        analytical weights.
    cache: str or None
        Root for fgivenx caching (no caching if None).
    parallel: bool, optional
        fgivenx parallel optional
    point_size: float, optional
        size of markers on scatter plot (in pts)
    thin: float, optional
        factor by which to reduce the number of samples before plotting the
        scatter plot. Must be in half-closed interval (0, 1].
    rasterize_contours: bool, optional
        fgivenx rasterize_contours option.
    tqdm_kwargs: dict, optional
        Keyword arguments to pass to the tqdm progress bar when it is used in
        fgivenx while plotting contours.

    Returns
    -------
    fig: matplotlib figure