def _plot_scores_as_grid(
        score_matrix, colour_map_object, min_colour_value, max_colour_value,
        x_tick_labels, x_axis_label, x_axis_text_colour, y_tick_labels,
        y_axis_label, y_axis_text_colour, title_string, output_file_name):
    """Plots model scores as 2-D grid.

    M = number of rows in grid
    N = number of columns in grid

    :param score_matrix: M-by-N numpy array of model scores.
    :param colour_map_object: Instance of `matplotlib.colors.ListedColormap`.
    :param min_colour_value: Minimum value in colour map.
    :param max_colour_value: Max value in colour map.
    :param x_tick_labels: length-N list of string labels.
    :param x_axis_label: String label for the entire x-axis.
    :param x_axis_text_colour: Colour for all text labels along x-axis.
    :param y_tick_labels: length-M list of string labels.
    :param y_axis_label: String label for the entire y-axis.
    :param y_axis_text_colour: Colour for all text labels along y-axis.
    :param title_string: Figure title.
    :param output_file_name: Path to output file (the figure will be saved
        here).
    """

    _, axes_object = pyplot.subplots(
        1, 1, figsize=(FIGURE_WIDTH_INCHES, FIGURE_HEIGHT_INCHES))

    score_matrix_to_plot = score_matrix + 0.
    score_matrix_to_plot[numpy.isnan(score_matrix_to_plot)] = 0.
    pyplot.imshow(
        score_matrix_to_plot, cmap=colour_map_object, origin='lower',
        vmin=min_colour_value, vmax=max_colour_value)

    x_tick_values = numpy.linspace(
        0, score_matrix_to_plot.shape[1] - 1,
        num=score_matrix_to_plot.shape[1], dtype=float)
    pyplot.xticks(x_tick_values, x_tick_labels, color=x_axis_text_colour)
    pyplot.xlabel(x_axis_label, color=x_axis_text_colour)

    y_tick_values = numpy.linspace(
        0, score_matrix_to_plot.shape[0] - 1,
        num=score_matrix_to_plot.shape[0], dtype=float)
    pyplot.yticks(y_tick_values, y_tick_labels, color=y_axis_text_colour)
    pyplot.ylabel(y_axis_label, color=y_axis_text_colour)

    pyplot.title(title_string)
    plotting_utils.add_linear_colour_bar(
        axes_object_or_list=axes_object,
        values_to_colour=score_matrix_to_plot,
        colour_map=colour_map_object, colour_min=min_colour_value,
        colour_max=max_colour_value, orientation='vertical',
        extend_min=True, extend_max=True, font_size=FONT_SIZE)

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

    imagemagick_utils.trim_whitespace(
        input_file_name=output_file_name, output_file_name=output_file_name)
Exemple #2
0
def _plot_locating_variable(
        locating_var_matrix_m01_s01, title_string, annotation_string,
        output_file_name):
    """Plots locating variable.

    M = number of rows in grid
    N = number of columns in grid

    :param locating_var_matrix_m01_s01: M-by-N numpy array with values of
        locating variable.
    :param title_string: Title (will be placed above figure).
    :param annotation_string: Text annotation (will be placed in top left of
    figure).
    :param output_file_name: Path to output file (figure will be saved here).
    """

    (narr_row_limits, narr_column_limits, axes_object, basemap_object
    ) = _init_basemap(BORDER_COLOUR)

    matrix_to_plot = locating_var_matrix_m01_s01[
        narr_row_limits[0]:(narr_row_limits[1] + 1),
        narr_column_limits[0]:(narr_column_limits[1] + 1)
    ] * LOCATING_VAR_MULTIPLIER

    max_colour_value = numpy.nanpercentile(
        numpy.absolute(matrix_to_plot), MAX_COLOUR_PERCENTILE)
    min_colour_value = -1 * max_colour_value

    nwp_plotting.plot_subgrid(
        field_matrix=matrix_to_plot,
        model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object,
        basemap_object=basemap_object,
        colour_map=LOCATING_VAR_COLOUR_MAP_OBJECT,
        min_value_in_colour_map=min_colour_value,
        max_value_in_colour_map=max_colour_value,
        first_row_in_full_grid=narr_row_limits[0],
        first_column_in_full_grid=narr_column_limits[0])

    plotting_utils.add_linear_colour_bar(
        axes_object_or_list=axes_object,
        values_to_colour=matrix_to_plot,
        colour_map=LOCATING_VAR_COLOUR_MAP_OBJECT, colour_min=min_colour_value,
        colour_max=max_colour_value, orientation='vertical', extend_min=True,
        extend_max=True, fraction_of_axis_length=COLOUR_BAR_LENGTH_FRACTION)

    pyplot.title(title_string)
    plotting_utils.annotate_axes(
        axes_object=axes_object, annotation_string=annotation_string)

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

    imagemagick_utils.trim_whitespace(input_file_name=output_file_name,
                                      output_file_name=output_file_name)
Exemple #3
0
def _plot_feature_maps_one_layer(feature_matrix, layer_name, output_dir_name):
    """Plots all feature maps for one layer.

    E = number of examples
    M = number of spatial rows
    N = number of spatial columns
    C = number of channels

    :param feature_matrix: E-by-M-by-N-by-C numpy array of feature values.
    :param layer_name: Name of layer that output feature values.
    :param output_dir_name: Name of output directory for this layer.
    """

    num_examples = feature_matrix.shape[0]
    num_channels = feature_matrix.shape[-1]

    num_panel_rows = int(numpy.round(numpy.sqrt(num_channels)))
    annotation_string_by_channel = [None] * num_channels

    # annotation_string_by_channel = [
    #     'Filter {0:d}'.format(c + 1) for c in range(num_channels)
    # ]

    max_colour_value = numpy.percentile(numpy.absolute(feature_matrix), 99)
    min_colour_value = -1 * max_colour_value

    for i in range(num_examples):
        _, these_axes_objects = (
            feature_map_plotting.plot_many_2d_feature_maps(
                feature_matrix=feature_matrix[i, 2:-2, 2:-2, ...],
                annotation_string_by_panel=annotation_string_by_channel,
                num_panel_rows=num_panel_rows,
                colour_map_object=pyplot.cm.seismic,
                min_colour_value=min_colour_value,
                max_colour_value=max_colour_value))

        plotting_utils.add_linear_colour_bar(
            axes_object_or_list=these_axes_objects,
            values_to_colour=feature_matrix[i, ...],
            colour_map=pyplot.cm.seismic,
            colour_min=min_colour_value,
            colour_max=max_colour_value,
            orientation='horizontal',
            extend_min=True,
            extend_max=True)

        # this_title_string = 'Layer "{0:s}", example {1:d}'.format(layer_name, i)
        # pyplot.suptitle(this_title_string, fontsize=TITLE_FONT_SIZE)

        this_figure_file_name = '{0:s}/example{1:06d}.jpg'.format(
            output_dir_name, i)

        print 'Saving figure to: "{0:s}"...'.format(this_figure_file_name)
        pyplot.savefig(this_figure_file_name, dpi=FIGURE_RESOLUTION_DPI)
        pyplot.close()
Exemple #4
0
def _plot_temperature_grid(temperature_matrix_kelvins):
    """Plots temperature grid as colour map.

    M = number of rows in grid
    N = number of columns in grid

    :param temperature_matrix_kelvins: M-by-N numpy array of temperatures.
    :return: axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    """

    (edge_temperature_matrix_kelvins, edge_x_coords_metres,
     edge_y_coords_metres) = grids.xy_field_grid_points_to_edges(
         field_matrix=temperature_matrix_kelvins,
         x_min_metres=0.,
         y_min_metres=0.,
         x_spacing_metres=1.,
         y_spacing_metres=1.)

    _, axes_object = pyplot.subplots(1,
                                     1,
                                     figsize=(FIGURE_WIDTH_INCHES,
                                              FIGURE_HEIGHT_INCHES))

    pyplot.pcolormesh(edge_x_coords_metres,
                      edge_y_coords_metres,
                      edge_temperature_matrix_kelvins,
                      cmap=_create_colour_scheme(temperature_matrix_kelvins),
                      vmin=numpy.min(temperature_matrix_kelvins),
                      vmax=numpy.max(temperature_matrix_kelvins),
                      shading='flat',
                      edgecolors='None',
                      axes=axes_object)

    colour_bar_object = plotting_utils.add_linear_colour_bar(
        axes_object_or_list=axes_object,
        values_to_colour=temperature_matrix_kelvins,
        colour_map=_create_colour_scheme(temperature_matrix_kelvins),
        colour_min=numpy.min(temperature_matrix_kelvins),
        colour_max=numpy.max(temperature_matrix_kelvins),
        orientation='vertical',
        extend_min=False,
        extend_max=False)

    colour_bar_object.set_ticks([])
    colour_bar_object.set_label(r'Thermal variable ($\tau$)')

    pyplot.xticks([], [])
    pyplot.yticks([], [])
    return axes_object
def _plot_one_time(
        predictor_matrix, predictor_names, front_polyline_table, high_low_table,
        thermal_colour_map_object, max_thermal_prctile_for_colours,
        narr_row_limits, narr_column_limits, title_string, letter_label,
        output_file_name):
    """Plots predictors at one time.

    M = number of rows in grid
    N = number of columns in grid
    C = number of channels (predictors)

    :param predictor_matrix: M-by-N-by-C numpy array of predictor values.
    :param predictor_names: length-C list of predictor names.
    :param front_polyline_table: pandas DataFrame returned by
        `fronts_io.read_polylines_from_file`.
    :param high_low_table: pandas DataFrame returned by
        `wpc_bulletin_io.read_highs_and_lows`.
    :param thermal_colour_map_object: See documentation at top of file.
    :param max_thermal_prctile_for_colours: Same.
    :param narr_row_limits: length-2 numpy array, indicating the first and last
        NARR rows in `predictor_matrix`.  If narr_row_limits = [i, k],
        `predictor_matrix` spans rows i...k of the full NARR grid.
    :param narr_column_limits: Same but for columns.
    :param title_string: Title (will be placed above figure).
    :param letter_label: Letter label.  If this is "a", the label "(a)" will be
        printed at the top left of the figure.
    :param output_file_name: Path to output file (figure will be saved here).
    """

    _, axes_object, basemap_object = nwp_plotting.init_basemap(
        model_name=nwp_model_utils.NARR_MODEL_NAME,
        first_row_in_full_grid=narr_row_limits[0],
        last_row_in_full_grid=narr_row_limits[1],
        first_column_in_full_grid=narr_column_limits[0],
        last_column_in_full_grid=narr_column_limits[1]
    )

    plotting_utils.plot_coastlines(
        basemap_object=basemap_object, axes_object=axes_object,
        line_colour=BORDER_COLOUR
    )
    plotting_utils.plot_countries(
        basemap_object=basemap_object, axes_object=axes_object,
        line_colour=BORDER_COLOUR
    )
    plotting_utils.plot_states_and_provinces(
        basemap_object=basemap_object, axes_object=axes_object,
        line_colour=BORDER_COLOUR
    )
    plotting_utils.plot_parallels(
        basemap_object=basemap_object, axes_object=axes_object,
        bottom_left_lat_deg=-90., upper_right_lat_deg=90.,
        parallel_spacing_deg=PARALLEL_SPACING_DEG
    )
    plotting_utils.plot_meridians(
        basemap_object=basemap_object, axes_object=axes_object,
        bottom_left_lng_deg=0., upper_right_lng_deg=360.,
        meridian_spacing_deg=MERIDIAN_SPACING_DEG
    )

    num_predictors = len(predictor_names)
    for j in range(num_predictors):
        if predictor_names[j] in WIND_FIELD_NAMES:
            continue

        min_colour_value = numpy.percentile(
            predictor_matrix[..., j], 100. - max_thermal_prctile_for_colours)
        max_colour_value = numpy.percentile(
            predictor_matrix[..., j], max_thermal_prctile_for_colours)

        nwp_plotting.plot_subgrid(
            field_matrix=predictor_matrix[..., j],
            model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object,
            basemap_object=basemap_object, colour_map=thermal_colour_map_object,
            min_value_in_colour_map=min_colour_value,
            max_value_in_colour_map=max_colour_value,
            first_row_in_full_grid=narr_row_limits[0],
            first_column_in_full_grid=narr_column_limits[0]
        )

        plotting_utils.add_linear_colour_bar(
            axes_object_or_list=axes_object,
            values_to_colour=predictor_matrix[..., j],
            colour_map=thermal_colour_map_object, colour_min=min_colour_value,
            colour_max=max_colour_value, orientation='horizontal',
            extend_min=True, extend_max=True, fraction_of_axis_length=0.9)

    u_wind_index = predictor_names.index(
        processed_narr_io.U_WIND_GRID_RELATIVE_NAME)
    v_wind_index = predictor_names.index(
        processed_narr_io.V_WIND_GRID_RELATIVE_NAME)

    nwp_plotting.plot_wind_barbs_on_subgrid(
        u_wind_matrix_m_s01=predictor_matrix[..., u_wind_index],
        v_wind_matrix_m_s01=predictor_matrix[..., v_wind_index],
        model_name=nwp_model_utils.NARR_MODEL_NAME,
        axes_object=axes_object, basemap_object=basemap_object,
        first_row_in_full_grid=narr_row_limits[0],
        first_column_in_full_grid=narr_column_limits[0],
        plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB,
        plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB,
        barb_length=WIND_BARB_LENGTH, empty_barb_radius=EMPTY_WIND_BARB_RADIUS,
        fill_empty_barb=False, colour_map=WIND_COLOUR_MAP_OBJECT,
        colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT,
        colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT)

    if high_low_table is None:
        num_pressure_systems = 0
    else:
        num_pressure_systems = len(high_low_table.index)

    for i in range(num_pressure_systems):
        this_system_type_string = high_low_table[
            wpc_bulletin_io.SYSTEM_TYPE_COLUMN].values[i]

        if this_system_type_string == wpc_bulletin_io.HIGH_PRESSURE_STRING:
            this_string = 'H'
        else:
            this_string = 'L'

        this_x_coord_metres, this_y_coord_metres = basemap_object(
            high_low_table[wpc_bulletin_io.LONGITUDE_COLUMN].values[i],
            high_low_table[wpc_bulletin_io.LATITUDE_COLUMN].values[i]
        )

        axes_object.text(
            this_x_coord_metres, this_y_coord_metres, this_string,
            fontsize=PRESSURE_SYSTEM_FONT_SIZE, color=PRESSURE_SYSTEM_COLOUR,
            fontweight='bold', horizontalalignment='center',
            verticalalignment='center')

    num_fronts = len(front_polyline_table.index)

    for i in range(num_fronts):
        this_front_type_string = front_polyline_table[
            front_utils.FRONT_TYPE_COLUMN].values[i]

        if this_front_type_string == front_utils.WARM_FRONT_STRING_ID:
            this_colour = WARM_FRONT_COLOUR
        else:
            this_colour = COLD_FRONT_COLOUR

        front_plotting.plot_front_with_markers(
            line_latitudes_deg=front_polyline_table[
                front_utils.LATITUDES_COLUMN].values[i],
            line_longitudes_deg=front_polyline_table[
                front_utils.LONGITUDES_COLUMN].values[i],
            axes_object=axes_object, basemap_object=basemap_object,
            front_type_string=front_polyline_table[
                front_utils.FRONT_TYPE_COLUMN].values[i],
            marker_colour=this_colour)

    pyplot.title(title_string)

    if letter_label is not None:
        plotting_utils.annotate_axes(
            axes_object=axes_object,
            annotation_string='({0:s})'.format(letter_label)
        )

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

    imagemagick_utils.trim_whitespace(input_file_name=output_file_name,
                                      output_file_name=output_file_name)
Exemple #6
0
def _run():
    """Plots input example.

    This is effectively the main method.

    :return: figure_file_name: Path to output file (where the figure was saved).
    """

    valid_time_unix_sec = time_conversion.string_to_unix_sec(
        VALID_TIME_STRING, TIME_FORMAT)
    front_file_name = fronts_io.find_file_for_one_time(
        top_directory_name=TOP_FRONT_DIR_NAME,
        file_type=fronts_io.POLYLINE_FILE_TYPE,
        valid_time_unix_sec=valid_time_unix_sec)

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

    num_narr_fields = len(NARR_FIELD_NAMES)
    narr_matrix_by_field = [numpy.array([])] * num_narr_fields

    for j in range(num_narr_fields):
        if NARR_FIELD_NAMES[j] in WIND_FIELD_NAMES:
            this_directory_name = '{0:s}/earth_relative_wind'.format(
                TOP_NARR_DIRECTORY_NAME)
        else:
            this_directory_name = TOP_NARR_DIRECTORY_NAME + ''

        this_file_name = processed_narr_io.find_file_for_one_time(
            top_directory_name=this_directory_name,
            field_name=NARR_FIELD_NAMES[j],
            pressure_level_mb=PRESSURE_LEVEL_MB,
            valid_time_unix_sec=valid_time_unix_sec)

        print 'Reading data from: "{0:s}"...'.format(this_file_name)
        narr_matrix_by_field[j] = processed_narr_io.read_fields_from_file(
            this_file_name)[0][0, ...]
        narr_matrix_by_field[j] = utils.fill_nans(narr_matrix_by_field[j])

        if NARR_FIELD_NAMES[j] == processed_narr_io.WET_BULB_THETA_NAME:
            narr_matrix_by_field[j] = (narr_matrix_by_field[j] -
                                       ZERO_CELSIUS_IN_KELVINS)

    # (_, front_centroid_latitude_deg, front_centroid_longitude_deg
    # ) = _find_nearest_front(
    #     front_line_table=front_line_table,
    #     query_latitude_deg=APPROX_FRONT_LATITUDE_DEG,
    #     query_longitude_deg=APPROX_FRONT_LONGITUDE_DEG)

    front_centroid_latitude_deg = APPROX_FRONT_LATITUDE_DEG + 0.
    front_centroid_longitude_deg = APPROX_FRONT_LONGITUDE_DEG + 0.

    projection_object = nwp_model_utils.init_model_projection(
        nwp_model_utils.NARR_MODEL_NAME)
    these_x_metres, these_y_metres = nwp_model_utils.project_latlng_to_xy(
        latitudes_deg=numpy.array([front_centroid_latitude_deg]),
        longitudes_deg=numpy.array([front_centroid_longitude_deg]),
        projection_object=projection_object,
        model_name=nwp_model_utils.NARR_MODEL_NAME)

    front_centroid_x_metres = these_x_metres[0]
    front_centroid_y_metres = these_y_metres[0]

    grid_spacing_metres, _ = nwp_model_utils.get_xy_grid_spacing(
        model_name=nwp_model_utils.NARR_MODEL_NAME)
    center_narr_row_index = int(
        numpy.round(front_centroid_y_metres / grid_spacing_metres))
    center_narr_column_index = int(
        numpy.round(front_centroid_x_metres / grid_spacing_metres))

    first_narr_row_index = center_narr_row_index - NUM_ROWS_IN_HALF_GRID
    last_narr_row_index = center_narr_row_index + NUM_ROWS_IN_HALF_GRID
    first_narr_column_index = (center_narr_column_index -
                               NUM_COLUMNS_IN_HALF_GRID)
    last_narr_column_index = center_narr_column_index + NUM_COLUMNS_IN_HALF_GRID

    for j in range(num_narr_fields):
        narr_matrix_by_field[j] = narr_matrix_by_field[j][
            first_narr_row_index:(last_narr_row_index + 1),
            first_narr_column_index:(last_narr_column_index + 1)]

    _, axes_object, basemap_object = nwp_plotting.init_basemap(
        model_name=nwp_model_utils.NARR_MODEL_NAME,
        first_row_in_full_grid=first_narr_row_index,
        last_row_in_full_grid=last_narr_row_index,
        first_column_in_full_grid=first_narr_column_index,
        last_column_in_full_grid=last_narr_column_index,
        resolution_string='i')

    plotting_utils.plot_coastlines(basemap_object=basemap_object,
                                   axes_object=axes_object,
                                   line_colour=BORDER_COLOUR)
    plotting_utils.plot_countries(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  line_colour=BORDER_COLOUR)
    plotting_utils.plot_states_and_provinces(basemap_object=basemap_object,
                                             axes_object=axes_object,
                                             line_colour=BORDER_COLOUR)
    plotting_utils.plot_parallels(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  bottom_left_lat_deg=-90.,
                                  upper_right_lat_deg=90.,
                                  parallel_spacing_deg=PARALLEL_SPACING_DEG)
    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  bottom_left_lng_deg=0.,
                                  upper_right_lng_deg=360.,
                                  meridian_spacing_deg=MERIDIAN_SPACING_DEG)

    for j in range(num_narr_fields):
        if NARR_FIELD_NAMES[j] in WIND_FIELD_NAMES:
            continue

        min_colour_value = numpy.percentile(narr_matrix_by_field[j],
                                            MIN_COLOUR_PERCENTILE)
        max_colour_value = numpy.percentile(narr_matrix_by_field[j],
                                            MAX_COLOUR_PERCENTILE)

        nwp_plotting.plot_subgrid(
            field_matrix=narr_matrix_by_field[j],
            model_name=nwp_model_utils.NARR_MODEL_NAME,
            axes_object=axes_object,
            basemap_object=basemap_object,
            colour_map=THERMAL_COLOUR_MAP_OBJECT,
            min_value_in_colour_map=min_colour_value,
            max_value_in_colour_map=max_colour_value,
            first_row_in_full_grid=first_narr_row_index,
            first_column_in_full_grid=first_narr_column_index)

        plotting_utils.add_linear_colour_bar(
            axes_object_or_list=axes_object,
            values_to_colour=narr_matrix_by_field[j],
            colour_map=THERMAL_COLOUR_MAP_OBJECT,
            colour_min=min_colour_value,
            colour_max=max_colour_value,
            orientation='horizontal',
            extend_min=True,
            extend_max=True)

    u_wind_index = NARR_FIELD_NAMES.index(
        processed_narr_io.U_WIND_EARTH_RELATIVE_NAME)
    v_wind_index = NARR_FIELD_NAMES.index(
        processed_narr_io.V_WIND_EARTH_RELATIVE_NAME)

    nwp_plotting.plot_wind_barbs_on_subgrid(
        u_wind_matrix_m_s01=narr_matrix_by_field[u_wind_index],
        v_wind_matrix_m_s01=narr_matrix_by_field[v_wind_index],
        model_name=nwp_model_utils.NARR_MODEL_NAME,
        axes_object=axes_object,
        basemap_object=basemap_object,
        first_row_in_full_grid=first_narr_row_index,
        first_column_in_full_grid=first_narr_column_index,
        plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB,
        plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB,
        barb_length=WIND_BARB_LENGTH,
        empty_barb_radius=EMPTY_WIND_BARB_RADIUS,
        colour_map=WIND_COLOUR_MAP_OBJECT,
        colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT,
        colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT)

    num_fronts = len(front_line_table.index)
    for i in range(num_fronts):
        this_front_type_string = front_line_table[
            front_utils.FRONT_TYPE_COLUMN].values[i]
        if this_front_type_string == front_utils.WARM_FRONT_STRING_ID:
            this_colour = WARM_FRONT_COLOUR
        else:
            this_colour = COLD_FRONT_COLOUR

        # front_plotting.plot_polyline(
        #     latitudes_deg=front_line_table[
        #         front_utils.LATITUDES_COLUMN].values[i],
        #     longitudes_deg=front_line_table[
        #         front_utils.LONGITUDES_COLUMN].values[i],
        #     basemap_object=basemap_object, axes_object=axes_object,
        #     front_type=front_line_table[
        #         front_utils.FRONT_TYPE_COLUMN].values[i],
        #     line_width=FRONT_LINE_WIDTH, line_colour=this_colour)

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

    imagemagick_utils.trim_whitespace(input_file_name=OUTPUT_FILE_NAME,
                                      output_file_name=OUTPUT_FILE_NAME)
Exemple #7
0
def _plot_narr_fields(
        wet_bulb_theta_matrix_kelvins, u_wind_matrix_m_s01, v_wind_matrix_m_s01,
        title_string, annotation_string, output_file_name):
    """Plots NARR fields.

    M = number of rows in grid
    N = number of columns in grid

    :param wet_bulb_theta_matrix_kelvins: M-by-N numpy array of wet-bulb
        potential temperatures.
    :param u_wind_matrix_m_s01: M-by-N numpy array of u-wind components (metres
        per second).
    :param v_wind_matrix_m_s01: Same but for v-wind.
    :param title_string: Title (will be placed above figure).
    :param annotation_string: Text annotation (will be placed in top left of
        figure).
    :param output_file_name: Path to output file (figure will be saved here).
    """

    (narr_row_limits, narr_column_limits, axes_object, basemap_object
    ) = _init_basemap(BORDER_COLOUR)

    wet_bulb_theta_matrix_to_plot = wet_bulb_theta_matrix_kelvins[
        narr_row_limits[0]:(narr_row_limits[1] + 1),
        narr_column_limits[0]:(narr_column_limits[1] + 1)
    ] - ZERO_CELSIUS_IN_KELVINS
    u_wind_matrix_to_plot = u_wind_matrix_m_s01[
        narr_row_limits[0]:(narr_row_limits[1] + 1),
        narr_column_limits[0]:(narr_column_limits[1] + 1)
    ]
    v_wind_matrix_to_plot = v_wind_matrix_m_s01[
        narr_row_limits[0]:(narr_row_limits[1] + 1),
        narr_column_limits[0]:(narr_column_limits[1] + 1)
    ]

    nwp_plotting.plot_subgrid(
        field_matrix=wet_bulb_theta_matrix_to_plot,
        model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object,
        basemap_object=basemap_object, colour_map=THERMAL_COLOUR_MAP_OBJECT,
        min_value_in_colour_map=numpy.nanpercentile(
            wet_bulb_theta_matrix_to_plot, MIN_COLOUR_PERCENTILE),
        max_value_in_colour_map=numpy.nanpercentile(
            wet_bulb_theta_matrix_to_plot, MAX_COLOUR_PERCENTILE),
        first_row_in_full_grid=narr_row_limits[0],
        first_column_in_full_grid=narr_column_limits[0])

    plotting_utils.add_linear_colour_bar(
        axes_object_or_list=axes_object,
        values_to_colour=wet_bulb_theta_matrix_to_plot,
        colour_map=THERMAL_COLOUR_MAP_OBJECT,
        colour_min=numpy.nanpercentile(
            wet_bulb_theta_matrix_to_plot, MIN_COLOUR_PERCENTILE),
        colour_max=numpy.nanpercentile(
            wet_bulb_theta_matrix_to_plot, MAX_COLOUR_PERCENTILE),
        orientation='vertical', extend_min=True, extend_max=True,
        fraction_of_axis_length=COLOUR_BAR_LENGTH_FRACTION)

    nwp_plotting.plot_wind_barbs_on_subgrid(
        u_wind_matrix_m_s01=u_wind_matrix_to_plot,
        v_wind_matrix_m_s01=v_wind_matrix_to_plot,
        model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object,
        basemap_object=basemap_object,
        first_row_in_full_grid=narr_row_limits[0],
        first_column_in_full_grid=narr_column_limits[0],
        plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB,
        plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB,
        barb_length=WIND_BARB_LENGTH, empty_barb_radius=EMPTY_WIND_BARB_RADIUS,
        fill_empty_barb=False, colour_map=WIND_COLOUR_MAP_OBJECT,
        colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT,
        colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT)

    pyplot.title(title_string)
    plotting_utils.annotate_axes(
        axes_object=axes_object, annotation_string=annotation_string)

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

    imagemagick_utils.trim_whitespace(input_file_name=output_file_name,
                                      output_file_name=output_file_name)
def _plot_one_time(valid_time_string, pressure_level_mb, title_string,
                   annotation_string, narr_rotation_cos_matrix,
                   narr_rotation_sin_matrix):
    """Plots WPC fronts and NARR fields at one time.

    M = number of grid rows in the full NARR
    N = number of grid columns in the full NARR

    :param valid_time_string: Valid time (format "yyyy-mm-dd-HH").
    :param pressure_level_mb: Pressure level (millibars).
    :param title_string: Title (will be placed above figure).
    :param annotation_string: Annotation (will be placed above and left of
        figure).
    :param narr_rotation_cos_matrix: M-by-N numpy array of cosines for wind-
        rotation angles.
    :param narr_rotation_sin_matrix: M-by-N numpy array of sines for wind-
        rotation angles.
    """

    narr_row_limits, narr_column_limits = (
        nwp_plotting.latlng_limits_to_rowcol_limits(
            min_latitude_deg=MIN_LATITUDE_DEG,
            max_latitude_deg=MAX_LATITUDE_DEG,
            min_longitude_deg=MIN_LONGITUDE_DEG,
            max_longitude_deg=MAX_LONGITUDE_DEG,
            model_name=nwp_model_utils.NARR_MODEL_NAME))

    valid_time_unix_sec = time_conversion.string_to_unix_sec(
        valid_time_string, DEFAULT_TIME_FORMAT)

    front_file_name = fronts_io.find_file_for_one_time(
        top_directory_name=TOP_FRONT_DIR_NAME,
        file_type=fronts_io.POLYLINE_FILE_TYPE,
        valid_time_unix_sec=valid_time_unix_sec)

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

    num_narr_fields = len(NARR_FIELD_NAMES)
    narr_matrix_by_field = [numpy.array([])] * num_narr_fields

    for j in range(num_narr_fields):
        this_file_name = processed_narr_io.find_file_for_one_time(
            top_directory_name=TOP_NARR_DIRECTORY_NAME,
            field_name=NARR_FIELD_NAMES[j],
            pressure_level_mb=pressure_level_mb,
            valid_time_unix_sec=valid_time_unix_sec)

        print 'Reading data from: "{0:s}"...'.format(this_file_name)
        narr_matrix_by_field[j] = processed_narr_io.read_fields_from_file(
            this_file_name)[0][0, ...]

        narr_matrix_by_field[j] = utils.fill_nans(narr_matrix_by_field[j])
        narr_matrix_by_field[j] = narr_matrix_by_field[j][narr_row_limits[0]:(
            narr_row_limits[1] +
            1), narr_column_limits[0]:(narr_column_limits[1] + 1)]

        if NARR_FIELD_NAMES[j] == processed_narr_io.WET_BULB_THETA_NAME:
            narr_matrix_by_field[j] = (narr_matrix_by_field[j] -
                                       ZERO_CELSIUS_IN_KELVINS)

    _, axes_object, basemap_object = nwp_plotting.init_basemap(
        model_name=nwp_model_utils.NARR_MODEL_NAME,
        first_row_in_full_grid=narr_row_limits[0],
        last_row_in_full_grid=narr_row_limits[1],
        first_column_in_full_grid=narr_column_limits[0],
        last_column_in_full_grid=narr_column_limits[1])

    plotting_utils.plot_coastlines(basemap_object=basemap_object,
                                   axes_object=axes_object,
                                   line_colour=BORDER_COLOUR)
    plotting_utils.plot_countries(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  line_colour=BORDER_COLOUR)
    plotting_utils.plot_states_and_provinces(basemap_object=basemap_object,
                                             axes_object=axes_object,
                                             line_colour=BORDER_COLOUR)
    plotting_utils.plot_parallels(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  bottom_left_lat_deg=-90.,
                                  upper_right_lat_deg=90.,
                                  parallel_spacing_deg=PARALLEL_SPACING_DEG)
    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  bottom_left_lng_deg=0.,
                                  upper_right_lng_deg=360.,
                                  meridian_spacing_deg=MERIDIAN_SPACING_DEG)

    for j in range(num_narr_fields):
        if NARR_FIELD_NAMES[j] in WIND_FIELD_NAMES:
            continue

        min_colour_value = numpy.percentile(narr_matrix_by_field[j],
                                            MIN_COLOUR_PERCENTILE)
        max_colour_value = numpy.percentile(narr_matrix_by_field[j],
                                            MAX_COLOUR_PERCENTILE)

        nwp_plotting.plot_subgrid(
            field_matrix=narr_matrix_by_field[j],
            model_name=nwp_model_utils.NARR_MODEL_NAME,
            axes_object=axes_object,
            basemap_object=basemap_object,
            colour_map=THERMAL_COLOUR_MAP_OBJECT,
            min_value_in_colour_map=min_colour_value,
            max_value_in_colour_map=max_colour_value,
            first_row_in_full_grid=narr_row_limits[0],
            first_column_in_full_grid=narr_column_limits[0])

        plotting_utils.add_linear_colour_bar(
            axes_object_or_list=axes_object,
            values_to_colour=narr_matrix_by_field[j],
            colour_map=THERMAL_COLOUR_MAP_OBJECT,
            colour_min=min_colour_value,
            colour_max=max_colour_value,
            orientation='horizontal',
            extend_min=True,
            extend_max=True,
            fraction_of_axis_length=0.9)

    this_cos_matrix = narr_rotation_cos_matrix[narr_row_limits[0]:(
        narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] +
                                                        1)]

    this_sin_matrix = narr_rotation_sin_matrix[narr_row_limits[0]:(
        narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] +
                                                        1)]

    u_wind_index = NARR_FIELD_NAMES.index(
        processed_narr_io.U_WIND_GRID_RELATIVE_NAME)
    v_wind_index = NARR_FIELD_NAMES.index(
        processed_narr_io.V_WIND_GRID_RELATIVE_NAME)

    narr_matrix_by_field[u_wind_index], narr_matrix_by_field[v_wind_index] = (
        nwp_model_utils.rotate_winds_to_earth_relative(
            u_winds_grid_relative_m_s01=narr_matrix_by_field[u_wind_index],
            v_winds_grid_relative_m_s01=narr_matrix_by_field[v_wind_index],
            rotation_angle_cosines=this_cos_matrix,
            rotation_angle_sines=this_sin_matrix))

    nwp_plotting.plot_wind_barbs_on_subgrid(
        u_wind_matrix_m_s01=narr_matrix_by_field[u_wind_index],
        v_wind_matrix_m_s01=narr_matrix_by_field[v_wind_index],
        model_name=nwp_model_utils.NARR_MODEL_NAME,
        axes_object=axes_object,
        basemap_object=basemap_object,
        first_row_in_full_grid=narr_row_limits[0],
        first_column_in_full_grid=narr_column_limits[0],
        plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB,
        plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB,
        barb_length=WIND_BARB_LENGTH,
        empty_barb_radius=EMPTY_WIND_BARB_RADIUS,
        fill_empty_barb=False,
        colour_map=WIND_COLOUR_MAP_OBJECT,
        colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT,
        colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT)

    num_fronts = len(front_line_table.index)

    for i in range(num_fronts):
        this_front_type_string = front_line_table[
            front_utils.FRONT_TYPE_COLUMN].values[i]

        if this_front_type_string == front_utils.WARM_FRONT_STRING_ID:
            this_colour = WARM_FRONT_COLOUR
        else:
            this_colour = COLD_FRONT_COLOUR

        front_plotting.plot_front_with_markers(
            line_latitudes_deg=front_line_table[
                front_utils.LATITUDES_COLUMN].values[i],
            line_longitudes_deg=front_line_table[
                front_utils.LONGITUDES_COLUMN].values[i],
            axes_object=axes_object,
            basemap_object=basemap_object,
            front_type_string=front_line_table[
                front_utils.FRONT_TYPE_COLUMN].values[i],
            marker_colour=this_colour)

    pyplot.title(title_string)
    plotting_utils.annotate_axes(axes_object=axes_object,
                                 annotation_string=annotation_string)

    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=OUTPUT_DIR_NAME)
    figure_file_name = '{0:s}/fronts_{1:04d}mb_{2:s}.jpg'.format(
        OUTPUT_DIR_NAME, pressure_level_mb, valid_time_string)

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

    imagemagick_utils.trim_whitespace(input_file_name=figure_file_name,
                                      output_file_name=figure_file_name)
    return figure_file_name
def _plot_observations_one_time(
        valid_time_string, title_string, annotation_string, output_file_name):
    """Plots observations (NARR predictors and WPC fronts) for one valid time.

    :param valid_time_string: Valid time (format "yyyy-mm-dd-HH").
    :param title_string: Title (will be placed above figure).
    :param annotation_string: Text annotation (will be placed in top left of
        figure).
    :param output_file_name: Path to output file (figure will be saved here).
    """

    (narr_row_limits, narr_column_limits
    ) = nwp_plotting.latlng_limits_to_rowcol_limits(
        min_latitude_deg=MIN_LATITUDE_DEG, max_latitude_deg=MAX_LATITUDE_DEG,
        min_longitude_deg=MIN_LONGITUDE_DEG,
        max_longitude_deg=MAX_LONGITUDE_DEG,
        model_name=nwp_model_utils.NARR_MODEL_NAME)

    valid_time_unix_sec = time_conversion.string_to_unix_sec(
        valid_time_string, INPUT_TIME_FORMAT)
    front_file_name = fronts_io.find_file_for_one_time(
        top_directory_name=TOP_FRONT_DIR_NAME,
        file_type=fronts_io.POLYLINE_FILE_TYPE,
        valid_time_unix_sec=valid_time_unix_sec)

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

    num_narr_fields = len(NARR_FIELD_NAMES)
    narr_matrix_by_field = [numpy.array([])] * num_narr_fields

    for j in range(num_narr_fields):
        if NARR_FIELD_NAMES[j] in WIND_FIELD_NAMES:
            this_directory_name = TOP_NARR_WIND_DIR_NAME + ''
        else:
            this_directory_name = TOP_NARR_DIR_NAME + ''

        this_file_name = processed_narr_io.find_file_for_one_time(
            top_directory_name=this_directory_name,
            field_name=NARR_FIELD_NAMES[j], pressure_level_mb=PRESSURE_LEVEL_MB,
            valid_time_unix_sec=valid_time_unix_sec)

        print 'Reading data from: "{0:s}"...'.format(this_file_name)
        narr_matrix_by_field[j] = processed_narr_io.read_fields_from_file(
            this_file_name)[0][0, ...]

        narr_matrix_by_field[j] = utils.fill_nans(narr_matrix_by_field[j])
        narr_matrix_by_field[j] = narr_matrix_by_field[j][
            narr_row_limits[0]:(narr_row_limits[1] + 1),
            narr_column_limits[0]:(narr_column_limits[1] + 1)
        ]

        if NARR_FIELD_NAMES[j] == processed_narr_io.WET_BULB_THETA_NAME:
            narr_matrix_by_field[j] = (
                narr_matrix_by_field[j] - ZERO_CELSIUS_IN_KELVINS
            )

    _, axes_object, basemap_object = nwp_plotting.init_basemap(
        model_name=nwp_model_utils.NARR_MODEL_NAME,
        first_row_in_full_grid=narr_row_limits[0],
        last_row_in_full_grid=narr_row_limits[1],
        first_column_in_full_grid=narr_column_limits[0],
        last_column_in_full_grid=narr_column_limits[1])

    plotting_utils.plot_coastlines(
        basemap_object=basemap_object, axes_object=axes_object,
        line_colour=BORDER_COLOUR)
    plotting_utils.plot_countries(
        basemap_object=basemap_object, axes_object=axes_object,
        line_colour=BORDER_COLOUR)
    plotting_utils.plot_states_and_provinces(
        basemap_object=basemap_object, axes_object=axes_object,
        line_colour=BORDER_COLOUR)
    plotting_utils.plot_parallels(
        basemap_object=basemap_object, axes_object=axes_object,
        bottom_left_lat_deg=-90., upper_right_lat_deg=90.,
        parallel_spacing_deg=PARALLEL_SPACING_DEG)
    plotting_utils.plot_meridians(
        basemap_object=basemap_object, axes_object=axes_object,
        bottom_left_lng_deg=0., upper_right_lng_deg=360.,
        meridian_spacing_deg=MERIDIAN_SPACING_DEG)

    for j in range(num_narr_fields):
        if NARR_FIELD_NAMES[j] in WIND_FIELD_NAMES:
            continue

        min_colour_value = numpy.percentile(
            narr_matrix_by_field[j], MIN_COLOUR_PERCENTILE)
        max_colour_value = numpy.percentile(
            narr_matrix_by_field[j], MAX_COLOUR_PERCENTILE)

        nwp_plotting.plot_subgrid(
            field_matrix=narr_matrix_by_field[j],
            model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object,
            basemap_object=basemap_object, colour_map=THERMAL_COLOUR_MAP_OBJECT,
            min_value_in_colour_map=min_colour_value,
            max_value_in_colour_map=max_colour_value,
            first_row_in_full_grid=narr_row_limits[0],
            first_column_in_full_grid=narr_column_limits[0])

        plotting_utils.add_linear_colour_bar(
            axes_object_or_list=axes_object,
            values_to_colour=narr_matrix_by_field[j],
            colour_map=THERMAL_COLOUR_MAP_OBJECT, colour_min=min_colour_value,
            colour_max=max_colour_value, orientation='vertical',
            extend_min=True, extend_max=True,
            fraction_of_axis_length=LENGTH_FRACTION_FOR_THETA_COLOUR_BAR)

    u_wind_index = NARR_FIELD_NAMES.index(
        processed_narr_io.U_WIND_EARTH_RELATIVE_NAME)
    v_wind_index = NARR_FIELD_NAMES.index(
        processed_narr_io.V_WIND_EARTH_RELATIVE_NAME)

    nwp_plotting.plot_wind_barbs_on_subgrid(
        u_wind_matrix_m_s01=narr_matrix_by_field[u_wind_index],
        v_wind_matrix_m_s01=narr_matrix_by_field[v_wind_index],
        model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object,
        basemap_object=basemap_object,
        first_row_in_full_grid=narr_row_limits[0],
        first_column_in_full_grid=narr_column_limits[0],
        plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB,
        plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB,
        barb_length=WIND_BARB_LENGTH, empty_barb_radius=EMPTY_WIND_BARB_RADIUS,
        colour_map=WIND_COLOUR_MAP_OBJECT,
        colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT,
        colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT)

    num_fronts = len(front_line_table.index)
    for i in range(num_fronts):
        this_front_type_string = front_line_table[
            front_utils.FRONT_TYPE_COLUMN].values[i]
        if this_front_type_string == front_utils.WARM_FRONT_STRING_ID:
            this_colour = WARM_FRONT_COLOUR
        else:
            this_colour = COLD_FRONT_COLOUR

        front_plotting.plot_polyline(
            latitudes_deg=front_line_table[
                front_utils.LATITUDES_COLUMN].values[i],
            longitudes_deg=front_line_table[
                front_utils.LONGITUDES_COLUMN].values[i],
            basemap_object=basemap_object, axes_object=axes_object,
            front_type=front_line_table[
                front_utils.FRONT_TYPE_COLUMN].values[i],
            line_width=FRONT_LINE_WIDTH, line_colour=this_colour)

    pyplot.title(title_string)
    plotting_utils.annotate_axes(
        axes_object=axes_object, annotation_string=annotation_string)

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

    imagemagick_utils.trim_whitespace(input_file_name=output_file_name,
                                      output_file_name=output_file_name)
def _run(example_file_name, top_front_line_dir_name, num_examples,
         example_indices, thetaw_colour_map_name, thetaw_max_colour_percentile,
         output_dir_name):
    """Plots one or more input examples.

    This is effectively the main method.

    :param example_file_name: See documentation at top of file.
    :param top_front_line_dir_name: Same.
    :param num_examples: Same.
    :param example_indices: Same.
    :param thetaw_colour_map_name: Same.
    :param thetaw_max_colour_percentile: Same.
    :param output_dir_name: Same.
    """

    if num_examples <= 0:
        num_examples = None

    if num_examples is None:
        error_checking.assert_is_geq_numpy_array(example_indices, 0)
    else:
        error_checking.assert_is_greater(num_examples, 0)

    error_checking.assert_is_geq(thetaw_max_colour_percentile, 0)
    error_checking.assert_is_leq(thetaw_max_colour_percentile, 100)
    thetaw_colour_map_object = pyplot.cm.get_cmap(thetaw_colour_map_name)

    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    print 'Reading normalized examples from: "{0:s}"...'.format(
        example_file_name)

    example_dict = trainval_io.read_downsized_3d_examples(
        netcdf_file_name=example_file_name,
        num_half_rows_to_keep=NUM_HALF_ROWS,
        num_half_columns_to_keep=NUM_HALF_COLUMNS,
        predictor_names_to_keep=NARR_PREDICTOR_NAMES)

    # TODO(thunderhoser): This is a HACK (assuming that normalization method is
    # z-score and not min-max).
    mean_value_matrix = example_dict[trainval_io.FIRST_NORM_PARAM_KEY]
    standard_deviation_matrix = example_dict[trainval_io.SECOND_NORM_PARAM_KEY]

    normalization_dict = {
        ml_utils.MIN_VALUE_MATRIX_KEY: None,
        ml_utils.MAX_VALUE_MATRIX_KEY: None,
        ml_utils.MEAN_VALUE_MATRIX_KEY: mean_value_matrix,
        ml_utils.STDEV_MATRIX_KEY: standard_deviation_matrix
    }

    example_dict[trainval_io.PREDICTOR_MATRIX_KEY] = (
        ml_utils.denormalize_predictors(
            predictor_matrix=example_dict[trainval_io.PREDICTOR_MATRIX_KEY],
            normalization_dict=normalization_dict))

    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_examples_total = len(example_dict[trainval_io.TARGET_TIMES_KEY])
    example_indices = numpy.linspace(0,
                                     num_examples_total - 1,
                                     num=num_examples_total,
                                     dtype=int)

    if num_examples is not None:
        num_examples = min([num_examples, num_examples_total])
        example_indices = numpy.random.choice(example_indices,
                                              size=num_examples,
                                              replace=False)

    thetaw_index = NARR_PREDICTOR_NAMES.index(
        processed_narr_io.WET_BULB_THETA_NAME)
    u_wind_index = NARR_PREDICTOR_NAMES.index(
        processed_narr_io.U_WIND_GRID_RELATIVE_NAME)
    v_wind_index = NARR_PREDICTOR_NAMES.index(
        processed_narr_io.V_WIND_GRID_RELATIVE_NAME)

    for i in example_indices:
        this_center_row_index = example_dict[trainval_io.ROW_INDICES_KEY][i]
        this_first_row_index = this_center_row_index - NUM_HALF_ROWS
        this_last_row_index = this_center_row_index + NUM_HALF_ROWS

        this_center_column_index = example_dict[
            trainval_io.COLUMN_INDICES_KEY][i]
        this_first_column_index = this_center_column_index - NUM_HALF_COLUMNS
        this_last_column_index = this_center_column_index + NUM_HALF_COLUMNS

        this_u_wind_matrix_m_s01 = example_dict[
            trainval_io.PREDICTOR_MATRIX_KEY][i, ..., u_wind_index]
        this_v_wind_matrix_m_s01 = example_dict[
            trainval_io.PREDICTOR_MATRIX_KEY][i, ..., v_wind_index]
        this_cos_matrix = narr_rotation_cos_matrix[this_first_row_index:(
            this_last_row_index +
            1), this_first_column_index:(this_last_column_index + 1)]
        this_sin_matrix = narr_rotation_sin_matrix[this_first_row_index:(
            this_last_row_index +
            1), this_first_column_index:(this_last_column_index + 1)]

        this_u_wind_matrix_m_s01, this_v_wind_matrix_m_s01 = (
            nwp_model_utils.rotate_winds_to_earth_relative(
                u_winds_grid_relative_m_s01=this_u_wind_matrix_m_s01,
                v_winds_grid_relative_m_s01=this_v_wind_matrix_m_s01,
                rotation_angle_cosines=this_cos_matrix,
                rotation_angle_sines=this_sin_matrix))

        _, axes_object, basemap_object = nwp_plotting.init_basemap(
            model_name=nwp_model_utils.NARR_MODEL_NAME,
            first_row_in_full_grid=this_first_row_index,
            last_row_in_full_grid=this_last_row_index,
            first_column_in_full_grid=this_first_column_index,
            last_column_in_full_grid=this_last_column_index,
            resolution_string='i')

        plotting_utils.plot_coastlines(basemap_object=basemap_object,
                                       axes_object=axes_object,
                                       line_colour=BORDER_COLOUR,
                                       line_width=BORDER_WIDTH)
        plotting_utils.plot_countries(basemap_object=basemap_object,
                                      axes_object=axes_object,
                                      line_colour=BORDER_COLOUR,
                                      line_width=BORDER_WIDTH)
        plotting_utils.plot_states_and_provinces(basemap_object=basemap_object,
                                                 axes_object=axes_object,
                                                 line_colour=BORDER_COLOUR,
                                                 line_width=BORDER_WIDTH)
        plotting_utils.plot_parallels(
            basemap_object=basemap_object,
            axes_object=axes_object,
            bottom_left_lat_deg=-90.,
            upper_right_lat_deg=90.,
            parallel_spacing_deg=PARALLEL_SPACING_DEG)
        plotting_utils.plot_meridians(
            basemap_object=basemap_object,
            axes_object=axes_object,
            bottom_left_lng_deg=0.,
            upper_right_lng_deg=360.,
            meridian_spacing_deg=MERIDIAN_SPACING_DEG)

        this_thetaw_matrix_kelvins = example_dict[
            trainval_io.PREDICTOR_MATRIX_KEY][i, ..., thetaw_index]

        this_min_value = numpy.percentile(this_thetaw_matrix_kelvins,
                                          100. - thetaw_max_colour_percentile)
        this_max_value = numpy.percentile(this_thetaw_matrix_kelvins,
                                          thetaw_max_colour_percentile)

        nwp_plotting.plot_subgrid(
            field_matrix=this_thetaw_matrix_kelvins,
            model_name=nwp_model_utils.NARR_MODEL_NAME,
            axes_object=axes_object,
            basemap_object=basemap_object,
            colour_map=thetaw_colour_map_object,
            min_value_in_colour_map=this_min_value,
            max_value_in_colour_map=this_max_value,
            first_row_in_full_grid=this_first_row_index,
            first_column_in_full_grid=this_first_column_index)

        colour_bar_object = plotting_utils.add_linear_colour_bar(
            axes_object_or_list=axes_object,
            values_to_colour=this_thetaw_matrix_kelvins,
            colour_map=thetaw_colour_map_object,
            colour_min=this_min_value,
            colour_max=this_max_value,
            orientation='vertical',
            extend_min=True,
            extend_max=True,
            fraction_of_axis_length=0.8)

        colour_bar_object.set_label(
            r'Wet-bulb potential temperature ($^{\circ}$C)')

        nwp_plotting.plot_wind_barbs_on_subgrid(
            u_wind_matrix_m_s01=this_u_wind_matrix_m_s01,
            v_wind_matrix_m_s01=this_v_wind_matrix_m_s01,
            model_name=nwp_model_utils.NARR_MODEL_NAME,
            axes_object=axes_object,
            basemap_object=basemap_object,
            first_row_in_full_grid=this_first_row_index,
            first_column_in_full_grid=this_first_column_index,
            barb_length=WIND_BARB_LENGTH,
            empty_barb_radius=EMPTY_WIND_BARB_RADIUS,
            fill_empty_barb=False,
            colour_map=WIND_COLOUR_MAP_OBJECT,
            colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT,
            colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT)

        this_front_file_name = fronts_io.find_file_for_one_time(
            top_directory_name=top_front_line_dir_name,
            file_type=fronts_io.POLYLINE_FILE_TYPE,
            valid_time_unix_sec=example_dict[trainval_io.TARGET_TIMES_KEY][i])

        print time_conversion.unix_sec_to_string(
            example_dict[trainval_io.TARGET_TIMES_KEY][i], '%Y-%m-%d-%H')

        this_polyline_table = fronts_io.read_polylines_from_file(
            this_front_file_name)
        this_num_fronts = len(this_polyline_table.index)

        for j in range(this_num_fronts):
            this_front_type_string = this_polyline_table[
                front_utils.FRONT_TYPE_COLUMN].values[j]

            if this_front_type_string == front_utils.WARM_FRONT_STRING_ID:
                this_colour = WARM_FRONT_COLOUR
            else:
                this_colour = COLD_FRONT_COLOUR

            front_plotting.plot_front_with_markers(
                line_latitudes_deg=this_polyline_table[
                    front_utils.LATITUDES_COLUMN].values[j],
                line_longitudes_deg=this_polyline_table[
                    front_utils.LONGITUDES_COLUMN].values[j],
                axes_object=axes_object,
                basemap_object=basemap_object,
                front_type_string=this_polyline_table[
                    front_utils.FRONT_TYPE_COLUMN].values[j],
                marker_colour=this_colour,
                marker_size=FRONT_MARKER_SIZE,
                marker_spacing_metres=FRONT_SPACING_METRES)

        this_output_file_name = '{0:s}/example{1:06d}.jpg'.format(
            output_dir_name, i)

        print 'Saving figure to: "{0:s}"...'.format(this_output_file_name)
        pyplot.savefig(this_output_file_name, dpi=FIGURE_RESOLUTION_DPI)
        pyplot.close()
Exemple #11
0
def plot_performance_diagram(axes_object=None,
                             pod_by_threshold=None,
                             success_ratio_by_threshold=None,
                             line_colour=DEFAULT_PERF_DIAG_LINE_COLOUR,
                             line_width=DEFAULT_PERF_DIAG_LINE_WIDTH,
                             bias_line_colour=DEFAULT_FREQ_BIAS_LINE_COLOUR,
                             bias_line_width=DEFAULT_FREQ_BIAS_LINE_WIDTH,
                             csi_colour_map=DEFAULT_CSI_COLOUR_MAP):
    """Plots performance diagram.

    T = number of binarization thresholds

    For the definition of a "binarization threshold" and the role they play in
    performance diagrams, see
    `model_evaluation.get_points_in_performance_diagram`.

    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param pod_by_threshold: length-T numpy array of POD (probability of
        detection) values.
    :param success_ratio_by_threshold: length-T numpy array of success ratios.
    :param line_colour: Colour (in any format accepted by `matplotlib.colors`).
    :param line_width: Line width (real positive number).
    :param bias_line_colour: Colour of contour lines for frequency bias.
    :param bias_line_width: Width of contour lines for frequency bias.
    :param csi_colour_map: Colour map (instance of `matplotlib.pyplot.cm`) for
        CSI (critical success index) contours.
    """

    error_checking.assert_is_numpy_array(pod_by_threshold, num_dimensions=1)
    error_checking.assert_is_geq_numpy_array(pod_by_threshold,
                                             0.,
                                             allow_nan=True)
    error_checking.assert_is_leq_numpy_array(pod_by_threshold,
                                             1.,
                                             allow_nan=True)
    num_thresholds = len(pod_by_threshold)

    error_checking.assert_is_numpy_array(success_ratio_by_threshold,
                                         exact_dimensions=numpy.array(
                                             [num_thresholds]))
    error_checking.assert_is_geq_numpy_array(success_ratio_by_threshold,
                                             0.,
                                             allow_nan=True)
    error_checking.assert_is_leq_numpy_array(success_ratio_by_threshold,
                                             1.,
                                             allow_nan=True)

    success_ratio_matrix, pod_matrix = model_eval.get_sr_pod_grid()
    csi_matrix = model_eval.csi_from_sr_and_pod(success_ratio_matrix,
                                                pod_matrix)
    frequency_bias_matrix = model_eval.frequency_bias_from_sr_and_pod(
        success_ratio_matrix, pod_matrix)

    pyplot.contourf(success_ratio_matrix,
                    pod_matrix,
                    csi_matrix,
                    LEVELS_FOR_CSI_CONTOURS,
                    cmap=csi_colour_map,
                    vmin=0.,
                    vmax=1.,
                    axes=axes_object)
    colour_bar_object = plotting_utils.add_linear_colour_bar(
        axes_object,
        values_to_colour=csi_matrix,
        colour_map=csi_colour_map,
        colour_min=0.,
        colour_max=1.,
        orientation='vertical',
        extend_min=False,
        extend_max=False)
    colour_bar_object.set_label('CSI (critical success index)')

    bias_colour_tuple = ()
    for _ in range(len(LEVELS_FOR_FREQ_BIAS_CONTOURS)):
        bias_colour_tuple += (bias_line_colour, )

    bias_contour_object = pyplot.contour(success_ratio_matrix,
                                         pod_matrix,
                                         frequency_bias_matrix,
                                         LEVELS_FOR_FREQ_BIAS_CONTOURS,
                                         colors=bias_colour_tuple,
                                         linewidths=bias_line_width,
                                         linestyles='dashed',
                                         axes=axes_object)
    pyplot.clabel(bias_contour_object,
                  inline=True,
                  inline_spacing=PIXEL_PADDING_FOR_FREQ_BIAS_LABELS,
                  fmt=STRING_FORMAT_FOR_FREQ_BIAS_LABELS,
                  fontsize=FONT_SIZE)

    nan_flags = numpy.logical_or(numpy.isnan(success_ratio_by_threshold),
                                 numpy.isnan(pod_by_threshold))
    if not numpy.all(nan_flags):
        real_indices = numpy.where(numpy.invert(nan_flags))[0]
        axes_object.plot(success_ratio_by_threshold[real_indices],
                         pod_by_threshold[real_indices],
                         color=line_colour,
                         linestyle='solid',
                         linewidth=line_width)

    axes_object.set_xlabel('Success ratio (1 - FAR)')
    axes_object.set_ylabel('POD (probability of detection)')
    axes_object.set_xlim(0., 1.)
    axes_object.set_ylim(0., 1.)
def plot_saliency_for_sounding(saliency_matrix,
                               sounding_field_names,
                               pressure_levels_mb,
                               colour_map_object,
                               max_absolute_colour_value,
                               min_font_size=DEFAULT_MIN_SOUNDING_FONT_SIZE,
                               max_font_size=DEFAULT_MAX_SOUNDING_FONT_SIZE):
    """Plots saliency for one sounding.

    P = number of pressure levels
    F = number of fields

    :param saliency_matrix: P-by-F numpy array of saliency values.
    :param sounding_field_names: length-F list of field names.
    :param pressure_levels_mb: length-P list of pressure levels (millibars).
    :param colour_map_object: See doc for `plot_2d_grid`.
    :param max_absolute_colour_value: Same.
    :param min_font_size: Same.
    :param max_font_size: Same.
    """

    error_checking.assert_is_greater_numpy_array(pressure_levels_mb, 0.)
    error_checking.assert_is_numpy_array(pressure_levels_mb, num_dimensions=1)

    error_checking.assert_is_list(sounding_field_names)
    error_checking.assert_is_numpy_array(numpy.array(sounding_field_names),
                                         num_dimensions=1)

    num_pressure_levels = len(pressure_levels_mb)
    num_sounding_fields = len(sounding_field_names)

    error_checking.assert_is_numpy_array_without_nan(saliency_matrix)
    error_checking.assert_is_numpy_array(saliency_matrix,
                                         exact_dimensions=numpy.array([
                                             num_pressure_levels,
                                             num_sounding_fields
                                         ]))

    try:
        u_wind_index = sounding_field_names.index(soundings.U_WIND_NAME)
        v_wind_index = sounding_field_names.index(soundings.V_WIND_NAME)
        plot_wind_barbs = True
    except ValueError:
        plot_wind_barbs = False

    if plot_wind_barbs:
        u_wind_saliency_values = saliency_matrix[:, u_wind_index]
        v_wind_saliency_values = saliency_matrix[:, v_wind_index]
        wind_saliency_magnitudes = numpy.sqrt(u_wind_saliency_values**2 +
                                              v_wind_saliency_values**2)

        colour_norm_object = pyplot.Normalize(vmin=0.,
                                              vmax=max_absolute_colour_value)
        rgb_matrix_for_wind = colour_map_object(
            colour_norm_object(wind_saliency_magnitudes))[..., :-1]

        non_wind_flags = numpy.array(
            [f not in WIND_COMPONENT_NAMES for f in sounding_field_names],
            dtype=bool)
        non_wind_indices = numpy.where(non_wind_flags)[0]

        saliency_matrix = saliency_matrix[:, non_wind_indices]
        sounding_field_names = [
            sounding_field_names[k] for k in non_wind_indices
        ]

        sounding_field_names.append(WIND_NAME)
        num_sounding_fields = len(sounding_field_names)

    rgb_matrix, font_size_matrix = _saliency_to_colour_and_size(
        saliency_matrix=saliency_matrix,
        colour_map_object=colour_map_object,
        max_absolute_colour_value=max_absolute_colour_value,
        min_font_size=min_font_size,
        max_font_size=max_font_size)

    _, axes_object = pyplot.subplots(1,
                                     1,
                                     figsize=(FIGURE_WIDTH_INCHES,
                                              FIGURE_HEIGHT_INCHES))
    axes_object.set_axis_bgcolor(SOUNDING_SALIENCY_BACKGROUND_COLOUR)

    for k in range(num_sounding_fields):
        if sounding_field_names[k] == WIND_NAME:
            for j in range(num_pressure_levels):
                this_vector = numpy.array(
                    [u_wind_saliency_values[j], v_wind_saliency_values[j]])
                this_vector = (WIND_SALIENCY_MULTIPLIER * this_vector /
                               numpy.linalg.norm(this_vector, ord=2))

                axes_object.barbs(k,
                                  pressure_levels_mb[j],
                                  this_vector[0],
                                  this_vector[1],
                                  length=WIND_BARB_LENGTH,
                                  fill_empty=True,
                                  rounding=False,
                                  sizes={'emptybarb': EMPTY_WIND_BARB_RADIUS},
                                  color=rgb_matrix_for_wind[j, ...])

            continue

        for j in range(num_pressure_levels):
            if saliency_matrix[j, k] >= 0:
                axes_object.text(k,
                                 pressure_levels_mb[j],
                                 '+',
                                 fontsize=font_size_matrix[j, k],
                                 color=rgb_matrix[j, k, ...],
                                 horizontalalignment='center',
                                 verticalalignment='center')
            else:
                axes_object.text(k,
                                 pressure_levels_mb[j],
                                 '_',
                                 fontsize=font_size_matrix[j, k],
                                 color=rgb_matrix[j, k, ...],
                                 horizontalalignment='center',
                                 verticalalignment='bottom')

    axes_object.set_xlim(-0.5, num_sounding_fields - 0.5)
    axes_object.set_ylim(100, 1000)
    axes_object.invert_yaxis()
    pyplot.yscale('log')
    pyplot.minorticks_off()

    y_tick_locations = numpy.linspace(100, 1000, num=10, dtype=int)
    y_tick_labels = ['{0:d}'.format(p) for p in y_tick_locations]
    pyplot.yticks(y_tick_locations, y_tick_labels)

    x_tick_locations = numpy.linspace(0,
                                      num_sounding_fields - 1,
                                      num=num_sounding_fields,
                                      dtype=float)
    x_tick_labels = [FIELD_NAME_TO_LATEX_DICT[f] for f in sounding_field_names]
    pyplot.xticks(x_tick_locations, x_tick_labels)

    colour_bar_object = plotting_utils.add_linear_colour_bar(
        axes_object_or_list=axes_object,
        values_to_colour=saliency_matrix,
        colour_map=colour_map_object,
        colour_min=0.,
        colour_max=max_absolute_colour_value,
        orientation='vertical',
        extend_min=True,
        extend_max=True)

    colour_bar_object.set_label('Saliency (absolute value)')
Exemple #13
0
def _plot_front_densities(num_fronts_matrix,
                          colour_map_object,
                          title_string,
                          annotation_string,
                          output_file_name,
                          mask_matrix=None,
                          add_colour_bar=True):
    """Plots number of fronts at each NARR grid cell.

    M = number of grid rows (unique y-coordinates at grid points)
    N = number of grid columns (unique x-coordinates at grid points)

    :param num_fronts_matrix: M-by-N numpy array with number of fronts at each
        grid cell.
    :param colour_map_object: Instance of `matplotlib.pyplot.cm`.
    :param title_string: Title (will be placed above figure).
    :param annotation_string: Text annotation (will be placed in top left of
        figure).
    :param output_file_name: Path to output (image) file.  The figure will be
        saved here.
    :param mask_matrix: M-by-N numpy array of integers.  If
        mask_matrix[i, j] = 0, grid cell [i, j] will be masked out in the map.
        If `mask_matrix is None`, there will be no masking.
    :param add_colour_bar: Boolean flag.  If True, will add colour bar.
    """

    _, axes_object, basemap_object = narr_plotting.init_basemap()

    plotting_utils.plot_coastlines(basemap_object=basemap_object,
                                   axes_object=axes_object,
                                   line_colour=BORDER_COLOUR)
    plotting_utils.plot_countries(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  line_colour=BORDER_COLOUR)
    plotting_utils.plot_states_and_provinces(basemap_object=basemap_object,
                                             axes_object=axes_object,
                                             line_colour=BORDER_COLOUR)
    plotting_utils.plot_parallels(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  bottom_left_lat_deg=-90.,
                                  upper_right_lat_deg=90.,
                                  parallel_spacing_deg=PARALLEL_SPACING_DEG)
    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  bottom_left_lng_deg=0.,
                                  upper_right_lng_deg=360.,
                                  meridian_spacing_deg=MERIDIAN_SPACING_DEG)

    num_fronts_matrix = num_fronts_matrix.astype(float)
    max_colour_value = numpy.percentile(num_fronts_matrix,
                                        MAX_COLOUR_PERCENTILE)

    if mask_matrix is not None:
        num_fronts_matrix[mask_matrix == 0] = numpy.nan

    narr_plotting.plot_xy_grid(data_matrix=num_fronts_matrix,
                               axes_object=axes_object,
                               basemap_object=basemap_object,
                               colour_map=colour_map_object,
                               colour_minimum=0.,
                               colour_maximum=max_colour_value)

    if add_colour_bar:
        plotting_utils.add_linear_colour_bar(
            axes_object_or_list=axes_object,
            values_to_colour=num_fronts_matrix,
            colour_map=colour_map_object,
            colour_min=0.,
            colour_max=max_colour_value,
            orientation='horizontal',
            extend_min=False,
            extend_max=True)

    pyplot.title(title_string)
    plotting_utils.annotate_axes(axes_object=axes_object,
                                 annotation_string=annotation_string)

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

    imagemagick_utils.trim_whitespace(input_file_name=output_file_name,
                                      output_file_name=output_file_name)
def _plot_feature_maps_one_layer(feature_matrix, storm_ids,
                                 storm_times_unix_sec, layer_name,
                                 output_dir_name):
    """Plots all feature maps for one layer.

    E = number of examples (storm objects)
    M = number of spatial rows
    N = number of spatial columns
    H = number of spatial depths (heights)
    C = number of channels

    :param feature_matrix: numpy array (E x M x N x C or E x M x N x H x C) of
        feature maps.
    :param storm_ids: length-E list of storm IDs.
    :param storm_times_unix_sec: length-E numpy array of storm times.
    :param layer_name: Name of layer.
    :param output_dir_name: Name of output directory for this layer.
    """

    num_spatial_dimensions = len(feature_matrix.shape) - 2
    num_storm_objects = feature_matrix.shape[0]
    num_channels = feature_matrix.shape[-1]

    if num_spatial_dimensions == 3:
        num_heights = feature_matrix.shape[-2]
    else:
        num_heights = None

    num_panel_rows = int(numpy.round(numpy.sqrt(num_channels)))
    annotation_string_by_channel = [None] * num_channels

    # annotation_string_by_channel = [
    #     'Filter {0:d}'.format(c + 1) for c in range(num_channels)
    # ]

    if num_channels >= NUM_PANELS_FOR_NO_FONT:
        annotation_string_by_channel = [''] * num_channels
        font_size = TINY_FONT_SIZE + 0
    elif num_channels >= NUM_PANELS_FOR_TINY_FONT:
        font_size = TINY_FONT_SIZE + 0
    elif num_channels >= NUM_PANELS_FOR_SMALL_FONT:
        font_size = SMALL_FONT_SIZE + 0
    else:
        font_size = MAIN_FONT_SIZE + 0

    max_colour_value = numpy.percentile(numpy.absolute(feature_matrix), 99)
    min_colour_value = -1 * max_colour_value

    for i in range(num_storm_objects):
        this_time_string = time_conversion.unix_sec_to_string(
            storm_times_unix_sec[i], TIME_FORMAT)

        if num_spatial_dimensions == 2:
            _, these_axes_objects = (
                feature_map_plotting.plot_many_2d_feature_maps(
                    feature_matrix=numpy.flip(feature_matrix[i, ...], axis=0),
                    annotation_string_by_panel=annotation_string_by_channel,
                    num_panel_rows=num_panel_rows,
                    colour_map_object=pyplot.cm.seismic,
                    min_colour_value=min_colour_value,
                    max_colour_value=max_colour_value,
                    font_size=font_size))

            plotting_utils.add_linear_colour_bar(
                axes_object_or_list=these_axes_objects,
                values_to_colour=feature_matrix[i, ...],
                colour_map=pyplot.cm.seismic,
                colour_min=min_colour_value,
                colour_max=max_colour_value,
                orientation='horizontal',
                extend_min=True,
                extend_max=True)

            this_title_string = 'Layer "{0:s}", storm "{1:s}" at {2:s}'.format(
                layer_name, storm_ids[i], this_time_string)
            pyplot.suptitle(this_title_string, fontsize=MAIN_FONT_SIZE)

            this_figure_file_name = (
                '{0:s}/storm={1:s}_{2:s}_features.jpg').format(
                    output_dir_name, storm_ids[i].replace('_', '-'),
                    this_time_string)

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

        else:
            for k in range(num_heights):
                _, these_axes_objects = (
                    feature_map_plotting.plot_many_2d_feature_maps(
                        feature_matrix=numpy.flip(feature_matrix[i, :, :,
                                                                 k, :],
                                                  axis=0),
                        annotation_string_by_panel=annotation_string_by_channel,
                        num_panel_rows=num_panel_rows,
                        colour_map_object=pyplot.cm.seismic,
                        min_colour_value=min_colour_value,
                        max_colour_value=max_colour_value,
                        font_size=font_size))

                plotting_utils.add_linear_colour_bar(
                    axes_object_or_list=these_axes_objects,
                    values_to_colour=feature_matrix[i, :, :, k, :],
                    colour_map=pyplot.cm.seismic,
                    colour_min=min_colour_value,
                    colour_max=max_colour_value,
                    orientation='horizontal',
                    extend_min=True,
                    extend_max=True)

                this_title_string = (
                    'Layer "{0:s}", height {1:d} of {2:d}, storm "{3:s}" at '
                    '{4:s}').format(layer_name, k + 1, num_heights,
                                    storm_ids[i], this_time_string)

                pyplot.suptitle(this_title_string, fontsize=MAIN_FONT_SIZE)

                this_figure_file_name = (
                    '{0:s}/storm={1:s}_{2:s}_features_height{3:02d}.jpg'
                ).format(output_dir_name, storm_ids[i].replace('_', '-'),
                         this_time_string, k + 1)

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