Esempio n. 1
0
def cmp_dimensions(benchmark_path='/home/cmg76/Works/exo-top/benchmarks/lees_topo_grids/',
                   data_path='/raid1/cmg76/aspect/model-output/', save=True, fig_path=fig_path_bullard, **kwargs):
    """ load 3D spectrum from digitised plot """
    df3 = pd.read_csv(benchmark_path + 'psd_freefree.csv', index_col=False, comment='#', header=0)
    psd3 = df3.y.to_numpy()  # km^2 km^2
    wl3 = df3.x.to_numpy()  # km
    k3 = 2 * np.pi / wl3

    d = 600  # km
    alpha = 4e-5
    dT = 442  # potential temperature difference K

    """ load 2D spectrum from aspect data """
    psd2, k2 = sh.load_model_spectrum_pkl(path='', data_path=data_path_bullard, case='Lees-Ra1e6-2D')
    psd2 = psd2 * d ** 3 * alpha ** 2 * dT ** 2
    k2 = k2 * d ** -1

    # convert from km^3 to km^4
    psd2_iso = 1 / k2 * psd2  # Jacobs eqn 5 but pi changed to 1 in numerator says JFR

    """ plot """
    fig, ax = plt.subplots()
    ax.loglog(k2, psd2_iso, 'o-', lw=1, alpha=0.5, c='xkcd:slate', label='2D benchmark test')
    ax.loglog(k3, psd3, '^-', lw=1, alpha=0.5, c='xkcd:forest green', label='3D form Lees')
    ax.set_xlabel(r'Wavenumber (km$^{-1}$)')
    ax.set_ylabel(r'PSD (km$^{2}$ km$^{2}$)')
    ax.legend()

    if save:
        plot_save(fig, fname='2D_benchmark', fig_path=fig_path)
Esempio n. 2
0
def animate_Ra_time(default='Earthbaseline',
                    fig_path='plat/',
                    figsize=(9, 9),
                    labelsize=16,
                    ylabelpad=10,
                    xlabelpad=10,
                    ticksize=12,
                    fname='ani_1D',
                    scalar=False,
                    i_static=None,
                    x_test2=None,
                    xticks=[0.1, 0.3, 1, 2, 3, 4, 5, 6],
                    yticks=None,
                    aspect_cases=None,
                    ms_scat=20,
                    marker_scat='o',
                    c_scat='g',
                    data_path='',
                    x_test=0.815 * M_E,
                    x_min=0.03 * M_E,
                    x_max=6 * M_E,
                    y_param=None,
                    x_param='M_p',
                    x2_param='Ra_i_eff',
                    xscale=M_E**-1,
                    x2scale=1,
                    yscale=1,
                    fps=15,
                    c='b',
                    y2label=r'$\Delta h_{rms}$ (m)',
                    y2scale=1,
                    anim_param='t',
                    anim_tpref='t = ',
                    anim_tsuff=' Gyr',
                    anim_scale=sec2Gyr,
                    secy=False,
                    tf=10,
                    ti=2,
                    ylabel='',
                    x_min_planets=0.1 * M_E,
                    ini_dict=None,
                    logx=True,
                    text=True,
                    dark=True,
                    lw=3,
                    nplanets=20,
                    alpha_lines=1,
                    xlabel=r'$M_p$ ($M_E$)',
                    x2label=r'Ra$_{i, eff}$',
                    **kwargs):
    # params refer to variable names in 1D model
    if aspect_cases is None:
        aspect_cases = [
            'Ra3e8-eta1e8-wide-ascii', 'Ra3e8-eta1e7-wide-ascii',
            'Ra3e8-eta1e6-wide', 'Ra1e8-eta1e8-wide-ascii',
            'Ra1e8-eta1e7-wide', 'Ra1e8-eta1e6-wide'
        ]
    ## too much effort to do animated subplots (and massive files)

    fig, ax = plt.subplots(figsize=figsize)

    # only need to load aspect data once and then re-dimensionalise it
    cases_x, cases_y = [], []
    for case in aspect_cases:
        ax, x_aspect_data, y_aspect_data = overplot_aspect_data(
            ax,
            case,
            x_param=x2_param,
            y_param=y_param,
            data_path=data_path,
            pkl_suffix=['_T', '_h'],
            markersize=ms_scat,
            marker=marker_scat,
            return_data=True,
            visible=False,
            **kwargs)
        cases_x.append(x_aspect_data)
        cases_y.append(y_aspect_data)
    scat_data = np.vstack((cases_x, cases_y)).T  # shape N, 2

    # run evolutions
    if x_min_planets is None:
        x_min_planets = x_min
    initial_kwargs = {'tf': tf}
    if ini_dict is not None:
        initial_kwargs.update(ini_dict)
    pl_test = build_planet_from_id(ident=default,
                                   nondimensional=True,
                                   initial_kwargs=initial_kwargs,
                                   verbose=True,
                                   update_kwargs={x_param: x_test},
                                   **kwargs)
    if x_test2 is not None:
        pl_test2 = build_planet_from_id(ident=default,
                                        nondimensional=True,
                                        initial_kwargs=initial_kwargs,
                                        verbose=True,
                                        update_kwargs={x_param: x_test2},
                                        **kwargs)
    pl_mass = bulk_planets(n=nplanets,
                           name=x_param,
                           mini=x_min,
                           maxi=x_max,
                           like=default,
                           random=False,
                           nondimensional=True,
                           logscale=logx,
                           initial_kwargs=initial_kwargs,
                           t_eval=pl_test.t,
                           **kwargs)
    i_start_time = np.argmax(
        pl_test.t >= ti / sec2Gyr)  # don't animate any cases before here
    if i_static is None:
        # index to make static figure
        i_static = i_start_time

    if anim_param == 't':
        anim_vec = np.array(pl_mass[-1].t)

    # only plot planets with x value greater than x_min_planets (this is to extend axis limits for aspect compare)
    x_orig = np.array([vars(pl)[x_param] for pl in pl_mass]) * xscale
    ax.set_xlim(
        x_orig.min(), x_orig.max()
    )  # need to set limits for twin axis before removing small points so u can see Ra
    i_plot = np.argmax(x_orig >= x_min_planets * xscale)
    pl_pl = pl_mass[i_plot:]
    x = x_orig[i_plot:]
    y = np.array([vars(pl)[y_param + '_prime'][i_static]
                  for pl in pl_pl]) * yscale
    p1, = ax.plot(x, y, c=c, lw=lw, alpha=alpha_lines)
    pl_scat = ax.scatter(vars(pl_test)[x_param] * xscale,
                         vars(pl_test)[y_param + '_prime'][i_static] * yscale,
                         marker='$V$',
                         s=ms_scat * 2,
                         c='xkcd:goldenrod',
                         zorder=100)
    if x_test2 is not None:
        pl_scat2 = ax.scatter(vars(pl_test2)[x_param] * xscale,
                              vars(pl_test2)[y_param + '_prime'][i_static] *
                              yscale,
                              marker='$M$',
                              s=ms_scat * 2,
                              c='xkcd:goldenrod',
                              zorder=100)
    else:
        pl_scat2 = ax.scatter([], [], visible=False)

    # secondary x axis

    # attempt to scale x2 axis
    x2_orig = np.array([
        vars(pl)[x2_param][i_static] for pl in pl_mass
    ]) * x2scale  # limits corresponding to tiny planets for extra space
    x2 = x2_orig[i_plot:]
    global x2_orig_i
    x2_orig_i = x2_orig

    def mass2Ra(u):
        f = InterpolatedUnivariateSpline(x_orig, x2_orig_i, k=3)
        return f(u)

    def Ra2mass(u):
        f = InterpolatedUnivariateSpline(x2_orig_i, x_orig, k=3)
        return f(u)

    ax2 = ax.secondary_xaxis('top', functions=(mass2Ra, Ra2mass))
    p2, = ax.plot(Ra2mass(x2), y, c=c, lw=lw, alpha=alpha_lines, ls='--')
    aspect_scat = ax.scatter(Ra2mass(cases_x),
                             cases_y,
                             c=c_scat,
                             s=ms_scat,
                             marker=marker_scat,
                             zorder=100,
                             visible=True)

    # ax2 = ax.twiny()
    # ax2.set_xlim(x2_orig.min(), x2_orig.max())
    # p2, = ax2.plot(x2, y, c=c, lw=lw, alpha=alpha_lines, ls='--')
    # aspect_scat = ax2.scatter(cases_x, cases_y, c=c_scat, s=markersize, marker=marker, visible=True)

    # secondary y axis
    global alpha_m
    global dT_i
    global dm
    alpha_m = pl_test.alpha_m
    dT_i = pl_test.T_scale[i_static]
    dm = pl_test.L_scale

    def h_todim(u):
        return u * alpha_m * dT_i * dm * y2scale

    def h_tonondim(u):
        return u / (alpha_m * dT_i * dm * y2scale)

    if secy:
        ax3 = ax.secondary_yaxis('right', functions=(h_todim, h_tonondim))
        ax3.set_ylabel(y2label, fontsize=labelsize, labelpad=ylabelpad)
        ax3.tick_params(axis='y', which='major', labelsize=ticksize)

    # setup plot params
    ax2.set_xlabel(x2label, fontsize=labelsize, labelpad=xlabelpad)
    ax2.tick_params(axis='x', which='major', labelsize=ticksize)
    ax.set_xlabel(xlabel, fontsize=labelsize, labelpad=xlabelpad)
    ax.set_ylabel(ylabel, fontsize=labelsize, labelpad=ylabelpad)
    ax.tick_params(axis='both', which='major', labelsize=ticksize)
    # ax.xaxis.set_major_formatter(ticker.ScalarFormatter())
    # ax.xaxis.set_minor_formatter(ticker.ScalarFormatter())
    ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%g'))
    ax.xaxis.set_minor_formatter(ticker.NullFormatter())
    ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%g'))
    ax.yaxis.set_minor_formatter(ticker.NullFormatter())
    ax2.yaxis.set_major_formatter(ticker.FormatStrFormatter('%g'))
    ax2.yaxis.set_minor_formatter(ticker.NullFormatter())
    if logx:
        ax.set_xscale('log')
        ax.set_yscale('log')
        # ax2.set_xscale('log')
        # ax2.set_yscale('log')
    if xticks is not None:
        ax.set_xticks(xticks)
    if yticks is not None:
        ax.set_yticks(yticks)

    # colour and adjust
    if dark:
        if secy:
            fig, ax, ax2, ax3 = dark_background(fig, [ax, ax2, ax3])
        else:
            fig, ax, ax2 = dark_background(fig, [ax, ax2])
        c_text = 'xkcd:off white'
    else:
        c_text = 'k'
    if text:
        ani_text = ax.text(0.95,
                           0.95,
                           anim_tpref +
                           '{:4.1f}'.format(anim_vec[i_static] * anim_scale) +
                           anim_tsuff,
                           fontsize=ticksize,
                           c=c_text,
                           horizontalalignment='right',
                           verticalalignment='top',
                           transform=ax.transAxes)
    else:
        ani_text = ax.text(0.5, 0.5, '', alpha=0, transform=ax.transAxes)

    ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%g'))
    ax.xaxis.set_minor_formatter(ticker.NullFormatter())
    ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%g'))
    ax.yaxis.set_minor_formatter(ticker.NullFormatter())

    plt.subplots_adjust(bottom=0.2, top=0.8, left=0.15)
    plt.tight_layout()

    # save non-animated snapshot
    plot_save(fig,
              fname=fname + '_static',
              fig_path=fig_path,
              bbox_inches=None)

    # animation stuff
    def init():
        p1.set_ydata(([np.nan] * len(x)))
        p2.set_ydata(([np.nan] * len(x)))
        aspect_scat.set_offsets([[], []])
        pl_scat.set_offsets([[], []])
        if x_test2 is not None:
            pl_scat2.set_offsets([[], []])
        ani_text.set_text('')
        return p1, p2, aspect_scat, pl_scat, ani_text, pl_scat2

    def animate(i, cases_x, cases_y, pl_pl, y_param, x2_param, yscale, x2scale,
                pl_mass, anim_vec, anim_tpref, anim_scale, anim_tsuff,
                pl_scat2):

        # update secondary x
        global x2_orig_i
        x2_orig_i = np.array([vars(pl)[x2_param][i] for pl in pl_mass
                              ]) * x2scale  # new x2 based on original size
        new_cases_x = Ra2mass(
            cases_x)  # Ra_i_eff axis - doesn't move if axis isn't moving
        new_cases_y = cases_y
        new_scat_data = np.vstack((new_cases_x, new_cases_y)).T  # shape N, 2

        # update secondary y
        global dT_i
        dT_i = pl_test.T_scale[i]

        p1y = np.array([vars(pl)[y_param + '_prime'][i]
                        for pl in pl_pl]) * yscale
        # p2x = np.array([vars(pl)[x2_param][i] for pl in pl_pl]) * x2scale
        # p2y = np.array([vars(pl)[y_param + '_prime'][i] for pl in pl_pl]) * yscale

        p1.set_ydata(p1y)  # update the data.
        # p2.set_xdata(Ra2mass(p2x))  # note this is attached to Ra axis
        # p2.set_ydata(p2y)
        aspect_scat.set_offsets(new_scat_data)

        pl_scat_x = vars(pl_test)[x_param] * xscale
        pl_scat_y = vars(pl_test)[y_param + '_prime'][i] * yscale
        pl_scat_data = np.vstack((pl_scat_x, pl_scat_y)).T  # shape N, 2
        pl_scat.set_offsets(pl_scat_data)

        if pl_scat2 is not None:
            pl_scat2_x = vars(pl_test2)[x_param] * xscale
            pl_scat2_y = vars(pl_test2)[y_param + '_prime'][i] * yscale
            pl_scat2_data = np.vstack((pl_scat2_x, pl_scat2_y)).T  # shape N, 2
            pl_scat2.set_offsets(pl_scat2_data)
        else:
            pl_scat2 = None

        # ax2.set_xlim(min(x2_orig_i), max(x2_orig_i))  # added ax attribute here
        ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%g'))
        ax.xaxis.set_minor_formatter(ticker.NullFormatter())
        ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%g'))
        ax.yaxis.set_minor_formatter(ticker.NullFormatter())

        ani_text.set_text(anim_tpref +
                          '{:4.1f}'.format(anim_vec[i] * anim_scale) +
                          anim_tsuff)
        return p1, p2, aspect_scat, pl_scat, ani_text, pl_scat2

    # print('i frames', i_start_time, len(anim_vec), 'len', len(range(i_start_time, len(anim_vec))))
    # print('len x2', len(vars(pl_mass[-1])[x2_param]))
    # print('len y', len(vars(pl_mass[-1])[y_param + '_prime']))
    # for ii in range(len(pl_mass)):
    #     print('   ii, x2:', len(vars(pl_mass[ii])[x2_param]), pl_mass[ii].M_p/M_E)

    ani = animation.FuncAnimation(
        fig,
        animate,
        frames=range(i_start_time, len(anim_vec)),
        init_func=init,
        fargs=(cases_x, cases_y, pl_pl, y_param, x2_param, yscale, x2scale,
               pl_mass, anim_vec, anim_tpref, anim_scale, anim_tsuff,
               pl_scat2),
        blit=False,
        repeat=True,
        interval=200,
    )  # interval: delay between frames in ms

    print('finished!')
    ani.save(fig_path + fname + '.gif',
             writer='imagemagick',
             fps=fps,
             savefig_kwargs={'facecolor': fig.get_facecolor()})
    print('saved to', fig_path + fname)
Esempio n. 3
0
def plot_1D_evolutions(default,
                       nplanets=45,
                       labelsize=23,
                       ticksize=16,
                       clabelpad=4,
                       save=True,
                       fname='evol_summary',
                       zmin=None,
                       zmax=None,
                       zname=None,
                       zlabel=None,
                       zscale=1,
                       ylabels_dict=None,
                       age=4.5,
                       ini_dict=None,
                       cmap='rainbow',
                       **kwargs):
    if ylabels_dict is None:
        ylabels_dict = {
            'T_m': ('$T_i$ (K)', 1),
            'T_scale': ('$\Delta T$ (K)', 1),
            'eta_m': ('$\eta (T_m)$', 1),
            'delta_eta': ('$\eta_0/\eta_{\Delta T}$', 1),
            'delta_rh': ('$\delta_{u}$ (km)', 1e-3),
            'd_m': ('$d_m$ (km)', 1e-3),
            'D_l': ('$D_l$ (km)', 1e-3),
            'Ra_i': ('Ra$_i$', 1),
            # 'H_rad_m': ('$H_{rad}$ (TW)', 1e-12)
        }
    initial_kwargs = {'tf': age}
    if ini_dict is not None:
        initial_kwargs.update(ini_dict)
    planets = bulk_planets(nplanets,
                           name=zname,
                           mini=zmin,
                           maxi=zmax,
                           like=default,
                           initial_kwargs=initial_kwargs,
                           nondimensional=True,
                           **kwargs)
    z_vec = np.array([vars(pl)[zname] for pl in planets]) * zscale
    cols = colorize(z_vec, cmap=cmap)[0]

    for ii, pl in enumerate(planets):
        if ii == 0:
            fig = None
            axes = None
        fig, axes = plot_output(pl,
                                ylabels_dict,
                                ncols=2,
                                plots_save=False,
                                fig=fig,
                                axes=axes,
                                legend=False,
                                title='',
                                line_args={'c': cols[ii]},
                                **kwargs)

    sc = fig.gca().scatter(None, None, vmin=zmin, vmax=zmax, cmap='rainbow')
    sm = plt.cm.ScalarMappable(cmap=cmap,
                               norm=plt.Normalize(vmin=zmin * zscale,
                                                  vmax=zmax * zscale))
    sm._A = []
    fig.subplots_adjust(right=0.85, wspace=0.5)
    cbar_ax = fig.add_axes([0.9, 0.15, 0.04, 0.7])
    fig.colorbar(sm, cax=cbar_ax)
    cbar_ax.set_ylabel(zlabel, fontsize=labelsize, labelpad=clabelpad)
    cbar_ax.tick_params(axis='y', labelsize=ticksize)
    if save:
        plot_save(fig, fname, tight_layout=False, **kwargs)
    return fig, axes
Esempio n. 4
0
def plot_h_heuristic_variations(default='Earthbaseline',
                                x_param='M_p',
                                x_min=0.1 * M_E,
                                x_max=10 * M_E,
                                y_params=None,
                                xlabel=r'$M_p$ ($M_E$)',
                                x2_param='Ra_i_eff',
                                x2label=r'Ra$_i$',
                                save=True,
                                age=4.5,
                                fname='heuristic_mass_dependence',
                                overplot_aspect_cases_x_param='Ra_i_eff',
                                ylabels=None,
                                labelpad=10,
                                nplanets=20,
                                markersize=20,
                                marker='*',
                                ini_dict=None,
                                yscales=None,
                                legend=True,
                                xscale=M_E**-1,
                                x2scale=1,
                                nondimensional=True,
                                fig=None,
                                axes=None,
                                c='xkcd:drab green',
                                c2='xkcd:electric purple',
                                lw=2,
                                labelsize=20,
                                legsize=14,
                                ticksize=14,
                                overplot_aspect_cases=None,
                                logx=True,
                                alpha=0.7,
                                xleglabel=r'$M_p$, 1D model',
                                x2leglabel=r'Ra$_i$, 1D model',
                                return_artists=False,
                                aspectleglabel=r'Ra$_i$, 2D model',
                                x_min_planets=None,
                                **kwargs):
    if nondimensional and ylabels is None:
        ylabels = [
            r'$\Delta h^\prime_{rms}$', r'$\Delta T^\prime_{rh}$',
            r'$\delta^\prime_u$',
            r'$\alpha^\prime \Delta T^\prime_{rh} \delta^\prime_u$'
        ]
    elif ylabels is None:
        ylabels = [
            r'$\Delta h_{rms}$ (km)', r'$\Delta T_{rh}$ (K)',
            r'$\delta_u$ (km)', r'$\alpha \Delta T_{rh} \delta_u$ (km)'
        ]
    if y_params is None:
        y_params = ['dyn_top_rms', 'dT_rh', 'delta_rh', 'heuristic_h']
    if overplot_aspect_cases is None:
        overplot_aspect_cases = []
    if x_min_planets is None:
        x_min_planets = x_min

    initial_kwargs = {'tf': age}
    if ini_dict is not None:
        initial_kwargs.update(ini_dict)

    pl_mass = bulk_planets(n=nplanets,
                           name=x_param,
                           mini=x_min,
                           maxi=x_max,
                           like=default,
                           random=False,
                           nondimensional=nondimensional,
                           logscale=logx,
                           initial_kwargs=initial_kwargs,
                           **kwargs)

    if nondimensional and yscales is None:
        yscales = [1, 1, 1, 1]
        for yy in range(len(y_params)):
            y_params[yy] = y_params[yy] + '_prime'

    elif yscales is None:
        yscales = [1e-3, 1, 1e-3, 1e-3]

    if axes is None:
        fig, axes = plt.subplots(len(y_params),
                                 1,
                                 figsize=(4, 3 * len(y_params)))

    lines = []
    for row, ax in enumerate(axes):
        ax.set_ylabel(ylabels[row], fontsize=labelsize, labelpad=labelpad)
        x = np.array([vars(pl)[x_param] for pl in pl_mass]) * xscale
        y = np.array([vars(pl)[y_params[row]][-1]
                      for pl in pl_mass]) * yscales[row]
        # only plot planets with x value greater than x_min_planets (this is to extend axis limits for aspect compare)
        i_plot = np.argmax(x >= x_min_planets * xscale)
        p1, = ax.plot(x[i_plot:],
                      y[i_plot:],
                      c=c,
                      lw=lw,
                      label=xleglabel,
                      alpha=alpha)
        # ax.scatter(x[i_plot:], y[i_plot:], c=c, lw=0, alpha=alpha, marker='v')
        ax.set_xlim(x.min(), x.max())
        if logx:
            ax.set_xscale('log')
        if row + 1 == len(axes):  # only label bottom row
            ax.tick_params(axis='both', which='both', labelsize=ticksize)
            ax.set_xlabel(xlabel, fontsize=labelsize, labelpad=labelpad)
            lines.append(p1)
        else:
            ax.tick_params(axis='x', which='both', labelbottom='off')
            ax.tick_params(axis='y', which='both', labelsize=ticksize)
            ax.xaxis.set_major_formatter(NullFormatter())

        if x2_param is not None:
            ax2 = ax.twiny()
            x2 = np.array([vars(pl)[x2_param][-1] for pl in pl_mass]) * x2scale
            p2, = ax2.plot(x2[i_plot:],
                           y[i_plot:],
                           c=c2,
                           lw=lw,
                           label=x2leglabel,
                           alpha=alpha,
                           ls='--')
            # ax2.scatter(x2[i_plot:], y[i_plot:], c=c2, lw=0, alpha=alpha, marker='^')
            ax2.set_xlim(x2.min(), x2.max())
            if logx:
                ax2.set_xscale('log')
            if row == 0:  # only label top row
                ax2.tick_params(axis='both', which='both', labelsize=ticksize)
                ax2.set_xlabel(x2label, fontsize=labelsize, labelpad=labelpad)
                lines.append(p2)
            else:
                ax2.tick_params(axis='x', which='both', labeltop='off')
                ax2.xaxis.set_major_formatter(NullFormatter())

        if not (not overplot_aspect_cases):
            if overplot_aspect_cases_x_param == x_param:
                ax_op = ax
                c_op = c
            elif overplot_aspect_cases_x_param == x2_param:
                ax_op = ax2
                c_op = c2
            else:
                raise Exception(
                    'x param for overplotting aspect data must match ax or ax2'
                )
            for case in overplot_aspect_cases:
                ax_op = overplot_aspect_data(
                    ax_op,
                    case,
                    x_param=overplot_aspect_cases_x_param,
                    y_param=y_params[row]
                    [:-6],  # remove prime, assume nondimensional
                    pkl_suffix=['_T', '_h'],
                    c=c_op,
                    markersize=markersize,
                    marker=marker,
                    **kwargs)

        # for a in axs:
        # tkw = dict(size=4, width=1.5)
        # a.tick_params(axis='y', colors=p1.get_color(), **tkw)
    if legend:
        if not (not overplot_aspect_cases):
            p3 = mlines.Line2D([], [],
                               lw=0,
                               color=c_op,
                               marker=marker,
                               markersize=markersize / 4,
                               label=aspectleglabel)
            lines.append(p3)
        axes[0].legend(lines, [l.get_label() for l in lines],
                       fontsize=legsize,
                       frameon=True)
    fig.subplots_adjust(hspace=0.05)
    if save:
        plot_save(fig, fname, tight_layout=False, **kwargs)
Esempio n. 5
0
    # ax.ticklabel_format(style='plain', axis='y', useOffset=False)
    ax.legend(handles=handles,
              frameon=False,
              fontsize=25,
              ncol=1,
              bbox_to_anchor=(1.01, 1),
              loc='upper left')

    ax2.tick_params(axis='y', labelsize=ticksize, pad=15)
    ax2.set_yticks([1000, 1600, 2280])
    ax2.yaxis.set_major_formatter(ticker.ScalarFormatter())
    ax2.yaxis.set_minor_formatter(ticker.ScalarFormatter())

    plat.plot_save(fig,
                   fname='h_Ra_dim_' + regime,
                   fig_path=fig_path + 'slides/',
                   fig_fmt=fig_fmt,
                   facecolor=fig.get_facecolor())
    """ model vs data """
    c_contours = 'xkcd:off white'
    fc = 'k'
    fig, ax = plat.plot_model_data_errorbars(
        Ra_ls,
        eta_ls,
        regime_grid=regime_grid_td,
        t1_grid=t1_grid,
        load_grid=True,
        end_grid=end_grid,
        literature_file=None,
        legend=False,
        cmap=None,
Esempio n. 6
0
def Venus_correction(baseline_fname='base_spectrum.pkl',
                     fig_path='',
                     R_base=2,
                     lmin=1,
                     lmax=None,
                     set_axlabels=True,
                     save=True,
                     plot=True,
                     units='km4',
                     scale_to='Venus',
                     labelsize=16,
                     legsize=12,
                     alpha=0.5,
                     fig=None,
                     ax=None,
                     c_Ve='xkcd:sea',
                     c_fit='xkcd:slate',
                     x_name='degrees',
                     load_fname=None,
                     xlim=None,
                     show_orig=True,
                     V_label='Venus (Wieczorek 2015)',
                     is_1D=False,
                     marker_Ve='o',
                     ticksize=12,
                     **kwargs):
    R_Venus = get_pysh_constants('Venus', 'r')
    if 'km' in units:
        R_Venus = R_Venus * 1e-3  # in km
        to_km = True
    else:
        to_km = False
    if '4' in units:
        to_1D = False
    elif '3' in units:
        to_1D = True
    if scale_to != 'Venus':
        R_Venus = R_base

    # get PSDs - model is 1D
    l, phi = load_model_spectrum_pkl(fname=baseline_fname,
                                     path=fig_path,
                                     **kwargs)
    k = l_to_k(l, R_Venus)
    phi_iso = 1 / k * phi

    if lmax is None:
        lmax = np.max(l)

    if load_fname is None:
        # use Venus spectrum
        lV, phiV = get_psd_Venus(
            unit='per_lm', to_1D=False, lmax=lmax, to_km=to_km, verbose=False
        )  # power per lm in km^2 km^2, 2D because need to scale S anyways
        kV = l_to_k(lV, R_Venus)
    else:
        lV, phiV = load_model_spectrum_pkl(fname=load_fname,
                                           path=fig_path,
                                           **kwargs)
        # make sure same format (2D) as above
        kV = l_to_k(lV, R_Venus)
        phiV = phiV / kV

    print('lmax', lmax)
    print('lV', lV[0], '-', lV[-1])

    # remove 0 degree
    l, phi_iso, phi, k = l[lmin:lmax + 1], phi_iso[lmin:lmax +
                                                   1], phi[lmin:lmax +
                                                           1], k[lmin:lmax + 1]
    lV, phiV, kV = lV[lmin:lmax + 1], phiV[lmin:lmax + 1], kV[lmin:lmax + 1]

    # scale to Venus RMS at power
    # if to_1D:
    #     rms_V = parseval_rms(phiV, kV)
    #     rms_base = parseval_rms(phi_mdl, k)
    # else:
    rms_V = parseval_rms_2D(phiV, kV)
    rms_base = parseval_rms_2D(phi_iso, k)
    print('rms Venus', rms_V, 'km')
    print('rms base', rms_base, 'nondim')

    S = np.array(phi_iso) * (2 * l + 1) / (
        4 * np.pi * R_Venus**2)  # factor of 4piR^2 from Lees eq A7
    SV = np.array(phiV) * (2 * lV + 1) / (4 * np.pi * R_Venus**2)

    if scale_to == 'base':
        rms0 = rms_base
    elif scale_to == 'Venus':
        rms0 = rms_V
    elif isinstance(scale_to, float):
        # scale_to is float -> desired rms
        rms0 = scale_to

    S_sc = S * (rms0 / rms_base)**2  # scale
    phi_sc = S_sc / (2 * l + 1)  # conver to per lm
    SV_sc = SV * (rms0 / rms_V)**2  # scale
    phiV_sc = SV_sc / (2 * lV + 1)  # convert to per lm
    print('rms base new', parseval_rms_2D(4 * np.pi * R_Venus**2 * phi_sc, k))
    print('rms Venus new', parseval_rms_2D(4 * np.pi * R_Venus**2 * phiV_sc,
                                           kV))

    if to_1D:
        # convert back to 1D
        phiV_sc = phiV_sc * kV
        phi_sc = phi_sc * k
        print('rms base new 1D',
              parseval_rms(4 * np.pi * R_Venus**2 * phi_sc, k))
        print('rms Venus new 1D',
              parseval_rms(4 * np.pi * R_Venus**2 * phiV_sc, kV))

    if plot:
        if fig is None:
            fig, ax = plt.subplots()
        mdl_label = 'Numerical dynamic topography'
        if scale_to == 'Venus':
            mdl_label = mdl_label + ' @ Venus RMS'
        if x_name == 'degrees':
            if show_orig:
                ax.loglog(l,
                          4 * np.pi * R_Venus**2 * phi_sc,
                          marker='^',
                          ls='-',
                          lw=1,
                          alpha=alpha,
                          c=c_fit,
                          label=mdl_label)
            ax.loglog(lV,
                      4 * np.pi * R_Venus**2 * phiV_sc,
                      marker=marker_Ve,
                      ls='-',
                      lw=1,
                      alpha=alpha,
                      c=c_Ve,
                      label=V_label)
        elif x_name == 'wavenumber':
            kV = l_to_k(lV, R_Venus)
            k = l_to_k(l, R_Venus)
            if show_orig:
                ax.loglog(k,
                          4 * np.pi * R_Venus**2 * phi_sc,
                          marker='^',
                          ls='-',
                          lw=1,
                          alpha=alpha,
                          c=c_fit,
                          label=mdl_label)
            ax.loglog(kV,
                      4 * np.pi * R_Venus**2 * phiV_sc,
                      marker=marker_Ve,
                      ls='-',
                      lw=1,
                      alpha=alpha,
                      c=c_Ve,
                      label=V_label)
        if set_axlabels:
            ax.set_xlabel(r'Degree', fontsize=labelsize)
            if units == 'km4':
                ylabel = r'2D PSD (km$^{2}$ km$^{2}$)'
            elif units == 'km3':
                ylabel = r'1D PSD (km$^{2}$ km)'
            ax.set_ylabel(ylabel, fontsize=labelsize)
        ax.legend(frameon=False, fontsize=legsize)
        ax.tick_params(axis='both', which='major', labelsize=ticksize)
        if xlim is not None:
            ax.set_xlim(xlim)
        if save:
            plot_save(fig, fname='Venus_correction', fig_path=fig_path)

    if lmin > 0:
        lV = np.arange(0, lmax + 1)
        phiV_sc = np.insert(np.array(phiV_sc), 0,
                            [0.0] * lmin)  # no power below lmin

    if plot:
        return lV, phiV_sc, fig, ax
    return lV, phiV_sc
Esempio n. 7
0
def plot_norm_psd(baseline_fname='base_spectrum.pkl',
                  fig_path='',
                  psd_path=None,
                  lmin=1,
                  lmax=None,
                  x_name='degrees',
                  norm='rel_power',
                  c='xkcd:sea',
                  marker='o',
                  label='',
                  dims='1D',
                  R=2,
                  xlim=None,
                  ylim=None,
                  fig=None,
                  ax=None,
                  labelsize=16,
                  legsize=12,
                  ticksize=12,
                  save=True,
                  labelpad=12,
                  x2label='',
                  xlabel=None,
                  ylabel=None,
                  fname='norm_psd',
                  legend=True,
                  show_degrees=False,
                  **kwargs):
    if psd_path is None:
        psd_path = fig_path
    print('\n')
    # generic plotting a spectrum
    if R == 'Venus':
        R = get_pysh_constants('Venus', 'r')
    if baseline_fname == 'Venus':
        l, phi_iso = get_psd_Venus(
            unit='per_lm', to_1D=False, lmax=lmax, to_km=False,
            verbose=False)  # power per lm in m^2 m^2, 2D
        k = l_to_k(l, R)
        phi = k * phi_iso
    else:
        # get PSDs - model spectra are 1D and at fixed degrees
        l, phi = load_model_spectrum_pkl(fname=baseline_fname,
                                         path=psd_path,
                                         **kwargs)
        # print('loaded l', l)
        k = l_to_k(l, R)
        phi_iso = 1 / k * phi

    if lmax is None:
        lmax = np.max(l)
    if l[0] == 0:
        # remove 0 degree
        l, phi_iso, phi, k = l[lmin:lmax +
                               1], phi_iso[lmin:lmax +
                                           1], phi[lmin:lmax +
                                                   1], k[lmin:lmax + 1]

    # normalise
    _, phi_norm = norm_spectrum(k, phi, k_min=None, norm=norm, **kwargs)

    # print('l to plot', l[0], ':', l[-1])
    # print('k to plot', k[0], ':', k[-1])
    if fig is None:
        fig, ax = plt.subplots()
    if x_name == 'degrees':
        ax.loglog(l, phi_norm, marker=marker, ls='-', lw=1, c=c, label=label)
    elif x_name == 'wavenumber':
        ax.loglog(k, phi_norm, marker=marker, ls='-', lw=1, c=c, label=label)
    ax.set_xlabel(xlabel, fontsize=labelsize, labelpad=labelpad)
    ax.set_ylabel(ylabel, fontsize=labelsize, labelpad=labelpad)
    ax.tick_params(axis='both', which='major', labelsize=ticksize)
    if xlim is not None:
        ax.set_xlim(xlim)
    if ylim is not None:
        ax.set_ylim(ylim)
    if legend:
        ax.legend(frameon=False, fontsize=legsize)
    if save:
        plot_save(fig, fname=fname, fig_path=fig_path)

    if show_degrees and x_name == 'wavenumber':

        def to_deg(k):
            return k * R - 0.5

        def to_wn(l):
            return (l + 0.5) / (R)

        secax = ax.secondary_xaxis('top', functions=(to_deg, to_wn))
        secax.set_xlabel(x2label, fontsize=labelsize, labelpad=labelpad)
        secax.tick_params(axis='both', which='major', labelsize=ticksize)
        # secax.plot(l, phi_norm, marker='v', ls='--', lw=1, c='k', alpha=0.5, label='degrees test')

    # print('xlim k ', ax.get_xlim())
    # print('xlim l should be', k_to_l(np.array(ax.get_xlim()), R_b))
    return fig, ax
Esempio n. 8
0
    if show_guide:
        ax = show_beta_guide(ax,
                             x0=x0_guide,
                             y0=y0_guide,
                             x1=x1_guide,
                             m=-2,
                             c='k',
                             lw=3,
                             log=True,
                             **kwargs)

    fig = plt.gcf()
    plt.tight_layout()
    if save:
        plot_save(fig, fname='DCT_' + case, fig_path=fig_path, **kwargs)
    elif show:
        plt.show()
    return fig, ax


def fit_slope(S,
              k,
              k_min=None,
              k_max=None,
              ax=None,
              fmt='g-',
              plot=True,
              **kwargs):
    # find k range
    if k_min is not None and (k_min > np.min(k)):