def _run(input_dir_name, output_dir_name):
    """Creates figure showing overall model evaluation.

    This is effectively the main method.

    :param input_dir_name: See documentation at top of file.
    :param output_dir_name: Same.
    """

    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    panel_file_names = [
        '{0:s}/{1:s}'.format(input_dir_name, p)
        for p in PATHLESS_INPUT_FILE_NAMES
    ]
    resized_panel_file_names = [
        '{0:s}/{1:s}'.format(output_dir_name, p)
        for p in PATHLESS_INPUT_FILE_NAMES
    ]

    letter_label = None

    for i in range(len(panel_file_names)):
        print('Resizing panel and saving to: "{0:s}"...'.format(
            resized_panel_file_names[i]))

        imagemagick_utils.trim_whitespace(
            input_file_name=panel_file_names[i],
            output_file_name=resized_panel_file_names[i])

        if letter_label is None:
            letter_label = 'a'
        else:
            letter_label = chr(ord(letter_label) + 1)

        _overlay_text(image_file_name=resized_panel_file_names[i],
                      x_offset_from_left_px=0,
                      y_offset_from_top_px=TITLE_FONT_SIZE,
                      text_string='({0:s})'.format(letter_label))
        imagemagick_utils.resize_image(
            input_file_name=resized_panel_file_names[i],
            output_file_name=resized_panel_file_names[i],
            output_size_pixels=PANEL_SIZE_PX)

    concat_figure_file_name = '{0:s}/overall_evaluation.jpg'.format(
        output_dir_name)
    print(
        'Concatenating panels to: "{0:s}"...'.format(concat_figure_file_name))

    imagemagick_utils.concatenate_images(
        input_file_names=resized_panel_file_names,
        output_file_name=concat_figure_file_name,
        num_panel_rows=NUM_PANEL_ROWS,
        num_panel_columns=NUM_PANEL_COLUMNS)
    imagemagick_utils.resize_image(input_file_name=concat_figure_file_name,
                                   output_file_name=concat_figure_file_name,
                                   output_size_pixels=CONCAT_FIGURE_SIZE_PX)
Example #2
0
def _run(input_dir_name, output_dir_name):
    """Creates figure showing model performance as a function of hyperparams.

    This is effectively the main method.

    :param input_dir_name: See documentation at top of file.
    :param output_dir_name: Same.
    """

    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    num_scores = len(SCORE_NAMES)
    num_dense_layer_counts = len(DENSE_LAYER_COUNTS)

    for j in range(num_scores):
        panel_file_names = [
            '{0:s}/num-dense-layers={1:d}_{2:s}_grid.jpg'.format(
                input_dir_name, d, SCORE_NAMES[j]) for d in DENSE_LAYER_COUNTS
        ]
        resized_panel_file_names = [
            '{0:s}/num-dense-layers={1:d}_{2:s}_grid.jpg'.format(
                output_dir_name, d, SCORE_NAMES[j]) for d in DENSE_LAYER_COUNTS
        ]

        for i in range(num_dense_layer_counts):
            imagemagick_utils.trim_whitespace(
                input_file_name=panel_file_names[i],
                output_file_name=resized_panel_file_names[i])
            imagemagick_utils.resize_image(
                input_file_name=resized_panel_file_names[i],
                output_file_name=resized_panel_file_names[i],
                output_size_pixels=PANEL_SIZE_PX)

        concat_figure_file_name = '{0:s}/{1:s}_grid.jpg'.format(
            output_dir_name, SCORE_NAMES[j])
        print('Concatenating panels to: "{0:s}"...'.format(
            concat_figure_file_name))

        imagemagick_utils.concatenate_images(
            input_file_names=resized_panel_file_names,
            output_file_name=concat_figure_file_name,
            num_panel_rows=NUM_PANEL_ROWS,
            num_panel_columns=NUM_PANEL_COLUMNS)
        imagemagick_utils.resize_image(
            input_file_name=concat_figure_file_name,
            output_file_name=concat_figure_file_name,
            output_size_pixels=CONCAT_FIGURE_SIZE_PX)
        imagemagick_utils.trim_whitespace(
            input_file_name=concat_figure_file_name,
            output_file_name=concat_figure_file_name)
Example #3
0
def _run():
    """Plots dilation of WPC fronts.

    This is effectively the main method.
    """

    print 'Reading data from: "{0:s}"...'.format(FRONT_LINE_FILE_NAME)
    front_line_table = fronts_io.read_polylines_from_file(FRONT_LINE_FILE_NAME)

    print 'Reading data from: "{0:s}"...'.format(FRONTAL_GRID_FILE_NAME)
    frontal_grid_table = fronts_io.read_narr_grids_from_file(
        FRONTAL_GRID_FILE_NAME)

    num_grid_rows, num_grid_columns = nwp_model_utils.get_grid_dimensions(
        model_name=nwp_model_utils.NARR_MODEL_NAME)

    ternary_front_matrix = ml_utils.front_table_to_images(
        frontal_grid_table=frontal_grid_table,
        num_rows_per_image=num_grid_rows,
        num_columns_per_image=num_grid_columns)

    _plot_fronts(front_line_table=front_line_table,
                 ternary_front_matrix=ternary_front_matrix,
                 title_string='Observed fronts before dilation',
                 annotation_string='(a)',
                 output_file_name=BEFORE_FILE_NAME)

    ternary_front_matrix = ml_utils.dilate_ternary_target_images(
        target_matrix=ternary_front_matrix,
        dilation_distance_metres=DILATION_DISTANCE_METRES,
        verbose=False)

    _plot_fronts(front_line_table=front_line_table,
                 ternary_front_matrix=ternary_front_matrix,
                 title_string='Observed fronts after dilation',
                 annotation_string='(b)',
                 output_file_name=AFTER_FILE_NAME)

    print 'Concatenating figures to: "{0:s}"...'.format(CONCAT_FILE_NAME)

    imagemagick_utils.concatenate_images(
        input_file_names=[BEFORE_FILE_NAME, AFTER_FILE_NAME],
        output_file_name=CONCAT_FILE_NAME,
        num_panel_rows=1,
        num_panel_columns=2)

    imagemagick_utils.resize_image(input_file_name=CONCAT_FILE_NAME,
                                   output_file_name=CONCAT_FILE_NAME,
                                   output_size_pixels=CONCAT_SIZE_PIXELS)
def _run():
    """Concatenates figures showing dilation procedure and double penalty.

    This is effectively the main method.
    """

    dilation_image_object = Image.open(DILATION_FILE_NAME)
    double_penalty_image_object = Image.open(DOUBLE_PENALTY_FILE_NAME)

    new_dilation_width_px = double_penalty_image_object.size[0]
    width_ratio = (float(new_dilation_width_px) /
                   dilation_image_object.size[0])
    new_dilation_height_px = int(
        numpy.round(dilation_image_object.size[1] * width_ratio))

    small_dilation_file_name = DILATION_FILE_NAME.replace(
        '.jpg', '_resized.jpg')

    print 'Resizing dilation figure to: "{0:s}"...'.format(
        small_dilation_file_name)

    command_string = (
        '/usr/bin/convert "{0:s}" -resize {1:d}x{2:d} "{3:s}"').format(
            DILATION_FILE_NAME, new_dilation_width_px, new_dilation_height_px,
            small_dilation_file_name)

    os.system(command_string)

    print('Concatenating dilation and double-penalty figures to: "{0:s}"...'
          ).format(CONCAT_FILE_NAME)

    imagemagick_utils.concatenate_images(
        input_file_names=[small_dilation_file_name, DOUBLE_PENALTY_FILE_NAME],
        output_file_name=CONCAT_FILE_NAME,
        num_panel_rows=2,
        num_panel_columns=1)

    imagemagick_utils.trim_whitespace(input_file_name=CONCAT_FILE_NAME,
                                      output_file_name=CONCAT_FILE_NAME)

    imagemagick_utils.resize_image(input_file_name=CONCAT_FILE_NAME,
                                   output_file_name=CONCAT_FILE_NAME,
                                   output_size_pixels=CONCAT_SIZE_PIXELS)

    os.remove(small_dilation_file_name)
Example #5
0
def _run():
    """Plots determinization of front probabilities.

    This is effectively the main method.
    """

    prediction_dict = ml_utils.read_gridded_predictions(PREDICTION_FILE_NAME)
    class_probability_matrix = prediction_dict[ml_utils.PROBABILITY_MATRIX_KEY]

    for this_id in front_utils.VALID_INTEGER_IDS:
        if this_id == front_utils.NO_FRONT_INTEGER_ID:
            class_probability_matrix[..., this_id][numpy.isnan(
                class_probability_matrix[..., this_id])] = 1.
        else:
            class_probability_matrix[..., this_id][numpy.isnan(
                class_probability_matrix[..., this_id])] = 0.

    _plot_predictions(output_file_name=BEFORE_FILE_NAME,
                      title_string='Probabilities',
                      annotation_string='(a)',
                      class_probability_matrix=class_probability_matrix)

    predicted_label_matrix = object_eval.determinize_probabilities(
        class_probability_matrix=class_probability_matrix,
        binarization_threshold=BINARIZATION_THRESHOLD)

    _plot_predictions(output_file_name=AFTER_FILE_NAME,
                      title_string='Deterministic predictions',
                      annotation_string='(b)',
                      predicted_label_matrix=predicted_label_matrix)

    print 'Concatenating figures to: "{0:s}"...'.format(CONCAT_FILE_NAME)

    imagemagick_utils.concatenate_images(
        input_file_names=[BEFORE_FILE_NAME, AFTER_FILE_NAME],
        output_file_name=CONCAT_FILE_NAME,
        num_panel_rows=2,
        num_panel_columns=1)

    imagemagick_utils.resize_image(input_file_name=CONCAT_FILE_NAME,
                                   output_file_name=CONCAT_FILE_NAME,
                                   output_size_pixels=CONCAT_SIZE_PIXELS)
Example #6
0
def _run(evaluation_dir_name, num_months_per_chunk, num_hours_per_chunk,
         confidence_level, output_dir_name):
    """Plots temporally subset model evaluation.

    This is effectively the main method.

    :param evaluation_dir_name: See documentation at top of file.
    :param num_months_per_chunk: Same.
    :param num_hours_per_chunk: Same.
    :param confidence_level: Same.
    :param output_dir_name: Same.
    """

    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    panel_file_names = _plot_by_month(
        evaluation_dir_name=evaluation_dir_name,
        num_months_per_chunk=num_months_per_chunk,
        confidence_level=confidence_level,
        output_dir_name=output_dir_name)

    panel_file_names += _plot_by_hour(evaluation_dir_name=evaluation_dir_name,
                                      num_hours_per_chunk=num_hours_per_chunk,
                                      confidence_level=confidence_level,
                                      output_dir_name=output_dir_name)

    concat_file_name = '{0:s}/temporally_subset_eval.jpg'.format(
        output_dir_name)

    print('Concatenating panels to: "{0:s}"...'.format(concat_file_name))
    imagemagick_utils.concatenate_images(input_file_names=panel_file_names,
                                         output_file_name=concat_file_name,
                                         num_panel_rows=2,
                                         num_panel_columns=2)

    imagemagick_utils.resize_image(input_file_name=concat_file_name,
                                   output_file_name=concat_file_name,
                                   output_size_pixels=CONCAT_FIGURE_SIZE_PX)
def _plot_sounding_saliency(
        saliency_matrix, colour_map_object, max_colour_value,
        sounding_figure_object, sounding_axes_object,
        sounding_pressures_pascals, saliency_dict, model_metadata_dict,
        add_title, output_dir_name, pmm_flag, example_index=None):
    """Plots saliency for sounding.

    H = number of sounding heights
    F = number of sounding fields

    :param saliency_matrix: H-by-F numpy array of saliency values.
    :param colour_map_object: See documentation at top of file.
    :param max_colour_value: Same.
    :param sounding_figure_object: Figure handle (instance of
        `matplotlib.figure.Figure`) for sounding itself.
    :param sounding_axes_object: Axes handle (instance of
        `matplotlib.axes._subplots.AxesSubplot`) for sounding itself.
    :param sounding_pressures_pascals: length-H numpy array of sounding
        pressures.
    :param saliency_dict: Dictionary returned by `saliency_maps.read_file`.
    :param model_metadata_dict: Dictionary returned by
        `cnn.read_model_metadata`.
    :param add_title: Boolean flag.
    :param output_dir_name: Name of output directory.  Figures will be saved
        here.
    :param pmm_flag: Boolean flag.  If True, plotting PMM composite rather than
        one example.
    :param example_index: [used only if `pmm_flag == False`]
        Plotting the [i]th example, where i = `example_index`.
    """

    if max_colour_value is None:
        max_colour_value = numpy.percentile(
            numpy.absolute(saliency_matrix), MAX_COLOUR_PERCENTILE
        )

    training_option_dict = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY]
    sounding_field_names = training_option_dict[trainval_io.SOUNDING_FIELDS_KEY]

    if pmm_flag:
        full_storm_id_string = None
        storm_time_unix_sec = None
    else:
        full_storm_id_string = saliency_dict[saliency_maps.FULL_STORM_IDS_KEY][
            example_index]
        storm_time_unix_sec = saliency_dict[saliency_maps.STORM_TIMES_KEY][
            example_index]

    if add_title:
        title_string = 'Max absolute saliency = {0:.2e}'.format(
            max_colour_value)
        sounding_axes_object.set_title(title_string)

    left_panel_file_name = plot_examples.metadata_to_file_name(
        output_dir_name=output_dir_name, is_sounding=False, pmm_flag=pmm_flag,
        full_storm_id_string=full_storm_id_string,
        storm_time_unix_sec=storm_time_unix_sec,
        radar_field_name='sounding-actual')

    print('Saving figure to file: "{0:s}"...'.format(left_panel_file_name))
    sounding_figure_object.savefig(
        left_panel_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0,
        bbox_inches='tight')
    pyplot.close(sounding_figure_object)

    saliency_plotting.plot_saliency_for_sounding(
        saliency_matrix=saliency_matrix,
        sounding_field_names=sounding_field_names,
        pressure_levels_mb=PASCALS_TO_MB * sounding_pressures_pascals,
        colour_map_object=colour_map_object,
        max_absolute_colour_value=max_colour_value)

    right_panel_file_name = plot_examples.metadata_to_file_name(
        output_dir_name=output_dir_name, is_sounding=False, pmm_flag=pmm_flag,
        full_storm_id_string=full_storm_id_string,
        storm_time_unix_sec=storm_time_unix_sec,
        radar_field_name='sounding-saliency')

    print('Saving figure to file: "{0:s}"...'.format(right_panel_file_name))
    pyplot.savefig(right_panel_file_name, dpi=FIGURE_RESOLUTION_DPI,
                   pad_inches=0, bbox_inches='tight')
    pyplot.close()

    concat_file_name = plot_examples.metadata_to_file_name(
        output_dir_name=output_dir_name, is_sounding=True, pmm_flag=pmm_flag,
        full_storm_id_string=full_storm_id_string,
        storm_time_unix_sec=storm_time_unix_sec)

    print('Concatenating figures to: "{0:s}"...\n'.format(concat_file_name))
    imagemagick_utils.concatenate_images(
        input_file_names=[left_panel_file_name, right_panel_file_name],
        output_file_name=concat_file_name,
        num_panel_rows=1, num_panel_columns=2
    )

    imagemagick_utils.resize_image(
        input_file_name=concat_file_name, output_file_name=concat_file_name,
        output_size_pixels=SOUNDING_IMAGE_SIZE_PX)

    os.remove(left_panel_file_name)
    os.remove(right_panel_file_name)
Example #8
0
def _run(valid_time_string, smoothing_radius_pixels, front_percentile,
         num_closing_iters, pressure_level_mb, top_narr_directory_name,
         narr_mask_file_name, output_dir_name):
    """Plots NFA (numerical frontal analysis) procedure.

    This is effectively the main method.

    :param valid_time_string: See documentation at top of file.
    :param smoothing_radius_pixels: Same.
    :param front_percentile: Same.
    :param num_closing_iters: Same.
    :param pressure_level_mb: Same.
    :param top_narr_directory_name: Same.
    :param narr_mask_file_name: Same.
    :param output_dir_name: Same.
    """

    cutoff_radius_pixels = 4 * smoothing_radius_pixels
    valid_time_unix_sec = time_conversion.string_to_unix_sec(
        valid_time_string, INPUT_TIME_FORMAT)
    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    if narr_mask_file_name == '':
        num_grid_rows, num_grid_columns = nwp_model_utils.get_grid_dimensions(
            model_name=nwp_model_utils.NARR_MODEL_NAME)
        narr_mask_matrix = numpy.full(
            (num_grid_rows, num_grid_columns), 1, dtype=int)
    else:
        print 'Reading mask from: "{0:s}"...\n'.format(narr_mask_file_name)
        narr_mask_matrix = ml_utils.read_narr_mask(narr_mask_file_name)

    wet_bulb_theta_file_name = processed_narr_io.find_file_for_one_time(
        top_directory_name=top_narr_directory_name,
        field_name=processed_narr_io.WET_BULB_THETA_NAME,
        pressure_level_mb=pressure_level_mb,
        valid_time_unix_sec=valid_time_unix_sec)

    print 'Reading data from: "{0:s}"...'.format(wet_bulb_theta_file_name)
    wet_bulb_theta_matrix_kelvins = processed_narr_io.read_fields_from_file(
        wet_bulb_theta_file_name)[0][0, ...]
    wet_bulb_theta_matrix_kelvins = general_utils.fill_nans(
        wet_bulb_theta_matrix_kelvins)

    u_wind_file_name = processed_narr_io.find_file_for_one_time(
        top_directory_name=top_narr_directory_name,
        field_name=processed_narr_io.U_WIND_GRID_RELATIVE_NAME,
        pressure_level_mb=pressure_level_mb,
        valid_time_unix_sec=valid_time_unix_sec)

    print 'Reading data from: "{0:s}"...'.format(u_wind_file_name)
    u_wind_matrix_m_s01 = processed_narr_io.read_fields_from_file(
        u_wind_file_name)[0][0, ...]
    u_wind_matrix_m_s01 = general_utils.fill_nans(u_wind_matrix_m_s01)

    v_wind_file_name = processed_narr_io.find_file_for_one_time(
        top_directory_name=top_narr_directory_name,
        field_name=processed_narr_io.V_WIND_GRID_RELATIVE_NAME,
        pressure_level_mb=pressure_level_mb,
        valid_time_unix_sec=valid_time_unix_sec)

    print 'Reading data from: "{0:s}"...'.format(v_wind_file_name)
    v_wind_matrix_m_s01 = processed_narr_io.read_fields_from_file(
        v_wind_file_name)[0][0, ...]
    v_wind_matrix_m_s01 = general_utils.fill_nans(v_wind_matrix_m_s01)

    unsmoothed_narr_file_name = '{0:s}/unsmoothed_narr_fields.jpg'.format(
        output_dir_name)
    _plot_narr_fields(
        wet_bulb_theta_matrix_kelvins=wet_bulb_theta_matrix_kelvins,
        u_wind_matrix_m_s01=u_wind_matrix_m_s01,
        v_wind_matrix_m_s01=v_wind_matrix_m_s01,
        title_string='Predictors before smoothing', annotation_string='(a)',
        output_file_name=unsmoothed_narr_file_name)

    wet_bulb_theta_matrix_kelvins = nfa.gaussian_smooth_2d_field(
        field_matrix=wet_bulb_theta_matrix_kelvins,
        standard_deviation_pixels=smoothing_radius_pixels,
        cutoff_radius_pixels=cutoff_radius_pixels)

    u_wind_matrix_m_s01 = nfa.gaussian_smooth_2d_field(
        field_matrix=u_wind_matrix_m_s01,
        standard_deviation_pixels=smoothing_radius_pixels,
        cutoff_radius_pixels=cutoff_radius_pixels)

    v_wind_matrix_m_s01 = nfa.gaussian_smooth_2d_field(
        field_matrix=v_wind_matrix_m_s01,
        standard_deviation_pixels=smoothing_radius_pixels,
        cutoff_radius_pixels=cutoff_radius_pixels)

    smoothed_narr_file_name = '{0:s}/smoothed_narr_fields.jpg'.format(
        output_dir_name)
    _plot_narr_fields(
        wet_bulb_theta_matrix_kelvins=wet_bulb_theta_matrix_kelvins,
        u_wind_matrix_m_s01=u_wind_matrix_m_s01,
        v_wind_matrix_m_s01=v_wind_matrix_m_s01,
        title_string='Predictors after smoothing', annotation_string='(b)',
        output_file_name=smoothed_narr_file_name)

    x_spacing_metres, y_spacing_metres = nwp_model_utils.get_xy_grid_spacing(
        model_name=nwp_model_utils.NARR_MODEL_NAME)

    tfp_matrix_kelvins_m02 = nfa.get_thermal_front_param(
        thermal_field_matrix_kelvins=wet_bulb_theta_matrix_kelvins,
        x_spacing_metres=x_spacing_metres, y_spacing_metres=y_spacing_metres)
    tfp_matrix_kelvins_m02[narr_mask_matrix == 0] = 0.

    tfp_file_name = '{0:s}/tfp.jpg'.format(output_dir_name)
    tfp_title_string = (
        r'Thermal front parameter ($\times$ 10$^{-10}$ K m$^{-2}$)')
    _plot_tfp(tfp_matrix_kelvins_m02=tfp_matrix_kelvins_m02,
              title_string=tfp_title_string, annotation_string='(c)',
              output_file_name=tfp_file_name)

    proj_velocity_matrix_m_s01 = nfa.project_wind_to_thermal_gradient(
        u_matrix_grid_relative_m_s01=u_wind_matrix_m_s01,
        v_matrix_grid_relative_m_s01=v_wind_matrix_m_s01,
        thermal_field_matrix_kelvins=wet_bulb_theta_matrix_kelvins,
        x_spacing_metres=x_spacing_metres, y_spacing_metres=y_spacing_metres)

    locating_var_matrix_m01_s01 = nfa.get_locating_variable(
        tfp_matrix_kelvins_m02=tfp_matrix_kelvins_m02,
        projected_velocity_matrix_m_s01=proj_velocity_matrix_m_s01)

    locating_var_file_name = '{0:s}/locating_variable.jpg'.format(
        output_dir_name)
    locating_var_title_string = (
        r'Locating variable ($\times$ 10$^{-9}$ K m$^{-1}$ s$^{-1}$)')
    _plot_locating_variable(
        locating_var_matrix_m01_s01=locating_var_matrix_m01_s01,
        title_string=locating_var_title_string, annotation_string='(d)',
        output_file_name=locating_var_file_name)

    predicted_label_matrix = nfa.get_front_types(
        locating_var_matrix_m01_s01=locating_var_matrix_m01_s01,
        warm_front_percentile=front_percentile,
        cold_front_percentile=front_percentile)

    unclosed_fronts_file_name = '{0:s}/unclosed_fronts.jpg'.format(
        output_dir_name)
    _plot_front_types(
        predicted_label_matrix=predicted_label_matrix,
        title_string='Frontal regions before closing', annotation_string='(e)',
        output_file_name=unclosed_fronts_file_name)

    predicted_label_matrix = front_utils.close_frontal_image(
        ternary_image_matrix=predicted_label_matrix,
        num_iterations=num_closing_iters)

    closed_fronts_file_name = '{0:s}/closed_fronts.jpg'.format(output_dir_name)
    _plot_front_types(
        predicted_label_matrix=predicted_label_matrix,
        title_string='Frontal regions after closing', annotation_string='(f)',
        output_file_name=closed_fronts_file_name)

    concat_file_name = '{0:s}/nfa_procedure.jpg'.format(output_dir_name)
    print 'Concatenating figures to: "{0:s}"...'.format(concat_file_name)

    panel_file_names = [
        unsmoothed_narr_file_name, smoothed_narr_file_name, tfp_file_name,
        locating_var_file_name, unclosed_fronts_file_name,
        closed_fronts_file_name
    ]

    imagemagick_utils.concatenate_images(
        input_file_names=panel_file_names,
        output_file_name=concat_file_name, num_panel_rows=3,
        num_panel_columns=2)

    imagemagick_utils.resize_image(
        input_file_name=concat_file_name, output_file_name=concat_file_name,
        output_size_pixels=CONCAT_SIZE_PIXELS)
Example #9
0
def _run(saliency_file_names, composite_names, colour_map_name,
         max_colour_values, half_num_contours, smoothing_radius_grid_cells,
         output_dir_name):
    """Makes figure with saliency maps for MYRORSS model.

    This is effectively the main method.

    :param saliency_file_names: See documentation at top of file.
    :param composite_names: Same.
    :param colour_map_name: Same.
    :param max_colour_values: Same.
    :param half_num_contours: Same.
    :param smoothing_radius_grid_cells: Same.
    :param output_dir_name: Same.
    """

    # Process input args.
    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    if smoothing_radius_grid_cells <= 0:
        smoothing_radius_grid_cells = None

    colour_map_object = pyplot.cm.get_cmap(colour_map_name)
    error_checking.assert_is_geq(half_num_contours, 5)

    num_composites = len(saliency_file_names)
    expected_dim = numpy.array([num_composites], dtype=int)
    error_checking.assert_is_numpy_array(numpy.array(composite_names),
                                         exact_dimensions=expected_dim)

    max_colour_values[max_colour_values <= 0] = numpy.nan
    error_checking.assert_is_numpy_array(max_colour_values,
                                         exact_dimensions=expected_dim)

    composite_names_abbrev = [
        n.replace('_', '-').lower() for n in composite_names
    ]
    composite_names_verbose = [
        '({0:s}) {1:s}'.format(chr(ord('a') + i),
                               composite_names[i].replace('_', ' '))
        for i in range(num_composites)
    ]

    panel_file_names = [None] * num_composites

    for i in range(num_composites):
        panel_file_names[i], max_colour_values[i] = _plot_one_composite(
            saliency_file_name=saliency_file_names[i],
            composite_name_abbrev=composite_names_abbrev[i],
            composite_name_verbose=composite_names_verbose[i],
            colour_map_object=colour_map_object,
            max_colour_value=max_colour_values[i],
            half_num_contours=half_num_contours,
            smoothing_radius_grid_cells=smoothing_radius_grid_cells,
            output_dir_name=output_dir_name)

        _add_colour_bar(figure_file_name=panel_file_names[i],
                        colour_map_object=colour_map_object,
                        max_colour_value=max_colour_values[i],
                        temporary_dir_name=output_dir_name)

        print('\n')

    figure_file_name = '{0:s}/saliency_concat.jpg'.format(output_dir_name)
    print('Concatenating panels to: "{0:s}"...'.format(figure_file_name))

    num_panel_rows = int(numpy.floor(numpy.sqrt(num_composites)))
    num_panel_columns = int(numpy.ceil(float(num_composites) / num_panel_rows))

    imagemagick_utils.concatenate_images(input_file_names=panel_file_names,
                                         output_file_name=figure_file_name,
                                         border_width_pixels=25,
                                         num_panel_rows=num_panel_rows,
                                         num_panel_columns=num_panel_columns)
    imagemagick_utils.trim_whitespace(input_file_name=figure_file_name,
                                      output_file_name=figure_file_name,
                                      border_width_pixels=10)
Example #10
0
def _plot_one_composite(saliency_file_name, composite_name_abbrev,
                        composite_name_verbose, colour_map_object,
                        max_colour_value, half_num_contours,
                        smoothing_radius_grid_cells, output_dir_name):
    """Plots saliency map for one composite.

    :param saliency_file_name: Path to input file (will be read by
        `saliency.read_file`).
    :param composite_name_abbrev: Abbrev composite name (will be used in file
        names).
    :param composite_name_verbose: Verbose composite name (will be used in
        figure title).
    :param colour_map_object: See documentation at top of file.
    :param max_colour_value: Same.
    :param half_num_contours: Same.
    :param smoothing_radius_grid_cells: Same.
    :param output_dir_name: Name of output directory (figures will be saved
        here).
    :return: main_figure_file_name: Path to main image file created by this
        method.
    :return: max_colour_value: See input doc.
    """

    mean_radar_matrix, mean_saliency_matrix, model_metadata_dict = (
        _read_one_composite(
            saliency_file_name=saliency_file_name,
            smoothing_radius_grid_cells=smoothing_radius_grid_cells))

    if numpy.isnan(max_colour_value):
        max_colour_value = numpy.percentile(mean_saliency_matrix,
                                            MAX_COLOUR_PERCENTILE)

    training_option_dict = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY]
    field_names = training_option_dict[trainval_io.RADAR_FIELDS_KEY]

    num_fields = mean_radar_matrix.shape[-1]
    num_heights = mean_radar_matrix.shape[-2]

    handle_dict = plot_examples.plot_one_example(
        list_of_predictor_matrices=[mean_radar_matrix],
        model_metadata_dict=model_metadata_dict,
        pmm_flag=True,
        allow_whitespace=True,
        plot_panel_names=True,
        panel_name_font_size=PANEL_NAME_FONT_SIZE,
        add_titles=False,
        label_colour_bars=True,
        colour_bar_length=COLOUR_BAR_LENGTH,
        colour_bar_font_size=COLOUR_BAR_FONT_SIZE,
        num_panel_rows=num_heights)

    figure_objects = handle_dict[plot_examples.RADAR_FIGURES_KEY]
    axes_object_matrices = handle_dict[plot_examples.RADAR_AXES_KEY]

    for k in range(num_fields):
        this_saliency_matrix = mean_saliency_matrix[0, ..., k]

        saliency_plotting.plot_many_2d_grids_with_contours(
            saliency_matrix_3d=numpy.flip(this_saliency_matrix, axis=0),
            axes_object_matrix=axes_object_matrices[k],
            colour_map_object=colour_map_object,
            max_absolute_contour_level=max_colour_value,
            contour_interval=max_colour_value / half_num_contours)

    panel_file_names = [None] * num_fields

    for k in range(num_fields):
        panel_file_names[k] = '{0:s}/{1:s}_{2:s}.jpg'.format(
            output_dir_name, composite_name_abbrev,
            field_names[k].replace('_', '-'))

        print('Saving figure to: "{0:s}"...'.format(panel_file_names[k]))

        figure_objects[k].savefig(panel_file_names[k],
                                  dpi=FIGURE_RESOLUTION_DPI,
                                  pad_inches=0,
                                  bbox_inches='tight')
        pyplot.close(figure_objects[k])

    main_figure_file_name = '{0:s}/{1:s}_saliency.jpg'.format(
        output_dir_name, composite_name_abbrev)

    print('Concatenating panels to: "{0:s}"...'.format(main_figure_file_name))

    imagemagick_utils.concatenate_images(
        input_file_names=panel_file_names,
        output_file_name=main_figure_file_name,
        num_panel_rows=1,
        num_panel_columns=num_fields,
        border_width_pixels=50)

    imagemagick_utils.resize_image(input_file_name=main_figure_file_name,
                                   output_file_name=main_figure_file_name,
                                   output_size_pixels=CONCAT_FIGURE_SIZE_PX)

    imagemagick_utils.trim_whitespace(input_file_name=main_figure_file_name,
                                      output_file_name=main_figure_file_name,
                                      border_width_pixels=TITLE_FONT_SIZE + 25)

    _overlay_text(image_file_name=main_figure_file_name,
                  x_offset_from_center_px=0,
                  y_offset_from_top_px=0,
                  text_string=composite_name_verbose)

    imagemagick_utils.trim_whitespace(input_file_name=main_figure_file_name,
                                      output_file_name=main_figure_file_name,
                                      border_width_pixels=10)

    return main_figure_file_name, max_colour_value
Example #11
0
def _run():
    """Plots example of double penalty.

    This is effectively the main method.
    """

    print 'Reading data from: "{0:s}"...'.format(INPUT_FILE_NAME)
    actual_grid_point_table = fronts_io.read_narr_grids_from_file(
        INPUT_FILE_NAME)

    predicted_grid_point_table = copy.deepcopy(actual_grid_point_table)
    predicted_grid_point_table[
        front_utils.WARM_FRONT_COLUMN_INDICES_COLUMN] += 1
    predicted_grid_point_table[
        front_utils.COLD_FRONT_COLUMN_INDICES_COLUMN] += 1
    predicted_grid_point_table[front_utils.WARM_FRONT_ROW_INDICES_COLUMN] += 1
    predicted_grid_point_table[front_utils.COLD_FRONT_ROW_INDICES_COLUMN] += 1

    num_grid_rows, num_grid_columns = nwp_model_utils.get_grid_dimensions(
        model_name=nwp_model_utils.NARR_MODEL_NAME)

    actual_binary_matrix = ml_utils.front_table_to_images(
        frontal_grid_table=actual_grid_point_table,
        num_rows_per_image=num_grid_rows,
        num_columns_per_image=num_grid_columns)
    actual_binary_matrix = ml_utils.binarize_front_images(actual_binary_matrix)

    predicted_binary_matrix = ml_utils.front_table_to_images(
        frontal_grid_table=predicted_grid_point_table,
        num_rows_per_image=num_grid_rows,
        num_columns_per_image=num_grid_columns)
    predicted_binary_matrix = ml_utils.binarize_front_images(
        predicted_binary_matrix)

    _plot_fronts(actual_binary_matrix=actual_binary_matrix,
                 predicted_binary_matrix=predicted_binary_matrix,
                 title_string='Observed and predicted front\nwithout dilation',
                 annotation_string='(c)',
                 output_file_name=NO_DILATION_FILE_NAME)

    actual_binary_matrix = ml_utils.dilate_binary_target_images(
        target_matrix=actual_binary_matrix,
        dilation_distance_metres=DILATION_DISTANCE_METRES,
        verbose=False)
    predicted_binary_matrix = ml_utils.dilate_binary_target_images(
        target_matrix=predicted_binary_matrix,
        dilation_distance_metres=DILATION_DISTANCE_METRES,
        verbose=False)

    _plot_fronts(actual_binary_matrix=actual_binary_matrix,
                 predicted_binary_matrix=predicted_binary_matrix,
                 title_string='Observed and predicted front\nwith dilation',
                 annotation_string='(d)',
                 output_file_name=WITH_DILATION_FILE_NAME)

    print 'Concatenating figures to: "{0:s}"...'.format(CONCAT_FILE_NAME)

    imagemagick_utils.concatenate_images(
        input_file_names=[NO_DILATION_FILE_NAME, WITH_DILATION_FILE_NAME],
        output_file_name=CONCAT_FILE_NAME,
        num_panel_rows=1,
        num_panel_columns=2)

    imagemagick_utils.resize_image(input_file_name=CONCAT_FILE_NAME,
                                   output_file_name=CONCAT_FILE_NAME,
                                   output_size_pixels=CONCAT_SIZE_PIXELS)
def _run():
    """Makes event-attribution schematics for 2019 tornado-prediction paper.

    This is effectively the main method.
    """

    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=OUTPUT_DIR_NAME)

    # Interpolation with merger.
    figure_object, axes_object = _plot_interp_two_times(
        storm_object_table=_get_data_for_interp_with_merger()[0],
        tornado_table=_get_data_for_interp_with_merger()[1],
        legend_font_size=SMALL_LEGEND_FONT_SIZE, legend_position_string='upper right'
    )

    axes_object.set_title('Interpolation with merger')
    this_file_name = '{0:s}/interp_with_merger_standalone.jpg'.format(
        OUTPUT_DIR_NAME)

    print('Saving figure to: "{0:s}"...'.format(this_file_name))
    figure_object.savefig(
        this_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0,
        bbox_inches='tight'
    )

    plotting_utils.label_axes(axes_object=axes_object, label_string='(a)')
    panel_file_names = ['{0:s}/interp_with_merger.jpg'.format(OUTPUT_DIR_NAME)]

    print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1]))
    figure_object.savefig(
        panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0,
        bbox_inches='tight'
    )
    pyplot.close(figure_object)

    # Interpolation with split.
    figure_object, axes_object = _plot_interp_two_times(
        storm_object_table=_get_data_for_interp_with_split()[0],
        tornado_table=_get_data_for_interp_with_split()[1],
        legend_font_size=DEFAULT_FONT_SIZE,
        legend_position_string='upper left'
    )

    axes_object.set_title('Interpolation with split')
    this_file_name = '{0:s}/interp_with_split_standalone.jpg'.format(
        OUTPUT_DIR_NAME)

    print('Saving figure to: "{0:s}"...'.format(this_file_name))
    figure_object.savefig(
        this_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0,
        bbox_inches='tight'
    )

    plotting_utils.label_axes(axes_object=axes_object, label_string='(b)')
    panel_file_names.append(
        '{0:s}/interp_with_split.jpg'.format(OUTPUT_DIR_NAME)
    )

    print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1]))
    figure_object.savefig(
        panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0,
        bbox_inches='tight'
    )
    pyplot.close(figure_object)

    # Simple successors.
    figure_object, axes_object = _plot_attribution_one_track(
        storm_object_table=_get_track_for_simple_succ(),
        plot_legend=True, plot_x_ticks=True,
        legend_font_size=SMALL_LEGEND_FONT_SIZE, legend_location='lower right'
    )

    this_file_name = '{0:s}/simple_successors_standalone.jpg'.format(
        OUTPUT_DIR_NAME)

    print('Saving figure to: "{0:s}"...'.format(this_file_name))
    figure_object.savefig(
        this_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0,
        bbox_inches='tight'
    )

    plotting_utils.label_axes(axes_object=axes_object, label_string='(c)')
    axes_object.set_title('Linking to simple successors')
    panel_file_names.append(
        '{0:s}/simple_successors.jpg'.format(OUTPUT_DIR_NAME)
    )

    print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1]))
    figure_object.savefig(
        panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0,
        bbox_inches='tight'
    )
    pyplot.close(figure_object)

    # Simple predecessors, example 1.
    figure_object, axes_object = _plot_attribution_one_track(
        storm_object_table=_get_track1_for_simple_pred(),
        plot_legend=True, plot_x_ticks=False,
        legend_font_size=DEFAULT_FONT_SIZE, legend_location=(0.28, 0.1)
    )

    axes_object.set_title('Simple predecessors, example 1')
    this_file_name = '{0:s}/simple_predecessors_track1_standalone.jpg'.format(
        OUTPUT_DIR_NAME)

    print('Saving figure to: "{0:s}"...'.format(this_file_name))
    figure_object.savefig(
        this_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0,
        bbox_inches='tight'
    )

    plotting_utils.label_axes(axes_object=axes_object, label_string='(d)')
    axes_object.set_title('Linking to simple predecessors, example 1')
    panel_file_names.append(
        '{0:s}/simple_predecessors_track1.jpg'.format(OUTPUT_DIR_NAME)
    )

    print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1]))
    figure_object.savefig(
        panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0,
        bbox_inches='tight'
    )
    pyplot.close(figure_object)

    # Simple predecessors, example 2.
    figure_object, axes_object = _plot_attribution_one_track(
        storm_object_table=_get_track2_for_simple_pred(),
        plot_legend=False, plot_x_ticks=False
    )

    axes_object.set_title('Simple predecessors, example 2')
    this_file_name = '{0:s}/simple_predecessors_track2_standalone.jpg'.format(
        OUTPUT_DIR_NAME)

    print('Saving figure to: "{0:s}"...'.format(this_file_name))
    figure_object.savefig(
        this_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0,
        bbox_inches='tight'
    )

    plotting_utils.label_axes(axes_object=axes_object, label_string='(e)')
    axes_object.set_title('Linking to simple predecessors, example 2')
    panel_file_names.append(
        '{0:s}/simple_predecessors_track2.jpg'.format(OUTPUT_DIR_NAME)
    )

    print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1]))
    figure_object.savefig(
        panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0,
        bbox_inches='tight'
    )
    pyplot.close(figure_object)

    # Concatenate all panels into one figure.
    concat_file_name = '{0:s}/attribution_schemas.jpg'.format(OUTPUT_DIR_NAME)
    print('Concatenating panels to: "{0:s}"...'.format(concat_file_name))

    imagemagick_utils.concatenate_images(
        input_file_names=panel_file_names, output_file_name=concat_file_name,
        num_panel_rows=2, num_panel_columns=3)

    imagemagick_utils.resize_image(
        input_file_name=concat_file_name, output_file_name=concat_file_name,
        output_size_pixels=CONCAT_FIGURE_SIZE_PX)
Example #13
0
def _run(input_file_name, output_dir_name):
    """Plots mean example created by average_examples.py.

    This is effectively the main method.

    :param input_file_name: See documentation at top of file.
    :param output_dir_name: Same.
    """

    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    pickle_file_handle = open(input_file_name, 'rb')
    mean_example_dict = pickle.load(pickle_file_handle)
    pickle_file_handle.close()

    # Plot predictors with liquid-water content (LWC).
    figure_object = profile_plotting.plot_predictors(
        example_dict=mean_example_dict,
        example_index=0,
        plot_ice=False,
        use_log_scale=True)[0]

    panel_file_names = ['foo'] * 3
    panel_file_names[0] = '{0:s}/predictors_with_lwc.jpg'.format(
        output_dir_name)
    print('Saving figure to: "{0:s}"...'.format(panel_file_names[0]))

    figure_object.savefig(panel_file_names[0],
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)

    # Plot predictors with ice-water content (IWC).
    figure_object = profile_plotting.plot_predictors(
        example_dict=mean_example_dict,
        example_index=0,
        plot_ice=True,
        use_log_scale=True)[0]

    panel_file_names[1] = '{0:s}/predictors_with_iwc.jpg'.format(
        output_dir_name)
    print('Saving figure to: "{0:s}"...'.format(panel_file_names[1]))

    figure_object.savefig(panel_file_names[1],
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)

    # Plot targets.
    figure_object = profile_plotting.plot_targets(
        example_dict=mean_example_dict, example_index=0, use_log_scale=True)[0]

    panel_file_names[2] = '{0:s}/targets.jpg'.format(output_dir_name)
    print('Saving figure to: "{0:s}"...'.format(panel_file_names[2]))

    figure_object.savefig(panel_file_names[2],
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)

    # Concatenate panels.
    concat_figure_file_name = '{0:s}/predictors_and_targets.jpg'.format(
        output_dir_name)
    print(
        'Concatenating panels to: "{0:s}"...'.format(concat_figure_file_name))

    imagemagick_utils.concatenate_images(
        input_file_names=panel_file_names,
        output_file_name=concat_figure_file_name,
        num_panel_rows=2,
        num_panel_columns=2,
        border_width_pixels=50)
    imagemagick_utils.resize_image(input_file_name=concat_figure_file_name,
                                   output_file_name=concat_figure_file_name,
                                   output_size_pixels=CONCAT_FIGURE_SIZE_PX)
def plot_many_soundings(list_of_metpy_dictionaries,
                        title_strings,
                        num_panel_rows,
                        output_file_name,
                        temp_directory_name=None,
                        option_dict=None):
    """Creates paneled figure with many soundings.

    N = number of soundings to plot

    :param list_of_metpy_dictionaries: length-N list of dictionaries.  Each
        dictionary must satisfy the input format for `sounding_dict_for_metpy`
        in `plot_sounding`.
    :param title_strings: length-N list of titles.
    :param num_panel_rows: Number of rows in paneled figure.
    :param output_file_name: Path to output (image) file.
    :param temp_directory_name: Name of temporary directory.  Each panel will be
        stored here, then deleted after the panels have been concatenated into
        the final image.  If `temp_directory_name is None`, will use the default
        temp directory on the local machine.
    :param option_dict: See doc for `plot_sounding`.
    """

    error_checking.assert_is_numpy_array(numpy.array(title_strings),
                                         num_dimensions=1)
    num_soundings = len(title_strings)

    error_checking.assert_is_list(list_of_metpy_dictionaries)
    error_checking.assert_is_geq(len(list_of_metpy_dictionaries),
                                 num_soundings)
    error_checking.assert_is_leq(len(list_of_metpy_dictionaries),
                                 num_soundings)

    error_checking.assert_is_integer(num_panel_rows)
    error_checking.assert_is_geq(num_panel_rows, 1)
    error_checking.assert_is_leq(num_panel_rows, num_soundings)

    file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name)
    if temp_directory_name is not None:
        file_system_utils.mkdir_recursive_if_necessary(
            directory_name=temp_directory_name)

    temp_file_names = [None] * num_soundings
    num_panel_columns = int(numpy.ceil(float(num_soundings) / num_panel_rows))

    for i in range(num_panel_rows):
        for j in range(num_panel_columns):
            this_sounding_index = i * num_panel_columns + j
            if this_sounding_index >= num_soundings:
                break

            plot_sounding(sounding_dict_for_metpy=list_of_metpy_dictionaries[
                this_sounding_index],
                          title_string=title_strings[this_sounding_index],
                          option_dict=option_dict)

            temp_file_names[this_sounding_index] = '{0:s}.jpg'.format(
                tempfile.NamedTemporaryFile(dir=temp_directory_name,
                                            delete=False).name)

            print('Saving sounding to: "{0:s}"...'.format(
                temp_file_names[this_sounding_index]))

            pyplot.savefig(temp_file_names[this_sounding_index],
                           dpi=DOTS_PER_INCH)
            pyplot.close()

            imagemagick_utils.trim_whitespace(
                input_file_name=temp_file_names[this_sounding_index],
                output_file_name=temp_file_names[this_sounding_index],
                border_width_pixels=SINGLE_IMAGE_BORDER_WIDTH_PX)

            imagemagick_utils.resize_image(
                input_file_name=temp_file_names[this_sounding_index],
                output_file_name=temp_file_names[this_sounding_index],
                output_size_pixels=SINGLE_IMAGE_SIZE_PX)

    print('Concatenating panels into one figure: "{0:s}"...'.format(
        output_file_name))

    imagemagick_utils.concatenate_images(
        input_file_names=temp_file_names,
        output_file_name=output_file_name,
        num_panel_rows=num_panel_rows,
        num_panel_columns=num_panel_columns,
        border_width_pixels=PANELED_IMAGE_BORDER_WIDTH_PX)

    for i in range(num_soundings):
        os.remove(temp_file_names[i])
def _run():
    """Creates histograms of warm-front and cold-front lengths.

    This is effectively the main method.
    """

    input_file_names = glob.glob(INPUT_FILE_PATTERN)
    num_files = len(input_file_names)
    list_of_front_line_tables = [pandas.DataFrame()] * num_files

    for i in range(num_files):
        print 'Reading data from: "{0:s}"...'.format(input_file_names[i])

        list_of_front_line_tables[i] = fronts_io.read_polylines_from_file(
            input_file_names[i])
        if i == 0:
            continue

        list_of_front_line_tables[i] = list_of_front_line_tables[i].align(
            list_of_front_line_tables[0], axis=1)[0]

    print SEPARATOR_STRING
    front_line_table = pandas.concat(list_of_front_line_tables,
                                     axis=0,
                                     ignore_index=True)

    front_line_table = _project_fronts_latlng_to_narr(front_line_table)
    print SEPARATOR_STRING

    front_lengths_metres = _get_front_lengths(front_line_table)
    print SEPARATOR_STRING

    nan_flags = numpy.isnan(front_lengths_metres)
    warm_front_flags = numpy.array([
        s == front_utils.WARM_FRONT_STRING_ID
        for s in front_line_table[front_utils.FRONT_TYPE_COLUMN].values
    ])
    cold_front_flags = numpy.array([
        s == front_utils.COLD_FRONT_STRING_ID
        for s in front_line_table[front_utils.FRONT_TYPE_COLUMN].values
    ])

    warm_front_indices = numpy.where(
        numpy.logical_and(warm_front_flags, numpy.invert(nan_flags)))[0]
    cold_front_indices = numpy.where(
        numpy.logical_and(cold_front_flags, numpy.invert(nan_flags)))[0]

    warm_front_lengths_metres = front_lengths_metres[warm_front_indices]
    cold_front_lengths_metres = front_lengths_metres[cold_front_indices]

    print(
        'Number of fronts = {0:d} ... warm fronts with defined length = {1:d} '
        '... cold fronts with defined length = {2:d}').format(
            len(front_lengths_metres), len(warm_front_lengths_metres),
            len(cold_front_lengths_metres))

    _, num_warm_fronts_by_bin = histograms.create_histogram(
        input_values=warm_front_lengths_metres,
        num_bins=NUM_BINS,
        min_value=MIN_HISTOGRAM_LENGTH_METRES,
        max_value=MAX_HISTOGRAM_LENGTH_METRES)
    print 'Sum of bin counts for warm fronts = {0:d}'.format(
        numpy.sum(num_warm_fronts_by_bin))

    _plot_histogram(num_fronts_by_bin=num_warm_fronts_by_bin,
                    front_type_string=front_utils.WARM_FRONT_STRING_ID,
                    title_string='Warm fronts',
                    annotation_string='(a)',
                    output_file_name=WARM_FRONT_FILE_NAME)

    _, num_cold_fronts_by_bin = histograms.create_histogram(
        input_values=cold_front_lengths_metres,
        num_bins=NUM_BINS,
        min_value=MIN_HISTOGRAM_LENGTH_METRES,
        max_value=MAX_HISTOGRAM_LENGTH_METRES)
    print 'Sum of bin counts for cold fronts = {0:d}'.format(
        numpy.sum(num_cold_fronts_by_bin))

    _plot_histogram(num_fronts_by_bin=num_cold_fronts_by_bin,
                    front_type_string=front_utils.COLD_FRONT_STRING_ID,
                    title_string='Cold fronts',
                    annotation_string='(b)',
                    output_file_name=COLD_FRONT_FILE_NAME)

    print 'Concatenating figures to: "{0:s}"...'.format(CONCAT_FILE_NAME)
    imagemagick_utils.concatenate_images(
        input_file_names=[WARM_FRONT_FILE_NAME, COLD_FRONT_FILE_NAME],
        output_file_name=CONCAT_FILE_NAME,
        num_panel_rows=1,
        num_panel_columns=2,
        output_size_pixels=OUTPUT_SIZE_PIXELS)
Example #16
0
def _run(input_dir_name, heights_m_agl, output_dir_name):
    """Creates figure showing overall model evaluation.

    This is effectively the main method.

    :param input_dir_name: See documentation at top of file.
    :param heights_m_agl: Same.
    :param output_dir_name: Same.
    """

    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    num_heights = len(heights_m_agl)
    pathless_input_file_names = []

    for j in range(num_heights):
        first_file_name = (
            'shortwave-heating-rate-k-day01_{0:05d}metres_scores_without_units'
            '.jpg').format(heights_m_agl[j])

        second_file_name = (
            'shortwave-heating-rate-k-day01_{0:05d}metres_scores_with_units.jpg'
        ).format(heights_m_agl[j])

        pathless_input_file_names += [first_file_name, second_file_name]

    pathless_input_file_names += [
        'net-shortwave-flux-w-m02_scores_without_units.jpg',
        'net-shortwave-flux-w-m02_scores_with_units.jpg'
    ]

    panel_file_names = [
        '{0:s}/{1:s}'.format(input_dir_name, p)
        for p in pathless_input_file_names
    ]
    resized_panel_file_names = [
        '{0:s}/{1:s}'.format(output_dir_name, p)
        for p in pathless_input_file_names
    ]

    letter_label = None

    for i in range(len(panel_file_names)):
        print('Resizing panel and saving to: "{0:s}"...'.format(
            resized_panel_file_names[i]))

        imagemagick_utils.trim_whitespace(
            input_file_name=panel_file_names[i],
            output_file_name=resized_panel_file_names[i])

        if letter_label is None:
            letter_label = 'a'
        else:
            letter_label = chr(ord(letter_label) + 1)

        image_matrix = Image.open(resized_panel_file_names[i])
        _, figure_height_px = image_matrix.size

        _overlay_text(image_file_name=resized_panel_file_names[i],
                      x_offset_from_left_px=0,
                      y_offset_from_top_px=figure_height_px - 50,
                      text_string='({0:s})'.format(letter_label))
        imagemagick_utils.resize_image(
            input_file_name=resized_panel_file_names[i],
            output_file_name=resized_panel_file_names[i],
            output_size_pixels=PANEL_SIZE_PX)

    concat_figure_file_name = '{0:s}/evaluation_by_time.jpg'.format(
        output_dir_name)
    print(
        'Concatenating panels to: "{0:s}"...'.format(concat_figure_file_name))

    imagemagick_utils.concatenate_images(
        input_file_names=resized_panel_file_names,
        output_file_name=concat_figure_file_name,
        num_panel_rows=num_heights + 1,
        num_panel_columns=NUM_PANEL_COLUMNS)
    imagemagick_utils.resize_image(input_file_name=concat_figure_file_name,
                                   output_file_name=concat_figure_file_name,
                                   output_size_pixels=CONCAT_FIGURE_SIZE_PX)
                             fontsize=OVERLAY_FONT_SIZE,
                             color=MAIN_COLOUR,
                             horizontalalignment='center',
                             verticalalignment='center')

    # plotting_utils.annotate_axes(
    #     axes_object=axes_object, annotation_string='(b)',
    #     font_colour=ANNOTATION_COLOUR)

    print 'Saving figure to: "{0:s}"...'.format(TERNARY_CT_FILE_NAME)
    file_system_utils.mkdir_recursive_if_necessary(
        file_name=TERNARY_CT_FILE_NAME)
    pyplot.savefig(TERNARY_CT_FILE_NAME, dpi=OUTPUT_RESOLUTION_DPI)
    pyplot.close()

    imagemagick_utils.trim_whitespace(input_file_name=TERNARY_CT_FILE_NAME,
                                      output_file_name=TERNARY_CT_FILE_NAME)


if __name__ == '__main__':
    _plot_binary_table()
    _plot_ternary_table()

    print 'Concatenating figures to: "{0:s}"...'.format(CONCAT_FILE_NAME)
    imagemagick_utils.concatenate_images(
        input_file_names=[BINARY_CT_FILE_NAME, TERNARY_CT_FILE_NAME],
        output_file_name=CONCAT_FILE_NAME,
        num_panel_rows=1,
        num_panel_columns=2,
        output_size_pixels=OUTPUT_SIZE_PIXELS)
def _plot_one_example(
        radar_matrix, sounding_matrix, sounding_pressures_pascals,
        full_storm_id_string, storm_time_unix_sec, model_metadata_dict,
        output_dir_name):
    """Plots predictors for one example.

    M = number of rows in radar grid
    N = number of columns in radar grid
    H_r = number of heights in radar grid
    F_r = number of radar fields
    H_s = number of sounding heights
    F_s = number of sounding fields

    :param radar_matrix: numpy array (1 x M x N x H_r x F_r) of radar values.
    :param sounding_matrix: numpy array (1 x H_s x F_s) of sounding values.
    :param sounding_pressures_pascals: numpy array (length H_s) of sounding
        pressures.
    :param full_storm_id_string: Full storm ID.
    :param storm_time_unix_sec: Valid time.
    :param model_metadata_dict: Dictionary returned by
        `cnn.read_model_metadata`.
    :param output_dir_name: Name of output directory (figures will be saved
        here).
    :return: radar_figure_file_name: Path to radar figure created by this
        method.
    """

    training_option_dict = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY]
    radar_field_names = training_option_dict[trainval_io.RADAR_FIELDS_KEY]

    num_radar_fields = radar_matrix.shape[-1]
    num_radar_heights = radar_matrix.shape[-2]

    handle_dict = plot_examples.plot_one_example(
        list_of_predictor_matrices=[radar_matrix, sounding_matrix],
        model_metadata_dict=model_metadata_dict,
        pmm_flag=False, example_index=0, plot_sounding=True,
        sounding_pressures_pascals=sounding_pressures_pascals,
        allow_whitespace=True, plot_panel_names=True,
        panel_name_font_size=PANEL_NAME_FONT_SIZE,
        add_titles=False, label_colour_bars=True,
        colour_bar_length=COLOUR_BAR_LENGTH,
        colour_bar_font_size=COLOUR_BAR_FONT_SIZE,
        num_panel_rows=num_radar_heights
    )

    sounding_file_name = plot_examples.metadata_to_file_name(
        output_dir_name=output_dir_name, is_sounding=True, pmm_flag=False,
        full_storm_id_string=full_storm_id_string,
        storm_time_unix_sec=storm_time_unix_sec
    )

    print('Saving figure to: "{0:s}"...'.format(sounding_file_name))

    sounding_figure_object = handle_dict[plot_examples.SOUNDING_FIGURE_KEY]
    sounding_figure_object.savefig(
        sounding_file_name, dpi=FIGURE_RESOLUTION_DPI,
        pad_inches=0, bbox_inches='tight'
    )
    pyplot.close(sounding_figure_object)

    figure_objects = handle_dict[plot_examples.RADAR_FIGURES_KEY]
    panel_file_names = [None] * num_radar_fields

    for k in range(num_radar_fields):
        panel_file_names[k] = plot_examples.metadata_to_file_name(
            output_dir_name=output_dir_name, is_sounding=False, pmm_flag=False,
            full_storm_id_string=full_storm_id_string,
            storm_time_unix_sec=storm_time_unix_sec,
            radar_field_name=radar_field_names[k]
        )

        print('Saving figure to: "{0:s}"...'.format(panel_file_names[k]))

        figure_objects[k].savefig(
            panel_file_names[k], dpi=FIGURE_RESOLUTION_DPI,
            pad_inches=0, bbox_inches='tight'
        )
        pyplot.close(figure_objects[k])

    radar_figure_file_name = plot_examples.metadata_to_file_name(
        output_dir_name=output_dir_name, is_sounding=False, pmm_flag=False,
        full_storm_id_string=full_storm_id_string,
        storm_time_unix_sec=storm_time_unix_sec
    )

    print('Concatenating panels to: "{0:s}"...'.format(radar_figure_file_name))

    imagemagick_utils.concatenate_images(
        input_file_names=panel_file_names,
        output_file_name=radar_figure_file_name,
        num_panel_rows=1, num_panel_columns=num_radar_fields,
        border_width_pixels=50
    )
    imagemagick_utils.resize_image(
        input_file_name=radar_figure_file_name,
        output_file_name=radar_figure_file_name,
        output_size_pixels=CONCAT_FIGURE_SIZE_PX
    )
    imagemagick_utils.trim_whitespace(
        input_file_name=radar_figure_file_name,
        output_file_name=radar_figure_file_name,
        border_width_pixels=10
    )

    for this_file_name in panel_file_names:
        os.remove(this_file_name)

    return radar_figure_file_name
Example #19
0
def _plot_one_composite(saliency_file_name, monte_carlo_file_name,
                        composite_name_abbrev, composite_name_verbose,
                        colour_map_object, max_colour_value, half_num_contours,
                        smoothing_radius_grid_cells, output_dir_name):
    """Plots saliency map for one composite.

    :param saliency_file_name: Path to saliency file (will be read by
        `saliency.read_file`).
    :param monte_carlo_file_name: Path to Monte Carlo file (will be read by
        `_read_monte_carlo_file`).
    :param composite_name_abbrev: Abbrev composite name (will be used in file
        names).
    :param composite_name_verbose: Verbose composite name (will be used in
        figure title).
    :param colour_map_object: See documentation at top of file.
    :param max_colour_value: Same.
    :param half_num_contours: Same.
    :param smoothing_radius_grid_cells: Same.
    :param output_dir_name: Name of output directory (figures will be saved
        here).
    :return: main_figure_file_name: Path to main image file created by this
        method.
    """

    (mean_radar_matrices, mean_saliency_matrices, significance_matrices,
     model_metadata_dict) = _read_one_composite(
         saliency_file_name=saliency_file_name,
         smoothing_radius_grid_cells=smoothing_radius_grid_cells,
         monte_carlo_file_name=monte_carlo_file_name)

    refl_heights_m_agl = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY][
        trainval_io.RADAR_HEIGHTS_KEY]
    num_refl_heights = len(refl_heights_m_agl)

    handle_dict = plot_examples.plot_one_example(
        list_of_predictor_matrices=mean_radar_matrices,
        model_metadata_dict=model_metadata_dict,
        pmm_flag=True,
        plot_sounding=False,
        allow_whitespace=True,
        plot_panel_names=True,
        panel_name_font_size=PANEL_NAME_FONT_SIZE,
        add_titles=False,
        label_colour_bars=True,
        colour_bar_length=COLOUR_BAR_LENGTH,
        colour_bar_font_size=COLOUR_BAR_FONT_SIZE,
        num_panel_rows=num_refl_heights)

    axes_object_matrices = handle_dict[plot_examples.RADAR_AXES_KEY]

    this_saliency_matrix = numpy.flip(mean_saliency_matrices[0][0, ..., 0],
                                      axis=0)
    saliency_plotting.plot_many_2d_grids_with_contours(
        saliency_matrix_3d=this_saliency_matrix,
        axes_object_matrix=axes_object_matrices[0],
        colour_map_object=colour_map_object,
        max_absolute_contour_level=max_colour_value,
        contour_interval=max_colour_value / half_num_contours,
        row_major=True)

    this_sig_matrix = numpy.flip(significance_matrices[0][0, ..., 0], axis=0)
    significance_plotting.plot_many_2d_grids_without_coords(
        significance_matrix=this_sig_matrix,
        axes_object_matrix=axes_object_matrices[0],
        marker_size=2,
        row_major=True)

    this_saliency_matrix = numpy.flip(mean_saliency_matrices[1][0, ...],
                                      axis=0)
    saliency_plotting.plot_many_2d_grids_with_contours(
        saliency_matrix_3d=this_saliency_matrix,
        axes_object_matrix=axes_object_matrices[1],
        colour_map_object=colour_map_object,
        max_absolute_contour_level=max_colour_value,
        contour_interval=max_colour_value / half_num_contours,
        row_major=False)

    this_sig_matrix = numpy.flip(significance_matrices[1][0, ...], axis=0)
    significance_plotting.plot_many_2d_grids_without_coords(
        significance_matrix=this_sig_matrix,
        axes_object_matrix=axes_object_matrices[1],
        marker_size=2,
        row_major=False)

    refl_figure_object = handle_dict[plot_examples.RADAR_FIGURES_KEY][0]
    refl_figure_file_name = '{0:s}/{1:s}_reflectivity.jpg'.format(
        output_dir_name, composite_name_abbrev)

    print('Saving figure to: "{0:s}"...'.format(refl_figure_file_name))
    refl_figure_object.savefig(refl_figure_file_name,
                               dpi=FIGURE_RESOLUTION_DPI,
                               pad_inches=0,
                               bbox_inches='tight')
    pyplot.close(refl_figure_object)

    shear_figure_object = handle_dict[plot_examples.RADAR_FIGURES_KEY][1]
    shear_figure_file_name = '{0:s}/{1:s}_shear.jpg'.format(
        output_dir_name, composite_name_abbrev)

    print('Saving figure to: "{0:s}"...'.format(shear_figure_file_name))
    shear_figure_object.savefig(shear_figure_file_name,
                                dpi=FIGURE_RESOLUTION_DPI,
                                pad_inches=0,
                                bbox_inches='tight')
    pyplot.close(shear_figure_object)

    main_figure_file_name = '{0:s}/{1:s}_saliency.jpg'.format(
        output_dir_name, composite_name_abbrev)
    print('Concatenating panels to: "{0:s}"...'.format(main_figure_file_name))

    imagemagick_utils.concatenate_images(
        input_file_names=[refl_figure_file_name, shear_figure_file_name],
        output_file_name=main_figure_file_name,
        num_panel_rows=1,
        num_panel_columns=2,
        border_width_pixels=50,
        extra_args_string='-gravity south')
    imagemagick_utils.resize_image(input_file_name=main_figure_file_name,
                                   output_file_name=main_figure_file_name,
                                   output_size_pixels=CONCAT_FIGURE_SIZE_PX)
    imagemagick_utils.trim_whitespace(input_file_name=main_figure_file_name,
                                      output_file_name=main_figure_file_name,
                                      border_width_pixels=TITLE_FONT_SIZE + 25)
    _overlay_text(image_file_name=main_figure_file_name,
                  x_offset_from_center_px=0,
                  y_offset_from_top_px=0,
                  text_string=composite_name_verbose)
    imagemagick_utils.trim_whitespace(input_file_name=main_figure_file_name,
                                      output_file_name=main_figure_file_name,
                                      border_width_pixels=10)

    return main_figure_file_name
def _plot_sounding_saliency(
        sounding_matrix, sounding_saliency_matrix, sounding_field_names,
        saliency_metadata_dict, colour_map_object, max_colour_value_by_example,
        output_dir_name):
    """Plots soundings along with their saliency maps.

    E = number of examples
    H = number of sounding heights
    F = number of sounding fields

    :param sounding_matrix: E-by-H-by-F numpy array of sounding values.
    :param sounding_saliency_matrix: E-by-H-by-F numpy array of corresponding
        saliency values.
    :param sounding_field_names: length-F list of field names.
    :param saliency_metadata_dict: Dictionary returned by
        `saliency_maps.read_standard_file`.
    :param colour_map_object: See doc for `_plot_2d3d_radar_saliency`.
    :param max_colour_value_by_example: Same.
    :param output_dir_name: Name of output directory (figures will be saved
        here).
    """

    # TODO(thunderhoser): Generalize this method to deal with
    # probability-matched means.

    num_examples = sounding_matrix.shape[0]

    try:
        metpy_dict_by_example = dl_utils.soundings_to_metpy_dictionaries(
            sounding_matrix=sounding_matrix, field_names=sounding_field_names)
    except:
        sounding_pressure_matrix_pa = numpy.expand_dims(
            saliency_metadata_dict[saliency_maps.SOUNDING_PRESSURES_KEY],
            axis=-1)

        this_sounding_matrix = numpy.concatenate(
            (sounding_matrix, sounding_pressure_matrix_pa), axis=-1)

        metpy_dict_by_example = dl_utils.soundings_to_metpy_dictionaries(
            sounding_matrix=this_sounding_matrix,
            field_names=sounding_field_names + [soundings.PRESSURE_NAME])

    for i in range(num_examples):
        this_storm_id = saliency_metadata_dict[
            saliency_maps.STORM_IDS_KEY][i]
        this_storm_time_string = time_conversion.unix_sec_to_string(
            saliency_metadata_dict[saliency_maps.STORM_TIMES_KEY][i],
            TIME_FORMAT)

        this_title_string = 'Storm "{0:s}" at {1:s}'.format(
            this_storm_id, this_storm_time_string)
        sounding_plotting.plot_sounding(
            sounding_dict_for_metpy=metpy_dict_by_example[i],
            title_string=this_title_string)

        this_left_file_name = (
            '{0:s}/{1:s}_{2:s}_sounding-actual.jpg'
        ).format(
            output_dir_name, this_storm_id.replace('_', '-'),
            this_storm_time_string
        )

        print 'Saving figure to file: "{0:s}"...'.format(
            this_left_file_name)
        pyplot.savefig(this_left_file_name, dpi=FIGURE_RESOLUTION_DPI)
        pyplot.close()

        imagemagick_utils.trim_whitespace(
            input_file_name=this_left_file_name,
            output_file_name=this_left_file_name)

        saliency_plotting.plot_saliency_for_sounding(
            saliency_matrix=sounding_saliency_matrix[i, ...],
            sounding_field_names=sounding_field_names,
            pressure_levels_mb=metpy_dict_by_example[i][
                soundings.PRESSURE_COLUMN_METPY],
            colour_map_object=colour_map_object,
            max_absolute_colour_value=max_colour_value_by_example[i])

        this_right_file_name = (
            '{0:s}/{1:s}_{2:s}_sounding-saliency.jpg'
        ).format(
            output_dir_name, this_storm_id.replace('_', '-'),
            this_storm_time_string
        )

        print 'Saving figure to file: "{0:s}"...'.format(
            this_right_file_name)
        pyplot.savefig(this_right_file_name, dpi=FIGURE_RESOLUTION_DPI)
        pyplot.close()

        imagemagick_utils.trim_whitespace(
            input_file_name=this_right_file_name,
            output_file_name=this_right_file_name)

        this_file_name = (
            '{0:s}/saliency_{1:s}_{2:s}_sounding.jpg'
        ).format(
            output_dir_name, this_storm_id.replace('_', '-'),
            this_storm_time_string
        )

        print 'Concatenating panels into file: "{0:s}"...\n'.format(
            this_file_name)

        imagemagick_utils.concatenate_images(
            input_file_names=[this_left_file_name, this_right_file_name],
            output_file_name=this_file_name, num_panel_rows=1,
            num_panel_columns=2)

        imagemagick_utils.resize_image(
            input_file_name=this_file_name,
            output_file_name=this_file_name,
            output_size_pixels=SOUNDING_IMAGE_SIZE_PX)

        os.remove(this_left_file_name)
        os.remove(this_right_file_name)
def _run(input_dir_name, site_names_for_reliability, site_name_for_histogram,
         output_dir_name):
    """Creates figure showing overall model evaluation.

    This is effectively the main method.

    :param input_dir_name: See documentation at top of file.
    :param site_names_for_reliability: Same.
    :param site_name_for_histogram: Same.
    :param output_dir_name: Same.
    """

    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    pathless_input_file_names = [
        'shortwave-surface-down-flux-w-m02_attributes_{0:s}.jpg'.format(
            site_name_for_histogram),
        'shortwave-toa-up-flux-w-m02_attributes_{0:s}.jpg'.format(
            site_name_for_histogram),
        'net-shortwave-flux-w-m02_attributes_{0:s}.jpg'.format(
            site_name_for_histogram),
        'shortwave-heating-rate-k-day01_bias_profile.jpg',
        'shortwave-heating-rate-k-day01_mean-absolute-error_profile.jpg',
        'shortwave-heating-rate-k-day01_mae-skill-score_profile.jpg'
    ]

    num_sites_for_relia = len(site_names_for_reliability)

    for j in range(num_sites_for_relia):
        this_file_name = (
            'shortwave-heating-rate-k-day01_reliability_{0:s}.jpg').format(
                site_names_for_reliability[j])

        pathless_input_file_names.append(this_file_name)

    panel_file_names = [
        '{0:s}/{1:s}'.format(input_dir_name, p)
        for p in pathless_input_file_names
    ]
    resized_panel_file_names = [
        '{0:s}/{1:s}'.format(output_dir_name, p)
        for p in pathless_input_file_names
    ]

    letter_label = None

    for i in range(len(panel_file_names)):
        print('Resizing panel and saving to: "{0:s}"...'.format(
            resized_panel_file_names[i]))

        imagemagick_utils.trim_whitespace(
            input_file_name=panel_file_names[i],
            output_file_name=resized_panel_file_names[i])

        if letter_label is None:
            letter_label = 'a'
        else:
            letter_label = chr(ord(letter_label) + 1)

        _overlay_text(image_file_name=resized_panel_file_names[i],
                      x_offset_from_left_px=0,
                      y_offset_from_top_px=TITLE_FONT_SIZE,
                      text_string='({0:s})'.format(letter_label))
        imagemagick_utils.resize_image(
            input_file_name=resized_panel_file_names[i],
            output_file_name=resized_panel_file_names[i],
            output_size_pixels=PANEL_SIZE_PX)

    concat_figure_file_name = '{0:s}/evaluation_by_site.jpg'.format(
        output_dir_name)
    print(
        'Concatenating panels to: "{0:s}"...'.format(concat_figure_file_name))

    imagemagick_utils.concatenate_images(
        input_file_names=resized_panel_file_names,
        output_file_name=concat_figure_file_name,
        num_panel_rows=NUM_PANEL_ROWS,
        num_panel_columns=NUM_PANEL_COLUMNS)
    imagemagick_utils.resize_image(input_file_name=concat_figure_file_name,
                                   output_file_name=concat_figure_file_name,
                                   output_size_pixels=CONCAT_FIGURE_SIZE_PX)
Example #22
0
def _run(experiment_dir_name, matching_distance_metres, output_dir_name):
    """Plots results of object-conversion experiment.

    This is effectively the main method.

    :param experiment_dir_name: See documentation at top of file.
    :param matching_distance_metres: Same.
    :param output_dir_name: Same.
    """

    num_binarization_thresholds = len(UNIQUE_BINARIZATION_THRESHOLDS)
    num_min_areas = len(UNIQUE_MIN_AREAS_METRES2)
    num_min_lengths = len(UNIQUE_MIN_LENGTHS_METRES)

    all_scores_file_name = '{0:s}/obe_{1:d}km_all-scores.p'.format(
        output_dir_name,
        int(numpy.round(matching_distance_metres * METRES_TO_KM)))

    if os.path.isfile(all_scores_file_name):
        print 'Reading data from: "{0:s}"...\n'.format(all_scores_file_name)
        pickle_file_handle = open(all_scores_file_name, 'rb')
        score_dict = pickle.load(pickle_file_handle)
        pickle_file_handle.close()

        csi_matrix = score_dict['csi_matrix'][1:, ...]
        pod_matrix = score_dict['pod_matrix'][1:, ...]
        success_ratio_matrix = score_dict['success_ratio_matrix'][1:, ...]
        frequency_bias_matrix = score_dict['frequency_bias_matrix'][1:, ...]

    else:
        csi_matrix = numpy.full(
            (num_binarization_thresholds, num_min_areas, num_min_lengths),
            numpy.nan)
        pod_matrix = csi_matrix + 0.
        success_ratio_matrix = csi_matrix + 0.
        frequency_bias_matrix = csi_matrix + 0.

        for i in range(num_binarization_thresholds):
            for j in range(num_min_areas):
                for k in range(num_min_lengths):
                    this_file_name = (
                        '{0:s}/obe_{1:d}km_binarization-threshold={2:.3f}_'
                        'min-area-metres2={3:013d}_min-length-metres={4:07d}.p'
                    ).format(
                        experiment_dir_name,
                        int(
                            numpy.round(matching_distance_metres *
                                        METRES_TO_KM)),
                        UNIQUE_BINARIZATION_THRESHOLDS[i],
                        UNIQUE_MIN_AREAS_METRES2[j],
                        UNIQUE_MIN_LENGTHS_METRES[k])

                    if not os.path.isfile(this_file_name):
                        warning_string = (
                            'Cannot find file.  Expected at: "{0:s}"'
                        ).format(this_file_name)
                        warnings.warn(warning_string)
                        continue

                    print 'Reading data from: "{0:s}"...'.format(
                        this_file_name)
                    this_evaluation_dict = object_eval.read_evaluation_results(
                        this_file_name)

                    csi_matrix[i, j, k] = this_evaluation_dict[
                        object_eval.BINARY_CSI_KEY]
                    pod_matrix[i, j, k] = this_evaluation_dict[
                        object_eval.BINARY_POD_KEY]
                    success_ratio_matrix[i, j, k] = this_evaluation_dict[
                        object_eval.BINARY_SUCCESS_RATIO_KEY]
                    frequency_bias_matrix[i, j, k] = this_evaluation_dict[
                        object_eval.BINARY_FREQUENCY_BIAS_KEY]

        print SEPARATOR_STRING

        score_dict = {
            'csi_matrix': csi_matrix,
            'pod_matrix': pod_matrix,
            'success_ratio_matrix': success_ratio_matrix,
            'frequency_bias_matrix': frequency_bias_matrix
        }

        print 'Writing scores to: "{0:s}"...'.format(all_scores_file_name)
        pickle_file_handle = open(all_scores_file_name, 'wb')
        pickle.dump(score_dict, pickle_file_handle)
        pickle_file_handle.close()

    this_offset = numpy.nanpercentile(
        numpy.absolute(frequency_bias_matrix - 1), MAX_COLOUR_PERCENTILE)
    min_colour_frequency_bias = 1 - this_offset
    max_colour_frequency_bias = 1 + this_offset

    csi_file_names = []
    pod_file_names = []
    success_ratio_file_names = []
    frequency_bias_file_names = []

    for i in range(num_binarization_thresholds):
        if numpy.mod(i, NUM_PANEL_COLUMNS) == 0:
            this_y_axis_text_colour = BLACK_COLOUR + 0.
        else:
            this_y_axis_text_colour = WHITE_COLOUR + 0.

        if i >= num_binarization_thresholds - NUM_PANEL_COLUMNS:
            this_x_axis_text_colour = BLACK_COLOUR + 0.
        else:
            this_x_axis_text_colour = WHITE_COLOUR + 0.

        this_title_string = r'$p_{NF}^*$'
        this_title_string += ' = {0:.3f}'.format(
            UNIQUE_BINARIZATION_THRESHOLDS[i])

        this_file_name = '{0:s}/csi_binarization-threshold={1:.4f}.jpg'.format(
            output_dir_name, UNIQUE_BINARIZATION_THRESHOLDS[i])
        csi_file_names.append(this_file_name)

        _plot_scores_as_grid(
            score_matrix=numpy.transpose(csi_matrix[i, ...]),
            colour_map_object=SEQUENTIAL_COLOUR_MAP_OBJECT,
            min_colour_value=numpy.nanpercentile(csi_matrix,
                                                 MIN_COLOUR_PERCENTILE),
            max_colour_value=numpy.nanpercentile(csi_matrix,
                                                 MAX_COLOUR_PERCENTILE),
            y_tick_labels=UNIQUE_MIN_LENGTH_STRINGS,
            y_axis_label=MIN_LENGTH_AXIS_LABEL,
            y_axis_text_colour=this_y_axis_text_colour,
            x_tick_labels=UNIQUE_MIN_AREA_STRINGS,
            x_axis_label=MIN_AREA_AXIS_LABEL,
            x_axis_text_colour=this_x_axis_text_colour,
            title_string=this_title_string,
            output_file_name=csi_file_names[-1])

        this_file_name = '{0:s}/pod_binarization-threshold={1:.4f}.jpg'.format(
            output_dir_name, UNIQUE_BINARIZATION_THRESHOLDS[i])
        pod_file_names.append(this_file_name)

        _plot_scores_as_grid(
            score_matrix=numpy.transpose(pod_matrix[i, ...]),
            colour_map_object=SEQUENTIAL_COLOUR_MAP_OBJECT,
            min_colour_value=numpy.nanpercentile(pod_matrix,
                                                 MIN_COLOUR_PERCENTILE),
            max_colour_value=numpy.nanpercentile(pod_matrix,
                                                 MAX_COLOUR_PERCENTILE),
            y_tick_labels=UNIQUE_MIN_LENGTH_STRINGS,
            y_axis_label=MIN_LENGTH_AXIS_LABEL,
            y_axis_text_colour=this_y_axis_text_colour,
            x_tick_labels=UNIQUE_MIN_AREA_STRINGS,
            x_axis_label=MIN_AREA_AXIS_LABEL,
            x_axis_text_colour=this_x_axis_text_colour,
            title_string=this_title_string,
            output_file_name=pod_file_names[-1])

        this_file_name = (
            '{0:s}/success_ratio_binarization-threshold={1:.4f}.jpg').format(
                output_dir_name, UNIQUE_BINARIZATION_THRESHOLDS[i])
        success_ratio_file_names.append(this_file_name)

        _plot_scores_as_grid(
            score_matrix=numpy.transpose(success_ratio_matrix[i, ...]),
            colour_map_object=SEQUENTIAL_COLOUR_MAP_OBJECT,
            min_colour_value=numpy.nanpercentile(success_ratio_matrix,
                                                 MIN_COLOUR_PERCENTILE),
            max_colour_value=numpy.nanpercentile(success_ratio_matrix,
                                                 MAX_COLOUR_PERCENTILE),
            y_tick_labels=UNIQUE_MIN_LENGTH_STRINGS,
            y_axis_label=MIN_LENGTH_AXIS_LABEL,
            y_axis_text_colour=this_y_axis_text_colour,
            x_tick_labels=UNIQUE_MIN_AREA_STRINGS,
            x_axis_label=MIN_AREA_AXIS_LABEL,
            x_axis_text_colour=this_x_axis_text_colour,
            title_string=this_title_string,
            output_file_name=success_ratio_file_names[-1])

        this_file_name = (
            '{0:s}/frequency_bias_binarization-threshold={1:.4f}.jpg').format(
                output_dir_name, UNIQUE_BINARIZATION_THRESHOLDS[i])
        frequency_bias_file_names.append(this_file_name)

        _plot_scores_as_grid(score_matrix=numpy.transpose(
            frequency_bias_matrix[i, ...]),
                             colour_map_object=DIVERGENT_COLOUR_MAP_OBJECT,
                             min_colour_value=min_colour_frequency_bias,
                             max_colour_value=max_colour_frequency_bias,
                             y_tick_labels=UNIQUE_MIN_LENGTH_STRINGS,
                             y_axis_label=MIN_LENGTH_AXIS_LABEL,
                             y_axis_text_colour=this_y_axis_text_colour,
                             x_tick_labels=UNIQUE_MIN_AREA_STRINGS,
                             x_axis_label=MIN_AREA_AXIS_LABEL,
                             x_axis_text_colour=this_x_axis_text_colour,
                             title_string=this_title_string,
                             output_file_name=frequency_bias_file_names[-1])

        print '\n'

    this_file_name = '{0:s}/csi.jpg'.format(output_dir_name)
    print 'Concatenating panels to: "{0:s}"...'.format(this_file_name)
    imagemagick_utils.concatenate_images(input_file_names=csi_file_names,
                                         output_file_name=this_file_name,
                                         num_panel_rows=NUM_PANEL_ROWS,
                                         num_panel_columns=NUM_PANEL_COLUMNS,
                                         output_size_pixels=FIGURE_SIZE_PIXELS)

    this_file_name = '{0:s}/pod.jpg'.format(output_dir_name)
    print 'Concatenating panels to: "{0:s}"...'.format(this_file_name)
    imagemagick_utils.concatenate_images(input_file_names=pod_file_names,
                                         output_file_name=this_file_name,
                                         num_panel_rows=NUM_PANEL_ROWS,
                                         num_panel_columns=NUM_PANEL_COLUMNS,
                                         output_size_pixels=FIGURE_SIZE_PIXELS)

    this_file_name = '{0:s}/success_ratio.jpg'.format(output_dir_name)
    print 'Concatenating panels to: "{0:s}"...'.format(this_file_name)
    imagemagick_utils.concatenate_images(
        input_file_names=success_ratio_file_names,
        output_file_name=this_file_name,
        num_panel_rows=NUM_PANEL_ROWS,
        num_panel_columns=NUM_PANEL_COLUMNS,
        output_size_pixels=FIGURE_SIZE_PIXELS)

    this_file_name = '{0:s}/frequency_bias.jpg'.format(output_dir_name)
    print 'Concatenating panels to: "{0:s}"...'.format(this_file_name)
    imagemagick_utils.concatenate_images(
        input_file_names=frequency_bias_file_names,
        output_file_name=this_file_name,
        num_panel_rows=NUM_PANEL_ROWS,
        num_panel_columns=NUM_PANEL_COLUMNS,
        output_size_pixels=FIGURE_SIZE_PIXELS)
def _plot_sounding_saliency(
        saliency_matrix, colour_map_object, max_colour_value, sounding_matrix,
        saliency_dict, model_metadata_dict, output_dir_name, pmm_flag,
        example_index=None):
    """Plots saliency for sounding.

    H = number of sounding heights
    F = number of sounding fields

    If plotting a composite rather than one example, `full_storm_id_string` and
    `storm_time_unix_sec` can be None.

    :param saliency_matrix: H-by-F numpy array of saliency values.
    :param colour_map_object: See documentation at top of file.
    :param max_colour_value: Max value in colour scheme for saliency.
    :param sounding_matrix: H-by-F numpy array of actual sounding values.
    :param saliency_dict: Dictionary returned from
        `saliency_maps.read_standard_file` or `saliency_maps.read_pmm_file`.
    :param model_metadata_dict: Dictionary returned by
        `cnn.read_model_metadata`.
    :param output_dir_name: Path to output directory.  Figure will be saved
        here.
    :param pmm_flag: Boolean flag.  If True, will plot composite rather than one
        example.
    :param example_index: [used only if `pmm_flag == False`]
        Will plot the [i]th example, where i = `example_index`.
    """

    if pmm_flag:
        example_index = 0

    training_option_dict = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY]
    sounding_field_names = training_option_dict[trainval_io.SOUNDING_FIELDS_KEY]
    sounding_heights_m_agl = training_option_dict[
        trainval_io.SOUNDING_HEIGHTS_KEY]

    sounding_matrix = numpy.expand_dims(sounding_matrix, axis=0)

    if saliency_maps.SOUNDING_PRESSURES_KEY in saliency_dict:
        pressure_matrix_pascals = numpy.expand_dims(
            saliency_dict[saliency_maps.SOUNDING_PRESSURES_KEY], axis=-1
        )

        pressure_matrix_pascals = pressure_matrix_pascals[[example_index], ...]
        sounding_matrix = numpy.concatenate(
            (sounding_matrix, pressure_matrix_pascals), axis=-1
        )

        sounding_dict_for_metpy = dl_utils.soundings_to_metpy_dictionaries(
            sounding_matrix=sounding_matrix,
            field_names=sounding_field_names + [soundings.PRESSURE_NAME]
        )[0]
    else:
        sounding_dict_for_metpy = dl_utils.soundings_to_metpy_dictionaries(
            sounding_matrix=sounding_matrix, field_names=sounding_field_names,
            height_levels_m_agl=sounding_heights_m_agl,
            storm_elevations_m_asl=numpy.array([0.])
        )[0]

    if pmm_flag:
        full_storm_id_string = None
        storm_time_unix_sec = None
        title_string = 'PMM composite'
    else:
        full_storm_id_string = saliency_dict[saliency_maps.FULL_IDS_KEY][
            example_index]
        storm_time_unix_sec = saliency_dict[saliency_maps.STORM_TIMES_KEY][
            example_index]

        title_string = 'Storm "{0:s}" at {1:s}'.format(
            full_storm_id_string,
            time_conversion.unix_sec_to_string(
                storm_time_unix_sec, plot_input_examples.TIME_FORMAT)
        )

    sounding_plotting.plot_sounding(
        sounding_dict_for_metpy=sounding_dict_for_metpy,
        title_string=title_string)

    left_panel_file_name = plot_input_examples.metadata_to_file_name(
        output_dir_name=output_dir_name, is_sounding=False, pmm_flag=pmm_flag,
        full_storm_id_string=full_storm_id_string,
        storm_time_unix_sec=storm_time_unix_sec,
        radar_field_name='sounding-actual')

    print('Saving figure to file: "{0:s}"...'.format(left_panel_file_name))
    pyplot.savefig(left_panel_file_name, dpi=FIGURE_RESOLUTION_DPI)
    pyplot.close()

    imagemagick_utils.trim_whitespace(
        input_file_name=left_panel_file_name,
        output_file_name=left_panel_file_name)

    saliency_plotting.plot_saliency_for_sounding(
        saliency_matrix=saliency_matrix,
        sounding_field_names=sounding_field_names,
        pressure_levels_mb=sounding_dict_for_metpy[
            soundings.PRESSURE_COLUMN_METPY],
        colour_map_object=colour_map_object,
        max_absolute_colour_value=max_colour_value)

    right_panel_file_name = plot_input_examples.metadata_to_file_name(
        output_dir_name=output_dir_name, is_sounding=False, pmm_flag=pmm_flag,
        full_storm_id_string=full_storm_id_string,
        storm_time_unix_sec=storm_time_unix_sec,
        radar_field_name='sounding-saliency')

    print('Saving figure to file: "{0:s}"...'.format(right_panel_file_name))
    pyplot.savefig(right_panel_file_name, dpi=FIGURE_RESOLUTION_DPI)
    pyplot.close()

    imagemagick_utils.trim_whitespace(
        input_file_name=right_panel_file_name,
        output_file_name=right_panel_file_name)

    concat_file_name = plot_input_examples.metadata_to_file_name(
        output_dir_name=output_dir_name, is_sounding=True, pmm_flag=pmm_flag,
        full_storm_id_string=full_storm_id_string,
        storm_time_unix_sec=storm_time_unix_sec)

    print('Concatenating figures to: "{0:s}"...\n'.format(concat_file_name))
    imagemagick_utils.concatenate_images(
        input_file_names=[left_panel_file_name, right_panel_file_name],
        output_file_name=concat_file_name, num_panel_rows=1,
        num_panel_columns=2)

    imagemagick_utils.resize_image(
        input_file_name=concat_file_name, output_file_name=concat_file_name,
        output_size_pixels=SOUNDING_IMAGE_SIZE_PX)

    os.remove(left_panel_file_name)
    os.remove(right_panel_file_name)
def _run(valid_time_strings):
    """Plots predicted and observed fronts for one time step.

    This is effectively the main method.

    :param valid_time_strings: See documentation at top of file.
    """

    num_times = 2
    error_checking.assert_is_numpy_array(
        numpy.array(valid_time_strings),
        exact_dimensions=numpy.array([num_times]))

    valid_times_unix_sec = numpy.array(
        [time_conversion.string_to_unix_sec(s, INPUT_TIME_FORMAT)
         for s in valid_time_strings],
        dtype=int)

    num_grid_rows, num_grid_columns = nwp_model_utils.get_grid_dimensions(
        model_name=nwp_model_utils.NARR_MODEL_NAME)

    print 'Reading data from: "{0:s}"...'.format(OBJECT_PREDICTION_FILE_NAME)
    predicted_region_table = object_eval.read_predictions_and_obs(
        OBJECT_PREDICTION_FILE_NAME)[0]

    figure_file_names = numpy.full((3, num_times), '', dtype=object)

    for i in range(num_times):
        this_prediction_file_name = ml_utils.find_gridded_prediction_file(
            directory_name=TOP_PREDICTION_DIR_NAME,
            first_target_time_unix_sec=valid_times_unix_sec[i],
            last_target_time_unix_sec=valid_times_unix_sec[i])

        print 'Reading data from: "{0:s}"...'.format(this_prediction_file_name)
        this_prediction_dict = ml_utils.read_gridded_predictions(
            this_prediction_file_name)
        this_probability_matrix = this_prediction_dict[
            ml_utils.PROBABILITY_MATRIX_KEY]
        this_probability_matrix[numpy.isnan(this_probability_matrix)] = 0.

        figure_file_names[0, i] = '{0:s}/gridded_predictions_{1:s}.jpg'.format(
            OUTPUT_DIR_NAME, valid_time_strings[i])
        this_title_string = 'Gridded predictions at {0:s}'.format(
            time_conversion.unix_sec_to_string(
                valid_times_unix_sec[i], OUTPUT_TIME_FORMAT)
        )

        _plot_predictions_one_time(
            output_file_name=figure_file_names[0, i],
            title_string=this_title_string,
            annotation_string=GRIDDED_PREDICTION_PANEL_LABELS[i],
            class_probability_matrix=this_probability_matrix,
            plot_warm_colour_bar=i == 0,
            plot_cold_colour_bar=i == num_times - 1)

        this_predicted_region_table = predicted_region_table.loc[
            predicted_region_table[front_utils.TIME_COLUMN] ==
            valid_times_unix_sec[i]
        ]
        this_predicted_label_matrix = object_eval.regions_to_images(
            predicted_region_table=this_predicted_region_table,
            num_grid_rows=num_grid_rows, num_grid_columns=num_grid_columns)

        figure_file_names[1, i] = '{0:s}/object_predictions_{1:s}.jpg'.format(
            OUTPUT_DIR_NAME, valid_time_strings[i])
        this_title_string = 'Object-based predictions at {0:s}'.format(
            time_conversion.unix_sec_to_string(
                valid_times_unix_sec[i], OUTPUT_TIME_FORMAT)
        )

        _plot_predictions_one_time(
            output_file_name=figure_file_names[1, i],
            title_string=this_title_string,
            annotation_string=OBJECT_PREDICTION_PANEL_LABELS[i],
            predicted_label_matrix=this_predicted_label_matrix)

        figure_file_names[2, i] = '{0:s}/observations_{1:s}.jpg'.format(
            OUTPUT_DIR_NAME, valid_time_strings[i])
        this_title_string = 'Observations at {0:s}'.format(
            time_conversion.unix_sec_to_string(
                valid_times_unix_sec[i], OUTPUT_TIME_FORMAT)
        )

        _plot_observations_one_time(
            valid_time_string=valid_time_strings[i],
            title_string=this_title_string,
            annotation_string=OBSERVATION_PANEL_LABELS[i],
            output_file_name=figure_file_names[2, i])
        print '\n'

    print 'Concatenating figures to: "{0:s}"...'.format(CONCAT_FILE_NAME)
    imagemagick_utils.concatenate_images(
        input_file_names=numpy.ravel(figure_file_names).tolist(),
        output_file_name=CONCAT_FILE_NAME,
        num_panel_rows=NUM_PANEL_ROWS, num_panel_columns=NUM_PANEL_COLUMNS,
        output_size_pixels=FIGURE_SIZE_PIXELS)
def _run(tropical_example_dir_name, non_tropical_example_dir_name,
         num_histogram_bins, output_dir_name):
    """Plots distribution of each target variable.

    This is effectively the main method.

    :param tropical_example_dir_name: See documentation at top of file.
    :param non_tropical_example_dir_name: Same.
    :param num_histogram_bins: Same.
    :param output_dir_name: Same.
    """

    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    first_time_unix_sec = (
        time_conversion.first_and_last_times_in_year(FIRST_YEAR)[0])
    last_time_unix_sec = (
        time_conversion.first_and_last_times_in_year(LAST_YEAR)[-1])

    example_file_names = example_io.find_many_files(
        directory_name=tropical_example_dir_name,
        first_time_unix_sec=first_time_unix_sec,
        last_time_unix_sec=last_time_unix_sec,
        raise_error_if_all_missing=True,
        raise_error_if_any_missing=True)

    example_file_names += example_io.find_many_files(
        directory_name=non_tropical_example_dir_name,
        first_time_unix_sec=first_time_unix_sec,
        last_time_unix_sec=last_time_unix_sec,
        raise_error_if_all_missing=True,
        raise_error_if_any_missing=True)

    example_dicts = []

    for this_file_name in example_file_names:
        print('Reading data from: "{0:s}"...'.format(this_file_name))
        this_example_dict = example_io.read_file(this_file_name)
        this_example_dict = example_utils.subset_by_field(
            example_dict=this_example_dict, field_names=TARGET_NAMES_IN_FILE)

        example_dicts.append(this_example_dict)

    example_dict = example_utils.concat_examples(example_dicts)
    del example_dicts

    letter_label = None
    panel_file_names = []

    for this_target_name in TARGET_NAMES:
        if this_target_name in TARGET_NAMES_IN_FILE:
            these_target_values = example_utils.get_field_from_dict(
                example_dict=example_dict, field_name=this_target_name)
        else:
            down_fluxes_w_m02 = example_utils.get_field_from_dict(
                example_dict=example_dict,
                field_name=example_utils.SHORTWAVE_SURFACE_DOWN_FLUX_NAME)
            up_fluxes_w_m02 = example_utils.get_field_from_dict(
                example_dict=example_dict,
                field_name=example_utils.SHORTWAVE_TOA_UP_FLUX_NAME)
            these_target_values = down_fluxes_w_m02 - up_fluxes_w_m02

        these_target_values = numpy.ravel(these_target_values)

        if letter_label is None:
            letter_label = 'a'
        else:
            letter_label = chr(ord(letter_label) + 1)

        this_file_name = _plot_histogram_one_target(
            target_values=these_target_values,
            target_name=this_target_name,
            num_bins=num_histogram_bins,
            letter_label=letter_label,
            output_dir_name=output_dir_name)
        panel_file_names.append(this_file_name)

    concat_file_name = '{0:s}/target_distributions.jpg'.format(output_dir_name)
    print('Concatenating panels to: "{0:s}"...'.format(concat_file_name))

    imagemagick_utils.concatenate_images(input_file_names=panel_file_names,
                                         output_file_name=concat_file_name,
                                         num_panel_rows=2,
                                         num_panel_columns=2,
                                         border_width_pixels=25)
    imagemagick_utils.trim_whitespace(input_file_name=concat_file_name,
                                      output_file_name=concat_file_name)
Example #26
0
def _run(evaluation_dir_name, smoothing_radius_grid_cells,
         score_colour_map_name, num_ex_colour_map_name, max_colour_percentile,
         output_dir_name):
    """Plots spatially subset model evaluation.

    This is effectively the main method.

    :param evaluation_dir_name: See documentation at top of file.
    :param smoothing_radius_grid_cells: Same.
    :param score_colour_map_name: Same.
    :param num_ex_colour_map_name: Same.
    :param max_colour_percentile: Same.
    :param output_dir_name: Same.
    """

    if smoothing_radius_grid_cells <= 0:
        smoothing_radius_grid_cells = None

    score_colour_map_object = pyplot.get_cmap(score_colour_map_name)
    num_ex_colour_map_object = pyplot.get_cmap(num_ex_colour_map_name)
    error_checking.assert_is_geq(max_colour_percentile, 90.)
    error_checking.assert_is_leq(max_colour_percentile, 100.)

    grid_metafile_name = grids.find_equidistant_metafile(
        directory_name=evaluation_dir_name, raise_error_if_missing=True)

    print('Reading grid metadata from: "{0:s}"...'.format(grid_metafile_name))
    grid_metadata_dict = grids.read_equidistant_metafile(grid_metafile_name)
    print(SEPARATOR_STRING)

    num_grid_rows = len(grid_metadata_dict[grids.Y_COORDS_KEY])
    num_grid_columns = len(grid_metadata_dict[grids.X_COORDS_KEY])

    auc_matrix = numpy.full((num_grid_rows, num_grid_columns), numpy.nan)
    csi_matrix = numpy.full((num_grid_rows, num_grid_columns), numpy.nan)
    pod_matrix = numpy.full((num_grid_rows, num_grid_columns), numpy.nan)
    far_matrix = numpy.full((num_grid_rows, num_grid_columns), numpy.nan)
    num_examples_matrix = numpy.full((num_grid_rows, num_grid_columns),
                                     0,
                                     dtype=int)
    num_positive_examples_matrix = numpy.full(
        (num_grid_rows, num_grid_columns), 0, dtype=int)

    for i in range(num_grid_rows):
        for j in range(num_grid_columns):
            this_eval_file_name = model_eval.find_file(
                directory_name=evaluation_dir_name,
                grid_row=i,
                grid_column=j,
                raise_error_if_missing=False)

            if not os.path.isfile(this_eval_file_name):
                warning_string = (
                    'Cannot find file (this may or may not be a problem).  '
                    'Expected at: "{0:s}"').format(this_eval_file_name)

                warnings.warn(warning_string)
                continue

            print('Reading data from: "{0:s}"...'.format(this_eval_file_name))
            this_evaluation_dict = model_eval.read_evaluation(
                this_eval_file_name)

            num_examples_matrix[i, j] = len(
                this_evaluation_dict[model_eval.OBSERVED_LABELS_KEY])
            num_positive_examples_matrix[i, j] = numpy.sum(
                this_evaluation_dict[model_eval.OBSERVED_LABELS_KEY])

            this_evaluation_table = this_evaluation_dict[
                model_eval.EVALUATION_TABLE_KEY]

            auc_matrix[i, j] = numpy.nanmean(
                this_evaluation_table[model_eval.AUC_KEY].values)
            csi_matrix[i, j] = numpy.nanmean(
                this_evaluation_table[model_eval.CSI_KEY].values)
            pod_matrix[i, j] = numpy.nanmean(
                this_evaluation_table[model_eval.POD_KEY].values)
            far_matrix[i, j] = 1. - numpy.nanmean(
                this_evaluation_table[model_eval.SUCCESS_RATIO_KEY].values)

    print(SEPARATOR_STRING)

    auc_matrix[num_positive_examples_matrix == 0] = numpy.nan
    csi_matrix[num_positive_examples_matrix == 0] = numpy.nan
    pod_matrix[num_positive_examples_matrix == 0] = numpy.nan
    far_matrix[num_positive_examples_matrix == 0] = numpy.nan

    if smoothing_radius_grid_cells is not None:
        print((
            'Applying Gaussian smoother with e-folding radius of {0:.1f} grid '
            'cells...').format(smoothing_radius_grid_cells))

        orig_num_examples_matrix = num_examples_matrix + 0
        num_examples_matrix = general_utils.apply_gaussian_filter(
            input_matrix=num_examples_matrix.astype(float),
            e_folding_radius_grid_cells=smoothing_radius_grid_cells)
        num_examples_matrix = numpy.round(num_examples_matrix).astype(int)
        num_examples_matrix[orig_num_examples_matrix == 0] = 0  # HACK

        num_positive_examples_matrix = general_utils.apply_gaussian_filter(
            input_matrix=num_positive_examples_matrix.astype(float),
            e_folding_radius_grid_cells=smoothing_radius_grid_cells)
        num_positive_examples_matrix = (
            numpy.round(num_positive_examples_matrix).astype(int))
        num_positive_examples_matrix[num_examples_matrix == 0] = 0

        auc_matrix = general_utils.apply_gaussian_filter(
            input_matrix=ge_utils.fill_nans(auc_matrix),
            e_folding_radius_grid_cells=smoothing_radius_grid_cells)
        csi_matrix = general_utils.apply_gaussian_filter(
            input_matrix=ge_utils.fill_nans(csi_matrix),
            e_folding_radius_grid_cells=smoothing_radius_grid_cells)
        pod_matrix = general_utils.apply_gaussian_filter(
            input_matrix=ge_utils.fill_nans(pod_matrix),
            e_folding_radius_grid_cells=smoothing_radius_grid_cells)
        far_matrix = general_utils.apply_gaussian_filter(
            input_matrix=ge_utils.fill_nans(far_matrix),
            e_folding_radius_grid_cells=smoothing_radius_grid_cells)

        auc_matrix[num_positive_examples_matrix == 0] = numpy.nan
        csi_matrix[num_positive_examples_matrix == 0] = numpy.nan
        pod_matrix[num_positive_examples_matrix == 0] = numpy.nan
        far_matrix[num_positive_examples_matrix == 0] = numpy.nan

    panel_file_names = []
    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    # Plot number of examples.
    this_data_matrix = numpy.maximum(numpy.log10(num_examples_matrix), 0.)
    this_data_matrix[this_data_matrix == 0] = numpy.nan
    max_colour_value = numpy.nanpercentile(this_data_matrix,
                                           max_colour_percentile)

    figure_object, axes_object = _plot_one_value(
        data_matrix=this_data_matrix,
        grid_metadata_dict=grid_metadata_dict,
        colour_map_object=num_ex_colour_map_object,
        min_colour_value=0.,
        max_colour_value=max_colour_value,
        plot_cbar_min_arrow=False,
        plot_cbar_max_arrow=True,
        log_scale=True)

    axes_object.set_title(r'Number of examples')
    plotting_utils.label_axes(axes_object=axes_object, label_string='(a)')

    panel_file_names.append('{0:s}/num_examples.jpg'.format(output_dir_name))
    print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1]))

    figure_object.savefig(panel_file_names[-1],
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)

    # Plot number of positive examples.
    this_data_matrix = num_positive_examples_matrix.astype(float)
    this_data_matrix[this_data_matrix == 0] = numpy.nan

    max_colour_value = numpy.nanpercentile(this_data_matrix,
                                           max_colour_percentile)
    min_colour_value = numpy.nanpercentile(this_data_matrix,
                                           100. - max_colour_percentile)

    figure_object, axes_object = _plot_one_value(
        data_matrix=this_data_matrix,
        grid_metadata_dict=grid_metadata_dict,
        colour_map_object=num_ex_colour_map_object,
        min_colour_value=min_colour_value,
        max_colour_value=max_colour_value,
        plot_cbar_min_arrow=True,
        plot_cbar_max_arrow=True)

    axes_object.set_title('Number of tornadic examples')
    plotting_utils.label_axes(axes_object=axes_object, label_string='(b)')

    panel_file_names.append(
        '{0:s}/num_positive_examples.jpg'.format(output_dir_name))
    print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1]))

    figure_object.savefig(panel_file_names[-1],
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)

    # Plot AUC.
    max_colour_value = numpy.nanpercentile(auc_matrix, max_colour_percentile)
    min_colour_value = numpy.maximum(
        numpy.nanpercentile(auc_matrix, 100. - max_colour_percentile), 0.5)

    figure_object, axes_object = _plot_one_value(
        data_matrix=auc_matrix,
        grid_metadata_dict=grid_metadata_dict,
        colour_map_object=score_colour_map_object,
        min_colour_value=min_colour_value,
        max_colour_value=max_colour_value,
        plot_cbar_min_arrow=True,
        plot_cbar_max_arrow=max_colour_value < 1.)

    axes_object.set_title('AUC (area under ROC curve)')
    plotting_utils.label_axes(axes_object=axes_object, label_string='(c)')

    panel_file_names.append('{0:s}/auc.jpg'.format(output_dir_name))
    print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1]))

    figure_object.savefig(panel_file_names[-1],
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)

    # Plot CSI.
    max_colour_value = numpy.nanpercentile(csi_matrix, max_colour_percentile)
    min_colour_value = numpy.nanpercentile(csi_matrix,
                                           100. - max_colour_percentile)

    figure_object, axes_object = _plot_one_value(
        data_matrix=csi_matrix,
        grid_metadata_dict=grid_metadata_dict,
        colour_map_object=score_colour_map_object,
        min_colour_value=min_colour_value,
        max_colour_value=max_colour_value,
        plot_cbar_min_arrow=min_colour_value > 0.,
        plot_cbar_max_arrow=max_colour_value < 1.)

    axes_object.set_title('CSI (critical success index)')
    plotting_utils.label_axes(axes_object=axes_object, label_string='(d)')

    panel_file_names.append('{0:s}/csi.jpg'.format(output_dir_name))
    print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1]))

    figure_object.savefig(panel_file_names[-1],
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)

    # Plot POD.
    max_colour_value = numpy.nanpercentile(pod_matrix, max_colour_percentile)
    min_colour_value = numpy.nanpercentile(pod_matrix,
                                           100. - max_colour_percentile)

    figure_object, axes_object = _plot_one_value(
        data_matrix=pod_matrix,
        grid_metadata_dict=grid_metadata_dict,
        colour_map_object=score_colour_map_object,
        min_colour_value=min_colour_value,
        max_colour_value=max_colour_value,
        plot_cbar_min_arrow=min_colour_value > 0.,
        plot_cbar_max_arrow=max_colour_value < 1.)

    axes_object.set_title('POD (probability of detection)')
    plotting_utils.label_axes(axes_object=axes_object, label_string='(e)')

    panel_file_names.append('{0:s}/pod.jpg'.format(output_dir_name))
    print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1]))

    figure_object.savefig(panel_file_names[-1],
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)

    # Plot FAR.
    max_colour_value = numpy.nanpercentile(far_matrix, max_colour_percentile)
    min_colour_value = numpy.nanpercentile(far_matrix,
                                           100. - max_colour_percentile)

    figure_object, axes_object = _plot_one_value(
        data_matrix=far_matrix,
        grid_metadata_dict=grid_metadata_dict,
        colour_map_object=score_colour_map_object,
        min_colour_value=min_colour_value,
        max_colour_value=max_colour_value,
        plot_cbar_min_arrow=min_colour_value > 0.,
        plot_cbar_max_arrow=max_colour_value < 1.)

    axes_object.set_title('FAR (false-alarm ratio)')
    plotting_utils.label_axes(axes_object=axes_object, label_string='(f)')

    panel_file_names.append('{0:s}/far.jpg'.format(output_dir_name))
    print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1]))

    figure_object.savefig(panel_file_names[-1],
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)

    # Concatenate panels.
    concat_file_name = '{0:s}/spatially_subset_evaluation.jpg'.format(
        output_dir_name)
    print('Concatenating panels to: "{0:s}"...'.format(concat_file_name))

    imagemagick_utils.concatenate_images(input_file_names=panel_file_names,
                                         output_file_name=concat_file_name,
                                         num_panel_rows=NUM_PANEL_ROWS,
                                         num_panel_columns=NUM_PANEL_COLUMNS)

    imagemagick_utils.resize_image(input_file_name=concat_file_name,
                                   output_file_name=concat_file_name,
                                   output_size_pixels=CONCAT_FIGURE_SIZE_PX)
Example #27
0
def _add_colour_bar(figure_file_name, colour_map_object, max_colour_value,
                    temporary_dir_name):
    """Adds colour bar to saved image file.

    :param figure_file_name: Path to saved image file.  Colour bar will be added
        to this image.
    :param colour_map_object: Colour scheme (instance of `matplotlib.pyplot.cm`
        or similar).
    :param max_colour_value: Max value in colour scheme.
    :param temporary_dir_name: Name of temporary output directory.
    """

    this_image_matrix = Image.open(figure_file_name)
    figure_width_px, figure_height_px = this_image_matrix.size
    figure_width_inches = float(figure_width_px) / FIGURE_RESOLUTION_DPI
    figure_height_inches = float(figure_height_px) / FIGURE_RESOLUTION_DPI

    extra_figure_object, extra_axes_object = pyplot.subplots(
        1, 1, figsize=(figure_width_inches, figure_height_inches))
    extra_axes_object.axis('off')

    dummy_values = numpy.array([0., max_colour_value])

    colour_bar_object = plotting_utils.plot_linear_colour_bar(
        axes_object_or_matrix=extra_axes_object,
        data_matrix=dummy_values,
        colour_map_object=colour_map_object,
        min_value=0.,
        max_value=max_colour_value,
        orientation_string='vertical',
        fraction_of_axis_length=1.25,
        extend_min=False,
        extend_max=True,
        font_size=COLOUR_BAR_FONT_SIZE,
        aspect_ratio=50.)

    tick_values = colour_bar_object.get_ticks()

    if max_colour_value <= 0.005:
        tick_strings = ['{0:.4f}'.format(v) for v in tick_values]
    elif max_colour_value <= 0.05:
        tick_strings = ['{0:.3f}'.format(v) for v in tick_values]
    else:
        tick_strings = ['{0:.2f}'.format(v) for v in tick_values]

    colour_bar_object.set_ticks(tick_values)
    colour_bar_object.set_ticklabels(tick_strings)

    extra_file_name = '{0:s}/saliency_colour-bar.jpg'.format(
        temporary_dir_name)
    print('Saving colour bar to: "{0:s}"...'.format(extra_file_name))

    extra_figure_object.savefig(extra_file_name,
                                dpi=FIGURE_RESOLUTION_DPI,
                                pad_inches=0,
                                bbox_inches='tight')
    pyplot.close(extra_figure_object)

    print('Concatenating colour bar to: "{0:s}"...'.format(figure_file_name))

    imagemagick_utils.concatenate_images(
        input_file_names=[figure_file_name, extra_file_name],
        output_file_name=figure_file_name,
        num_panel_rows=1,
        num_panel_columns=2,
        extra_args_string='-gravity Center')

    os.remove(extra_file_name)
    imagemagick_utils.trim_whitespace(input_file_name=figure_file_name,
                                      output_file_name=figure_file_name)
Example #28
0
def _run():
    """Plots conversion of gridded probabilities into objects.

    This is effectively the main method.
    """

    prediction_dict = ml_utils.read_gridded_predictions(PREDICTION_FILE_NAME)
    class_probability_matrix = prediction_dict[ml_utils.PROBABILITY_MATRIX_KEY]

    for this_id in front_utils.VALID_INTEGER_IDS:
        if this_id == front_utils.NO_FRONT_INTEGER_ID:
            class_probability_matrix[..., this_id][numpy.isnan(
                class_probability_matrix[..., this_id])] = 1.
        else:
            class_probability_matrix[..., this_id][numpy.isnan(
                class_probability_matrix[..., this_id])] = 0.

    predicted_label_matrix = object_eval.determinize_probabilities(
        class_probability_matrix=class_probability_matrix,
        binarization_threshold=BINARIZATION_THRESHOLD)

    _plot_predictions(predicted_label_matrix=predicted_label_matrix,
                      title_string='All frontal regions',
                      annotation_string='(b)',
                      output_file_name=ALL_REGIONS_FILE_NAME)

    valid_time_unix_sec = time_conversion.string_to_unix_sec(
        VALID_TIME_STRING, TIME_FORMAT)
    valid_times_unix_sec = numpy.array([valid_time_unix_sec], dtype=int)
    predicted_region_table = object_eval.images_to_regions(
        predicted_label_matrix=predicted_label_matrix,
        image_times_unix_sec=valid_times_unix_sec)

    num_grid_rows, num_grid_columns = nwp_model_utils.get_grid_dimensions(
        model_name=nwp_model_utils.NARR_MODEL_NAME)
    grid_spacing_metres = nwp_model_utils.get_xy_grid_spacing(
        model_name=nwp_model_utils.NARR_MODEL_NAME)[0]

    predicted_region_table = object_eval.discard_regions_with_small_area(
        predicted_region_table=predicted_region_table,
        x_grid_spacing_metres=grid_spacing_metres,
        y_grid_spacing_metres=grid_spacing_metres,
        min_area_metres2=MIN_REGION_AREA_METRES2)
    predicted_label_matrix = object_eval.regions_to_images(
        predicted_region_table=predicted_region_table,
        num_grid_rows=num_grid_rows,
        num_grid_columns=num_grid_columns)

    _plot_predictions(predicted_label_matrix=predicted_label_matrix,
                      title_string='Large frontal regions',
                      annotation_string='(c)',
                      output_file_name=LARGE_REGIONS_FILE_NAME)

    predicted_region_table = object_eval.skeletonize_frontal_regions(
        predicted_region_table=predicted_region_table,
        num_grid_rows=num_grid_rows,
        num_grid_columns=num_grid_columns)
    predicted_label_matrix = object_eval.regions_to_images(
        predicted_region_table=predicted_region_table,
        num_grid_rows=num_grid_rows,
        num_grid_columns=num_grid_columns)

    _plot_predictions(predicted_label_matrix=predicted_label_matrix,
                      title_string='All skeleton lines',
                      annotation_string='(d)',
                      output_file_name=ALL_SKELETONS_FILE_NAME)

    predicted_region_table = object_eval.find_main_skeletons(
        predicted_region_table=predicted_region_table,
        image_times_unix_sec=valid_times_unix_sec,
        num_grid_rows=num_grid_rows,
        num_grid_columns=num_grid_columns,
        x_grid_spacing_metres=grid_spacing_metres,
        y_grid_spacing_metres=grid_spacing_metres,
        min_endpoint_length_metres=MIN_ENDPOINT_LENGTH_METRES)

    predicted_label_matrix = object_eval.regions_to_images(
        predicted_region_table=predicted_region_table,
        num_grid_rows=num_grid_rows,
        num_grid_columns=num_grid_columns)

    _plot_predictions(predicted_label_matrix=predicted_label_matrix,
                      title_string='Main skeleton lines',
                      annotation_string='(e)',
                      output_file_name=MAIN_SKELETONS_FILE_NAME)

    print 'Concatenating figures to: "{0:s}"...'.format(CONCAT_FILE_NAME)

    panel_file_names = [
        PROBABILITY_FILE_NAME, ALL_REGIONS_FILE_NAME, LARGE_REGIONS_FILE_NAME,
        ALL_SKELETONS_FILE_NAME, MAIN_SKELETONS_FILE_NAME
    ]

    imagemagick_utils.concatenate_images(input_file_names=panel_file_names,
                                         output_file_name=CONCAT_FILE_NAME,
                                         num_panel_rows=2,
                                         num_panel_columns=3)

    imagemagick_utils.resize_image(input_file_name=CONCAT_FILE_NAME,
                                   output_file_name=CONCAT_FILE_NAME,
                                   output_size_pixels=CONCAT_SIZE_PIXELS)
        file_name=AFTER_POOLING_FILE_NAME)
    pyplot.savefig(AFTER_POOLING_FILE_NAME, dpi=OUTPUT_RESOLUTION_DPI)
    pyplot.close()

    imagemagick_utils.trim_whitespace(input_file_name=AFTER_POOLING_FILE_NAME,
                                      output_file_name=AFTER_POOLING_FILE_NAME)

    return feature_matrix


if __name__ == '__main__':
    FEATURE_MATRIX = _plot_feature_map_before_conv()
    KERNEL_MATRIX = _plot_kernel()

    FEATURE_MATRIX = _do_convolution(feature_matrix=FEATURE_MATRIX,
                                     kernel_matrix=KERNEL_MATRIX)
    _plot_feature_map_after_conv(FEATURE_MATRIX)

    FEATURE_MATRIX = _do_max_pooling(FEATURE_MATRIX)
    _plot_feature_map_after_pooling(FEATURE_MATRIX)

    print 'Concatenating figures to: "{0:s}"...'.format(CONCAT_FILE_NAME)
    imagemagick_utils.concatenate_images(input_file_names=[
        BEFORE_CONV_FILE_NAME, KERNEL_FILE_NAME, AFTER_POOLING_FILE_NAME,
        AFTER_CONV_FILE_NAME
    ],
                                         output_file_name=CONCAT_FILE_NAME,
                                         num_panel_rows=2,
                                         num_panel_columns=2,
                                         output_size_pixels=OUTPUT_SIZE_PIXELS)
def _run():
    """Plots weird WPC fronts, along with theta_w and wind barbs from NARR.
    This is effectively the main method.
    """

    narr_latitude_matrix_deg, narr_longitude_matrix_deg = (
        nwp_model_utils.get_latlng_grid_point_matrices(
            model_name=nwp_model_utils.NARR_MODEL_NAME))

    narr_rotation_cos_matrix, narr_rotation_sin_matrix = (
        nwp_model_utils.get_wind_rotation_angles(
            latitudes_deg=narr_latitude_matrix_deg,
            longitudes_deg=narr_longitude_matrix_deg,
            model_name=nwp_model_utils.NARR_MODEL_NAME))

    num_panels = len(VALID_TIME_STRINGS)
    panel_file_names = [''] * num_panels
    this_annotation_string = None

    for i in range(num_panels):
        this_time_unix_sec = time_conversion.string_to_unix_sec(
            VALID_TIME_STRINGS[i], DEFAULT_TIME_FORMAT)
        this_title_string = time_conversion.unix_sec_to_string(
            this_time_unix_sec, NICE_TIME_FORMAT)

        if PRESSURE_LEVELS_MB[i] == 1000:
            this_title_string += ' at 1000 mb'
        else:
            this_title_string += ' at surface'

        if this_annotation_string is None:
            this_annotation_string = '(a)'
        else:
            this_orig_character = this_annotation_string[1]
            this_new_character = chr(ord(this_orig_character) + 1)
            this_annotation_string = this_annotation_string.replace(
                this_orig_character, this_new_character)

        this_file_name = _plot_one_time(
            valid_time_string=VALID_TIME_STRINGS[i],
            pressure_level_mb=PRESSURE_LEVELS_MB[i],
            title_string=this_title_string,
            annotation_string=this_annotation_string,
            narr_rotation_cos_matrix=narr_rotation_cos_matrix,
            narr_rotation_sin_matrix=narr_rotation_sin_matrix)

        panel_file_names[i] = this_file_name
        print '\n'

    concat_file_name = '{0:s}/weird_fronts.jpg'.format(OUTPUT_DIR_NAME)

    print 'Concatenating figures to: "{0:s}"...'.format(concat_file_name)

    num_panels = len(panel_file_names)
    num_panel_columns = int(numpy.ceil(float(num_panels) / 2))

    imagemagick_utils.concatenate_images(input_file_names=panel_file_names,
                                         output_file_name=concat_file_name,
                                         num_panel_rows=NUM_PANEL_ROWS,
                                         num_panel_columns=num_panel_columns)

    imagemagick_utils.trim_whitespace(input_file_name=concat_file_name,
                                      output_file_name=concat_file_name)

    imagemagick_utils.resize_image(input_file_name=concat_file_name,
                                   output_file_name=concat_file_name,
                                   output_size_pixels=CONCAT_SIZE_PIXELS)