Пример #1
0
def plot_drydown(sim_data, flux_data, met_data, name, date_range):
    """Plot behaviour during dry-downs.

    Plots rainfall, as well as Qh and Qle for obs and simulations.

    :sim_data: xarray dataset from a simulation
    :flux_data: xarray dataset from a simulation
    :met_data: xarray dataset from a simulation
    :name: model name
    :returns: plot filename
    """
    year_range = [parse(d).year for d in date_range]
    year_range[1] += 1
    year_range = ['%s-01-01' % d for d in year_range]

    site = pals_site_name(met_data)

    sns.set_palette(
        sns.color_palette(['#aa0000', '#ff4444', '#0000aa', '#4477ff']))

    # Plot rainfall in mm
    Rainf = (pals_xr_to_df(met_data.sel(time=slice(*year_range)),
                           ['Rainf']).resample('1W', how='sum') * 1000).mean()

    obs = (pals_xr_to_df(flux_data.sel(time=slice(*year_range)),
                         ['Qh', 'Qle']).resample('1D')).mean()

    sim = (pals_xr_to_df(sim_data.sel(time=slice(*year_range)),
                         ['Qh', 'Qle']).resample('1D')).mean()

    x_vals = Rainf.index.to_pydatetime()

    fig, ax = pl.subplots()
    ax.bar(x_vals, Rainf.values, width=7, color='lightblue', linewidth=0)

    x_vals = obs.index.to_pydatetime()
    for c in obs:
        if c == 'Qle':
            offset = 0
        if c == 'Qh':
            offset = 100
        ax.plot(x_vals,
                pd.rolling_mean(obs[c], 14) + offset,
                label='Obs %s + %d' % (c, offset))
        ax.plot(x_vals,
                pd.rolling_mean(sim[c], 14) + offset,
                label='Sim %s + %d' % (c, offset))

    ax.axvspan(parse(date_range[0]),
               parse(date_range[1]),
               color='black',
               alpha=0.1,
               zorder=-100)

    pl.legend(loc=0)

    pl.title('{n}: drydown plot at {s}'.format(n=name, s=site))

    filename = '{n}_{s}_drydown_timeseries_plot.png'.format(n=name, s=site)
    return filename
Пример #2
0
def plot_drydown_daily_cycles(sim_data, flux_data, met_data, name, date_range):
    """Plot daily cycle behaviour during dry-downs.

    Plots rainfall, as well as Qh and Qle for obs and simulations.

    :sim_data: xarray dataset from a simulation
    :flux_data: xarray dataset from a simulation
    :met_data: xarray dataset from a simulation
    :name: model name
    :returns: plot filename
    """
    d_range = [np.datetime64(parse(d)) for d in date_range]
    del_t = np.timedelta64(7, 'D')
    first_cycle = d_range[0] + [-del_t, del_t]
    last_cycle = d_range[1] + [-del_t, del_t]

    site = pals_site_name(met_data)

    sns.set_palette(
        sns.color_palette(['#aa0000', '#ff4444', '#0000aa', '#4477ff']))

    fig, _ = pl.subplots(2, 1, sharey=True)

    periods = {0: 'start', 1: 'end'}

    flux_vars = list(
        set(['Qh', 'Qle']).intersection(list(sim_data.data_vars)).intersection(
            list(sim_data.data_vars)))

    for i, dr in enumerate([first_cycle, last_cycle]):
        obs_df = pals_xr_to_df(flux_data.sel(time=slice(*dr)), flux_vars)
        obs = obs_df.groupby(obs_df.index.time).mean()

        sim_df = pals_xr_to_df(sim_data.sel(time=slice(*dr)), flux_vars)
        sim = sim_df.groupby(sim_df.index.time).mean()

        x_vals = obs.index.values
        ax = pl.subplot(2, 1, i + 1)
        for c in obs:
            if c == 'Qle':
                offset = 0
            if c == 'Qh':
                offset = 100
            ax.plot(x_vals, obs[c] + offset, label='Obs %s + %d' % (c, offset))
            ax.plot(x_vals, sim[c] + offset, label='Sim %s + %d' % (c, offset))

        pl.title('{n}: daily cycles for {p} of drydown at {s}'.format(
            n=name, s=site, p=periods[i]))

        pl.legend(loc=0)

    fig.tight_layout()

    filename = '{n}_{s}_drydown_daily_cycles_plot.png'.format(n=name, s=site)
    return filename
Пример #3
0
def get_multimodel_data(site, names, variables):
    """Returns a DF with variable columns, time/model indices."""

    data = []
    for n in names:
        path = "model_data/{n}/{n}_{s}.nc".format(n=n, s=site)
        try:
            with xr.open_dataset(path) as ds:
                df = pals_xr_to_df(ds, variables)
                df['name'] = n

                # offset time indices
                if n == 'COLASSiB.2.0':
                    df.index = df.index + pd.Timedelta('-30min')
                if n == 'ORCHIDEE.trunk_r1401':
                    df.index = df.index + pd.Timedelta('-15min')

                df.set_index('name', append=True, inplace=True)
                data.append(df)

        except (OSError, RuntimeError) as e:
            raise Exception(path, e)

    df = pd.concat(data)
    df.columns.name = 'variable'
    return df
Пример #4
0
def diagnostic_plots(sim_data, flux_data, name, site=None):
    """Plot standard diagnostic plots for a single site

    :sim_data: xarray dataset
    :flux_data: xarray dataset
    :name: mode name
    :returns: list of paths to plots

    """
    if site is None:
        site = pals_site_name(flux_data)

    logger.info('Running standard plots for %s at %s' % (name, site))

    base_path = 'source/models/{n}'.format(n=name)
    rel_path = 'figures/{s}'.format(s=site)
    fig_path = os.path.join(base_path, rel_path)
    os.makedirs(fig_path, exist_ok=True)

    files = []

    # benchmark_names = ['1lin', '2lin', '3km27']
    benchmark_names = ['S_lin', 'ST_lin', 'STH_km27']

    try:
        benchmarks = [get_benchmark(bname, site) for bname in benchmark_names]
    except RuntimeError as e:
        logger.warning("Benchmark(s) not available at {s}, skipping. {e}".format(s=site, e=e))
        return

    sns.set_palette(sns.color_palette(['red', 'pink', 'orange', 'black', 'blue']))

    # Generalise if more multi-variable plots needed
    metric_df = get_PLUMBER_metrics(name, site)
    for plot in [p_plumber_metrics, p_metric_rank_counts]:
        filename = plot(metric_df, name, site)
        rel_plot_path = save_plot(base_path, rel_path, filename)
        files.append(rel_plot_path)

    flux_vars = ['Qle', 'Qh', 'NEE']

    for var in flux_vars:
        try:
            data = pd.concat([pals_xr_to_df(ds, [var]) for ds in
                              benchmarks + [flux_data, sim_data]], axis=1)
        except Exception as e:
            logger.warning('Data missing for {v} at {s}, skipping. {e}'.format(v=var, s=site, e=e))
            continue

        data.columns = benchmark_names + ['observed', 'modelled']

        for plot in DIAGNOSTIC_PLOTS.values():
            filename = plot(data, name, var, site)
            rel_plot_path = save_plot(base_path, rel_path, filename)
            files.append(rel_plot_path)

    return files
Пример #5
0
def get_test_data(site, met_vars, use_names, qc=False, fix_closure=True):

    # We use gap-filled data for the testing period, or the model fails.
    met_test_xr = get_met_data(site)[site]
    met_test = pals_xr_to_df(met_test_xr,
                             variables=met_vars,
                             qc=qc,
                             name=use_names)

    return dict(site=site,
                met_vars=met_vars,
                fix_closure=fix_closure,
                met_test=met_test,
                met_test_xr=met_test_xr)