Пример #1
0
def _plot_model_point(model, psi_cube, ecs_cube, lambda_cube):
    """Plot a single model point for emergent relationship."""
    col = _get_model_color(model, lambda_cube)
    style = plot.get_dataset_style(model, 'cox18nature')
    AXES.plot(psi_cube.extract(iris.Constraint(dataset=model)).data,
              ecs_cube.extract(iris.Constraint(dataset=model)).data,
              linestyle='none',
              marker=style['mark'],
              markeredgecolor=col,
              markerfacecolor=col,
              markersize=style['size'])
Пример #2
0
def plot_temperature_anomaly(cfg, tas_cubes, lambda_cube, obs_name):
    """Plot temperature anomaly versus time."""
    for cube in tas_cubes.values():
        cube.data -= np.mean(
            cube.extract(
                iris.Constraint(year=lambda cell: 1961 <= cell <= 1990)).data)

    # Save netcdf file and provenance
    filename = 'temperature_anomaly_{}'.format(obs_name)
    netcdf_path = get_diagnostic_filename(filename, cfg)
    io.save_1d_data(tas_cubes, netcdf_path, 'year', TASA_ATTRS)
    project = _get_project(cfg)
    provenance_record = get_provenance_record(
        "Simulated change in global temperature from {} models (coloured "
        "lines), compared to the global temperature anomaly from the {} "
        "dataset (black dots). The anomalies are relative to a baseline "
        "period of 1961-1990.".format(project, obs_name), ['anomaly'],
        ['times'], _get_ancestor_files(cfg, obs_name))

    # Plot
    if cfg['write_plots']:
        models = lambda_cube.coord('dataset').points

        # Plot lines
        for model in models:
            cube = tas_cubes[model]
            AXES.plot(cube.coord('year').points,
                      cube.data,
                      color=_get_model_color(model, lambda_cube))
        obs_style = plot.get_dataset_style('OBS', 'cox18nature')
        obs_cube = tas_cubes[obs_name]
        AXES.plot(obs_cube.coord('year').points,
                  obs_cube.data,
                  linestyle='none',
                  marker='o',
                  markeredgecolor=obs_style['color'],
                  markerfacecolor=obs_style['color'])

        # Plot appearance
        AXES.set_title('Simulation of global warming record')
        AXES.set_xlabel('Year')
        AXES.set_ylabel('Temperature anomaly / K')
        legend = _get_line_plot_legend()

        # Save plot
        provenance_record['plot_file'] = _save_fig(cfg, filename, legend)

    # Write provenance
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(netcdf_path, provenance_record)
def plot_data(cfg, cube):
    """Create scatterplot for cube."""
    if not cfg['write_plots']:
        return None
    logger.debug("Plotting scatterplot for cube %s",
                 cube.summary(shorten=True))
    (_, axes) = plt.subplots()
    project = cube.attributes.get('project')

    # Plot
    for (idx, dataset_name) in enumerate(cube.coord('dataset').points):
        style = plot.get_dataset_style(dataset_name, cfg.get('dataset_style'))
        y_data = cube.extract(iris.Constraint(dataset=dataset_name)).data
        axes.plot(idx + 1,
                  y_data,
                  marker=style['mark'],
                  linestyle='none',
                  markeredgecolor=style['color'],
                  markerfacecolor=style['facecolor'],
                  label=dataset_name)

    # Plot appearance
    title = cube.long_name
    if project is not None:
        title += f' for {project}'
    axes.set_title(title)
    axes.tick_params(axis='x',
                     which='both',
                     bottom=False,
                     top=False,
                     labelbottom=False)
    axes.set_ylabel(f"{cube.var_name.upper()} / {cube.units}")
    axes.set_ylim(cfg.get('y_range'))
    legend = axes.legend(loc='center left',
                         bbox_to_anchor=[1.05, 0.5],
                         borderaxespad=0.0,
                         ncol=2)

    # Save plot
    plot_path = get_plot_filename(cube.var_name, cfg)
    plt.savefig(plot_path,
                orientation='landscape',
                bbox_inches='tight',
                additional_artists=[legend])
    logger.info("Wrote %s", plot_path)
    plt.close()
    return plot_path
Пример #4
0
def plot_psi(cfg, psi_cubes, lambda_cube, obs_name):
    """Plot temperature variability metric psi versus time."""
    filename = 'temperature_variability_metric_{}'.format(obs_name)
    netcdf_path = get_diagnostic_filename(filename, cfg)
    io.save_1d_data(psi_cubes, netcdf_path, 'year', PSI_ATTRS)
    project = _get_project(cfg)
    provenance_record = get_provenance_record(
        "Psi metric of variability versus time, from the {0} models "
        "(coloured lines), and the {1} observational data (black circles). "
        "The psi values are calculated for windows of width {2} yr, after "
        "linear de-trending in each window. These {2}-yr windows are shown "
        "for different end times.".format(project, obs_name,
                                          cfg.get('window_length', 55)),
        ['corr', 'var'], ['times'], _get_ancestor_files(cfg, obs_name))

    # Plot
    if cfg['write_plots']:
        models = lambda_cube.coord('dataset').points

        # Plot lines
        for model in models:
            cube = psi_cubes[model]
            AXES.plot(cube.coord('year').points,
                      cube.data,
                      color=_get_model_color(model, lambda_cube))
        obs_style = plot.get_dataset_style('OBS', 'cox18nature')
        obs_cube = psi_cubes[obs_name]
        AXES.plot(obs_cube.coord('year').points,
                  obs_cube.data,
                  linestyle='none',
                  marker='o',
                  markeredgecolor=obs_style['color'],
                  markerfacecolor=obs_style['color'])

        # Plot appearance
        AXES.set_title('Metric of variability versus time')
        AXES.set_xlabel('Year')
        AXES.set_ylabel(r'$\Psi$ / K')
        legend = _get_line_plot_legend()

        # Save plot
        provenance_record['plot_file'] = _save_fig(cfg, filename, legend)

    # Write provenance
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(netcdf_path, provenance_record)
Пример #5
0
def _get_line_plot_legend():
    """Add legend for line plots."""
    color_obs = plot.get_dataset_style('OBS', 'cox18nature')['color']
    handles = [
        mlines.Line2D([], [],
                      color=COLOR_SMALL_LAMBDA,
                      label=r'$\lambda < 1.0$ Wm$^{-2}$K$^{-1}$'),
        mlines.Line2D([], [],
                      color=COLOR_LARGE_LAMBDA,
                      label=r'$\lambda > 1.0$ Wm$^{-2}$K$^{-1}$'),
        mlines.Line2D([], [],
                      linestyle='none',
                      marker='o',
                      markeredgecolor=color_obs,
                      markerfacecolor=color_obs,
                      label='Observations'),
    ]
    return AXES.legend(handles=handles, loc='upper left')
Пример #6
0
def _get_style(dataset_name, cfg):
    """Get style for individual data points."""
    style = plot.get_dataset_style(dataset_name, cfg.get('dataset_style'))
    if not cfg.get('marker_file'):
        return style
    marker_file = os.path.expanduser(cfg['marker_file'])
    if not os.path.isabs(marker_file):
        marker_file = io.get_ancestor_file(cfg, marker_file)
    data_frame = pd.read_csv(marker_file)
    marker_column = cfg['marker_column']
    for column in ('dataset', marker_column):
        if column not in data_frame.columns:
            raise ValueError(
                f"Marker file '{marker_file}' does not contain necessary "
                f"column '{column}'")
    marker = data_frame[marker_column][data_frame['dataset'] == dataset_name]
    if len(marker) != 1:
        raise ValueError(
            f"Expected exactly one entry for marker of '{dataset_name}' in "
            f"file '{marker_file}', got {len(marker):d}")
    style['mark'] = marker.values[0]
    return style
Пример #7
0
def plot_data(cfg, ecs_cube, tcr_cube):
    """Plot data."""
    if not cfg['write_plots']:
        return None
    logger.debug("Plotting Fig. 9.42b of IPCC AR5")
    (_, axes) = plt.subplots()
    project = ecs_cube.attributes['project']

    # Apply logarithms if desired
    if cfg.get('log_x'):
        ecs_cube.data = np.ma.log(ecs_cube.data)
    if cfg.get('log_y'):
        tcr_cube.data = np.ma.log(tcr_cube.data)

    # Plot scatterplot
    for dataset_name in ecs_cube.coord('dataset').points:
        style = plot.get_dataset_style(dataset_name, cfg.get('dataset_style'))
        ecs = ecs_cube.extract(iris.Constraint(dataset=dataset_name)).data
        tcr = tcr_cube.extract(iris.Constraint(dataset=dataset_name)).data

        # Plot single point
        axes.plot(ecs,
                  tcr,
                  marker=style['mark'],
                  linestyle='none',
                  markeredgecolor=style['color'],
                  markerfacecolor=style['facecolor'],
                  label=dataset_name)

    # Plot regression line and MMM
    (reg_line, mmm, r_value) = _get_reg_line(ecs_cube, tcr_cube)
    axes.plot(reg_line[0], reg_line[1], 'k-')
    axes.plot(mmm[0], mmm[1], 'ro', label=f'{project} mean')

    # Plot appearance
    axes.set_title(f"TCR vs. ECS for {project} models")
    if cfg.get('log_x'):
        axes.set_xlim([0.8, 2.0])
        axes.set_xlabel('log(ECS / K)')
    else:
        axes.set_xlim([1.5, 6.0])
        axes.set_xlabel('ECS / K')
    if cfg.get('log_y'):
        axes.set_ylim([0.3, 1.2])
        axes.set_ylabel('log(TCR / K)')
    else:
        axes.set_ylim([0.5, 3.5])
        axes.set_ylabel('TCR / K')
    legend = axes.legend(loc='center left',
                         bbox_to_anchor=[1.05, 0.5],
                         borderaxespad=0.0,
                         ncol=2)
    axes.text(0.05, 0.9, f'$R^2$ = {r_value**2:.2f}', transform=axes.transAxes)

    # Save plot
    plot_path = get_plot_filename('ch09_fig09_42b', cfg)
    plt.savefig(plot_path,
                dpi=300,
                orientation='landscape',
                bbox_inches='tight',
                additional_artists=[legend])
    logger.info("Wrote %s", plot_path)
    plt.close()
    return plot_path
def plot_deangelis_fig3b4(cfg, data_model, reg_prw_obs):
    """Plot DeAngelis Fig. 3b and prepare 4."""
    # Fig 4
    #    model_scheme_name = dict([(1, ['Correlated-k-distribution, N >= 20',
    #                                   'dodgerblue']),
    #                              (2, ['Correlated-k-distribution, 10 < N < 20',
    #                                   'limegreen']),
    #                              (3, ['Pseudo-k-distribution, N >= 20',
    #                                   'gold']),
    #                              (4, ['Pseudo-k-distribution, 10 < N < 20',
    #                                   'darkorange']),
    #                              (5, ['7-band parameterization (N = 7)',
    #                                   'crimson']),
    #                              (6, ['Pade approximants, higher res.',
    #                                   'slategrey']),
    #                              (7, ['Pade approximants, lower res.',
    #                                   'silver']),
    #                              (8, ['unknown',
    #                                   'xkcd:pale purple'])])

    # Plot data
    fig, axx = plt.subplots(figsize=(8, 8))

    mdrsnstdts = np.zeros((len(data_model.keys()), 3))

    for iii, modelkey in enumerate(data_model.keys()):
        mdrsnstdts[iii, 0] = (list(data_model[modelkey]))[0]
        mdrsnstdts[iii, 1] = (list(data_model[modelkey]))[2]
        mdrsnstdts[iii, 2] = (list(data_model[modelkey]))[3]
        axx.fill([
            mdrsnstdts[iii, 1] - 2.0 * mdrsnstdts[iii, 2],
            mdrsnstdts[iii, 1] + 2.0 * mdrsnstdts[iii, 2],
            mdrsnstdts[iii, 1] + 2.0 * mdrsnstdts[iii, 2],
            mdrsnstdts[iii, 1] - 2.0 * mdrsnstdts[iii, 2]
        ], [
            mdrsnstdts[iii, 0] - 0.01, mdrsnstdts[iii, 0] - 0.01,
            mdrsnstdts[iii, 0] + 0.01, mdrsnstdts[iii, 0] + 0.01
        ],
                 color=(0.8, 0.8, 0.8))
        style = (select_metadata(cfg['input_data'].values(),
                                 dataset=modelkey))[0]['project']
        style = plot.get_dataset_style(modelkey, style_file=style.lower())
        axx.plot(mdrsnstdts[iii, 1],
                 mdrsnstdts[iii, 0],
                 marker=style['mark'],
                 color=style['color'],
                 markerfacecolor=style['facecolor'],
                 linestyle='none',
                 markersize=10,
                 markeredgewidth=2.0,
                 label=modelkey)

    prw = {}
    if reg_prw_obs:
        prw["min"] = np.zeros(len(reg_prw_obs.keys()))
        prw["max"] = np.zeros(len(reg_prw_obs.keys()))
        for iii, modelkey in enumerate(reg_prw_obs.keys()):
            (prw["min"])[iii] = reg_prw_obs[modelkey].slope - 2.0 * \
                reg_prw_obs[modelkey].stderr
            (prw["max"])[iii] = reg_prw_obs[modelkey].slope + 2.0 * \
                reg_prw_obs[modelkey].stderr
        prw["mean"] = (np.min(prw["min"]) + np.max(prw["max"])) / 2.0
        prw["diff"] = np.max(prw["max"]) - prw["mean"]
    else:
        prw["mean"] = 0.0
        prw["diff"] = 0.0

    axx = set_axx_deangelis3b(axx, prw["mean"], prw["diff"])

    # Regression line
    reg = stats.linregress(mdrsnstdts[:, 1], mdrsnstdts[:, 0])

    axx.plot(np.linspace(0.0, 0.15, 2),
             reg.slope * np.linspace(0.0, 0.15, 2) + reg.intercept,
             linestyle='solid',
             color='r',
             label='Fit (r ={:.2f})'.format(reg.rvalue))

    axx.legend(ncol=2, loc=2)
    fig.tight_layout()
    fig.savefig(get_plot_filename('fig3b', cfg), dpi=300)
    plt.close()

    caption = 'Scatter plot and regression line the between the ratio ' + \
        'of the change of ' + \
        'netto short wave radiation (rsnst) and the change of the ' + \
        'Water Vapor Path (prw) against the ratio of the change of ' + \
        'netto short wave radiation for clear skye (rsnstcs) and the ' + \
        'the change of surface temperature (tas).' + \
        'The width of horizontal ' + \
        'shading for models and the vertical dashed lines for ' + \
        'observations (Obs.) represent statistical uncertainties of ' + \
        'the ratio, as the 95% confidence interval (CI) of the regression ' + \
        'slope to the rsnst versus prw curve. For the observations ' + \
        'the minimum of the lower bounds of all CIs to the maximum of ' + \
        'the upper bounds of all CIs is shown.'

    provenance_record = get_provenance_record(
        _get_sel_files_var(cfg, ['prw', 'tas', 'rsnst', 'rsnstcs']), caption,
        ['other'], ['global'])

    diagnostic_file = get_diagnostic_filename('fig3b', cfg)

    logger.info("Saving analysis results to %s", diagnostic_file)

    iris.save(cube_to_save_matrix(
        mdrsnstdts, {
            'var_name':
            'mdrsnstdts',
            'long_name':
            'Change of Netto' + 'Short Wave ' + 'Radiation ' + 'with Change ' +
            'of the ' + 'Water Vapor Path',
            'units':
            '% kg-1 m2'
        }),
              target=diagnostic_file)

    logger.info("Recording provenance of %s:\n%s", diagnostic_file,
                pformat(provenance_record))
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(diagnostic_file, provenance_record)

    # Fig 4
    plot_deangelis_fig4(cfg, data_model, mdrsnstdts, prw)