コード例 #1
0
def _run(top_tracking_dir_name, first_spc_date_string, last_spc_date_string,
         colour_map_name, min_plot_latitude_deg, max_plot_latitude_deg,
         min_plot_longitude_deg, max_plot_longitude_deg, output_file_name):
    """Plots storm tracks for a continuous time period.

    This is effectively the main method.

    :param top_tracking_dir_name: See documentation at top of file.
    :param first_spc_date_string: Same.
    :param last_spc_date_string: Same.
    :param colour_map_name: Same.
    :param min_plot_latitude_deg: Same.
    :param max_plot_latitude_deg: Same.
    :param min_plot_longitude_deg: Same.
    :param max_plot_longitude_deg: Same.
    :param output_file_name: Same.
    """

    if colour_map_name in ['', 'None']:
        colour_map_object = 'random'
    else:
        colour_map_object = pyplot.cm.get_cmap(colour_map_name)

    if min_plot_latitude_deg <= SENTINEL_VALUE:
        min_plot_latitude_deg = None
    if max_plot_latitude_deg <= SENTINEL_VALUE:
        max_plot_latitude_deg = None
    if min_plot_longitude_deg <= SENTINEL_VALUE:
        min_plot_longitude_deg = None
    if max_plot_longitude_deg <= SENTINEL_VALUE:
        max_plot_longitude_deg = None

    file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name)

    spc_date_strings = time_conversion.get_spc_dates_in_range(
        first_spc_date_string=first_spc_date_string,
        last_spc_date_string=last_spc_date_string)

    list_of_storm_object_tables = []

    for this_spc_date_string in spc_date_strings:
        these_file_names = tracking_io.find_files_one_spc_date(
            top_tracking_dir_name=top_tracking_dir_name,
            tracking_scale_metres2=echo_top_tracking.
            DUMMY_TRACKING_SCALE_METRES2,
            source_name=tracking_utils.SEGMOTION_NAME,
            spc_date_string=this_spc_date_string,
            raise_error_if_missing=False)[0]

        if len(these_file_names) == 0:
            continue

        this_storm_object_table = tracking_io.read_many_files(
            these_file_names)[REQUIRED_COLUMNS]

        list_of_storm_object_tables.append(this_storm_object_table)

        if this_spc_date_string != spc_date_strings[-1]:
            print(MINOR_SEPARATOR_STRING)

        if len(list_of_storm_object_tables) == 1:
            continue

        list_of_storm_object_tables[-1] = list_of_storm_object_tables[
            -1].align(list_of_storm_object_tables[0], axis=1)[0]

    print(SEPARATOR_STRING)
    storm_object_table = pandas.concat(list_of_storm_object_tables,
                                       axis=0,
                                       ignore_index=True)

    # TODO(thunderhoser): HACK
    first_time_unix_sec = time_conversion.string_to_unix_sec(
        '2011-04-27-20', '%Y-%m-%d-%H')
    storm_object_table = storm_object_table.loc[storm_object_table[
        tracking_utils.VALID_TIME_COLUMN] >= first_time_unix_sec]

    if min_plot_latitude_deg is None:
        min_plot_latitude_deg = numpy.min(
            storm_object_table[tracking_utils.CENTROID_LATITUDE_COLUMN].values
        ) - LATLNG_BUFFER_DEG

    if max_plot_latitude_deg is None:
        max_plot_latitude_deg = numpy.max(
            storm_object_table[tracking_utils.CENTROID_LATITUDE_COLUMN].values
        ) + LATLNG_BUFFER_DEG

    if min_plot_longitude_deg is None:
        min_plot_longitude_deg = numpy.min(
            storm_object_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].values
        ) - LATLNG_BUFFER_DEG

    if max_plot_longitude_deg is None:
        max_plot_longitude_deg = numpy.max(
            storm_object_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].values
        ) + LATLNG_BUFFER_DEG

    _, axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=min_plot_latitude_deg,
            max_latitude_deg=max_plot_latitude_deg,
            min_longitude_deg=min_plot_longitude_deg,
            max_longitude_deg=max_plot_longitude_deg,
            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,
                                  num_parallels=NUM_PARALLELS,
                                  line_colour=numpy.full(3, 1.))
    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  num_meridians=NUM_MERIDIANS,
                                  line_colour=numpy.full(3, 1.))

    colour_bar_object = storm_plotting.plot_storm_tracks(
        storm_object_table=storm_object_table,
        axes_object=axes_object,
        basemap_object=basemap_object,
        colour_map_object=colour_map_object)

    valid_times_unix_sec = (
        storm_object_table[tracking_utils.VALID_TIME_COLUMN].values)

    # TODO(thunderhoser): HACK
    tick_times_unix_sec = time_periods.range_and_interval_to_list(
        start_time_unix_sec=numpy.min(valid_times_unix_sec),
        end_time_unix_sec=numpy.max(valid_times_unix_sec),
        time_interval_sec=1800,
        include_endpoint=True)
    tick_time_strings = [
        time_conversion.unix_sec_to_string(t, COLOUR_BAR_TIME_FORMAT)
        for t in tick_times_unix_sec
    ]

    colour_bar_object.set_ticks(tick_times_unix_sec)
    colour_bar_object.set_ticklabels(tick_time_strings)

    print('Saving figure to: "{0:s}"...'.format(output_file_name))
    pyplot.savefig(output_file_name,
                   dpi=FIGURE_RESOLUTION_DPI,
                   pad_inches=0,
                   bbox_inches='tight')
    pyplot.close()
コード例 #2
0
def _run(top_tracking_dir_name, first_spc_date_string, last_spc_date_string,
         colour_map_name, min_plot_latitude_deg, max_plot_latitude_deg,
         min_plot_longitude_deg, max_plot_longitude_deg, output_file_name):
    """Plots storm tracks for a continuous time period.

    This is effectively the main method.

    :param top_tracking_dir_name: See documentation at top of file.
    :param first_spc_date_string: Same.
    :param last_spc_date_string: Same.
    :param colour_map_name: Same.
    :param min_plot_latitude_deg: Same.
    :param max_plot_latitude_deg: Same.
    :param min_plot_longitude_deg: Same.
    :param max_plot_longitude_deg: Same.
    :param output_file_name: Same.
    """

    if colour_map_name in ['', 'None']:
        colour_map_object = 'random'
    else:
        colour_map_object = pyplot.cm.get_cmap(colour_map_name)

    if min_plot_latitude_deg <= SENTINEL_VALUE:
        min_plot_latitude_deg = None
    if max_plot_latitude_deg <= SENTINEL_VALUE:
        max_plot_latitude_deg = None
    if min_plot_longitude_deg <= SENTINEL_VALUE:
        min_plot_longitude_deg = None
    if max_plot_longitude_deg <= SENTINEL_VALUE:
        max_plot_longitude_deg = None

    file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name)

    spc_date_strings = time_conversion.get_spc_dates_in_range(
        first_spc_date_string=first_spc_date_string,
        last_spc_date_string=last_spc_date_string)

    list_of_storm_object_tables = []

    for this_spc_date_string in spc_date_strings:
        these_file_names = tracking_io.find_files_one_spc_date(
            top_tracking_dir_name=top_tracking_dir_name,
            tracking_scale_metres2=echo_top_tracking.
            DUMMY_TRACKING_SCALE_METRES2,
            source_name=tracking_utils.SEGMOTION_NAME,
            spc_date_string=this_spc_date_string,
            raise_error_if_missing=False)[0]

        if len(these_file_names) == 0:
            continue

        this_storm_object_table = tracking_io.read_many_files(
            these_file_names)[REQUIRED_COLUMNS]

        list_of_storm_object_tables.append(this_storm_object_table)

        if this_spc_date_string != spc_date_strings[-1]:
            print(MINOR_SEPARATOR_STRING)

        if len(list_of_storm_object_tables) == 1:
            continue

        list_of_storm_object_tables[-1] = list_of_storm_object_tables[
            -1].align(list_of_storm_object_tables[0], axis=1)[0]

    print(SEPARATOR_STRING)
    storm_object_table = pandas.concat(list_of_storm_object_tables,
                                       axis=0,
                                       ignore_index=True)

    if min_plot_latitude_deg is None:
        min_plot_latitude_deg = numpy.min(
            storm_object_table[tracking_utils.CENTROID_LATITUDE_COLUMN].values
        ) - LATLNG_BUFFER_DEG

    if max_plot_latitude_deg is None:
        max_plot_latitude_deg = numpy.max(
            storm_object_table[tracking_utils.CENTROID_LATITUDE_COLUMN].values
        ) + LATLNG_BUFFER_DEG

    if min_plot_longitude_deg is None:
        min_plot_longitude_deg = numpy.min(
            storm_object_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].values
        ) - LATLNG_BUFFER_DEG

    if max_plot_longitude_deg is None:
        max_plot_longitude_deg = numpy.max(
            storm_object_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].values
        ) + LATLNG_BUFFER_DEG

    _, axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=min_plot_latitude_deg,
            max_latitude_deg=max_plot_latitude_deg,
            min_longitude_deg=min_plot_longitude_deg,
            max_longitude_deg=max_plot_longitude_deg,
            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,
                                  num_parallels=NUM_PARALLELS)

    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  num_meridians=NUM_MERIDIANS)

    storm_plotting.plot_storm_tracks(storm_object_table=storm_object_table,
                                     axes_object=axes_object,
                                     basemap_object=basemap_object,
                                     colour_map_object=colour_map_object)

    print('Saving figure to: "{0:s}"...'.format(output_file_name))
    pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI)
    pyplot.close()
コード例 #3
0
def _plot_tornado_and_radar(top_myrorss_dir_name, radar_field_name,
                            radar_height_m_asl, spc_date_string, tornado_table,
                            tornado_row, output_file_name):
    """Plots one unlinked tornado with radar field.

    :param top_myrorss_dir_name: See documentation at top of file.
    :param radar_field_name: Same.
    :param radar_height_m_asl: Same.
    :param spc_date_string: SPC date for linkage file (format "yyyymmdd").
    :param tornado_table: pandas DataFrame created by
        `linkage._read_input_tornado_reports`.
    :param tornado_row: Will plot only tornado in [j]th row of table, where j =
        `tornado_row`.
    :param output_file_name: Path to output file.  Figure will be saved here.
    """

    tornado_time_unix_sec = tornado_table[
        linkage.EVENT_TIME_COLUMN].values[tornado_row]

    radar_time_unix_sec = number_rounding.round_to_nearest(
        tornado_time_unix_sec, RADAR_TIME_INTERVAL_SEC)

    radar_spc_date_string = time_conversion.time_to_spc_date_string(
        radar_time_unix_sec)

    radar_file_name = myrorss_and_mrms_io.find_raw_file(
        top_directory_name=top_myrorss_dir_name,
        spc_date_string=radar_spc_date_string,
        unix_time_sec=radar_time_unix_sec,
        data_source=radar_utils.MYRORSS_SOURCE_ID,
        field_name=radar_field_name,
        height_m_asl=radar_height_m_asl,
        raise_error_if_missing=spc_date_string == radar_spc_date_string)

    if not os.path.isfile(radar_file_name):
        first_radar_time_unix_sec = number_rounding.ceiling_to_nearest(
            time_conversion.get_start_of_spc_date(spc_date_string),
            RADAR_TIME_INTERVAL_SEC)

        last_radar_time_unix_sec = number_rounding.floor_to_nearest(
            time_conversion.get_end_of_spc_date(spc_date_string),
            RADAR_TIME_INTERVAL_SEC)

        radar_time_unix_sec = max(
            [radar_time_unix_sec, first_radar_time_unix_sec])

        radar_time_unix_sec = min(
            [radar_time_unix_sec, last_radar_time_unix_sec])

        radar_file_name = myrorss_and_mrms_io.find_raw_file(
            top_directory_name=top_myrorss_dir_name,
            spc_date_string=spc_date_string,
            unix_time_sec=radar_time_unix_sec,
            data_source=radar_utils.MYRORSS_SOURCE_ID,
            field_name=radar_field_name,
            height_m_asl=radar_height_m_asl,
            raise_error_if_missing=True)

    radar_metadata_dict = myrorss_and_mrms_io.read_metadata_from_raw_file(
        netcdf_file_name=radar_file_name,
        data_source=radar_utils.MYRORSS_SOURCE_ID)

    sparse_grid_table = (myrorss_and_mrms_io.read_data_from_sparse_grid_file(
        netcdf_file_name=radar_file_name,
        field_name_orig=radar_metadata_dict[
            myrorss_and_mrms_io.FIELD_NAME_COLUMN_ORIG],
        data_source=radar_utils.MYRORSS_SOURCE_ID,
        sentinel_values=radar_metadata_dict[radar_utils.SENTINEL_VALUE_COLUMN])
                         )

    radar_matrix, grid_point_latitudes_deg, grid_point_longitudes_deg = (
        radar_s2f.sparse_to_full_grid(sparse_grid_table=sparse_grid_table,
                                      metadata_dict=radar_metadata_dict))

    radar_matrix = numpy.flip(radar_matrix, axis=0)
    grid_point_latitudes_deg = grid_point_latitudes_deg[::-1]

    axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=numpy.min(grid_point_latitudes_deg),
            max_latitude_deg=numpy.max(grid_point_latitudes_deg),
            min_longitude_deg=numpy.min(grid_point_longitudes_deg),
            max_longitude_deg=numpy.max(grid_point_longitudes_deg),
            resolution_string='i')[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,
                                  num_parallels=NUM_PARALLELS)

    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  num_meridians=NUM_MERIDIANS)

    radar_plotting.plot_latlng_grid(
        field_matrix=radar_matrix,
        field_name=radar_field_name,
        axes_object=axes_object,
        min_grid_point_latitude_deg=numpy.min(grid_point_latitudes_deg),
        min_grid_point_longitude_deg=numpy.min(grid_point_longitudes_deg),
        latitude_spacing_deg=numpy.diff(grid_point_latitudes_deg[:2])[0],
        longitude_spacing_deg=numpy.diff(grid_point_longitudes_deg[:2])[0])

    tornado_latitude_deg = tornado_table[
        linkage.EVENT_LATITUDE_COLUMN].values[tornado_row]

    tornado_longitude_deg = tornado_table[
        linkage.EVENT_LONGITUDE_COLUMN].values[tornado_row]

    axes_object.plot(tornado_longitude_deg,
                     tornado_latitude_deg,
                     linestyle='None',
                     marker=TORNADO_MARKER_TYPE,
                     markersize=TORNADO_MARKER_SIZE,
                     markeredgewidth=TORNADO_MARKER_EDGE_WIDTH,
                     markerfacecolor=plotting_utils.colour_from_numpy_to_tuple(
                         TORNADO_MARKER_COLOUR),
                     markeredgecolor=plotting_utils.colour_from_numpy_to_tuple(
                         TORNADO_MARKER_COLOUR))

    tornado_time_string = time_conversion.unix_sec_to_string(
        tornado_time_unix_sec, TIME_FORMAT)

    title_string = (
        'Unlinked tornado at {0:s}, {1:.2f} deg N, {2:.2f} deg E').format(
            tornado_time_string, tornado_latitude_deg, tornado_longitude_deg)

    pyplot.title(title_string, fontsize=TITLE_FONT_SIZE)

    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)
コード例 #4
0
def _run(top_tracking_dir_name, first_spc_date_string, last_spc_date_string,
         storm_colour, storm_opacity, include_secondary_ids,
         min_plot_latitude_deg, max_plot_latitude_deg, min_plot_longitude_deg,
         max_plot_longitude_deg, top_myrorss_dir_name, radar_field_name,
         radar_height_m_asl, output_dir_name):
    """Plots storm outlines (along with IDs) at each time step.

    This is effectively the main method.

    :param top_tracking_dir_name: See documentation at top of file.
    :param first_spc_date_string: Same.
    :param last_spc_date_string: Same.
    :param storm_colour: Same.
    :param storm_opacity: Same.
    :param include_secondary_ids: Same.
    :param min_plot_latitude_deg: Same.
    :param max_plot_latitude_deg: Same.
    :param min_plot_longitude_deg: Same.
    :param max_plot_longitude_deg: Same.
    :param top_myrorss_dir_name: Same.
    :param radar_field_name: Same.
    :param radar_height_m_asl: Same.
    :param output_dir_name: Same.
    """

    if top_myrorss_dir_name in ['', 'None']:
        top_myrorss_dir_name = None

    if radar_field_name != radar_utils.REFL_NAME:
        radar_height_m_asl = None

    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    spc_date_strings = time_conversion.get_spc_dates_in_range(
        first_spc_date_string=first_spc_date_string,
        last_spc_date_string=last_spc_date_string)

    tracking_file_names = []

    for this_spc_date_string in spc_date_strings:
        tracking_file_names += (tracking_io.find_files_one_spc_date(
            top_tracking_dir_name=top_tracking_dir_name,
            tracking_scale_metres2=DUMMY_TRACKING_SCALE_METRES2,
            source_name=DUMMY_SOURCE_NAME,
            spc_date_string=this_spc_date_string,
            raise_error_if_missing=False)[0])

    storm_object_table = tracking_io.read_many_files(tracking_file_names)
    print(SEPARATOR_STRING)

    latitude_limits_deg, longitude_limits_deg = _get_plotting_limits(
        min_plot_latitude_deg=min_plot_latitude_deg,
        max_plot_latitude_deg=max_plot_latitude_deg,
        min_plot_longitude_deg=min_plot_longitude_deg,
        max_plot_longitude_deg=max_plot_longitude_deg,
        storm_object_table=storm_object_table)

    min_plot_latitude_deg = latitude_limits_deg[0]
    max_plot_latitude_deg = latitude_limits_deg[1]
    min_plot_longitude_deg = longitude_limits_deg[0]
    max_plot_longitude_deg = longitude_limits_deg[1]

    valid_times_unix_sec = numpy.unique(
        storm_object_table[tracking_utils.VALID_TIME_COLUMN].values)
    num_times = len(valid_times_unix_sec)

    for i in range(num_times):
        these_current_rows = numpy.where(
            storm_object_table[tracking_utils.VALID_TIME_COLUMN].values ==
            valid_times_unix_sec[i])[0]

        these_current_subrows = _filter_storm_objects_latlng(
            storm_object_table=storm_object_table.iloc[these_current_rows],
            min_latitude_deg=min_plot_latitude_deg,
            max_latitude_deg=max_plot_latitude_deg,
            min_longitude_deg=min_plot_longitude_deg,
            max_longitude_deg=max_plot_longitude_deg)

        if len(these_current_subrows) == 0:
            continue

        these_current_rows = these_current_rows[these_current_subrows]

        this_storm_object_table = _find_relevant_storm_objects(
            storm_object_table=storm_object_table,
            current_rows=these_current_rows)

        these_latlng_rows = _filter_storm_objects_latlng(
            storm_object_table=this_storm_object_table,
            min_latitude_deg=min_plot_latitude_deg,
            max_latitude_deg=max_plot_latitude_deg,
            min_longitude_deg=min_plot_longitude_deg,
            max_longitude_deg=max_plot_longitude_deg)

        if top_myrorss_dir_name is None:
            this_radar_matrix = None
            these_radar_latitudes_deg = None
            these_radar_longitudes_deg = None
        else:
            this_myrorss_file_name = myrorss_and_mrms_io.find_raw_file(
                top_directory_name=top_myrorss_dir_name,
                unix_time_sec=valid_times_unix_sec[i],
                spc_date_string=time_conversion.time_to_spc_date_string(
                    valid_times_unix_sec[i]),
                field_name=radar_field_name,
                data_source=radar_utils.MYRORSS_SOURCE_ID,
                height_m_asl=radar_height_m_asl,
                raise_error_if_missing=True)

            print(
                'Reading data from: "{0:s}"...'.format(this_myrorss_file_name))

            this_metadata_dict = (
                myrorss_and_mrms_io.read_metadata_from_raw_file(
                    netcdf_file_name=this_myrorss_file_name,
                    data_source=radar_utils.MYRORSS_SOURCE_ID))

            this_sparse_grid_table = (
                myrorss_and_mrms_io.read_data_from_sparse_grid_file(
                    netcdf_file_name=this_myrorss_file_name,
                    field_name_orig=this_metadata_dict[
                        myrorss_and_mrms_io.FIELD_NAME_COLUMN_ORIG],
                    data_source=radar_utils.MYRORSS_SOURCE_ID,
                    sentinel_values=this_metadata_dict[
                        radar_utils.SENTINEL_VALUE_COLUMN]))

            (this_radar_matrix, these_radar_latitudes_deg,
             these_radar_longitudes_deg) = radar_s2f.sparse_to_full_grid(
                 sparse_grid_table=this_sparse_grid_table,
                 metadata_dict=this_metadata_dict)

            this_radar_matrix = numpy.flipud(this_radar_matrix)
            these_radar_latitudes_deg = these_radar_latitudes_deg[::-1]

        _, this_axes_object, this_basemap_object = (
            plotting_utils.create_equidist_cylindrical_map(
                min_latitude_deg=min_plot_latitude_deg,
                max_latitude_deg=max_plot_latitude_deg,
                min_longitude_deg=min_plot_longitude_deg,
                max_longitude_deg=max_plot_longitude_deg,
                resolution_string='i'))

        _plot_storm_outlines_one_time(
            storm_object_table=this_storm_object_table.iloc[these_latlng_rows],
            valid_time_unix_sec=valid_times_unix_sec[i],
            axes_object=this_axes_object,
            basemap_object=this_basemap_object,
            storm_colour=storm_colour,
            storm_opacity=storm_opacity,
            include_secondary_ids=include_secondary_ids,
            output_dir_name=output_dir_name,
            radar_matrix=this_radar_matrix,
            radar_field_name=radar_field_name,
            radar_latitudes_deg=these_radar_latitudes_deg,
            radar_longitudes_deg=these_radar_longitudes_deg)
コード例 #5
0
def _plot_echo_tops(echo_top_matrix_km_asl, latitudes_deg, longitudes_deg,
                    plot_colour_bar, convective_flag_matrix=None):
    """Plots grid of 40-dBZ echo tops.

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

    :param echo_top_matrix_km_asl: M-by-N numpy array of echo tops (km above sea
        level).
    :param latitudes_deg: length-M numpy array of latitudes (deg N).
    :param longitudes_deg: length-N numpy array of longitudes (deg E).
    :param plot_colour_bar: Boolean flag.
    :param convective_flag_matrix: M-by-N numpy array of Boolean flags,
        indicating which grid cells are convective.  If
        `convective_flag_matrix is None`, all grid cells will be plotted.  If
        `convective_flag_matrix is not None`, only convective grid cells will be
        plotted.
    :return: figure_object: Figure handle (instance of
        `matplotlib.figure.Figure`).
    :return: axes_object: Axes handle (instance of
        `matplotlib.axes._subplots.AxesSubplot`).
    :return: basemap_object: Basemap handle (instance of
        `mpl_toolkits.basemap.Basemap`).
    """

    figure_object, axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=numpy.min(latitudes_deg),
            max_latitude_deg=numpy.max(latitudes_deg),
            min_longitude_deg=numpy.min(longitudes_deg),
            max_longitude_deg=numpy.max(longitudes_deg), resolution_string='h'
        )
    )

    # plotting_utils.plot_coastlines(
    #     basemap_object=basemap_object, axes_object=axes_object,
    #     line_colour=plotting_utils.DEFAULT_COUNTRY_COLOUR
    # )
    plotting_utils.plot_countries(
        basemap_object=basemap_object, axes_object=axes_object
    )
    plotting_utils.plot_states_and_provinces(
        basemap_object=basemap_object, axes_object=axes_object
    )
    plotting_utils.plot_parallels(
        basemap_object=basemap_object, axes_object=axes_object,
        num_parallels=NUM_PARALLELS, line_width=0
    )
    plotting_utils.plot_meridians(
        basemap_object=basemap_object, axes_object=axes_object,
        num_meridians=NUM_MERIDIANS, line_width=0
    )

    matrix_to_plot = echo_top_matrix_km_asl + 0.
    if convective_flag_matrix is not None:
        matrix_to_plot[convective_flag_matrix == False] = numpy.nan

    radar_plotting.plot_latlng_grid(
        field_matrix=matrix_to_plot, field_name=radar_utils.ECHO_TOP_40DBZ_NAME,
        axes_object=axes_object,
        min_grid_point_latitude_deg=numpy.min(latitudes_deg),
        min_grid_point_longitude_deg=numpy.min(longitudes_deg),
        latitude_spacing_deg=numpy.diff(latitudes_deg[:2])[0],
        longitude_spacing_deg=numpy.diff(longitudes_deg[:2])[0]
    )

    if not plot_colour_bar:
        return figure_object, axes_object, basemap_object

    colour_map_object, colour_norm_object = (
        radar_plotting.get_default_colour_scheme(
            radar_utils.ECHO_TOP_40DBZ_NAME)
    )

    colour_bar_object = plotting_utils.plot_colour_bar(
        axes_object_or_matrix=axes_object, data_matrix=matrix_to_plot,
        colour_map_object=colour_map_object,
        colour_norm_object=colour_norm_object, orientation_string='horizontal',
        extend_min=False, extend_max=True, fraction_of_axis_length=1.
    )

    colour_bar_object.set_label('40-dBZ echo top (kft ASL)')

    return figure_object, axes_object, basemap_object
コード例 #6
0
def _plot_one_example_one_time(storm_object_table, full_id_string,
                               valid_time_unix_sec, tornado_table,
                               top_myrorss_dir_name, radar_field_name,
                               radar_height_m_asl, latitude_limits_deg,
                               longitude_limits_deg):
    """Plots one example with surrounding context at one time.

    :param storm_object_table: pandas DataFrame, containing only storm objects
        at one time with the relevant primary ID.  Columns are documented in
        `storm_tracking_io.write_file`.
    :param full_id_string: Full ID of storm of interest.
    :param valid_time_unix_sec: Valid time.
    :param tornado_table: pandas DataFrame created by
        `linkage._read_input_tornado_reports`.
    :param top_myrorss_dir_name: See documentation at top of file.
    :param radar_field_name: Same.
    :param radar_height_m_asl: Same.
    :param latitude_limits_deg: See doc for `_get_plotting_limits`.
    :param longitude_limits_deg: Same.
    """

    min_plot_latitude_deg = latitude_limits_deg[0]
    max_plot_latitude_deg = latitude_limits_deg[1]
    min_plot_longitude_deg = longitude_limits_deg[0]
    max_plot_longitude_deg = longitude_limits_deg[1]

    radar_file_name = myrorss_and_mrms_io.find_raw_file(
        top_directory_name=top_myrorss_dir_name,
        spc_date_string=time_conversion.time_to_spc_date_string(
            valid_time_unix_sec),
        unix_time_sec=valid_time_unix_sec,
        data_source=radar_utils.MYRORSS_SOURCE_ID,
        field_name=radar_field_name,
        height_m_asl=radar_height_m_asl,
        raise_error_if_missing=True)

    print('Reading data from: "{0:s}"...'.format(radar_file_name))

    radar_metadata_dict = myrorss_and_mrms_io.read_metadata_from_raw_file(
        netcdf_file_name=radar_file_name,
        data_source=radar_utils.MYRORSS_SOURCE_ID)

    sparse_grid_table = (myrorss_and_mrms_io.read_data_from_sparse_grid_file(
        netcdf_file_name=radar_file_name,
        field_name_orig=radar_metadata_dict[
            myrorss_and_mrms_io.FIELD_NAME_COLUMN_ORIG],
        data_source=radar_utils.MYRORSS_SOURCE_ID,
        sentinel_values=radar_metadata_dict[radar_utils.SENTINEL_VALUE_COLUMN])
                         )

    radar_matrix, grid_point_latitudes_deg, grid_point_longitudes_deg = (
        radar_s2f.sparse_to_full_grid(sparse_grid_table=sparse_grid_table,
                                      metadata_dict=radar_metadata_dict))

    radar_matrix = numpy.flip(radar_matrix, axis=0)
    grid_point_latitudes_deg = grid_point_latitudes_deg[::-1]

    axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=min_plot_latitude_deg,
            max_latitude_deg=max_plot_latitude_deg,
            min_longitude_deg=min_plot_longitude_deg,
            max_longitude_deg=max_plot_longitude_deg,
            resolution_string='i')[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,
                                  num_parallels=NUM_PARALLELS)

    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  num_meridians=NUM_MERIDIANS)

    radar_plotting.plot_latlng_grid(
        field_matrix=radar_matrix,
        field_name=radar_field_name,
        axes_object=axes_object,
        min_grid_point_latitude_deg=numpy.min(grid_point_latitudes_deg),
        min_grid_point_longitude_deg=numpy.min(grid_point_longitudes_deg),
        latitude_spacing_deg=numpy.diff(grid_point_latitudes_deg[:2])[0],
        longitude_spacing_deg=numpy.diff(grid_point_longitudes_deg[:2])[0])

    colour_map_object, colour_norm_object = (
        radar_plotting.get_default_colour_scheme(radar_field_name))

    plotting_utils.plot_colour_bar(axes_object_or_matrix=axes_object,
                                   data_matrix=radar_matrix,
                                   colour_map_object=colour_map_object,
                                   colour_norm_object=colour_norm_object,
                                   orientation_string='horizontal',
                                   extend_min=False,
                                   extend_max=True,
                                   fraction_of_axis_length=0.8)

    first_list, second_list = temporal_tracking.full_to_partial_ids(
        [full_id_string])
    primary_id_string = first_list[0]
    secondary_id_string = second_list[0]

    # Plot outlines of unrelated storms (with different primary IDs).
    this_storm_object_table = storm_object_table.loc[storm_object_table[
        tracking_utils.PRIMARY_ID_COLUMN] != primary_id_string]

    storm_plotting.plot_storm_outlines(
        storm_object_table=this_storm_object_table,
        axes_object=axes_object,
        basemap_object=basemap_object,
        line_width=2,
        line_colour='k',
        line_style='dashed')

    # Plot outlines of related storms (with the same primary ID).
    this_storm_object_table = storm_object_table.loc[
        (storm_object_table[tracking_utils.PRIMARY_ID_COLUMN] ==
         primary_id_string) & (storm_object_table[
             tracking_utils.SECONDARY_ID_COLUMN] != secondary_id_string)]

    this_num_storm_objects = len(this_storm_object_table.index)

    if this_num_storm_objects > 0:
        storm_plotting.plot_storm_outlines(
            storm_object_table=this_storm_object_table,
            axes_object=axes_object,
            basemap_object=basemap_object,
            line_width=2,
            line_colour='k',
            line_style='solid')

        for j in range(len(this_storm_object_table)):
            axes_object.text(
                this_storm_object_table[
                    tracking_utils.CENTROID_LONGITUDE_COLUMN].values[j],
                this_storm_object_table[
                    tracking_utils.CENTROID_LATITUDE_COLUMN].values[j],
                'P',
                fontsize=FONT_SIZE,
                color=FONT_COLOUR,
                fontweight='bold',
                horizontalalignment='center',
                verticalalignment='center')

    # Plot outline of storm of interest (same secondary ID).
    this_storm_object_table = storm_object_table.loc[storm_object_table[
        tracking_utils.SECONDARY_ID_COLUMN] == secondary_id_string]

    storm_plotting.plot_storm_outlines(
        storm_object_table=this_storm_object_table,
        axes_object=axes_object,
        basemap_object=basemap_object,
        line_width=4,
        line_colour='k',
        line_style='solid')

    this_num_storm_objects = len(this_storm_object_table.index)

    plot_forecast = (this_num_storm_objects > 0 and FORECAST_PROBABILITY_COLUMN
                     in list(this_storm_object_table))

    if plot_forecast:
        this_polygon_object_latlng = this_storm_object_table[
            tracking_utils.LATLNG_POLYGON_COLUMN].values[0]

        this_latitude_deg = numpy.min(
            numpy.array(this_polygon_object_latlng.exterior.xy[1]))

        this_longitude_deg = this_storm_object_table[
            tracking_utils.CENTROID_LONGITUDE_COLUMN].values[0]

        label_string = 'Prob = {0:.3f}\nat {1:s}'.format(
            this_storm_object_table[FORECAST_PROBABILITY_COLUMN].values[0],
            time_conversion.unix_sec_to_string(valid_time_unix_sec,
                                               TORNADO_TIME_FORMAT))

        bounding_box_dict = {
            'facecolor':
            plotting_utils.colour_from_numpy_to_tuple(
                PROBABILITY_BACKGROUND_COLOUR),
            'alpha':
            PROBABILITY_BACKGROUND_OPACITY,
            'edgecolor':
            'k',
            'linewidth':
            1
        }

        axes_object.text(this_longitude_deg,
                         this_latitude_deg,
                         label_string,
                         fontsize=FONT_SIZE,
                         color=plotting_utils.colour_from_numpy_to_tuple(
                             PROBABILITY_FONT_COLOUR),
                         fontweight='bold',
                         bbox=bounding_box_dict,
                         horizontalalignment='center',
                         verticalalignment='top',
                         zorder=1e10)

    tornado_latitudes_deg = tornado_table[linkage.EVENT_LATITUDE_COLUMN].values
    tornado_longitudes_deg = tornado_table[
        linkage.EVENT_LONGITUDE_COLUMN].values

    tornado_times_unix_sec = tornado_table[linkage.EVENT_TIME_COLUMN].values
    tornado_time_strings = [
        time_conversion.unix_sec_to_string(t, TORNADO_TIME_FORMAT)
        for t in tornado_times_unix_sec
    ]

    axes_object.plot(tornado_longitudes_deg,
                     tornado_latitudes_deg,
                     linestyle='None',
                     marker=TORNADO_MARKER_TYPE,
                     markersize=TORNADO_MARKER_SIZE,
                     markeredgewidth=TORNADO_MARKER_EDGE_WIDTH,
                     markerfacecolor=plotting_utils.colour_from_numpy_to_tuple(
                         TORNADO_MARKER_COLOUR),
                     markeredgecolor=plotting_utils.colour_from_numpy_to_tuple(
                         TORNADO_MARKER_COLOUR))

    num_tornadoes = len(tornado_latitudes_deg)

    for j in range(num_tornadoes):
        axes_object.text(tornado_longitudes_deg[j] + 0.02,
                         tornado_latitudes_deg[j] - 0.02,
                         tornado_time_strings[j],
                         fontsize=FONT_SIZE,
                         color=FONT_COLOUR,
                         fontweight='bold',
                         horizontalalignment='left',
                         verticalalignment='top')
コード例 #7
0
def _plot_one_field(reflectivity_matrix_dbz, latitudes_deg, longitudes_deg,
                    add_colour_bar, panel_letter, output_file_name):
    """Plots reflectivity field from one dataset.

    :param reflectivity_matrix_dbz: See doc for `_read_file`.
    :param latitudes_deg: Same.
    :param longitudes_deg: Same.
    :param add_colour_bar: Boolean flag.
    :param panel_letter: Panel letter (will be printed at top left of figure).
    :param output_file_name: Path to output file (figure will be saved here).
    """

    (figure_object, axes_object,
     basemap_object) = plotting_utils.create_equidist_cylindrical_map(
         min_latitude_deg=numpy.min(latitudes_deg),
         max_latitude_deg=numpy.max(latitudes_deg),
         min_longitude_deg=numpy.min(longitudes_deg),
         max_longitude_deg=numpy.max(longitudes_deg),
         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,
                                  num_parallels=NUM_PARALLELS)
    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  num_meridians=NUM_MERIDIANS)

    radar_plotting.plot_latlng_grid(
        field_matrix=reflectivity_matrix_dbz,
        field_name=RADAR_FIELD_NAME,
        axes_object=axes_object,
        min_grid_point_latitude_deg=numpy.min(latitudes_deg),
        min_grid_point_longitude_deg=numpy.min(longitudes_deg),
        latitude_spacing_deg=latitudes_deg[1] - latitudes_deg[0],
        longitude_spacing_deg=longitudes_deg[1] - longitudes_deg[0])

    if add_colour_bar:
        colour_map_object, colour_norm_object = (
            radar_plotting.get_default_colour_scheme(RADAR_FIELD_NAME))

        plotting_utils.plot_colour_bar(axes_object_or_matrix=axes_object,
                                       data_matrix=reflectivity_matrix_dbz,
                                       colour_map_object=colour_map_object,
                                       colour_norm_object=colour_norm_object,
                                       orientation_string='horizontal',
                                       padding=0.05,
                                       extend_min=False,
                                       extend_max=True,
                                       fraction_of_axis_length=1.)

    plotting_utils.label_axes(axes_object=axes_object,
                              label_string='({0:s})'.format(panel_letter),
                              y_coord_normalized=1.03)

    print('Saving figure to: "{0:s}"...'.format(output_file_name))
    figure_object.savefig(output_file_name,
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)
コード例 #8
0
def _plot_attribution_one_track(storm_object_table, plot_legend, plot_x_ticks,
                                legend_font_size=None, legend_location=None):
    """Plots tornado attribution for one storm track.

    :param storm_object_table: pandas DataFrame created by
        `_get_track1_for_simple_pred`, `_get_track2_for_simple_pred`, or
        `_get_track_for_simple_succ`.
    :param plot_legend: Boolean flag.
    :param plot_x_ticks: Boolean flag.
    :param legend_font_size: Font size in legend (used only if
        `plot_legend == True`).
    :param legend_location: Legend location (used only if
        `plot_legend == True`).
    :return: figure_object: See doc for `_plot_interp_two_times`.
    :return: axes_object: Same.
    """

    centroid_x_coords = storm_object_table[
        tracking_utils.CENTROID_X_COLUMN].values
    centroid_y_coords = storm_object_table[
        tracking_utils.CENTROID_Y_COLUMN].values
    secondary_id_strings = storm_object_table[
        tracking_utils.SECONDARY_ID_COLUMN].values

    storm_object_table = storm_object_table.assign(**{
        tracking_utils.CENTROID_LONGITUDE_COLUMN: centroid_x_coords,
        tracking_utils.CENTROID_LATITUDE_COLUMN: centroid_y_coords
    })

    figure_object, axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=numpy.min(centroid_y_coords),
            max_latitude_deg=numpy.max(centroid_y_coords),
            min_longitude_deg=numpy.min(centroid_x_coords),
            max_longitude_deg=numpy.max(centroid_x_coords)
        )
    )

    storm_plotting.plot_storm_tracks(
        storm_object_table=storm_object_table, axes_object=axes_object,
        basemap_object=basemap_object, colour_map_object=None,
        constant_colour=TRACK_COLOUR, line_width=TRACK_WIDTH,
        start_marker_type=None, end_marker_type=None)

    tornadic_flags = storm_object_table[TORNADIC_FLAG_COLUMN].values
    main_tornadic_flags = storm_object_table[SPECIAL_FLAG_COLUMN].values

    legend_handles = [None] * 3
    legend_strings = [None] * 3

    for i in range(len(centroid_x_coords)):
        if main_tornadic_flags[i]:
            this_handle = axes_object.plot(
                centroid_x_coords[i], centroid_y_coords[i], linestyle='None',
                marker=TORNADIC_STORM_MARKER_TYPE,
                markersize=TORNADIC_STORM_MARKER_SIZE,
                markerfacecolor=TORNADIC_STORM_COLOUR,
                markeredgecolor=TORNADIC_STORM_COLOUR,
                markeredgewidth=TORNADIC_STORM_MARKER_EDGE_WIDTH
            )[0]

            legend_handles[0] = this_handle
            legend_strings[0] = 'Object initially linked\nto tornado'

            axes_object.text(
                centroid_x_coords[i], centroid_y_coords[i] - TEXT_OFFSET,
                secondary_id_strings[i], color=TORNADIC_STORM_COLOUR,
                fontsize=DEFAULT_FONT_SIZE, fontweight='bold',
                horizontalalignment='center', verticalalignment='top')
        else:
            if tornadic_flags[i]:
                this_edge_colour = TORNADIC_STORM_COLOUR
                this_face_colour = TORNADIC_STORM_COLOUR
            else:
                this_edge_colour = NON_TORNADIC_STORM_COLOUR
                this_face_colour = 'white'

            this_handle = axes_object.plot(
                centroid_x_coords[i], centroid_y_coords[i], linestyle='None',
                marker=DEFAULT_MARKER_TYPE, markersize=DEFAULT_MARKER_SIZE,
                markerfacecolor=this_face_colour,
                markeredgecolor=this_edge_colour,
                markeredgewidth=DEFAULT_MARKER_EDGE_WIDTH
            )[0]

            if tornadic_flags[i] and legend_handles[1] is None:
                legend_handles[1] = this_handle
                legend_strings[1] = 'Also linked to tornado'

            if not tornadic_flags[i] and legend_handles[2] is None:
                legend_handles[2] = this_handle
                legend_strings[2] = 'Not linked to tornado'

            axes_object.text(
                centroid_x_coords[i], centroid_y_coords[i] - TEXT_OFFSET,
                secondary_id_strings[i], color=this_edge_colour,
                fontsize=DEFAULT_FONT_SIZE, fontweight='bold',
                horizontalalignment='center', verticalalignment='top')

    if plot_x_ticks:
        storm_times_minutes = storm_object_table[
            tracking_utils.VALID_TIME_COLUMN].values

        x_tick_values, unique_indices = numpy.unique(
            centroid_x_coords, return_index=True)
        x_tick_labels = [
            '{0:d}'.format(int(numpy.round(storm_times_minutes[i])))
            for i in unique_indices
        ]

        axes_object.set_xticks(x_tick_values)
        axes_object.set_xticklabels(x_tick_labels)
        axes_object.set_xlabel('Storm time (minutes)')
    else:
        axes_object.set_xticks([], [])
        axes_object.set_xlabel(r'Time $\longrightarrow$')

    axes_object.set_yticks([], [])

    y_min, y_max = axes_object.get_ylim()
    axes_object.set_ylim([y_min - 0.25, y_max])

    if plot_legend:
        axes_object.legend(
            legend_handles, legend_strings, fontsize=legend_font_size,
            loc=legend_location)

    return figure_object, axes_object
コード例 #9
0
def _plot_tropical_sites(output_file_name):
    """Plots tropical sites.

    :param output_file_name: Path to output file.  Figure will be saved here.
    """

    site_names = list(TROPICAL_SITE_TO_LATLNG.keys())
    latitudes_deg_n = numpy.array([
        TROPICAL_SITE_TO_LATLNG[n][0] for n in site_names
    ])
    longitudes_deg_e = numpy.array([
        TROPICAL_SITE_TO_LATLNG[n][1] for n in site_names
    ])

    min_latitude_deg_n = numpy.floor(numpy.min(latitudes_deg_n) - 1.)
    max_latitude_deg_n = numpy.ceil(numpy.max(latitudes_deg_n) + 1.)
    min_longitude_deg_e = numpy.floor(numpy.min(longitudes_deg_e) - 1.)
    max_longitude_deg_e = numpy.ceil(numpy.max(longitudes_deg_e) + 1.)

    min_latitude_deg_n = max([min_latitude_deg_n, 10.])
    max_latitude_deg_n = min([max_latitude_deg_n, 90.])
    min_longitude_deg_e = max([min_longitude_deg_e, 0.])
    max_longitude_deg_e = min([max_longitude_deg_e, 359.9999])

    figure_object, axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=min_latitude_deg_n,
            max_latitude_deg=max_latitude_deg_n,
            min_longitude_deg=min_longitude_deg_e,
            max_longitude_deg=max_longitude_deg_e,
            resolution_string='l'
        )
    )

    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_parallels(
        basemap_object=basemap_object, axes_object=axes_object,
        num_parallels=NUM_PARALLELS, line_colour=GRID_LINE_COLOUR,
        line_width=GRID_LINE_WIDTH, font_size=FONT_SIZE
    )
    plotting_utils.plot_meridians(
        basemap_object=basemap_object, axes_object=axes_object,
        num_meridians=NUM_MERIDIANS, line_colour=GRID_LINE_COLOUR,
        line_width=GRID_LINE_WIDTH, font_size=FONT_SIZE
    )

    x_coords, y_coords = basemap_object(longitudes_deg_e, latitudes_deg_n)

    axes_object.plot(
        x_coords, y_coords, linestyle='None',
        marker=MARKER_TYPE, markersize=MARKER_SIZE, markeredgewidth=0,
        markerfacecolor=TROPICAL_COLOUR, markeredgecolor=TROPICAL_COLOUR
    )

    for i in range(len(site_names)):
        horiz_align_string = TROPICAL_SITE_TO_ALIGNMENT[site_names[i]][0]
        vertical_align_string = TROPICAL_SITE_TO_ALIGNMENT[site_names[i]][1]

        if horiz_align_string == 'left':
            this_x_coord = x_coords[i] + 0.75
        elif horiz_align_string == 'right':
            this_x_coord = x_coords[i] - 0.75
        else:
            this_x_coord = x_coords[i] + 0.

        if vertical_align_string == 'bottom':
            this_y_coord = y_coords[i] + 0.75
        elif vertical_align_string == 'top':
            this_y_coord = y_coords[i] - 0.75
        else:
            this_y_coord = y_coords[i] + 0.

        axes_object.text(
            this_x_coord, this_y_coord, site_names[i],
            fontsize=FONT_SIZE, color=TROPICAL_COLOUR,
            horizontalalignment=horiz_align_string,
            verticalalignment=vertical_align_string
        )

    print('Saving figure to: "{0:s}"...'.format(output_file_name))
    figure_object.savefig(
        output_file_name, dpi=FIGURE_RESOLUTION_DPI,
        pad_inches=0, bbox_inches='tight'
    )
    pyplot.close(figure_object)
コード例 #10
0
def _plot_assorted2_sites(output_file_name):
    """Plots sites in the "Assorted2" set.

    :param output_file_name: Path to output file.  Figure will be saved here.
    """

    site_names = list(ASSORTED2_SITE_TO_LATLNG.keys())
    latitudes_deg_n = numpy.array([
        ASSORTED2_SITE_TO_LATLNG[n][0] for n in site_names
    ])
    longitudes_deg_e = numpy.array([
        ASSORTED2_SITE_TO_LATLNG[n][1] for n in site_names
    ])

    figure_object, axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=10., max_latitude_deg=90.,
            min_longitude_deg=0., max_longitude_deg=359.9999,
            resolution_string='l'
        )
    )

    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_parallels(
        basemap_object=basemap_object, axes_object=axes_object,
        num_parallels=NUM_PARALLELS, line_colour=GRID_LINE_COLOUR,
        line_width=GRID_LINE_WIDTH, font_size=FONT_SIZE
    )
    plotting_utils.plot_meridians(
        basemap_object=basemap_object, axes_object=axes_object,
        num_meridians=NUM_MERIDIANS, line_colour=GRID_LINE_COLOUR,
        line_width=GRID_LINE_WIDTH, font_size=FONT_SIZE
    )

    arctic_indices = numpy.where(latitudes_deg_n >= 66.5)[0]
    arctic_site_names = [site_names[i] for i in arctic_indices]
    arctic_x_coords, arctic_y_coords = basemap_object(
        longitudes_deg_e[arctic_indices], latitudes_deg_n[arctic_indices]
    )

    axes_object.plot(
        arctic_x_coords, arctic_y_coords, linestyle='None',
        marker=MARKER_TYPE, markersize=MARKER_SIZE, markeredgewidth=0,
        markerfacecolor=ARCTIC_COLOUR, markeredgecolor=ARCTIC_COLOUR
    )

    for i in range(len(arctic_site_names)):
        axes_object.text(
            arctic_x_coords[i], arctic_y_coords[i] - 2., arctic_site_names[i],
            fontsize=FONT_SIZE, color=ARCTIC_COLOUR,
            horizontalalignment='center', verticalalignment='top'
        )

    mid_latitude_indices = numpy.where(numpy.logical_and(
        latitudes_deg_n >= 30., latitudes_deg_n < 66.5
    ))[0]
    mid_latitude_site_names = [site_names[i] for i in mid_latitude_indices]
    mid_latitude_x_coords, mid_latitude_y_coords = basemap_object(
        longitudes_deg_e[mid_latitude_indices],
        latitudes_deg_n[mid_latitude_indices]
    )

    axes_object.plot(
        mid_latitude_x_coords, mid_latitude_y_coords, linestyle='None',
        marker=MARKER_TYPE, markersize=MARKER_SIZE, markeredgewidth=0,
        markerfacecolor=MID_LATITUDE_COLOUR, markeredgecolor=MID_LATITUDE_COLOUR
    )

    for i in range(len(mid_latitude_site_names)):
        axes_object.text(
            mid_latitude_x_coords[i], mid_latitude_y_coords[i] + 2.,
            mid_latitude_site_names[i],
            fontsize=FONT_SIZE, color=MID_LATITUDE_COLOUR,
            horizontalalignment='center', verticalalignment='bottom'
        )

    tropical_indices = numpy.where(latitudes_deg_n < 30.)[0]
    tropical_site_names = [site_names[i] for i in tropical_indices]
    tropical_x_coords, tropical_y_coords = basemap_object(
        longitudes_deg_e[tropical_indices], latitudes_deg_n[tropical_indices]
    )

    axes_object.plot(
        tropical_x_coords, tropical_y_coords, linestyle='None',
        marker=MARKER_TYPE, markersize=MARKER_SIZE, markeredgewidth=0,
        markerfacecolor=TROPICAL_COLOUR, markeredgecolor=TROPICAL_COLOUR
    )

    for i in range(len(tropical_site_names)):
        axes_object.text(
            tropical_x_coords[i], tropical_y_coords[i] + 2.,
            tropical_site_names[i],
            fontsize=FONT_SIZE, color=TROPICAL_COLOUR,
            horizontalalignment='center', verticalalignment='bottom'
        )

    print('Saving figure to: "{0:s}"...'.format(output_file_name))
    figure_object.savefig(
        output_file_name, dpi=FIGURE_RESOLUTION_DPI,
        pad_inches=0, bbox_inches='tight'
    )
    pyplot.close(figure_object)
コード例 #11
0
def _run(storm_metafile_name, top_tracking_dir_name, lead_time_seconds,
         output_file_name):
    """Plots spatial distribution of examples (storm objects) in file.

    This is effectively the main method.

    :param storm_metafile_name: See documentation at top of file.
    :param top_tracking_dir_name: Same.
    :param lead_time_seconds: Same.
    :param output_file_name: Same.
    """

    file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name)

    # Read storm metadata.
    print(
        'Reading storm metadata from: "{0:s}"...'.format(storm_metafile_name))
    orig_full_id_strings, orig_times_unix_sec = (
        tracking_io.read_ids_and_times(storm_metafile_name))
    orig_primary_id_strings = temporal_tracking.full_to_partial_ids(
        orig_full_id_strings)[0]

    # Find relevant tracking files.
    spc_date_strings = [
        time_conversion.time_to_spc_date_string(t) for t in orig_times_unix_sec
    ]
    spc_date_strings += [
        time_conversion.time_to_spc_date_string(t + lead_time_seconds)
        for t in orig_times_unix_sec
    ]
    spc_date_strings = list(set(spc_date_strings))

    tracking_file_names = []

    for this_spc_date_string in spc_date_strings:
        tracking_file_names += tracking_io.find_files_one_spc_date(
            top_tracking_dir_name=top_tracking_dir_name,
            tracking_scale_metres2=DUMMY_TRACKING_SCALE_METRES2,
            source_name=tracking_utils.SEGMOTION_NAME,
            spc_date_string=this_spc_date_string,
            raise_error_if_missing=False)[0]

    file_times_unix_sec = numpy.array(
        [tracking_io.file_name_to_time(f) for f in tracking_file_names],
        dtype=int)

    num_orig_storm_objects = len(orig_full_id_strings)
    num_files = len(file_times_unix_sec)
    keep_file_flags = numpy.full(num_files, 0, dtype=bool)

    for i in range(num_orig_storm_objects):
        these_flags = numpy.logical_and(
            file_times_unix_sec >= orig_times_unix_sec[i],
            file_times_unix_sec <= orig_times_unix_sec[i] + lead_time_seconds)
        keep_file_flags = numpy.logical_or(keep_file_flags, these_flags)

    del file_times_unix_sec
    keep_file_indices = numpy.where(keep_file_flags)[0]
    tracking_file_names = [tracking_file_names[k] for k in keep_file_indices]

    # Read relevant tracking files.
    num_files = len(tracking_file_names)
    storm_object_tables = [None] * num_files
    print(SEPARATOR_STRING)

    for i in range(num_files):
        print('Reading data from: "{0:s}"...'.format(tracking_file_names[i]))
        this_table = tracking_io.read_file(tracking_file_names[i])

        storm_object_tables[i] = this_table.loc[this_table[
            tracking_utils.PRIMARY_ID_COLUMN].isin(
                numpy.array(orig_primary_id_strings))]

        if i == 0:
            continue

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

    storm_object_table = pandas.concat(storm_object_tables,
                                       axis=0,
                                       ignore_index=True)
    print(SEPARATOR_STRING)

    # Find relevant storm objects.
    orig_object_rows = tracking_utils.find_storm_objects(
        all_id_strings=storm_object_table[
            tracking_utils.FULL_ID_COLUMN].values.tolist(),
        all_times_unix_sec=storm_object_table[
            tracking_utils.VALID_TIME_COLUMN].values,
        id_strings_to_keep=orig_full_id_strings,
        times_to_keep_unix_sec=orig_times_unix_sec)

    good_object_rows = numpy.array([], dtype=int)

    for i in range(num_orig_storm_objects):
        # Non-merging successors only!

        first_rows = temporal_tracking.find_successors(
            storm_object_table=storm_object_table,
            target_row=orig_object_rows[i],
            num_seconds_forward=lead_time_seconds,
            max_num_sec_id_changes=1,
            change_type_string=temporal_tracking.SPLIT_STRING,
            return_all_on_path=True)

        second_rows = temporal_tracking.find_successors(
            storm_object_table=storm_object_table,
            target_row=orig_object_rows[i],
            num_seconds_forward=lead_time_seconds,
            max_num_sec_id_changes=0,
            change_type_string=temporal_tracking.MERGER_STRING,
            return_all_on_path=True)

        first_rows = first_rows.tolist()
        second_rows = second_rows.tolist()
        these_rows = set(first_rows) & set(second_rows)
        these_rows = numpy.array(list(these_rows), dtype=int)

        good_object_rows = numpy.concatenate((good_object_rows, these_rows))

    good_object_rows = numpy.unique(good_object_rows)
    storm_object_table = storm_object_table.iloc[good_object_rows]

    times_of_day_sec = numpy.mod(
        storm_object_table[tracking_utils.VALID_TIME_COLUMN].values,
        NUM_SECONDS_IN_DAY)
    storm_object_table = storm_object_table.assign(
        **{tracking_utils.VALID_TIME_COLUMN: times_of_day_sec})

    min_plot_latitude_deg = -LATLNG_BUFFER_DEG + numpy.min(
        storm_object_table[tracking_utils.CENTROID_LATITUDE_COLUMN].values)
    max_plot_latitude_deg = LATLNG_BUFFER_DEG + numpy.max(
        storm_object_table[tracking_utils.CENTROID_LATITUDE_COLUMN].values)
    min_plot_longitude_deg = -LATLNG_BUFFER_DEG + numpy.min(
        storm_object_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].values)
    max_plot_longitude_deg = LATLNG_BUFFER_DEG + numpy.max(
        storm_object_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].values)

    _, axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=min_plot_latitude_deg,
            max_latitude_deg=max_plot_latitude_deg,
            min_longitude_deg=min_plot_longitude_deg,
            max_longitude_deg=max_plot_longitude_deg,
            resolution_string='i'))

    plotting_utils.plot_coastlines(basemap_object=basemap_object,
                                   axes_object=axes_object,
                                   line_colour=BORDER_COLOUR,
                                   line_width=BORDER_WIDTH * 2)
    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,
                                  num_parallels=NUM_PARALLELS,
                                  line_width=BORDER_WIDTH)
    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  num_meridians=NUM_MERIDIANS,
                                  line_width=BORDER_WIDTH)

    # colour_bar_object = storm_plotting.plot_storm_tracks(
    #     storm_object_table=storm_object_table, axes_object=axes_object,
    #     basemap_object=basemap_object, colour_map_object=COLOUR_MAP_OBJECT,
    #     colour_min_unix_sec=0, colour_max_unix_sec=NUM_SECONDS_IN_DAY - 1,
    #     line_width=TRACK_LINE_WIDTH,
    #     start_marker_type=None, end_marker_type=None
    # )

    colour_bar_object = storm_plotting.plot_storm_centroids(
        storm_object_table=storm_object_table,
        axes_object=axes_object,
        basemap_object=basemap_object,
        colour_map_object=COLOUR_MAP_OBJECT,
        colour_min_unix_sec=0,
        colour_max_unix_sec=NUM_SECONDS_IN_DAY - 1)

    tick_times_unix_sec = numpy.linspace(0,
                                         NUM_SECONDS_IN_DAY,
                                         num=NUM_HOURS_IN_DAY + 1,
                                         dtype=int)
    tick_times_unix_sec = tick_times_unix_sec[:-1]
    tick_times_unix_sec = tick_times_unix_sec[::2]

    tick_time_strings = [
        time_conversion.unix_sec_to_string(t, COLOUR_BAR_TIME_FORMAT)
        for t in tick_times_unix_sec
    ]

    colour_bar_object.set_ticks(tick_times_unix_sec)
    colour_bar_object.set_ticklabels(tick_time_strings)

    print('Saving figure to: "{0:s}"...'.format(output_file_name))
    pyplot.savefig(output_file_name,
                   dpi=FIGURE_RESOLUTION_DPI,
                   pad_inches=0,
                   bbox_inches='tight')
    pyplot.close()
コード例 #12
0
def _plot_schema(storm_object_table, output_file_name):
    """Plots schema for storm-velocity estimation.

    :param storm_object_table: pandas DataFrame created by
        `_create_tracking_data`.
    :param output_file_name: Path to output file (figure will be saved here).
    """

    centroid_x_coords = storm_object_table[
        tracking_utils.CENTROID_X_COLUMN].values
    centroid_y_coords = storm_object_table[
        tracking_utils.CENTROID_Y_COLUMN].values
    secondary_id_strings = storm_object_table[
        tracking_utils.SECONDARY_ID_COLUMN].values

    storm_object_table = storm_object_table.assign(
        **{
            tracking_utils.CENTROID_LONGITUDE_COLUMN: centroid_x_coords,
            tracking_utils.CENTROID_LATITUDE_COLUMN: centroid_y_coords
        })

    figure_object, axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=numpy.min(centroid_y_coords),
            max_latitude_deg=numpy.max(centroid_y_coords),
            min_longitude_deg=numpy.min(centroid_x_coords),
            max_longitude_deg=numpy.max(centroid_x_coords)))

    storm_plotting.plot_storm_tracks(storm_object_table=storm_object_table,
                                     axes_object=axes_object,
                                     basemap_object=basemap_object,
                                     colour_map_object=None,
                                     constant_colour=TRACK_COLOUR,
                                     line_width=TRACK_WIDTH,
                                     start_marker_type=None,
                                     end_marker_type=None)

    num_storm_objects = len(storm_object_table.index)

    predecessor_rows = temporal_tracking.find_predecessors(
        storm_object_table=storm_object_table,
        target_row=num_storm_objects - 1,
        num_seconds_back=100,
        return_all_on_path=False)

    legend_handles = [None] * 3
    legend_strings = [None] * 3

    this_handle = axes_object.plot(centroid_x_coords[[0, 0]],
                                   centroid_y_coords[[0, 0]],
                                   color=TRACK_COLOUR,
                                   linestyle='solid',
                                   linewidth=TRACK_WIDTH)[0]

    legend_handles[-1] = this_handle
    legend_strings[-1] = 'Storm track'

    for i in range(num_storm_objects):
        if i in predecessor_rows or i == num_storm_objects - 1:
            this_colour = SPECIAL_STORM_COLOUR
        else:
            this_colour = DEFAULT_STORM_COLOUR

        this_handle = axes_object.plot(centroid_x_coords[i],
                                       centroid_y_coords[i],
                                       linestyle='None',
                                       marker=MARKER_TYPE,
                                       markersize=MARKER_SIZE,
                                       markerfacecolor=this_colour,
                                       markeredgecolor=this_colour,
                                       markeredgewidth=MARKER_EDGE_WIDTH)[0]

        if i in predecessor_rows or i == num_storm_objects - 1:
            legend_handles[0] = this_handle
            legend_strings[0] = 'Object used in\nvelocity estimate'
        else:
            legend_handles[1] = this_handle
            legend_strings[1] = 'Object not used'

        axes_object.text(centroid_x_coords[i],
                         centroid_y_coords[i] - TEXT_OFFSET,
                         secondary_id_strings[i],
                         color=this_colour,
                         fontsize=FONT_SIZE,
                         fontweight='bold',
                         horizontalalignment='center',
                         verticalalignment='top')

    axes_object.set_yticks([], [])

    storm_times_minutes = storm_object_table[
        tracking_utils.VALID_TIME_COLUMN].values

    x_tick_values, unique_indices = numpy.unique(centroid_x_coords,
                                                 return_index=True)
    x_tick_labels = [
        '{0:d}'.format(storm_times_minutes[i]) for i in unique_indices
    ]

    axes_object.set_xticks(x_tick_values)
    axes_object.set_xticklabels(x_tick_labels)
    axes_object.set_xlabel('Time (minutes)')

    axes_object.legend(legend_handles,
                       legend_strings,
                       fontsize=FONT_SIZE,
                       loc=(0.02, 0.55))

    print('Saving figure to: "{0:s}"...'.format(output_file_name))
    figure_object.savefig(output_file_name,
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)
コード例 #13
0
def _plot_one_example_one_time(
        storm_object_table, full_id_string, valid_time_unix_sec,
        tornado_table, top_myrorss_dir_name, radar_field_name,
        radar_height_m_asl, latitude_limits_deg, longitude_limits_deg):
    """Plots one example with surrounding context at one time.

    :param storm_object_table: pandas DataFrame, containing only storm objects
        at one time with the relevant primary ID.  Columns are documented in
        `storm_tracking_io.write_file`.
    :param full_id_string: Full ID of storm of interest.
    :param valid_time_unix_sec: Valid time.
    :param tornado_table: pandas DataFrame created by
        `linkage._read_input_tornado_reports`.
    :param top_myrorss_dir_name: See documentation at top of file.
    :param radar_field_name: Same.
    :param radar_height_m_asl: Same.
    :param latitude_limits_deg: See doc for `_get_plotting_limits`.
    :param longitude_limits_deg: Same.
    """

    min_plot_latitude_deg = latitude_limits_deg[0]
    max_plot_latitude_deg = latitude_limits_deg[1]
    min_plot_longitude_deg = longitude_limits_deg[0]
    max_plot_longitude_deg = longitude_limits_deg[1]

    radar_file_name = myrorss_and_mrms_io.find_raw_file_inexact_time(
        top_directory_name=top_myrorss_dir_name,
        desired_time_unix_sec=valid_time_unix_sec,
        spc_date_string=time_conversion.time_to_spc_date_string(
            valid_time_unix_sec),
        data_source=radar_utils.MYRORSS_SOURCE_ID,
        field_name=radar_field_name, height_m_asl=radar_height_m_asl,
        max_time_offset_sec=
        myrorss_and_mrms_io.DEFAULT_MAX_TIME_OFFSET_FOR_NON_SHEAR_SEC,
        raise_error_if_missing=True)

    print('Reading data from: "{0:s}"...'.format(radar_file_name))

    radar_metadata_dict = myrorss_and_mrms_io.read_metadata_from_raw_file(
        netcdf_file_name=radar_file_name,
        data_source=radar_utils.MYRORSS_SOURCE_ID)

    sparse_grid_table = (
        myrorss_and_mrms_io.read_data_from_sparse_grid_file(
            netcdf_file_name=radar_file_name,
            field_name_orig=radar_metadata_dict[
                myrorss_and_mrms_io.FIELD_NAME_COLUMN_ORIG],
            data_source=radar_utils.MYRORSS_SOURCE_ID,
            sentinel_values=radar_metadata_dict[
                radar_utils.SENTINEL_VALUE_COLUMN]
        )
    )

    radar_matrix, grid_point_latitudes_deg, grid_point_longitudes_deg = (
        radar_s2f.sparse_to_full_grid(
            sparse_grid_table=sparse_grid_table,
            metadata_dict=radar_metadata_dict)
    )

    radar_matrix = numpy.flip(radar_matrix, axis=0)
    grid_point_latitudes_deg = grid_point_latitudes_deg[::-1]

    axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=min_plot_latitude_deg,
            max_latitude_deg=max_plot_latitude_deg,
            min_longitude_deg=min_plot_longitude_deg,
            max_longitude_deg=max_plot_longitude_deg, resolution_string='h'
        )[1:]
    )

    plotting_utils.plot_coastlines(
        basemap_object=basemap_object, axes_object=axes_object,
        line_colour=plotting_utils.DEFAULT_COUNTRY_COLOUR)

    plotting_utils.plot_countries(
        basemap_object=basemap_object, axes_object=axes_object)

    plotting_utils.plot_states_and_provinces(
        basemap_object=basemap_object, axes_object=axes_object)

    plotting_utils.plot_parallels(
        basemap_object=basemap_object, axes_object=axes_object,
        num_parallels=NUM_PARALLELS, line_width=0)

    plotting_utils.plot_meridians(
        basemap_object=basemap_object, axes_object=axes_object,
        num_meridians=NUM_MERIDIANS, line_width=0)

    radar_plotting.plot_latlng_grid(
        field_matrix=radar_matrix, field_name=radar_field_name,
        axes_object=axes_object,
        min_grid_point_latitude_deg=numpy.min(grid_point_latitudes_deg),
        min_grid_point_longitude_deg=numpy.min(grid_point_longitudes_deg),
        latitude_spacing_deg=numpy.diff(grid_point_latitudes_deg[:2])[0],
        longitude_spacing_deg=numpy.diff(grid_point_longitudes_deg[:2])[0]
    )

    colour_map_object, colour_norm_object = (
        radar_plotting.get_default_colour_scheme(radar_field_name)
    )

    plotting_utils.plot_colour_bar(
        axes_object_or_matrix=axes_object, data_matrix=radar_matrix,
        colour_map_object=colour_map_object,
        colour_norm_object=colour_norm_object, orientation_string='horizontal',
        padding=0.05, extend_min=False, extend_max=True,
        fraction_of_axis_length=0.8)

    first_list, second_list = temporal_tracking.full_to_partial_ids(
        [full_id_string]
    )
    primary_id_string = first_list[0]
    secondary_id_string = second_list[0]

    # Plot outlines of unrelated storms (with different primary IDs).
    this_storm_object_table = storm_object_table.loc[
        storm_object_table[tracking_utils.PRIMARY_ID_COLUMN] !=
        primary_id_string
    ]

    storm_plotting.plot_storm_outlines(
        storm_object_table=this_storm_object_table, axes_object=axes_object,
        basemap_object=basemap_object, line_width=AUXILIARY_STORM_WIDTH,
        line_colour='k', line_style='dashed')

    # Plot outlines of related storms (with the same primary ID).
    this_storm_object_table = storm_object_table.loc[
        (storm_object_table[tracking_utils.PRIMARY_ID_COLUMN] ==
         primary_id_string) &
        (storm_object_table[tracking_utils.SECONDARY_ID_COLUMN] !=
         secondary_id_string)
    ]

    this_num_storm_objects = len(this_storm_object_table.index)

    if this_num_storm_objects > 0:
        storm_plotting.plot_storm_outlines(
            storm_object_table=this_storm_object_table, axes_object=axes_object,
            basemap_object=basemap_object, line_width=AUXILIARY_STORM_WIDTH,
            line_colour='k', line_style='solid'
        )

        for j in range(len(this_storm_object_table)):
            axes_object.text(
                this_storm_object_table[
                    tracking_utils.CENTROID_LONGITUDE_COLUMN
                ].values[j],
                this_storm_object_table[
                    tracking_utils.CENTROID_LATITUDE_COLUMN
                ].values[j],
                'P',
                fontsize=MAIN_FONT_SIZE, color=FONT_COLOUR, fontweight='bold',
                horizontalalignment='center', verticalalignment='center'
            )

    # Plot outline of storm of interest (same secondary ID).
    this_storm_object_table = storm_object_table.loc[
        storm_object_table[tracking_utils.SECONDARY_ID_COLUMN] ==
        secondary_id_string
    ]

    storm_plotting.plot_storm_outlines(
        storm_object_table=this_storm_object_table, axes_object=axes_object,
        basemap_object=basemap_object, line_width=MAIN_STORM_WIDTH,
        line_colour='k', line_style='solid')

    this_num_storm_objects = len(this_storm_object_table.index)

    plot_forecast = (
        this_num_storm_objects > 0 and
        FORECAST_PROBABILITY_COLUMN in list(this_storm_object_table)
    )

    if plot_forecast:
        label_string = 'Prob = {0:.3f}\nat {1:s}'.format(
            this_storm_object_table[FORECAST_PROBABILITY_COLUMN].values[0],
            time_conversion.unix_sec_to_string(
                valid_time_unix_sec, TORNADO_TIME_FORMAT)
        )

        axes_object.set_title(
            label_string.replace('\n', ' '), fontsize=TITLE_FONT_SIZE
        )

    tornado_id_strings = tornado_table[tornado_io.TORNADO_ID_COLUMN].values

    for this_tornado_id_string in numpy.unique(tornado_id_strings):
        these_rows = numpy.where(
            tornado_id_strings == this_tornado_id_string
        )[0]

        this_tornado_table = tornado_table.iloc[these_rows].sort_values(
            linkage.EVENT_TIME_COLUMN, axis=0, ascending=True, inplace=False
        )
        _plot_one_tornado(
            tornado_table=this_tornado_table, axes_object=axes_object
        )
コード例 #14
0
def _run(top_orig_tracking_dir_name, top_new_tracking_dir_name,
         first_spc_date_string, last_spc_date_string, output_file_name):
    """Plots storms that were removed by remove_storms_outside_conus.py.

    This is effectively the main method.

    :param top_orig_tracking_dir_name: See documentation at top of file.
    :param top_new_tracking_dir_name: Same.
    :param first_spc_date_string: Same.
    :param last_spc_date_string: Same.
    :param output_file_name: Same.
    """

    file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name)

    spc_date_strings = time_conversion.get_spc_dates_in_range(
        first_spc_date_string=first_spc_date_string,
        last_spc_date_string=last_spc_date_string)

    orig_tracking_file_names = []

    for d in spc_date_strings:
        orig_tracking_file_names += tracking_io.find_files_one_spc_date(
            top_tracking_dir_name=top_orig_tracking_dir_name,
            tracking_scale_metres2=DUMMY_TRACKING_SCALE_METRES2,
            source_name=tracking_utils.SEGMOTION_NAME,
            spc_date_string=d,
            raise_error_if_missing=False)[0]

    valid_times_unix_sec = numpy.array(
        [tracking_io.file_name_to_time(f) for f in orig_tracking_file_names],
        dtype=int)

    new_tracking_file_names = [
        tracking_io.find_file(
            top_tracking_dir_name=top_new_tracking_dir_name,
            tracking_scale_metres2=DUMMY_TRACKING_SCALE_METRES2,
            source_name=tracking_utils.SEGMOTION_NAME,
            valid_time_unix_sec=t,
            spc_date_string=time_conversion.time_to_spc_date_string(t),
            raise_error_if_missing=True) for t in valid_times_unix_sec
    ]

    orig_storm_object_table = tracking_io.read_many_files(
        orig_tracking_file_names)
    print(SEPARATOR_STRING)

    new_storm_object_table = tracking_io.read_many_files(
        new_tracking_file_names)
    print(SEPARATOR_STRING)

    orig_storm_id_strings = (
        orig_storm_object_table[tracking_utils.FULL_ID_COLUMN].values.tolist())
    orig_storm_times_unix_sec = (
        orig_storm_object_table[tracking_utils.VALID_TIME_COLUMN].values)
    new_storm_id_strings = (
        new_storm_object_table[tracking_utils.FULL_ID_COLUMN].values.tolist())
    new_storm_times_unix_sec = (
        new_storm_object_table[tracking_utils.VALID_TIME_COLUMN].values)

    num_orig_storm_objects = len(orig_storm_object_table.index)
    orig_kept_flags = numpy.full(num_orig_storm_objects, 0, dtype=bool)

    these_indices = tracking_utils.find_storm_objects(
        all_id_strings=orig_storm_id_strings,
        all_times_unix_sec=orig_storm_times_unix_sec,
        id_strings_to_keep=new_storm_id_strings,
        times_to_keep_unix_sec=new_storm_times_unix_sec,
        allow_missing=False)

    orig_kept_flags[these_indices] = True
    orig_removed_indices = numpy.where(numpy.invert(orig_kept_flags))[0]
    print('{0:d} of {1:d} storm objects were outside CONUS.'.format(
        len(orig_removed_indices), num_orig_storm_objects))

    removed_storm_object_table = orig_storm_object_table.iloc[
        orig_removed_indices]
    removed_latitudes_deg = removed_storm_object_table[
        tracking_utils.CENTROID_LATITUDE_COLUMN].values

    removed_longitudes_deg = removed_storm_object_table[
        tracking_utils.CENTROID_LONGITUDE_COLUMN].values

    figure_object, axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=numpy.min(removed_latitudes_deg) - 1.,
            max_latitude_deg=numpy.max(removed_latitudes_deg) + 1.,
            min_longitude_deg=numpy.min(removed_longitudes_deg) - 1.,
            max_longitude_deg=numpy.max(removed_longitudes_deg) + 1.,
            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,
                                  num_parallels=NUM_PARALLELS)
    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  num_meridians=NUM_MERIDIANS)

    conus_latitudes_deg, conus_longitudes_deg = (
        conus_boundary.read_from_netcdf())
    conus_latitudes_deg, conus_longitudes_deg = conus_boundary.erode_boundary(
        latitudes_deg=conus_latitudes_deg,
        longitudes_deg=conus_longitudes_deg,
        erosion_distance_metres=EROSION_DISTANCE_METRES)

    axes_object.plot(conus_longitudes_deg,
                     conus_latitudes_deg,
                     color=LINE_COLOUR,
                     linestyle='solid',
                     linewidth=LINE_WIDTH)
    axes_object.plot(removed_longitudes_deg,
                     removed_latitudes_deg,
                     linestyle='None',
                     marker=MARKER_TYPE,
                     markersize=MARKER_SIZE,
                     markeredgewidth=0,
                     markerfacecolor=MARKER_COLOUR,
                     markeredgecolor=MARKER_COLOUR)

    print('Saving figure to: "{0:s}"...'.format(output_file_name))
    figure_object.savefig(output_file_name,
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)
コード例 #15
0
ファイル: plot_sites.py プロジェクト: thunderhoser/ml4rt
def _run(tropical_example_dir_name, non_tropical_example_dir_name,
         output_file_name):
    """Plots all sites wtih data.

    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 output_file_name: Same.
    """

    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])

    tropical_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=False)

    non_tropical_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=False)

    latitudes_deg_n = numpy.array([])
    longitudes_deg_e = numpy.array([])

    for this_file_name in tropical_file_names:
        print('Reading data from: "{0:s}"...'.format(this_file_name))
        this_example_dict = example_io.read_file(this_file_name)

        these_latitudes_deg_n = example_utils.get_field_from_dict(
            example_dict=this_example_dict,
            field_name=example_utils.LATITUDE_NAME)
        these_longitudes_deg_e = example_utils.get_field_from_dict(
            example_dict=this_example_dict,
            field_name=example_utils.LONGITUDE_NAME)

        latitudes_deg_n = numpy.concatenate(
            (latitudes_deg_n, these_latitudes_deg_n))
        longitudes_deg_e = numpy.concatenate(
            (longitudes_deg_e, these_longitudes_deg_e))

    for this_file_name in non_tropical_file_names:
        print('Reading data from: "{0:s}"...'.format(this_file_name))
        this_example_dict = example_io.read_file(this_file_name)

        these_latitudes_deg_n = example_utils.get_field_from_dict(
            example_dict=this_example_dict,
            field_name=example_utils.LATITUDE_NAME)
        these_longitudes_deg_e = example_utils.get_field_from_dict(
            example_dict=this_example_dict,
            field_name=example_utils.LONGITUDE_NAME)

        latitudes_deg_n = numpy.concatenate(
            (latitudes_deg_n, these_latitudes_deg_n))
        longitudes_deg_e = numpy.concatenate(
            (longitudes_deg_e, these_longitudes_deg_e))

    coord_matrix = numpy.transpose(
        numpy.vstack((latitudes_deg_n, longitudes_deg_e)))
    coord_matrix = number_rounding.round_to_nearest(coord_matrix,
                                                    LATLNG_TOLERANCE_DEG)
    coord_matrix = numpy.unique(coord_matrix, axis=0)

    latitudes_deg_n = coord_matrix[:, 0]
    longitudes_deg_e = coord_matrix[:, 1]

    figure_object, axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=MIN_PLOT_LATITUDE_DEG_N,
            max_latitude_deg=MAX_PLOT_LATITUDE_DEG_N,
            min_longitude_deg=MIN_PLOT_LONGITUDE_DEG_E,
            max_longitude_deg=MAX_PLOT_LONGITUDE_DEG_E,
            resolution_string='l'))

    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_parallels(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  num_parallels=NUM_PARALLELS,
                                  line_colour=GRID_LINE_COLOUR,
                                  line_width=GRID_LINE_WIDTH,
                                  font_size=FONT_SIZE)
    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  num_meridians=NUM_MERIDIANS,
                                  line_colour=GRID_LINE_COLOUR,
                                  line_width=GRID_LINE_WIDTH,
                                  font_size=FONT_SIZE)

    arctic_indices = numpy.where(latitudes_deg_n >= 66.5)[0]
    print(len(arctic_indices))

    arctic_x_coords, arctic_y_coords = basemap_object(
        longitudes_deg_e[arctic_indices], latitudes_deg_n[arctic_indices])
    axes_object.plot(arctic_x_coords,
                     arctic_y_coords,
                     linestyle='None',
                     marker=MARKER_TYPE,
                     markersize=MARKER_SIZE,
                     markeredgewidth=0,
                     markerfacecolor=ARCTIC_COLOUR,
                     markeredgecolor=ARCTIC_COLOUR)

    mid_latitude_indices = numpy.where(
        numpy.logical_and(latitudes_deg_n >= 30., latitudes_deg_n < 66.5))[0]
    print(len(mid_latitude_indices))

    mid_latitude_x_coords, mid_latitude_y_coords = basemap_object(
        longitudes_deg_e[mid_latitude_indices],
        latitudes_deg_n[mid_latitude_indices])
    axes_object.plot(mid_latitude_x_coords,
                     mid_latitude_y_coords,
                     linestyle='None',
                     marker=MARKER_TYPE,
                     markersize=MARKER_SIZE,
                     markeredgewidth=0,
                     markerfacecolor=MID_LATITUDE_COLOUR,
                     markeredgecolor=MID_LATITUDE_COLOUR)

    tropical_indices = numpy.where(latitudes_deg_n < 30.)[0]
    print(len(tropical_indices))

    tropical_x_coords, tropical_y_coords = basemap_object(
        longitudes_deg_e[tropical_indices], latitudes_deg_n[tropical_indices])
    axes_object.plot(tropical_x_coords,
                     tropical_y_coords,
                     linestyle='None',
                     marker=MARKER_TYPE,
                     markersize=MARKER_SIZE,
                     markeredgewidth=0,
                     markerfacecolor=TROPICAL_COLOUR,
                     markeredgecolor=TROPICAL_COLOUR)

    file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name)

    print('Saving figure to: "{0:s}"...'.format(output_file_name))
    figure_object.savefig(output_file_name,
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)
コード例 #16
0
def _plot_interp_two_times(storm_object_table, tornado_table, legend_font_size,
                           legend_position_string):
    """Plots interpolation for one pair of times.

    :param storm_object_table: See doc for `_get_interp_data_for_split`.
    :param tornado_table: Same.
    :param legend_font_size: Font size in legend.
    :param legend_position_string: Legend position.
    :return: figure_object: Figure handle (instance of
        `matplotlib.figure.Figure`).
    :return: axes_object: Axes handle (instance of
        `matplotlib.axes._subplots.AxesSubplot`).
    """

    centroid_x_coords = (
        storm_object_table[tracking_utils.CENTROID_X_COLUMN].values
    )
    centroid_y_coords = (
        storm_object_table[tracking_utils.CENTROID_Y_COLUMN].values
    )
    storm_times_minutes = (
        storm_object_table[tracking_utils.VALID_TIME_COLUMN].values
    ).astype(float)
    secondary_id_strings = (
        storm_object_table[tracking_utils.SECONDARY_ID_COLUMN].values
    )

    storm_object_table = storm_object_table.assign(**{
        tracking_utils.CENTROID_LONGITUDE_COLUMN: centroid_x_coords,
        tracking_utils.CENTROID_LATITUDE_COLUMN: centroid_y_coords
    })

    figure_object, axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=numpy.min(centroid_y_coords),
            max_latitude_deg=numpy.max(centroid_y_coords),
            min_longitude_deg=numpy.min(centroid_x_coords),
            max_longitude_deg=numpy.max(centroid_x_coords)
        )
    )

    storm_plotting.plot_storm_tracks(
        storm_object_table=storm_object_table, axes_object=axes_object,
        basemap_object=basemap_object, colour_map_object=None,
        constant_colour=TRACK_COLOUR, line_width=TRACK_WIDTH,
        start_marker_type=None, end_marker_type=None)

    num_storm_objects = len(storm_object_table.index)
    legend_handles = []
    legend_strings = []

    for i in range(num_storm_objects):
        this_patch_object = PolygonPatch(
            storm_object_table[POLYGON_COLUMN].values[i],
            lw=0, ec=NON_INTERP_COLOUR, fc=NON_INTERP_COLOUR,
            alpha=POLYGON_OPACITY)

        axes_object.add_patch(this_patch_object)

    this_handle = axes_object.plot(
        storm_object_table[tracking_utils.CENTROID_X_COLUMN].values,
        storm_object_table[tracking_utils.CENTROID_Y_COLUMN].values,
        linestyle='None', marker=DEFAULT_MARKER_TYPE,
        markersize=DEFAULT_MARKER_SIZE, markerfacecolor=NON_INTERP_COLOUR,
        markeredgecolor=NON_INTERP_COLOUR,
        markeredgewidth=DEFAULT_MARKER_EDGE_WIDTH
    )[0]

    legend_handles.append(this_handle)
    legend_strings.append('Actual storm')

    for i in range(num_storm_objects):
        axes_object.text(
            centroid_x_coords[i], centroid_y_coords[i] - TEXT_OFFSET,
            secondary_id_strings[i], color=TRACK_COLOUR,
            fontsize=DEFAULT_FONT_SIZE, fontweight='bold',
            horizontalalignment='center', verticalalignment='top')

    tornado_time_minutes = tornado_table[TORNADO_TIME_COLUMN].values[0]
    previous_time_minutes = numpy.max(
        storm_times_minutes[storm_times_minutes < tornado_time_minutes]
    )
    next_time_minutes = numpy.min(
        storm_times_minutes[storm_times_minutes > tornado_time_minutes]
    )

    previous_object_indices = numpy.where(
        storm_times_minutes == previous_time_minutes
    )[0]
    next_object_indices = numpy.where(
        storm_times_minutes == next_time_minutes
    )[0]

    previous_x_coord = numpy.mean(centroid_x_coords[previous_object_indices])
    previous_y_coord = numpy.mean(centroid_y_coords[previous_object_indices])
    next_x_coord = numpy.mean(centroid_x_coords[next_object_indices])
    next_y_coord = numpy.mean(centroid_y_coords[next_object_indices])

    if len(next_object_indices) == 1:
        midpoint_x_coord = previous_x_coord
        midpoint_y_coord = previous_y_coord
        midpoint_label_string = 'Midpoint of {0:s} and {1:s}'.format(
            secondary_id_strings[previous_object_indices[0]],
            secondary_id_strings[previous_object_indices[1]]
        )

        line_x_coords = numpy.array([midpoint_x_coord, next_x_coord])
        line_y_coords = numpy.array([midpoint_y_coord, next_y_coord])
    else:
        midpoint_x_coord = next_x_coord
        midpoint_y_coord = next_y_coord
        midpoint_label_string = 'Midpoint of {0:s} and {1:s}'.format(
            secondary_id_strings[next_object_indices[0]],
            secondary_id_strings[next_object_indices[1]]
        )

        line_x_coords = numpy.array([previous_x_coord, midpoint_x_coord])
        line_y_coords = numpy.array([previous_y_coord, midpoint_y_coord])

    this_handle = axes_object.plot(
        midpoint_x_coord, midpoint_y_coord, linestyle='None',
        marker=DEFAULT_MARKER_TYPE, markersize=DEFAULT_MARKER_SIZE,
        markerfacecolor=MIDPOINT_COLOUR, markeredgecolor=MIDPOINT_COLOUR,
        markeredgewidth=DEFAULT_MARKER_EDGE_WIDTH
    )[0]

    legend_handles.append(this_handle)
    legend_strings.append(midpoint_label_string)

    this_ratio = (
        (tornado_time_minutes - previous_time_minutes) /
        (next_time_minutes - previous_time_minutes)
    )
    interp_x_coord = previous_x_coord + (
        this_ratio * (next_x_coord - previous_x_coord)
    )
    interp_y_coord = previous_y_coord + (
        this_ratio * (next_y_coord - previous_y_coord)
    )

    if len(next_object_indices) == 1:
        x_offset = interp_x_coord - next_x_coord
        y_offset = interp_y_coord - next_y_coord
        interp_polygon_object_xy = storm_object_table[POLYGON_COLUMN].values[
            next_object_indices[0]
        ]
    else:
        x_offset = interp_x_coord - previous_x_coord
        y_offset = interp_y_coord - previous_y_coord
        interp_polygon_object_xy = storm_object_table[POLYGON_COLUMN].values[
            previous_object_indices[0]
        ]

    interp_polygon_object_xy = polygons.vertex_arrays_to_polygon_object(
        exterior_x_coords=(
            x_offset + numpy.array(interp_polygon_object_xy.exterior.xy[0])
        ),
        exterior_y_coords=(
            y_offset + numpy.array(interp_polygon_object_xy.exterior.xy[1])
        )
    )

    this_patch_object = PolygonPatch(
        interp_polygon_object_xy, lw=0, ec=INTERP_COLOUR, fc=INTERP_COLOUR,
        alpha=POLYGON_OPACITY)
    axes_object.add_patch(this_patch_object)

    this_handle = axes_object.plot(
        interp_x_coord, interp_y_coord, linestyle='None',
        marker=DEFAULT_MARKER_TYPE, markersize=DEFAULT_MARKER_SIZE,
        markerfacecolor=INTERP_COLOUR, markeredgecolor=INTERP_COLOUR,
        markeredgewidth=DEFAULT_MARKER_EDGE_WIDTH
    )[0]

    legend_handles.append(this_handle)
    legend_strings.append('Interpolated storm')

    this_handle = axes_object.plot(
        line_x_coords, line_y_coords,
        linestyle='dashed', color=MIDPOINT_COLOUR, linewidth=4
    )[0]

    legend_handles.insert(-1, this_handle)
    legend_strings.insert(-1, 'Interpolation line')

    this_handle = axes_object.plot(
        tornado_table[TORNADO_X_COLUMN].values[0],
        tornado_table[TORNADO_Y_COLUMN].values[0], linestyle='None',
        marker=TORNADO_MARKER_TYPE, markersize=TORNADO_MARKER_SIZE,
        markerfacecolor=INTERP_COLOUR, markeredgecolor=INTERP_COLOUR,
        markeredgewidth=TORNADO_MARKER_EDGE_WIDTH
    )[0]

    legend_handles.insert(1, this_handle)
    this_string = 'Tornado (at {0:d} min)'.format(
        int(numpy.round(tornado_time_minutes))
    )
    legend_strings.insert(1, this_string)

    x_tick_values, unique_indices = numpy.unique(
        centroid_x_coords, return_index=True)
    x_tick_labels = [
        '{0:d}'.format(int(numpy.round(storm_times_minutes[i])))
        for i in unique_indices
    ]

    axes_object.set_xticks(x_tick_values)
    axes_object.set_xticklabels(x_tick_labels)
    axes_object.set_xlabel('Storm time (minutes)')

    axes_object.set_yticks([], [])
    axes_object.legend(
        legend_handles, legend_strings, fontsize=legend_font_size,
        loc=legend_position_string)

    return figure_object, axes_object
コード例 #17
0
def _run(input_file_name, border_colour, polygon_colour, min_plot_latitude_deg,
         max_plot_latitude_deg, min_plot_longitude_deg, max_plot_longitude_deg,
         output_file_name):
    """Plots tornado-warning polygons.

    This is effectively the main method.

    :param input_file_name: See documentation at top of file.
    :param border_colour: Same.
    :param polygon_colour: Same.
    :param min_plot_latitude_deg: Same.
    :param max_plot_latitude_deg: Same.
    :param min_plot_longitude_deg: Same.
    :param max_plot_longitude_deg: Same.
    :param output_file_name: Same.
    """

    print('Reading data from: "{0:s}"...'.format(input_file_name))
    pickle_file_handle = open(input_file_name, 'rb')
    warning_table = pickle.load(pickle_file_handle)
    pickle_file_handle.close()

    num_warnings = len(warning_table.index)
    warning_min_latitudes_deg = numpy.full(num_warnings, numpy.nan)
    warning_max_latitudes_deg = numpy.full(num_warnings, numpy.nan)
    warning_min_longitudes_deg = numpy.full(num_warnings, numpy.nan)
    warning_max_longitudes_deg = numpy.full(num_warnings, numpy.nan)

    for i in range(num_warnings):
        this_vertex_dict_latlng = polygons.polygon_object_to_vertex_arrays(
            warning_table[POLYGON_COLUMN].values[i])

        warning_min_latitudes_deg[i] = numpy.min(
            this_vertex_dict_latlng[polygons.EXTERIOR_Y_COLUMN])
        warning_max_latitudes_deg[i] = numpy.max(
            this_vertex_dict_latlng[polygons.EXTERIOR_Y_COLUMN])
        warning_min_longitudes_deg[i] = numpy.min(
            this_vertex_dict_latlng[polygons.EXTERIOR_X_COLUMN])
        warning_max_longitudes_deg[i] = numpy.max(
            this_vertex_dict_latlng[polygons.EXTERIOR_X_COLUMN])

    if min_plot_latitude_deg <= SENTINEL_VALUE:
        min_plot_latitude_deg = (numpy.min(warning_min_latitudes_deg) -
                                 LATLNG_BUFFER_DEG)

    if max_plot_latitude_deg <= SENTINEL_VALUE:
        max_plot_latitude_deg = (numpy.max(warning_min_latitudes_deg) +
                                 LATLNG_BUFFER_DEG)

    if min_plot_longitude_deg <= SENTINEL_VALUE:
        min_plot_longitude_deg = (numpy.min(warning_min_longitudes_deg) -
                                  LATLNG_BUFFER_DEG)

    if max_plot_longitude_deg <= SENTINEL_VALUE:
        max_plot_longitude_deg = (numpy.max(warning_min_longitudes_deg) +
                                  LATLNG_BUFFER_DEG)

    good_latitude_flags = numpy.logical_and(
        warning_max_latitudes_deg >= min_plot_latitude_deg,
        warning_min_latitudes_deg <= max_plot_latitude_deg)

    good_longitude_flags = numpy.logical_and(
        warning_max_longitudes_deg >= min_plot_longitude_deg,
        warning_min_longitudes_deg <= max_plot_longitude_deg)

    good_indices = numpy.where(
        numpy.logical_and(good_latitude_flags, good_longitude_flags))[0]

    warning_table = warning_table.iloc[good_indices]

    _, axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=min_plot_latitude_deg,
            max_latitude_deg=max_plot_latitude_deg,
            min_longitude_deg=min_plot_longitude_deg,
            max_longitude_deg=max_plot_longitude_deg,
            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,
                                  num_parallels=NUM_PARALLELS)

    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  num_meridians=NUM_MERIDIANS)

    num_warnings = len(warning_table.index)
    polygon_colour_tuple = plotting_utils.colour_from_numpy_to_tuple(
        polygon_colour)

    for i in range(num_warnings):
        this_vertex_dict_latlng = polygons.polygon_object_to_vertex_arrays(
            warning_table[POLYGON_COLUMN].values[i])

        these_x_coords_metres, these_y_coords_metres = basemap_object(
            this_vertex_dict_latlng[polygons.EXTERIOR_X_COLUMN],
            this_vertex_dict_latlng[polygons.EXTERIOR_Y_COLUMN])

        axes_object.plot(these_x_coords_metres,
                         these_y_coords_metres,
                         color=polygon_colour_tuple,
                         linestyle='solid',
                         linewidth=LINE_WIDTH)

    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)
コード例 #18
0
def _run(top_linkage_dir_name, genesis_only, max_link_distance_metres,
         first_spc_date_string, last_spc_date_string, num_colours,
         min_plot_latitude_deg, max_plot_latitude_deg, min_plot_longitude_deg,
         max_plot_longitude_deg, output_file_name):
    """Plots tornado reports, storm tracks, and linkages.

    This is effectively the main method.

    :param top_linkage_dir_name: See documentation at top of file.
    :param genesis_only: Same.
    :param max_link_distance_metres: Same.
    :param first_spc_date_string: Same.
    :param last_spc_date_string: Same.
    :param num_colours: Same.
    :param min_plot_latitude_deg: Same.
    :param max_plot_latitude_deg: Same.
    :param min_plot_longitude_deg: Same.
    :param max_plot_longitude_deg: Same.
    :param output_file_name: Same.
    """

    if max_link_distance_metres < 0:
        max_link_distance_metres = None

    colour_map_object = _truncate_colour_map(
        orig_colour_map_object=pyplot.cm.get_cmap('YlOrRd'),
        num_colours=num_colours)

    event_type_string = (linkage.TORNADOGENESIS_EVENT_STRING
                         if genesis_only else linkage.TORNADO_EVENT_STRING)

    if min_plot_latitude_deg <= SENTINEL_VALUE:
        min_plot_latitude_deg = None
    if max_plot_latitude_deg <= SENTINEL_VALUE:
        max_plot_latitude_deg = None
    if min_plot_longitude_deg <= SENTINEL_VALUE:
        min_plot_longitude_deg = None
    if max_plot_longitude_deg <= SENTINEL_VALUE:
        max_plot_longitude_deg = None

    file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name)

    spc_date_strings = time_conversion.get_spc_dates_in_range(
        first_spc_date_string=first_spc_date_string,
        last_spc_date_string=last_spc_date_string)

    list_of_linkage_tables = []
    list_of_tornado_tables = []
    linkage_metadata_dict = None

    for this_spc_date_string in spc_date_strings:
        this_file_name = linkage.find_linkage_file(
            top_directory_name=top_linkage_dir_name,
            event_type_string=event_type_string,
            spc_date_string=this_spc_date_string,
            raise_error_if_missing=False)

        if not os.path.isfile(this_file_name):
            continue

        print('Reading data from: "{0:s}"...'.format(this_file_name))
        this_linkage_table, linkage_metadata_dict, this_tornado_table = (
            linkage.read_linkage_file(this_file_name))

        list_of_linkage_tables.append(this_linkage_table)
        list_of_tornado_tables.append(this_tornado_table)

        if len(list_of_linkage_tables) == 1:
            continue

        list_of_linkage_tables[-1] = list_of_linkage_tables[-1].align(
            list_of_linkage_tables[0], axis=1)[0]

        list_of_tornado_tables[-1] = list_of_tornado_tables[-1].align(
            list_of_tornado_tables[0], axis=1)[0]

    print(SEPARATOR_STRING)

    storm_to_tornadoes_table = pandas.concat(list_of_linkage_tables,
                                             axis=0,
                                             ignore_index=True)
    tornado_table = pandas.concat(list_of_tornado_tables,
                                  axis=0,
                                  ignore_index=True)

    column_dict_old_to_new = {
        linkage.EVENT_TIME_COLUMN: tornado_io.TIME_COLUMN,
        linkage.EVENT_LATITUDE_COLUMN: tornado_io.LATITUDE_COLUMN,
        linkage.EVENT_LONGITUDE_COLUMN: tornado_io.LONGITUDE_COLUMN
    }

    tornado_table.rename(columns=column_dict_old_to_new, inplace=True)
    tornado_table = tornado_io.segments_to_tornadoes(tornado_table)

    tornado_table = tornado_table.assign(
        **{
            SHORT_TORNADO_ID_COLUMN:
            _long_to_short_tornado_ids(tornado_table[
                tornado_io.TORNADO_ID_COLUMN].values)
        })

    if min_plot_latitude_deg is None:
        min_plot_latitude_deg = numpy.min(
            storm_to_tornadoes_table[tracking_utils.CENTROID_LATITUDE_COLUMN].
            values) - LATLNG_BUFFER_DEG

    if max_plot_latitude_deg is None:
        max_plot_latitude_deg = numpy.max(
            storm_to_tornadoes_table[tracking_utils.CENTROID_LATITUDE_COLUMN].
            values) + LATLNG_BUFFER_DEG

    if min_plot_longitude_deg is None:
        min_plot_longitude_deg = numpy.min(
            storm_to_tornadoes_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].
            values) - LATLNG_BUFFER_DEG

    if max_plot_longitude_deg is None:
        max_plot_longitude_deg = numpy.max(
            storm_to_tornadoes_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].
            values) + LATLNG_BUFFER_DEG

    # TODO(thunderhoser): Should maybe restrict this to an inner domain.
    storm_to_tornadoes_table = storm_to_tornadoes_table.loc[
        (storm_to_tornadoes_table[tracking_utils.CENTROID_LATITUDE_COLUMN] >=
         min_plot_latitude_deg)
        & (storm_to_tornadoes_table[tracking_utils.CENTROID_LATITUDE_COLUMN] <=
           max_plot_latitude_deg)]

    storm_to_tornadoes_table = storm_to_tornadoes_table.loc[
        (storm_to_tornadoes_table[tracking_utils.CENTROID_LONGITUDE_COLUMN] >=
         min_plot_longitude_deg)
        & (storm_to_tornadoes_table[tracking_utils.CENTROID_LONGITUDE_COLUMN]
           <= max_plot_longitude_deg)]

    tornado_io.subset_tornadoes(tornado_table=tornado_table,
                                min_latitude_deg=min_plot_latitude_deg,
                                max_latitude_deg=max_plot_latitude_deg,
                                min_longitude_deg=min_plot_longitude_deg,
                                max_longitude_deg=max_plot_longitude_deg)

    # TODO(thunderhoser): Make this subsetting optional.
    storm_to_tornadoes_table = _subset_storms_by_time(
        storm_to_tornadoes_table=storm_to_tornadoes_table,
        tornado_table=tornado_table,
        linkage_metadata_dict=linkage_metadata_dict,
        genesis_only=genesis_only)

    print(SEPARATOR_STRING)

    _, axes_object, basemap_object = (
        plotting_utils.create_equidist_cylindrical_map(
            min_latitude_deg=min_plot_latitude_deg,
            max_latitude_deg=max_plot_latitude_deg,
            min_longitude_deg=min_plot_longitude_deg,
            max_longitude_deg=max_plot_longitude_deg,
            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,
                                  num_parallels=NUM_PARALLELS)

    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  num_meridians=NUM_MERIDIANS)

    print('Plotting storm tracks...')
    storm_plotting.plot_storm_tracks(
        storm_object_table=storm_to_tornadoes_table,
        axes_object=axes_object,
        basemap_object=basemap_object,
        colour_map_object=colour_map_object,
        start_marker_type=None,
        end_marker_type=None)

    num_tornadoes = len(tornado_table.index)
    if num_tornadoes == 0:
        print('Saving figure to: "{0:s}"...'.format(output_file_name))
        pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI)
        pyplot.close()
        return

    colour_norm_object = pyplot.Normalize(
        numpy.min(
            storm_to_tornadoes_table[tracking_utils.VALID_TIME_COLUMN].values),
        numpy.max(
            storm_to_tornadoes_table[tracking_utils.VALID_TIME_COLUMN].values))

    print('Plotting tornado markers...')
    _plot_tornadoes(tornado_table=tornado_table,
                    colour_map_object=colour_map_object,
                    colour_norm_object=colour_norm_object,
                    genesis_only=genesis_only,
                    axes_object=axes_object,
                    basemap_object=basemap_object)

    print('Plotting tornado IDs with storm objects...')
    num_storm_objects = len(storm_to_tornadoes_table.index)

    for i in range(num_storm_objects):
        _plot_linkages_one_storm_object(
            storm_to_tornadoes_table=storm_to_tornadoes_table,
            storm_object_index=i,
            tornado_table=tornado_table,
            colour_map_object=colour_map_object,
            colour_norm_object=colour_norm_object,
            axes_object=axes_object,
            basemap_object=basemap_object,
            max_link_distance_metres=max_link_distance_metres)

    print('Saving figure to: "{0:s}"...'.format(output_file_name))
    pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI)
    pyplot.close()
コード例 #19
0
def _plot_score_one_field(latitude_matrix_deg,
                          longitude_matrix_deg,
                          score_matrix,
                          colour_map_object,
                          min_colour_value,
                          max_colour_value,
                          taper_cbar_top,
                          taper_cbar_bottom,
                          log_scale=False):
    """Plots one score for one field.

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

    :param latitude_matrix_deg: M-by-N numpy array of latitudes (deg N).
    :param longitude_matrix_deg: M-by-N numpy array of longitudes (deg E).
    :param score_matrix: M-by-N numpy array of score values.
    :param colour_map_object: Colour scheme (instance of `matplotlib.pyplot.cm`).
    :param min_colour_value: Minimum value in colour bar.
    :param max_colour_value: Max value in colour bar.
    :param taper_cbar_top: Boolean flag.  If True, will taper bottom of colour
        bar, implying that lower values are possible.
    :param taper_cbar_bottom: Same but for top of colour bar.
    :param log_scale: Boolean flag.  If True, will make colour bar logarithmic.
    :return: figure_object: Figure handle (instance of
        `matplotlib.figure.Figure`).
    :return: axes_object: Axes handle (instance of
        `matplotlib.axes._subplots.AxesSubplot`).
    """

    (figure_object, axes_object,
     basemap_object) = plotting_utils.create_equidist_cylindrical_map(
         min_latitude_deg=latitude_matrix_deg[0, 0],
         max_latitude_deg=latitude_matrix_deg[-1, -1],
         min_longitude_deg=longitude_matrix_deg[0, 0],
         max_longitude_deg=longitude_matrix_deg[-1, -1],
         resolution_string=RESOLUTION_STRING)

    latitude_spacing_deg = latitude_matrix_deg[1, 0] - latitude_matrix_deg[0,
                                                                           0]
    longitude_spacing_deg = (longitude_matrix_deg[0, 1] -
                             longitude_matrix_deg[0, 0])

    print(numpy.sum(numpy.invert(numpy.isnan(score_matrix))))

    (score_matrix_at_edges, grid_edge_latitudes_deg,
     grid_edge_longitudes_deg) = grids.latlng_field_grid_points_to_edges(
         field_matrix=score_matrix,
         min_latitude_deg=latitude_matrix_deg[0, 0],
         min_longitude_deg=longitude_matrix_deg[0, 0],
         lat_spacing_deg=latitude_spacing_deg,
         lng_spacing_deg=longitude_spacing_deg)

    score_matrix_at_edges = numpy.ma.masked_where(
        numpy.isnan(score_matrix_at_edges), score_matrix_at_edges)

    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
    # )
    plotting_utils.plot_parallels(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  num_parallels=NUM_PARALLELS,
                                  line_width=0)
    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  num_meridians=NUM_MERIDIANS,
                                  line_width=0)

    pyplot.pcolormesh(grid_edge_longitudes_deg,
                      grid_edge_latitudes_deg,
                      score_matrix_at_edges,
                      cmap=colour_map_object,
                      vmin=min_colour_value,
                      vmax=max_colour_value,
                      shading='flat',
                      edgecolors='None',
                      axes=axes_object,
                      zorder=-1e12)

    colour_bar_object = plotting_utils.plot_linear_colour_bar(
        axes_object_or_matrix=axes_object,
        data_matrix=score_matrix,
        colour_map_object=colour_map_object,
        min_value=min_colour_value,
        max_value=max_colour_value,
        orientation_string='horizontal',
        extend_min=taper_cbar_bottom,
        extend_max=taper_cbar_top,
        padding=0.05,
        font_size=COLOUR_BAR_FONT_SIZE)

    tick_values = colour_bar_object.get_ticks()

    if log_scale:
        tick_strings = [
            '{0:d}'.format(int(numpy.round(10**v))) for v in tick_values
        ]
    elif numpy.nanmax(numpy.absolute(score_matrix)) >= 6:
        tick_strings = [
            '{0:d}'.format(int(numpy.round(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)

    return figure_object, axes_object