def _init_basemap(border_colour): """Initializes basemap. :param border_colour: Colour (in any format accepted by matplotlib) of political borders. :return: narr_row_limits: length-2 numpy array of (min, max) NARR rows to plot. :return: narr_column_limits: length-2 numpy array of (min, max) NARR columns to plot. :return: axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`. :return: basemap_object: Instance of `mpl_toolkits.basemap.Basemap`. """ (narr_row_limits, narr_column_limits ) = nwp_plotting.latlng_limits_to_rowcol_limits( min_latitude_deg=MIN_LATITUDE_DEG, max_latitude_deg=MAX_LATITUDE_DEG, min_longitude_deg=MIN_LONGITUDE_DEG, max_longitude_deg=MAX_LONGITUDE_DEG, model_name=nwp_model_utils.NARR_MODEL_NAME) _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=narr_row_limits[0], last_row_in_full_grid=narr_row_limits[1], first_column_in_full_grid=narr_column_limits[0], last_column_in_full_grid=narr_column_limits[1]) plotting_utils.plot_coastlines( basemap_object=basemap_object, axes_object=axes_object, line_colour=border_colour) plotting_utils.plot_countries( basemap_object=basemap_object, axes_object=axes_object, line_colour=border_colour) plotting_utils.plot_states_and_provinces( basemap_object=basemap_object, axes_object=axes_object, line_colour=border_colour) plotting_utils.plot_parallels( basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians( basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) return narr_row_limits, narr_column_limits, axes_object, basemap_object
def _plot_one_time(predicted_region_table, title_string, letter_label, output_file_name, class_probability_matrix=None, predicted_label_matrix=None, plot_wf_colour_bar=True, plot_cf_colour_bar=True): """Plots predictions at one time. Either `class_probability_matrix` or `predicted_label_matrix` will be plotted -- not both. M = number of rows in NARR grid N = number of columns in NARR grid :param predicted_region_table: Subset of pandas DataFrame returned by `object_eval.read_predictions_and_obs`, containing predicted fronts at only one time. :param title_string: Title (will be placed above figure). :param letter_label: Letter label. If this is "a", the label "(a)" will be printed at the top left of the figure. :param output_file_name: Path to output file. :param class_probability_matrix: M-by-N-by-3 numpy array of class probabilities. :param predicted_label_matrix: M-by-N numpy array of predicted labels (integers in `front_utils.VALID_INTEGER_IDS`). :param plot_wf_colour_bar: Boolean flag. If True, will plot colour bar for warm-front probability. :param plot_cf_colour_bar: Boolean flag. If True, will plot colour bar for cold-front probability. """ narr_row_limits, narr_column_limits = ( nwp_plotting.latlng_limits_to_rowcol_limits( min_latitude_deg=MIN_LATITUDE_DEG, max_latitude_deg=MAX_LATITUDE_DEG, min_longitude_deg=MIN_LONGITUDE_DEG, max_longitude_deg=MAX_LONGITUDE_DEG, model_name=nwp_model_utils.NARR_MODEL_NAME)) _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=narr_row_limits[0], last_row_in_full_grid=narr_row_limits[1], first_column_in_full_grid=narr_column_limits[0], last_column_in_full_grid=narr_column_limits[1]) plotting_utils.plot_coastlines(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_countries(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_states_and_provinces(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_parallels(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) if class_probability_matrix is None: this_matrix = predicted_label_matrix[narr_row_limits[0]:( narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1)] front_plotting.plot_narr_grid( frontal_grid_matrix=this_matrix, axes_object=axes_object, basemap_object=basemap_object, first_row_in_narr_grid=narr_row_limits[0], first_column_in_narr_grid=narr_column_limits[0], opacity=0.25) else: this_wf_probability_matrix = class_probability_matrix[ narr_row_limits[0]:(narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1), front_utils.WARM_FRONT_INTEGER_ID] this_wf_probability_matrix[numpy.isnan( this_wf_probability_matrix)] = 0. prediction_plotting.plot_narr_grid( probability_matrix=this_wf_probability_matrix, front_string_id=front_utils.WARM_FRONT_STRING_ID, axes_object=axes_object, basemap_object=basemap_object, first_row_in_narr_grid=narr_row_limits[0], first_column_in_narr_grid=narr_column_limits[0], opacity=0.5) this_cf_probability_matrix = class_probability_matrix[ narr_row_limits[0]:(narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1), front_utils.COLD_FRONT_INTEGER_ID] this_cf_probability_matrix[numpy.isnan( this_cf_probability_matrix)] = 0. prediction_plotting.plot_narr_grid( probability_matrix=this_cf_probability_matrix, front_string_id=front_utils.COLD_FRONT_STRING_ID, axes_object=axes_object, basemap_object=basemap_object, first_row_in_narr_grid=narr_row_limits[0], first_column_in_narr_grid=narr_column_limits[0], opacity=0.5) if plot_wf_colour_bar: this_colour_map_object, this_colour_norm_object = ( prediction_plotting.get_warm_front_colour_map()[:2]) plotting_utils.add_colour_bar( axes_object_or_list=axes_object, colour_map=this_colour_map_object, colour_norm_object=this_colour_norm_object, values_to_colour=this_wf_probability_matrix, orientation='horizontal', extend_min=True, extend_max=False, fraction_of_axis_length=0.9) if plot_cf_colour_bar: this_colour_map_object, this_colour_norm_object = ( prediction_plotting.get_cold_front_colour_map()[:2]) plotting_utils.add_colour_bar( axes_object_or_list=axes_object, colour_map=this_colour_map_object, colour_norm_object=this_colour_norm_object, values_to_colour=this_cf_probability_matrix, orientation='horizontal', extend_min=True, extend_max=False, fraction_of_axis_length=0.9) narr_latitude_matrix_deg, narr_longitude_matrix_deg = ( nwp_model_utils.get_latlng_grid_point_matrices( model_name=nwp_model_utils.NARR_MODEL_NAME)) num_objects = len(predicted_region_table.index) for i in range(num_objects): these_rows = predicted_region_table[ object_eval.ROW_INDICES_COLUMN].values[i] these_columns = predicted_region_table[ object_eval.COLUMN_INDICES_COLUMN].values[i] front_plotting.plot_polyline( latitudes_deg=narr_latitude_matrix_deg[these_rows, these_columns], longitudes_deg=narr_longitude_matrix_deg[these_rows, these_columns], axes_object=axes_object, basemap_object=basemap_object, front_type=predicted_region_table[ front_utils.FRONT_TYPE_COLUMN].values[i], line_width=4) # predicted_object_matrix = object_eval.regions_to_images( # predicted_region_table=predicted_region_table, # num_grid_rows=num_grid_rows, num_grid_columns=num_grid_columns) # # this_matrix = predicted_object_matrix[ # 0, # narr_row_limits[0]:(narr_row_limits[1] + 1), # narr_column_limits[0]:(narr_column_limits[1] + 1) # ] # # front_plotting.plot_narr_grid( # frontal_grid_matrix=this_matrix, axes_object=axes_object, # basemap_object=basemap_object, # first_row_in_narr_grid=narr_row_limits[0], # first_column_in_narr_grid=narr_column_limits[0], opacity=1.) pyplot.title(title_string) if letter_label is not None: plotting_utils.annotate_axes( axes_object=axes_object, annotation_string='({0:s})'.format(letter_label)) print 'Saving figure to: "{0:s}"...'.format(output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _plot_fronts(actual_binary_matrix, predicted_binary_matrix, title_string, annotation_string, output_file_name): """Plots actual and predicted fronts. M = number of rows in grid N = number of columns in grid :param actual_binary_matrix: M-by-N numpy array. If actual_binary_matrix[i, j] = 1, there is an actual front passing through grid cell [i, j]. :param predicted_binary_matrix: Same but for predicted fronts. :param title_string: Title (will be placed above figure). :param annotation_string: Text annotation (will be placed in top left of figure). :param output_file_name: Path to output file (figure will be saved here). """ (narr_row_limits, narr_column_limits) = nwp_plotting.latlng_limits_to_rowcol_limits( min_latitude_deg=MIN_LATITUDE_DEG, max_latitude_deg=MAX_LATITUDE_DEG, min_longitude_deg=MIN_LONGITUDE_DEG, max_longitude_deg=MAX_LONGITUDE_DEG, model_name=nwp_model_utils.NARR_MODEL_NAME) _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=narr_row_limits[0], last_row_in_full_grid=narr_row_limits[1], first_column_in_full_grid=narr_column_limits[0], last_column_in_full_grid=narr_column_limits[1], resolution_string='i') plotting_utils.plot_coastlines(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_countries(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_states_and_provinces(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_parallels(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) this_colour_map_object, this_colour_norm_object = _get_colour_map(True) this_matrix = actual_binary_matrix[0, narr_row_limits[0]:( narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1)] nwp_plotting.plot_subgrid( field_matrix=this_matrix, model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, colour_map=this_colour_map_object, min_value_in_colour_map=this_colour_norm_object.boundaries[0], max_value_in_colour_map=this_colour_norm_object.boundaries[-1], first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0], opacity=ACTUAL_FRONT_OPACITY) this_colour_map_object, this_colour_norm_object = _get_colour_map(False) this_matrix = predicted_binary_matrix[0, narr_row_limits[0]:( narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1)] nwp_plotting.plot_subgrid( field_matrix=this_matrix, model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, colour_map=this_colour_map_object, min_value_in_colour_map=this_colour_norm_object.boundaries[0], max_value_in_colour_map=this_colour_norm_object.boundaries[-1], first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0], opacity=PREDICTED_FRONT_OPACITY) pyplot.title(title_string) plotting_utils.annotate_axes(axes_object=axes_object, annotation_string=annotation_string) print 'Saving figure to: "{0:s}"...'.format(output_file_name) file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _plot_one_time( predictor_matrix, predictor_names, front_polyline_table, high_low_table, thermal_colour_map_object, max_thermal_prctile_for_colours, narr_row_limits, narr_column_limits, title_string, letter_label, output_file_name): """Plots predictors at one time. M = number of rows in grid N = number of columns in grid C = number of channels (predictors) :param predictor_matrix: M-by-N-by-C numpy array of predictor values. :param predictor_names: length-C list of predictor names. :param front_polyline_table: pandas DataFrame returned by `fronts_io.read_polylines_from_file`. :param high_low_table: pandas DataFrame returned by `wpc_bulletin_io.read_highs_and_lows`. :param thermal_colour_map_object: See documentation at top of file. :param max_thermal_prctile_for_colours: Same. :param narr_row_limits: length-2 numpy array, indicating the first and last NARR rows in `predictor_matrix`. If narr_row_limits = [i, k], `predictor_matrix` spans rows i...k of the full NARR grid. :param narr_column_limits: Same but for columns. :param title_string: Title (will be placed above figure). :param letter_label: Letter label. If this is "a", the label "(a)" will be printed at the top left of the figure. :param output_file_name: Path to output file (figure will be saved here). """ _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=narr_row_limits[0], last_row_in_full_grid=narr_row_limits[1], first_column_in_full_grid=narr_column_limits[0], last_column_in_full_grid=narr_column_limits[1] ) plotting_utils.plot_coastlines( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR ) plotting_utils.plot_countries( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR ) plotting_utils.plot_states_and_provinces( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR ) plotting_utils.plot_parallels( basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG ) plotting_utils.plot_meridians( basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG ) num_predictors = len(predictor_names) for j in range(num_predictors): if predictor_names[j] in WIND_FIELD_NAMES: continue min_colour_value = numpy.percentile( predictor_matrix[..., j], 100. - max_thermal_prctile_for_colours) max_colour_value = numpy.percentile( predictor_matrix[..., j], max_thermal_prctile_for_colours) nwp_plotting.plot_subgrid( field_matrix=predictor_matrix[..., j], model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, colour_map=thermal_colour_map_object, min_value_in_colour_map=min_colour_value, max_value_in_colour_map=max_colour_value, first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0] ) plotting_utils.add_linear_colour_bar( axes_object_or_list=axes_object, values_to_colour=predictor_matrix[..., j], colour_map=thermal_colour_map_object, colour_min=min_colour_value, colour_max=max_colour_value, orientation='horizontal', extend_min=True, extend_max=True, fraction_of_axis_length=0.9) u_wind_index = predictor_names.index( processed_narr_io.U_WIND_GRID_RELATIVE_NAME) v_wind_index = predictor_names.index( processed_narr_io.V_WIND_GRID_RELATIVE_NAME) nwp_plotting.plot_wind_barbs_on_subgrid( u_wind_matrix_m_s01=predictor_matrix[..., u_wind_index], v_wind_matrix_m_s01=predictor_matrix[..., v_wind_index], model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0], plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB, plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB, barb_length=WIND_BARB_LENGTH, empty_barb_radius=EMPTY_WIND_BARB_RADIUS, fill_empty_barb=False, colour_map=WIND_COLOUR_MAP_OBJECT, colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT, colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT) if high_low_table is None: num_pressure_systems = 0 else: num_pressure_systems = len(high_low_table.index) for i in range(num_pressure_systems): this_system_type_string = high_low_table[ wpc_bulletin_io.SYSTEM_TYPE_COLUMN].values[i] if this_system_type_string == wpc_bulletin_io.HIGH_PRESSURE_STRING: this_string = 'H' else: this_string = 'L' this_x_coord_metres, this_y_coord_metres = basemap_object( high_low_table[wpc_bulletin_io.LONGITUDE_COLUMN].values[i], high_low_table[wpc_bulletin_io.LATITUDE_COLUMN].values[i] ) axes_object.text( this_x_coord_metres, this_y_coord_metres, this_string, fontsize=PRESSURE_SYSTEM_FONT_SIZE, color=PRESSURE_SYSTEM_COLOUR, fontweight='bold', horizontalalignment='center', verticalalignment='center') num_fronts = len(front_polyline_table.index) for i in range(num_fronts): this_front_type_string = front_polyline_table[ front_utils.FRONT_TYPE_COLUMN].values[i] if this_front_type_string == front_utils.WARM_FRONT_STRING_ID: this_colour = WARM_FRONT_COLOUR else: this_colour = COLD_FRONT_COLOUR front_plotting.plot_front_with_markers( line_latitudes_deg=front_polyline_table[ front_utils.LATITUDES_COLUMN].values[i], line_longitudes_deg=front_polyline_table[ front_utils.LONGITUDES_COLUMN].values[i], axes_object=axes_object, basemap_object=basemap_object, front_type_string=front_polyline_table[ front_utils.FRONT_TYPE_COLUMN].values[i], marker_colour=this_colour) pyplot.title(title_string) if letter_label is not None: plotting_utils.annotate_axes( axes_object=axes_object, annotation_string='({0:s})'.format(letter_label) ) print 'Saving figure to: "{0:s}"...'.format(output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
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()
def _plot_predictions_one_time( output_file_name, title_string, annotation_string, predicted_label_matrix=None, class_probability_matrix=None, plot_warm_colour_bar=True, plot_cold_colour_bar=True): """Plots predictions (objects or probability grid) for one valid time. :param output_file_name: Path to output file (figure will be saved here). :param title_string: Title (will be placed above figure). :param annotation_string: Text annotation (will be placed in top left of figure). :param predicted_label_matrix: See doc for `target_matrix` in `machine_learning_utils.write_gridded_predictions`. :param class_probability_matrix: [used iff `predicted_label_matrix is None`] See doc for `machine_learning_utils.write_gridded_predictions`. :param plot_warm_colour_bar: [used iff `predicted_label_matrix is None`] Boolean flag, indicating whether or not to plot colour bar for warm- front probability. :param plot_cold_colour_bar: Same but for cold-front probability. """ (narr_row_limits, narr_column_limits ) = nwp_plotting.latlng_limits_to_rowcol_limits( min_latitude_deg=MIN_LATITUDE_DEG, max_latitude_deg=MAX_LATITUDE_DEG, min_longitude_deg=MIN_LONGITUDE_DEG, max_longitude_deg=MAX_LONGITUDE_DEG, model_name=nwp_model_utils.NARR_MODEL_NAME) _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=narr_row_limits[0], last_row_in_full_grid=narr_row_limits[1], first_column_in_full_grid=narr_column_limits[0], last_column_in_full_grid=narr_column_limits[1]) plotting_utils.plot_coastlines( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_countries( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_states_and_provinces( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_parallels( basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians( basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) if class_probability_matrix is None: this_matrix = predicted_label_matrix[ 0, narr_row_limits[0]:(narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1) ] front_plotting.plot_narr_grid( frontal_grid_matrix=this_matrix, axes_object=axes_object, basemap_object=basemap_object, first_row_in_narr_grid=narr_row_limits[0], first_column_in_narr_grid=narr_column_limits[0], opacity=DETERMINISTIC_OPACITY) else: this_matrix = class_probability_matrix[ 0, narr_row_limits[0]:(narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1), front_utils.WARM_FRONT_INTEGER_ID ] prediction_plotting.plot_narr_grid( probability_matrix=this_matrix, front_string_id=front_utils.WARM_FRONT_STRING_ID, axes_object=axes_object, basemap_object=basemap_object, first_row_in_narr_grid=narr_row_limits[0], first_column_in_narr_grid=narr_column_limits[0], opacity=PROBABILISTIC_OPACITY) this_matrix = class_probability_matrix[ 0, narr_row_limits[0]:(narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1), front_utils.COLD_FRONT_INTEGER_ID ] prediction_plotting.plot_narr_grid( probability_matrix=this_matrix, front_string_id=front_utils.COLD_FRONT_STRING_ID, axes_object=axes_object, basemap_object=basemap_object, first_row_in_narr_grid=narr_row_limits[0], first_column_in_narr_grid=narr_column_limits[0], opacity=PROBABILISTIC_OPACITY) if plot_warm_colour_bar: (this_colour_map_object, this_colour_norm_object ) = prediction_plotting.get_warm_front_colour_map()[:2] plotting_utils.add_colour_bar( axes_object_or_list=axes_object, colour_map=this_colour_map_object, colour_norm_object=this_colour_norm_object, values_to_colour=class_probability_matrix[ ..., front_utils.WARM_FRONT_INTEGER_ID], orientation='vertical', extend_min=True, extend_max=False, fraction_of_axis_length=LENGTH_FRACTION_FOR_PROB_COLOUR_BAR) if plot_cold_colour_bar: (this_colour_map_object, this_colour_norm_object ) = prediction_plotting.get_cold_front_colour_map()[:2] plotting_utils.add_colour_bar( axes_object_or_list=axes_object, colour_map=this_colour_map_object, colour_norm_object=this_colour_norm_object, values_to_colour=class_probability_matrix[ ..., front_utils.COLD_FRONT_INTEGER_ID], orientation='vertical', extend_min=True, extend_max=False, fraction_of_axis_length=LENGTH_FRACTION_FOR_PROB_COLOUR_BAR) pyplot.title(title_string) plotting_utils.annotate_axes( axes_object=axes_object, annotation_string=annotation_string) print 'Saving figure to: "{0:s}"...'.format(output_file_name) file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace( input_file_name=output_file_name, output_file_name=output_file_name)
def _plot_predictions(predicted_label_matrix, title_string, annotation_string, output_file_name): """Plots predicted front locations. :param predicted_label_matrix: See doc for `target_matrix` in `machine_learning_utils.write_gridded_predictions`. :param title_string: Title (will be placed above figure). :param annotation_string: Text annotation (will be placed in top left of figure). :param output_file_name: Path to output file (figure will be saved here). """ (narr_row_limits, narr_column_limits) = nwp_plotting.latlng_limits_to_rowcol_limits( min_latitude_deg=MIN_LATITUDE_DEG, max_latitude_deg=MAX_LATITUDE_DEG, min_longitude_deg=MIN_LONGITUDE_DEG, max_longitude_deg=MAX_LONGITUDE_DEG, model_name=nwp_model_utils.NARR_MODEL_NAME) _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=narr_row_limits[0], last_row_in_full_grid=narr_row_limits[1], first_column_in_full_grid=narr_column_limits[0], last_column_in_full_grid=narr_column_limits[1]) plotting_utils.plot_coastlines(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_countries(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_states_and_provinces(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_parallels(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) this_matrix = predicted_label_matrix[0, narr_row_limits[0]:( narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1)] front_plotting.plot_narr_grid( frontal_grid_matrix=this_matrix, axes_object=axes_object, basemap_object=basemap_object, first_row_in_narr_grid=narr_row_limits[0], first_column_in_narr_grid=narr_column_limits[0], opacity=1.) pyplot.title(title_string) plotting_utils.annotate_axes(axes_object=axes_object, annotation_string=annotation_string) print 'Saving figure to: "{0:s}"...'.format(output_file_name) file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _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)
def _plot_rapruc_one_example( full_storm_id_string, storm_time_unix_sec, top_tracking_dir_name, latitude_buffer_deg, longitude_buffer_deg, lead_time_seconds, field_name_grib1, output_dir_name, rap_file_name=None, ruc_file_name=None): """Plots RAP or RUC field for one example. :param full_storm_id_string: Full storm ID. :param storm_time_unix_sec: Valid time. :param top_tracking_dir_name: See documentation at top of file. :param latitude_buffer_deg: Same. :param longitude_buffer_deg: Same. :param lead_time_seconds: Same. :param field_name_grib1: Same. :param output_dir_name: Same. :param rap_file_name: Path to file with RAP analysis. :param ruc_file_name: [used only if `rap_file_name is None`] Path to file with RUC analysis. """ tracking_file_name = tracking_io.find_file( top_tracking_dir_name=top_tracking_dir_name, tracking_scale_metres2=DUMMY_TRACKING_SCALE_METRES2, source_name=tracking_utils.SEGMOTION_NAME, valid_time_unix_sec=storm_time_unix_sec, spc_date_string= time_conversion.time_to_spc_date_string(storm_time_unix_sec), raise_error_if_missing=True ) print('Reading data from: "{0:s}"...'.format(tracking_file_name)) storm_object_table = tracking_io.read_file(tracking_file_name) storm_object_table = storm_object_table.loc[ storm_object_table[tracking_utils.FULL_ID_COLUMN] == full_storm_id_string ] extrap_times_sec = numpy.array([0, lead_time_seconds], dtype=int) storm_object_table = soundings._create_target_points_for_interp( storm_object_table=storm_object_table, lead_times_seconds=extrap_times_sec ) orig_latitude_deg = ( storm_object_table[tracking_utils.CENTROID_LATITUDE_COLUMN].values[0] ) orig_longitude_deg = ( storm_object_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].values[0] ) extrap_latitude_deg = ( storm_object_table[tracking_utils.CENTROID_LATITUDE_COLUMN].values[1] ) extrap_longitude_deg = ( storm_object_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].values[1] ) if rap_file_name is None: grib_file_name = ruc_file_name model_name = nwp_model_utils.RUC_MODEL_NAME else: grib_file_name = rap_file_name model_name = nwp_model_utils.RAP_MODEL_NAME pathless_grib_file_name = os.path.split(grib_file_name)[-1] grid_name = pathless_grib_file_name.split('_')[1] host_name = socket.gethostname() if 'casper' in host_name: wgrib_exe_name = '/glade/work/ryanlage/wgrib/wgrib' wgrib2_exe_name = '/glade/work/ryanlage/wgrib2/wgrib2/wgrib2' else: wgrib_exe_name = '/condo/swatwork/ralager/wgrib/wgrib' wgrib2_exe_name = '/condo/swatwork/ralager/grib2/wgrib2/wgrib2' print('Reading field "{0:s}" from: "{1:s}"...'.format( field_name_grib1, grib_file_name )) main_field_matrix = nwp_model_io.read_field_from_grib_file( grib_file_name=grib_file_name, field_name_grib1=field_name_grib1, model_name=model_name, grid_id=grid_name, wgrib_exe_name=wgrib_exe_name, wgrib2_exe_name=wgrib2_exe_name ) u_wind_name_grib1 = 'UGRD:{0:s}'.format( field_name_grib1.split(':')[-1] ) u_wind_name_grib1 = u_wind_name_grib1.replace('2 m', '10 m') print('Reading field "{0:s}" from: "{1:s}"...'.format( u_wind_name_grib1, grib_file_name )) u_wind_matrix_m_s01 = nwp_model_io.read_field_from_grib_file( grib_file_name=grib_file_name, field_name_grib1=u_wind_name_grib1, model_name=model_name, grid_id=grid_name, wgrib_exe_name=wgrib_exe_name, wgrib2_exe_name=wgrib2_exe_name ) v_wind_name_grib1 = 'VGRD:{0:s}'.format( u_wind_name_grib1.split(':')[-1] ) print('Reading field "{0:s}" from: "{1:s}"...'.format( v_wind_name_grib1, grib_file_name )) v_wind_matrix_m_s01 = nwp_model_io.read_field_from_grib_file( grib_file_name=grib_file_name, field_name_grib1=v_wind_name_grib1, model_name=model_name, grid_id=grid_name, wgrib_exe_name=wgrib_exe_name, wgrib2_exe_name=wgrib2_exe_name ) latitude_matrix_deg, longitude_matrix_deg = ( nwp_model_utils.get_latlng_grid_point_matrices( model_name=model_name, grid_name=grid_name) ) cosine_matrix, sine_matrix = nwp_model_utils.get_wind_rotation_angles( latitudes_deg=latitude_matrix_deg, longitudes_deg=longitude_matrix_deg, model_name=model_name ) u_wind_matrix_m_s01, v_wind_matrix_m_s01 = ( nwp_model_utils.rotate_winds_to_earth_relative( u_winds_grid_relative_m_s01=u_wind_matrix_m_s01, v_winds_grid_relative_m_s01=v_wind_matrix_m_s01, rotation_angle_cosines=cosine_matrix, rotation_angle_sines=sine_matrix) ) min_plot_latitude_deg = ( min([orig_latitude_deg, extrap_latitude_deg]) - latitude_buffer_deg ) max_plot_latitude_deg = ( max([orig_latitude_deg, extrap_latitude_deg]) + latitude_buffer_deg ) min_plot_longitude_deg = ( min([orig_longitude_deg, extrap_longitude_deg]) - longitude_buffer_deg ) max_plot_longitude_deg = ( max([orig_longitude_deg, extrap_longitude_deg]) + longitude_buffer_deg ) row_limits, column_limits = nwp_plotting.latlng_limits_to_rowcol_limits( 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, model_name=model_name, grid_id=grid_name ) main_field_matrix = main_field_matrix[ row_limits[0]:(row_limits[1] + 1), column_limits[0]:(column_limits[1] + 1) ] u_wind_matrix_m_s01 = u_wind_matrix_m_s01[ row_limits[0]:(row_limits[1] + 1), column_limits[0]:(column_limits[1] + 1) ] v_wind_matrix_m_s01 = v_wind_matrix_m_s01[ row_limits[0]:(row_limits[1] + 1), column_limits[0]:(column_limits[1] + 1) ] _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=model_name, grid_id=grid_name, first_row_in_full_grid=row_limits[0], last_row_in_full_grid=row_limits[1], first_column_in_full_grid=column_limits[0], last_column_in_full_grid=column_limits[1] ) plotting_utils.plot_coastlines( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR ) plotting_utils.plot_countries( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR ) plotting_utils.plot_states_and_provinces( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR ) plotting_utils.plot_parallels( basemap_object=basemap_object, axes_object=axes_object, num_parallels=NUM_PARALLELS ) plotting_utils.plot_meridians( basemap_object=basemap_object, axes_object=axes_object, num_meridians=NUM_MERIDIANS ) min_colour_value = numpy.nanpercentile( main_field_matrix, 100. - MAX_COLOUR_PERCENTILE ) max_colour_value = numpy.nanpercentile( main_field_matrix, MAX_COLOUR_PERCENTILE ) nwp_plotting.plot_subgrid( field_matrix=main_field_matrix, model_name=model_name, grid_id=grid_name, axes_object=axes_object, basemap_object=basemap_object, colour_map_object=COLOUR_MAP_OBJECT, min_colour_value=min_colour_value, max_colour_value=max_colour_value, first_row_in_full_grid=row_limits[0], first_column_in_full_grid=column_limits[0] ) nwp_plotting.plot_wind_barbs_on_subgrid( u_wind_matrix_m_s01=u_wind_matrix_m_s01, v_wind_matrix_m_s01=v_wind_matrix_m_s01, model_name=model_name, grid_id=grid_name, axes_object=axes_object, basemap_object=basemap_object, first_row_in_full_grid=row_limits[0], first_column_in_full_grid=column_limits[0], plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB, plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB, barb_length=WIND_BARB_LENGTH, empty_barb_radius=EMPTY_WIND_BARB_RADIUS, fill_empty_barb=True, colour_map=WIND_COLOUR_MAP_OBJECT, colour_minimum_kt=MIN_WIND_SPEED_KT, colour_maximum_kt=MAX_WIND_SPEED_KT ) orig_x_metres, orig_y_metres = basemap_object( orig_longitude_deg, orig_latitude_deg ) axes_object.plot( orig_x_metres, orig_y_metres, linestyle='None', marker=ORIGIN_MARKER_TYPE, markersize=ORIGIN_MARKER_SIZE, markeredgewidth=ORIGIN_MARKER_EDGE_WIDTH, markerfacecolor=MARKER_COLOUR, markeredgecolor=MARKER_COLOUR ) extrap_x_metres, extrap_y_metres = basemap_object( extrap_longitude_deg, extrap_latitude_deg ) axes_object.plot( extrap_x_metres, extrap_y_metres, linestyle='None', marker=EXTRAP_MARKER_TYPE, markersize=EXTRAP_MARKER_SIZE, markeredgewidth=EXTRAP_MARKER_EDGE_WIDTH, markerfacecolor=MARKER_COLOUR, markeredgecolor=MARKER_COLOUR ) plotting_utils.plot_linear_colour_bar( axes_object_or_matrix=axes_object, data_matrix=main_field_matrix, colour_map_object=COLOUR_MAP_OBJECT, min_value=min_colour_value, max_value=max_colour_value, orientation_string='vertical' ) output_file_name = '{0:s}/{1:s}_{2:s}.jpg'.format( output_dir_name, full_storm_id_string.replace('_', '-'), time_conversion.unix_sec_to_string( storm_time_unix_sec, FILE_NAME_TIME_FORMAT ) ) 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()
def _plot_front_densities(num_fronts_matrix, colour_map_object, title_string, annotation_string, output_file_name, mask_matrix=None, add_colour_bar=True): """Plots number of fronts at each NARR grid cell. M = number of grid rows (unique y-coordinates at grid points) N = number of grid columns (unique x-coordinates at grid points) :param num_fronts_matrix: M-by-N numpy array with number of fronts at each grid cell. :param colour_map_object: Instance of `matplotlib.pyplot.cm`. :param title_string: Title (will be placed above figure). :param annotation_string: Text annotation (will be placed in top left of figure). :param output_file_name: Path to output (image) file. The figure will be saved here. :param mask_matrix: M-by-N numpy array of integers. If mask_matrix[i, j] = 0, grid cell [i, j] will be masked out in the map. If `mask_matrix is None`, there will be no masking. :param add_colour_bar: Boolean flag. If True, will add colour bar. """ _, axes_object, basemap_object = narr_plotting.init_basemap() plotting_utils.plot_coastlines(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_countries(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_states_and_provinces(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_parallels(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) num_fronts_matrix = num_fronts_matrix.astype(float) max_colour_value = numpy.percentile(num_fronts_matrix, MAX_COLOUR_PERCENTILE) if mask_matrix is not None: num_fronts_matrix[mask_matrix == 0] = numpy.nan narr_plotting.plot_xy_grid(data_matrix=num_fronts_matrix, axes_object=axes_object, basemap_object=basemap_object, colour_map=colour_map_object, colour_minimum=0., colour_maximum=max_colour_value) if add_colour_bar: plotting_utils.add_linear_colour_bar( axes_object_or_list=axes_object, values_to_colour=num_fronts_matrix, colour_map=colour_map_object, colour_min=0., colour_max=max_colour_value, orientation='horizontal', extend_min=False, extend_max=True) pyplot.title(title_string) plotting_utils.annotate_axes(axes_object=axes_object, annotation_string=annotation_string) print 'Saving figure to: "{0:s}"...'.format(output_file_name) pyplot.savefig(output_file_name, dpi=OUTPUT_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _plot_forecast_one_time( gridded_forecast_dict, time_index, min_plot_latitude_deg, max_plot_latitude_deg, min_plot_longitude_deg, max_plot_longitude_deg, output_dir_name, tornado_dir_name=None): """Plots gridded forecast at one time. :param gridded_forecast_dict: Dictionary returned by `prediction_io.read_gridded_predictions`. :param time_index: Will plot the [i]th gridded forecast, where i = `time_index`. :param min_plot_latitude_deg: See documentation at top of file. :param max_plot_latitude_deg: Same. :param min_plot_longitude_deg: Same. :param max_plot_longitude_deg: Same. :param output_dir_name: Name of output directory. Figure will be saved here. :param tornado_dir_name: See documentation at top of file. """ init_time_unix_sec = gridded_forecast_dict[prediction_io.INIT_TIMES_KEY][ time_index ] min_lead_time_seconds = gridded_forecast_dict[ prediction_io.MIN_LEAD_TIME_KEY ] max_lead_time_seconds = gridded_forecast_dict[ prediction_io.MAX_LEAD_TIME_KEY ] first_valid_time_unix_sec = init_time_unix_sec + min_lead_time_seconds last_valid_time_unix_sec = init_time_unix_sec + max_lead_time_seconds tornado_latitudes_deg = numpy.array([]) tornado_longitudes_deg = numpy.array([]) if tornado_dir_name is not None: first_year = int( time_conversion.unix_sec_to_string(first_valid_time_unix_sec, '%Y') ) last_year = int( time_conversion.unix_sec_to_string(last_valid_time_unix_sec, '%Y') ) for this_year in range(first_year, last_year + 1): this_file_name = tornado_io.find_processed_file( directory_name=tornado_dir_name, year=this_year) print('Reading tornado reports from: "{0:s}"...'.format( this_file_name)) this_tornado_table = tornado_io.read_processed_file(this_file_name) this_tornado_table = this_tornado_table.loc[ (this_tornado_table[tornado_io.START_TIME_COLUMN] >= first_valid_time_unix_sec) & (this_tornado_table[tornado_io.START_TIME_COLUMN] <= last_valid_time_unix_sec) ] tornado_latitudes_deg = numpy.concatenate(( tornado_latitudes_deg, this_tornado_table[tornado_io.START_LAT_COLUMN].values )) tornado_longitudes_deg = numpy.concatenate(( tornado_longitudes_deg, this_tornado_table[tornado_io.START_LNG_COLUMN].values )) print('\n') custom_area = all([ x is not None for x in [min_plot_latitude_deg, max_plot_latitude_deg, min_plot_longitude_deg, max_plot_longitude_deg] ]) if custom_area: latlng_limit_dict = { plotting_utils.MIN_LATITUDE_KEY: min_plot_latitude_deg, plotting_utils.MAX_LATITUDE_KEY: max_plot_latitude_deg, plotting_utils.MIN_LONGITUDE_KEY: min_plot_longitude_deg, plotting_utils.MAX_LONGITUDE_KEY: max_plot_longitude_deg } else: latlng_limit_dict = None axes_object, basemap_object = plotting_utils.create_map_with_nwp_proj( model_name=nwp_model_utils.RAP_MODEL_NAME, grid_name=nwp_model_utils.NAME_OF_130GRID, xy_limit_dict=None, latlng_limit_dict=latlng_limit_dict, resolution_string='i' )[1:] # if not custom_area: # min_plot_latitude_deg = basemap_object.llcrnrlat # max_plot_latitude_deg = basemap_object.urcrnrlat # min_plot_longitude_deg = basemap_object.llcrnrlon # max_plot_longitude_deg = basemap_object.urcrnrlon x_offset_metres, y_offset_metres = _get_projection_offsets( basemap_object=basemap_object, pyproj_object=PYPROJ_OBJECT, test_latitudes_deg=TEST_LATITUDES_DEG, test_longitudes_deg=TEST_LONGITUDES_DEG) probability_matrix = gridded_forecast_dict[ prediction_io.XY_PROBABILITIES_KEY ][time_index] # If necessary, convert from sparse to dense matrix. if not isinstance(probability_matrix, numpy.ndarray): probability_matrix = probability_matrix.toarray() x_coords_metres = ( gridded_forecast_dict[prediction_io.GRID_X_COORDS_KEY] + x_offset_metres ) y_coords_metres = ( gridded_forecast_dict[prediction_io.GRID_Y_COORDS_KEY] + y_offset_metres ) probability_plotting.plot_xy_grid( probability_matrix=probability_matrix, x_min_metres=numpy.min(x_coords_metres), y_min_metres=numpy.min(y_coords_metres), x_spacing_metres=numpy.diff(x_coords_metres[:2])[0], y_spacing_metres=numpy.diff(y_coords_metres[:2])[0], axes_object=axes_object, basemap_object=basemap_object) 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) colour_map_object, colour_norm_object = ( probability_plotting.get_default_colour_map() ) plotting_utils.plot_colour_bar( axes_object_or_matrix=axes_object, data_matrix=probability_matrix, colour_map_object=colour_map_object, colour_norm_object=colour_norm_object, orientation_string='horizontal', extend_min=True, extend_max=True, fraction_of_axis_length=0.8) if len(tornado_latitudes_deg) > 0: tornado_x_coords_metres, tornado_y_coords_metres = basemap_object( tornado_longitudes_deg, tornado_latitudes_deg) axes_object.plot( tornado_x_coords_metres, tornado_y_coords_metres, 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) ) init_time_string = time_conversion.unix_sec_to_string( init_time_unix_sec, FILE_NAME_TIME_FORMAT ) # first_valid_time_string = time_conversion.unix_sec_to_string( # first_valid_time_unix_sec, FILE_NAME_TIME_FORMAT # ) # last_valid_time_string = time_conversion.unix_sec_to_string( # last_valid_time_unix_sec, FILE_NAME_TIME_FORMAT # ) # title_string = 'Forecast init {0:s}, valid {1:s} to {2:s}'.format( # init_time_string, first_valid_time_string, last_valid_time_string # ) # pyplot.title(title_string, fontsize=TITLE_FONT_SIZE) output_file_name = ( '{0:s}/gridded_forecast_init-{1:s}_lead-{2:06d}-{3:06d}sec.png' ).format( output_dir_name, init_time_string, min_lead_time_seconds, max_lead_time_seconds ) print('Saving figure to: "{0:s}"...'.format(output_file_name)) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _run(input_outlook_file_name, input_warning_file_name, border_colour, warning_colour, min_plot_latitude_deg, max_plot_latitude_deg, min_plot_longitude_deg, max_plot_longitude_deg, output_file_name): """Plots SPC convective outlook. This is effectively the main method. :param input_outlook_file_name: See documentation at top of file. :param input_warning_file_name: Same. :param border_colour: Same. :param warning_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 SPC outlook from: "{0:s}"...'.format(input_outlook_file_name)) pickle_file_handle = open(input_outlook_file_name, 'rb') outlook_table = pickle.load(pickle_file_handle) pickle_file_handle.close() risk_type_enums = numpy.array([ RISK_TYPE_STRING_TO_ENUM[s] for s in outlook_table[RISK_TYPE_COLUMN].values ], dtype=int) sort_indices = numpy.argsort(risk_type_enums) outlook_table = outlook_table.iloc[sort_indices] outlook_table = _get_bounding_boxes(outlook_table) if input_warning_file_name in ['', 'None']: warning_table = None else: print('Reading tornado warnings from: "{0:s}"...'.format( input_warning_file_name)) pickle_file_handle = open(input_warning_file_name, 'rb') warning_table = pickle.load(pickle_file_handle) pickle_file_handle.close() warning_table = _get_bounding_boxes(warning_table) 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, outlook_table=outlook_table, warning_table=warning_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] print(('Plotting limits = [{0:.2f}, {1:.2f}] deg N and [{2:.2f}, {3:.2f}] ' 'deg E').format(min_plot_latitude_deg, max_plot_latitude_deg, min_plot_longitude_deg, max_plot_longitude_deg)) latlng_limit_dict = { plotting_utils.MIN_LATITUDE_KEY: min_plot_latitude_deg, plotting_utils.MAX_LATITUDE_KEY: max_plot_latitude_deg, plotting_utils.MIN_LONGITUDE_KEY: min_plot_longitude_deg, plotting_utils.MAX_LONGITUDE_KEY: max_plot_longitude_deg } axes_object, basemap_object = plotting_utils.create_map_with_nwp_proj( model_name=nwp_model_utils.RAP_MODEL_NAME, grid_name=nwp_model_utils.NAME_OF_130GRID, xy_limit_dict=None, latlng_limit_dict=latlng_limit_dict, 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) _, unique_risk_type_indices = numpy.unique( outlook_table[RISK_TYPE_COLUMN].values, return_index=True) num_outlooks = len(outlook_table.index) legend_handles = [] legend_strings = [] for i in range(num_outlooks): this_risk_type_string = outlook_table[RISK_TYPE_COLUMN].values[i] this_colour = RISK_TYPE_STRING_TO_COLOUR[this_risk_type_string] this_vertex_dict_latlng = polygons.polygon_object_to_vertex_arrays( outlook_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]) this_polygon_object_xy = polygons.vertex_arrays_to_polygon_object( exterior_x_coords=these_x_coords_metres, exterior_y_coords=these_y_coords_metres) this_patch_object = PolygonPatch(this_polygon_object_xy, lw=0., ec=this_colour, fc=this_colour, alpha=OUTLOOK_OPACITY) this_handle = axes_object.add_patch(this_patch_object) if i in unique_risk_type_indices: this_string = '{0:s}{1:s}'.format(this_risk_type_string[0].upper(), this_risk_type_string[1:]) legend_strings.append(this_string) legend_handles.append(this_handle) if warning_table is None: num_warnings = 0 else: num_warnings = len(warning_table.index) warning_colour_tuple = plotting_utils.colour_from_numpy_to_tuple( warning_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=warning_colour_tuple, linestyle='solid', linewidth=WARNING_LINE_WIDTH) axes_object.legend(legend_handles, legend_strings, loc='upper left') print('Saving figure to: "{0:s}"...'.format(output_file_name)) file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _run(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()
def _plot_fronts(front_line_table, ternary_front_matrix, title_string, annotation_string, output_file_name): """Plots one set of WPC fronts (either before or after dilation). :param front_line_table: See doc for `fronts_io.write_polylines_to_file`. :param ternary_front_matrix: numpy array created by `machine_learning_utils.dilate_ternary_target_images`. :param title_string: Title (will be placed above figure). :param annotation_string: Text annotation (will be placed in top left of figure). :param output_file_name: Path to output file (figure will be saved here). """ (narr_row_limits, narr_column_limits) = nwp_plotting.latlng_limits_to_rowcol_limits( min_latitude_deg=MIN_LATITUDE_DEG, max_latitude_deg=MAX_LATITUDE_DEG, min_longitude_deg=MIN_LONGITUDE_DEG, max_longitude_deg=MAX_LONGITUDE_DEG, model_name=nwp_model_utils.NARR_MODEL_NAME) _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=narr_row_limits[0], last_row_in_full_grid=narr_row_limits[1], first_column_in_full_grid=narr_column_limits[0], last_column_in_full_grid=narr_column_limits[1]) plotting_utils.plot_coastlines(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_countries(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_states_and_provinces(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_parallels(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) this_matrix = ternary_front_matrix[0, narr_row_limits[0]:( narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1)] front_plotting.plot_narr_grid( frontal_grid_matrix=this_matrix, axes_object=axes_object, first_row_in_narr_grid=narr_row_limits[0], first_column_in_narr_grid=narr_column_limits[0], basemap_object=basemap_object, opacity=FRONT_LINE_OPACITY) num_fronts = len(front_line_table.index) for i in range(num_fronts): front_plotting.plot_polyline( latitudes_deg=front_line_table[ front_utils.LATITUDES_COLUMN].values[i], longitudes_deg=front_line_table[ front_utils.LONGITUDES_COLUMN].values[i], basemap_object=basemap_object, axes_object=axes_object, front_type=front_line_table[ front_utils.FRONT_TYPE_COLUMN].values[i], line_width=FRONT_LINE_WIDTH) pyplot.title(title_string) plotting_utils.annotate_axes(axes_object=axes_object, annotation_string=annotation_string) print 'Saving figure to: "{0:s}"...'.format(output_file_name) file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _run(example_file_name, top_front_line_dir_name, num_examples, example_indices, thetaw_colour_map_name, thetaw_max_colour_percentile, output_dir_name): """Plots one or more input examples. This is effectively the main method. :param example_file_name: See documentation at top of file. :param top_front_line_dir_name: Same. :param num_examples: Same. :param example_indices: Same. :param thetaw_colour_map_name: Same. :param thetaw_max_colour_percentile: Same. :param output_dir_name: Same. """ if num_examples <= 0: num_examples = None if num_examples is None: error_checking.assert_is_geq_numpy_array(example_indices, 0) else: error_checking.assert_is_greater(num_examples, 0) error_checking.assert_is_geq(thetaw_max_colour_percentile, 0) error_checking.assert_is_leq(thetaw_max_colour_percentile, 100) thetaw_colour_map_object = pyplot.cm.get_cmap(thetaw_colour_map_name) file_system_utils.mkdir_recursive_if_necessary( directory_name=output_dir_name) print 'Reading normalized examples from: "{0:s}"...'.format( example_file_name) example_dict = trainval_io.read_downsized_3d_examples( netcdf_file_name=example_file_name, num_half_rows_to_keep=NUM_HALF_ROWS, num_half_columns_to_keep=NUM_HALF_COLUMNS, predictor_names_to_keep=NARR_PREDICTOR_NAMES) # TODO(thunderhoser): This is a HACK (assuming that normalization method is # z-score and not min-max). mean_value_matrix = example_dict[trainval_io.FIRST_NORM_PARAM_KEY] standard_deviation_matrix = example_dict[trainval_io.SECOND_NORM_PARAM_KEY] normalization_dict = { ml_utils.MIN_VALUE_MATRIX_KEY: None, ml_utils.MAX_VALUE_MATRIX_KEY: None, ml_utils.MEAN_VALUE_MATRIX_KEY: mean_value_matrix, ml_utils.STDEV_MATRIX_KEY: standard_deviation_matrix } example_dict[trainval_io.PREDICTOR_MATRIX_KEY] = ( ml_utils.denormalize_predictors( predictor_matrix=example_dict[trainval_io.PREDICTOR_MATRIX_KEY], normalization_dict=normalization_dict)) narr_latitude_matrix_deg, narr_longitude_matrix_deg = ( nwp_model_utils.get_latlng_grid_point_matrices( model_name=nwp_model_utils.NARR_MODEL_NAME)) narr_rotation_cos_matrix, narr_rotation_sin_matrix = ( nwp_model_utils.get_wind_rotation_angles( latitudes_deg=narr_latitude_matrix_deg, longitudes_deg=narr_longitude_matrix_deg, model_name=nwp_model_utils.NARR_MODEL_NAME)) num_examples_total = len(example_dict[trainval_io.TARGET_TIMES_KEY]) example_indices = numpy.linspace(0, num_examples_total - 1, num=num_examples_total, dtype=int) if num_examples is not None: num_examples = min([num_examples, num_examples_total]) example_indices = numpy.random.choice(example_indices, size=num_examples, replace=False) thetaw_index = NARR_PREDICTOR_NAMES.index( processed_narr_io.WET_BULB_THETA_NAME) u_wind_index = NARR_PREDICTOR_NAMES.index( processed_narr_io.U_WIND_GRID_RELATIVE_NAME) v_wind_index = NARR_PREDICTOR_NAMES.index( processed_narr_io.V_WIND_GRID_RELATIVE_NAME) for i in example_indices: this_center_row_index = example_dict[trainval_io.ROW_INDICES_KEY][i] this_first_row_index = this_center_row_index - NUM_HALF_ROWS this_last_row_index = this_center_row_index + NUM_HALF_ROWS this_center_column_index = example_dict[ trainval_io.COLUMN_INDICES_KEY][i] this_first_column_index = this_center_column_index - NUM_HALF_COLUMNS this_last_column_index = this_center_column_index + NUM_HALF_COLUMNS this_u_wind_matrix_m_s01 = example_dict[ trainval_io.PREDICTOR_MATRIX_KEY][i, ..., u_wind_index] this_v_wind_matrix_m_s01 = example_dict[ trainval_io.PREDICTOR_MATRIX_KEY][i, ..., v_wind_index] this_cos_matrix = narr_rotation_cos_matrix[this_first_row_index:( this_last_row_index + 1), this_first_column_index:(this_last_column_index + 1)] this_sin_matrix = narr_rotation_sin_matrix[this_first_row_index:( this_last_row_index + 1), this_first_column_index:(this_last_column_index + 1)] this_u_wind_matrix_m_s01, this_v_wind_matrix_m_s01 = ( nwp_model_utils.rotate_winds_to_earth_relative( u_winds_grid_relative_m_s01=this_u_wind_matrix_m_s01, v_winds_grid_relative_m_s01=this_v_wind_matrix_m_s01, rotation_angle_cosines=this_cos_matrix, rotation_angle_sines=this_sin_matrix)) _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=this_first_row_index, last_row_in_full_grid=this_last_row_index, first_column_in_full_grid=this_first_column_index, last_column_in_full_grid=this_last_column_index, resolution_string='i') plotting_utils.plot_coastlines(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR, line_width=BORDER_WIDTH) plotting_utils.plot_countries(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR, line_width=BORDER_WIDTH) plotting_utils.plot_states_and_provinces(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR, line_width=BORDER_WIDTH) plotting_utils.plot_parallels( basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians( basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) this_thetaw_matrix_kelvins = example_dict[ trainval_io.PREDICTOR_MATRIX_KEY][i, ..., thetaw_index] this_min_value = numpy.percentile(this_thetaw_matrix_kelvins, 100. - thetaw_max_colour_percentile) this_max_value = numpy.percentile(this_thetaw_matrix_kelvins, thetaw_max_colour_percentile) nwp_plotting.plot_subgrid( field_matrix=this_thetaw_matrix_kelvins, model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, colour_map=thetaw_colour_map_object, min_value_in_colour_map=this_min_value, max_value_in_colour_map=this_max_value, first_row_in_full_grid=this_first_row_index, first_column_in_full_grid=this_first_column_index) colour_bar_object = plotting_utils.add_linear_colour_bar( axes_object_or_list=axes_object, values_to_colour=this_thetaw_matrix_kelvins, colour_map=thetaw_colour_map_object, colour_min=this_min_value, colour_max=this_max_value, orientation='vertical', extend_min=True, extend_max=True, fraction_of_axis_length=0.8) colour_bar_object.set_label( r'Wet-bulb potential temperature ($^{\circ}$C)') nwp_plotting.plot_wind_barbs_on_subgrid( u_wind_matrix_m_s01=this_u_wind_matrix_m_s01, v_wind_matrix_m_s01=this_v_wind_matrix_m_s01, model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, first_row_in_full_grid=this_first_row_index, first_column_in_full_grid=this_first_column_index, barb_length=WIND_BARB_LENGTH, empty_barb_radius=EMPTY_WIND_BARB_RADIUS, fill_empty_barb=False, colour_map=WIND_COLOUR_MAP_OBJECT, colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT, colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT) this_front_file_name = fronts_io.find_file_for_one_time( top_directory_name=top_front_line_dir_name, file_type=fronts_io.POLYLINE_FILE_TYPE, valid_time_unix_sec=example_dict[trainval_io.TARGET_TIMES_KEY][i]) print time_conversion.unix_sec_to_string( example_dict[trainval_io.TARGET_TIMES_KEY][i], '%Y-%m-%d-%H') this_polyline_table = fronts_io.read_polylines_from_file( this_front_file_name) this_num_fronts = len(this_polyline_table.index) for j in range(this_num_fronts): this_front_type_string = this_polyline_table[ front_utils.FRONT_TYPE_COLUMN].values[j] if this_front_type_string == front_utils.WARM_FRONT_STRING_ID: this_colour = WARM_FRONT_COLOUR else: this_colour = COLD_FRONT_COLOUR front_plotting.plot_front_with_markers( line_latitudes_deg=this_polyline_table[ front_utils.LATITUDES_COLUMN].values[j], line_longitudes_deg=this_polyline_table[ front_utils.LONGITUDES_COLUMN].values[j], axes_object=axes_object, basemap_object=basemap_object, front_type_string=this_polyline_table[ front_utils.FRONT_TYPE_COLUMN].values[j], marker_colour=this_colour, marker_size=FRONT_MARKER_SIZE, marker_spacing_metres=FRONT_SPACING_METRES) this_output_file_name = '{0:s}/example{1:06d}.jpg'.format( output_dir_name, i) print 'Saving figure to: "{0:s}"...'.format(this_output_file_name) pyplot.savefig(this_output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close()
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)
def _plot_observations_one_time( valid_time_string, title_string, annotation_string, output_file_name): """Plots observations (NARR predictors and WPC fronts) for one valid time. :param valid_time_string: Valid time (format "yyyy-mm-dd-HH"). :param title_string: Title (will be placed above figure). :param annotation_string: Text annotation (will be placed in top left of figure). :param output_file_name: Path to output file (figure will be saved here). """ (narr_row_limits, narr_column_limits ) = nwp_plotting.latlng_limits_to_rowcol_limits( min_latitude_deg=MIN_LATITUDE_DEG, max_latitude_deg=MAX_LATITUDE_DEG, min_longitude_deg=MIN_LONGITUDE_DEG, max_longitude_deg=MAX_LONGITUDE_DEG, model_name=nwp_model_utils.NARR_MODEL_NAME) valid_time_unix_sec = time_conversion.string_to_unix_sec( valid_time_string, INPUT_TIME_FORMAT) front_file_name = fronts_io.find_file_for_one_time( top_directory_name=TOP_FRONT_DIR_NAME, file_type=fronts_io.POLYLINE_FILE_TYPE, valid_time_unix_sec=valid_time_unix_sec) print 'Reading data from: "{0:s}"...'.format(front_file_name) front_line_table = fronts_io.read_polylines_from_file(front_file_name) num_narr_fields = len(NARR_FIELD_NAMES) narr_matrix_by_field = [numpy.array([])] * num_narr_fields for j in range(num_narr_fields): if NARR_FIELD_NAMES[j] in WIND_FIELD_NAMES: this_directory_name = TOP_NARR_WIND_DIR_NAME + '' else: this_directory_name = TOP_NARR_DIR_NAME + '' this_file_name = processed_narr_io.find_file_for_one_time( top_directory_name=this_directory_name, field_name=NARR_FIELD_NAMES[j], pressure_level_mb=PRESSURE_LEVEL_MB, valid_time_unix_sec=valid_time_unix_sec) print 'Reading data from: "{0:s}"...'.format(this_file_name) narr_matrix_by_field[j] = processed_narr_io.read_fields_from_file( this_file_name)[0][0, ...] narr_matrix_by_field[j] = utils.fill_nans(narr_matrix_by_field[j]) narr_matrix_by_field[j] = narr_matrix_by_field[j][ narr_row_limits[0]:(narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1) ] if NARR_FIELD_NAMES[j] == processed_narr_io.WET_BULB_THETA_NAME: narr_matrix_by_field[j] = ( narr_matrix_by_field[j] - ZERO_CELSIUS_IN_KELVINS ) _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=narr_row_limits[0], last_row_in_full_grid=narr_row_limits[1], first_column_in_full_grid=narr_column_limits[0], last_column_in_full_grid=narr_column_limits[1]) plotting_utils.plot_coastlines( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_countries( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_states_and_provinces( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_parallels( basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians( basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) for j in range(num_narr_fields): if NARR_FIELD_NAMES[j] in WIND_FIELD_NAMES: continue min_colour_value = numpy.percentile( narr_matrix_by_field[j], MIN_COLOUR_PERCENTILE) max_colour_value = numpy.percentile( narr_matrix_by_field[j], MAX_COLOUR_PERCENTILE) nwp_plotting.plot_subgrid( field_matrix=narr_matrix_by_field[j], model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, colour_map=THERMAL_COLOUR_MAP_OBJECT, min_value_in_colour_map=min_colour_value, max_value_in_colour_map=max_colour_value, first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0]) plotting_utils.add_linear_colour_bar( axes_object_or_list=axes_object, values_to_colour=narr_matrix_by_field[j], colour_map=THERMAL_COLOUR_MAP_OBJECT, colour_min=min_colour_value, colour_max=max_colour_value, orientation='vertical', extend_min=True, extend_max=True, fraction_of_axis_length=LENGTH_FRACTION_FOR_THETA_COLOUR_BAR) u_wind_index = NARR_FIELD_NAMES.index( processed_narr_io.U_WIND_EARTH_RELATIVE_NAME) v_wind_index = NARR_FIELD_NAMES.index( processed_narr_io.V_WIND_EARTH_RELATIVE_NAME) nwp_plotting.plot_wind_barbs_on_subgrid( u_wind_matrix_m_s01=narr_matrix_by_field[u_wind_index], v_wind_matrix_m_s01=narr_matrix_by_field[v_wind_index], model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0], plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB, plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB, barb_length=WIND_BARB_LENGTH, empty_barb_radius=EMPTY_WIND_BARB_RADIUS, colour_map=WIND_COLOUR_MAP_OBJECT, colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT, colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT) num_fronts = len(front_line_table.index) for i in range(num_fronts): this_front_type_string = front_line_table[ front_utils.FRONT_TYPE_COLUMN].values[i] if this_front_type_string == front_utils.WARM_FRONT_STRING_ID: this_colour = WARM_FRONT_COLOUR else: this_colour = COLD_FRONT_COLOUR front_plotting.plot_polyline( latitudes_deg=front_line_table[ front_utils.LATITUDES_COLUMN].values[i], longitudes_deg=front_line_table[ front_utils.LONGITUDES_COLUMN].values[i], basemap_object=basemap_object, axes_object=axes_object, front_type=front_line_table[ front_utils.FRONT_TYPE_COLUMN].values[i], line_width=FRONT_LINE_WIDTH, line_colour=this_colour) pyplot.title(title_string) plotting_utils.annotate_axes( axes_object=axes_object, annotation_string=annotation_string) print 'Saving figure to: "{0:s}"...'.format(output_file_name) file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _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')
def _plot_one_value(data_matrix, grid_metadata_dict, colour_map_object, min_colour_value, max_colour_value, plot_cbar_min_arrow, plot_cbar_max_arrow, log_scale=False): """Plots one value (score, num examples, or num positive examples). M = number of rows in grid N = number of columns in grid :param data_matrix: M-by-N numpy array of values to plot. :param grid_metadata_dict: Dictionary returned by `grids.read_equidistant_metafile`. :param colour_map_object: See documentation at top of file. :param min_colour_value: Minimum value in colour scheme. :param max_colour_value: Max value in colour scheme. :param plot_cbar_min_arrow: Boolean flag. If True, will plot arrow at bottom of colour bar (to signify that lower values are possible). :param plot_cbar_max_arrow: Boolean flag. If True, will plot arrow at top of colour bar (to signify that higher values are possible). :param log_scale: Boolean flag (True if `data_matrix` contains data in log scale). :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 = pyplot.subplots( 1, 1, figsize=(FIGURE_WIDTH_INCHES, FIGURE_HEIGHT_INCHES)) basemap_object, basemap_x_matrix_metres, basemap_y_matrix_metres = ( _get_basemap(grid_metadata_dict)) num_grid_rows = data_matrix.shape[0] num_grid_columns = data_matrix.shape[1] x_spacing_metres = ( (basemap_x_matrix_metres[0, -1] - basemap_x_matrix_metres[0, 0]) / (num_grid_columns - 1)) y_spacing_metres = ( (basemap_y_matrix_metres[-1, 0] - basemap_y_matrix_metres[0, 0]) / (num_grid_rows - 1)) data_matrix_at_edges, edge_x_coords_metres, edge_y_coords_metres = ( grids.xy_field_grid_points_to_edges( field_matrix=data_matrix, x_min_metres=basemap_x_matrix_metres[0, 0], y_min_metres=basemap_y_matrix_metres[0, 0], x_spacing_metres=x_spacing_metres, y_spacing_metres=y_spacing_metres)) data_matrix_at_edges = numpy.ma.masked_where( numpy.isnan(data_matrix_at_edges), data_matrix_at_edges) # data_matrix_at_edges[numpy.isnan(data_matrix_at_edges)] = -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) basemap_object.pcolormesh(edge_x_coords_metres, edge_y_coords_metres, data_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=data_matrix, colour_map_object=colour_map_object, min_value=min_colour_value, max_value=max_colour_value, orientation_string='horizontal', extend_min=plot_cbar_min_arrow, extend_max=plot_cbar_max_arrow, padding=0.05) 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(data_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
def _plot_data(num_days_matrix, grid_metadata_dict, colour_map_object): """Plots data. M = number of rows in grid N = number of columns in grid :param num_days_matrix: M-by-N numpy array with number of convective days for which grid cell is in domain. :param grid_metadata_dict: Dictionary created by `grids.create_equidistant_grid`. :param colour_map_object: See documentation at top of file. :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 = pyplot.subplots( 1, 1, figsize=(FIGURE_WIDTH_INCHES, FIGURE_HEIGHT_INCHES)) basemap_object, basemap_x_matrix_metres, basemap_y_matrix_metres = ( _get_basemap(grid_metadata_dict)) num_grid_rows = num_days_matrix.shape[0] num_grid_columns = num_days_matrix.shape[1] x_spacing_metres = ( (basemap_x_matrix_metres[0, -1] - basemap_x_matrix_metres[0, 0]) / (num_grid_columns - 1)) y_spacing_metres = ( (basemap_y_matrix_metres[-1, 0] - basemap_y_matrix_metres[0, 0]) / (num_grid_rows - 1)) matrix_to_plot, edge_x_coords_metres, edge_y_coords_metres = ( grids.xy_field_grid_points_to_edges( field_matrix=num_days_matrix, x_min_metres=basemap_x_matrix_metres[0, 0], y_min_metres=basemap_y_matrix_metres[0, 0], x_spacing_metres=x_spacing_metres, y_spacing_metres=y_spacing_metres)) matrix_to_plot = numpy.ma.masked_where(matrix_to_plot == 0, matrix_to_plot) 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) basemap_object.pcolormesh(edge_x_coords_metres, edge_y_coords_metres, matrix_to_plot, cmap=colour_map_object, vmin=1, vmax=numpy.max(num_days_matrix), 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=num_days_matrix, colour_map_object=colour_map_object, min_value=1, max_value=numpy.max(num_days_matrix), orientation_string='horizontal', extend_min=False, extend_max=False, padding=0.05) tick_values = colour_bar_object.get_ticks() tick_strings = ['{0:d}'.format(int(numpy.round(v))) for v in tick_values] colour_bar_object.set_ticks(tick_values) colour_bar_object.set_ticklabels(tick_strings) axes_object.set_title('Number of convective days by grid cell') return figure_object, axes_object
def _plot_one_time(valid_time_string, pressure_level_mb, title_string, annotation_string, narr_rotation_cos_matrix, narr_rotation_sin_matrix): """Plots WPC fronts and NARR fields at one time. M = number of grid rows in the full NARR N = number of grid columns in the full NARR :param valid_time_string: Valid time (format "yyyy-mm-dd-HH"). :param pressure_level_mb: Pressure level (millibars). :param title_string: Title (will be placed above figure). :param annotation_string: Annotation (will be placed above and left of figure). :param narr_rotation_cos_matrix: M-by-N numpy array of cosines for wind- rotation angles. :param narr_rotation_sin_matrix: M-by-N numpy array of sines for wind- rotation angles. """ narr_row_limits, narr_column_limits = ( nwp_plotting.latlng_limits_to_rowcol_limits( min_latitude_deg=MIN_LATITUDE_DEG, max_latitude_deg=MAX_LATITUDE_DEG, min_longitude_deg=MIN_LONGITUDE_DEG, max_longitude_deg=MAX_LONGITUDE_DEG, model_name=nwp_model_utils.NARR_MODEL_NAME)) valid_time_unix_sec = time_conversion.string_to_unix_sec( valid_time_string, DEFAULT_TIME_FORMAT) front_file_name = fronts_io.find_file_for_one_time( top_directory_name=TOP_FRONT_DIR_NAME, file_type=fronts_io.POLYLINE_FILE_TYPE, valid_time_unix_sec=valid_time_unix_sec) print 'Reading data from: "{0:s}"...'.format(front_file_name) front_line_table = fronts_io.read_polylines_from_file(front_file_name) num_narr_fields = len(NARR_FIELD_NAMES) narr_matrix_by_field = [numpy.array([])] * num_narr_fields for j in range(num_narr_fields): this_file_name = processed_narr_io.find_file_for_one_time( top_directory_name=TOP_NARR_DIRECTORY_NAME, field_name=NARR_FIELD_NAMES[j], pressure_level_mb=pressure_level_mb, valid_time_unix_sec=valid_time_unix_sec) print 'Reading data from: "{0:s}"...'.format(this_file_name) narr_matrix_by_field[j] = processed_narr_io.read_fields_from_file( this_file_name)[0][0, ...] narr_matrix_by_field[j] = utils.fill_nans(narr_matrix_by_field[j]) narr_matrix_by_field[j] = narr_matrix_by_field[j][narr_row_limits[0]:( narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1)] if NARR_FIELD_NAMES[j] == processed_narr_io.WET_BULB_THETA_NAME: narr_matrix_by_field[j] = (narr_matrix_by_field[j] - ZERO_CELSIUS_IN_KELVINS) _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=narr_row_limits[0], last_row_in_full_grid=narr_row_limits[1], first_column_in_full_grid=narr_column_limits[0], last_column_in_full_grid=narr_column_limits[1]) plotting_utils.plot_coastlines(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_countries(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_states_and_provinces(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_parallels(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) for j in range(num_narr_fields): if NARR_FIELD_NAMES[j] in WIND_FIELD_NAMES: continue min_colour_value = numpy.percentile(narr_matrix_by_field[j], MIN_COLOUR_PERCENTILE) max_colour_value = numpy.percentile(narr_matrix_by_field[j], MAX_COLOUR_PERCENTILE) nwp_plotting.plot_subgrid( field_matrix=narr_matrix_by_field[j], model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, colour_map=THERMAL_COLOUR_MAP_OBJECT, min_value_in_colour_map=min_colour_value, max_value_in_colour_map=max_colour_value, first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0]) plotting_utils.add_linear_colour_bar( axes_object_or_list=axes_object, values_to_colour=narr_matrix_by_field[j], colour_map=THERMAL_COLOUR_MAP_OBJECT, colour_min=min_colour_value, colour_max=max_colour_value, orientation='horizontal', extend_min=True, extend_max=True, fraction_of_axis_length=0.9) this_cos_matrix = narr_rotation_cos_matrix[narr_row_limits[0]:( narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1)] this_sin_matrix = narr_rotation_sin_matrix[narr_row_limits[0]:( narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1)] u_wind_index = NARR_FIELD_NAMES.index( processed_narr_io.U_WIND_GRID_RELATIVE_NAME) v_wind_index = NARR_FIELD_NAMES.index( processed_narr_io.V_WIND_GRID_RELATIVE_NAME) narr_matrix_by_field[u_wind_index], narr_matrix_by_field[v_wind_index] = ( nwp_model_utils.rotate_winds_to_earth_relative( u_winds_grid_relative_m_s01=narr_matrix_by_field[u_wind_index], v_winds_grid_relative_m_s01=narr_matrix_by_field[v_wind_index], rotation_angle_cosines=this_cos_matrix, rotation_angle_sines=this_sin_matrix)) nwp_plotting.plot_wind_barbs_on_subgrid( u_wind_matrix_m_s01=narr_matrix_by_field[u_wind_index], v_wind_matrix_m_s01=narr_matrix_by_field[v_wind_index], model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0], plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB, plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB, barb_length=WIND_BARB_LENGTH, empty_barb_radius=EMPTY_WIND_BARB_RADIUS, fill_empty_barb=False, colour_map=WIND_COLOUR_MAP_OBJECT, colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT, colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT) num_fronts = len(front_line_table.index) for i in range(num_fronts): this_front_type_string = front_line_table[ front_utils.FRONT_TYPE_COLUMN].values[i] if this_front_type_string == front_utils.WARM_FRONT_STRING_ID: this_colour = WARM_FRONT_COLOUR else: this_colour = COLD_FRONT_COLOUR front_plotting.plot_front_with_markers( line_latitudes_deg=front_line_table[ front_utils.LATITUDES_COLUMN].values[i], line_longitudes_deg=front_line_table[ front_utils.LONGITUDES_COLUMN].values[i], axes_object=axes_object, basemap_object=basemap_object, front_type_string=front_line_table[ front_utils.FRONT_TYPE_COLUMN].values[i], marker_colour=this_colour) pyplot.title(title_string) plotting_utils.annotate_axes(axes_object=axes_object, annotation_string=annotation_string) file_system_utils.mkdir_recursive_if_necessary( directory_name=OUTPUT_DIR_NAME) figure_file_name = '{0:s}/fronts_{1:04d}mb_{2:s}.jpg'.format( OUTPUT_DIR_NAME, pressure_level_mb, valid_time_string) print 'Saving figure to: "{0:s}"...'.format(figure_file_name) pyplot.savefig(figure_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=figure_file_name, output_file_name=figure_file_name) return figure_file_name
def _plot_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)
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()
def _run(erosion_distance_metres, output_file_name): """Plots boundary of continental United States (CONUS). This is effectively the main method. :param erosion_distance_metres: See documentation at top of file. :param output_file_name: Same. """ error_checking.assert_is_geq(erosion_distance_metres, 0.) file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name) latitudes_deg, longitudes_deg = conus_boundary.read_from_netcdf() if erosion_distance_metres > 0: latitudes_deg, longitudes_deg = conus_boundary.erode_boundary( latitudes_deg=latitudes_deg, longitudes_deg=longitudes_deg, erosion_distance_metres=erosion_distance_metres ) figure_object, axes_object, basemap_object = ( plotting_utils.create_lambert_conformal_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 ) 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 ) x_coords_metres, y_coords_metres = basemap_object( longitudes_deg, latitudes_deg ) axes_object.plot( x_coords_metres, y_coords_metres, color=CONUS_COLOUR, linestyle='solid', linewidth=CONUS_LINE_WIDTH ) 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)
def _run(): """Plots input example. This is effectively the main method. :return: figure_file_name: Path to output file (where the figure was saved). """ valid_time_unix_sec = time_conversion.string_to_unix_sec( VALID_TIME_STRING, TIME_FORMAT) front_file_name = fronts_io.find_file_for_one_time( top_directory_name=TOP_FRONT_DIR_NAME, file_type=fronts_io.POLYLINE_FILE_TYPE, valid_time_unix_sec=valid_time_unix_sec) print 'Reading data from: "{0:s}"...'.format(front_file_name) front_line_table = fronts_io.read_polylines_from_file(front_file_name) num_narr_fields = len(NARR_FIELD_NAMES) narr_matrix_by_field = [numpy.array([])] * num_narr_fields for j in range(num_narr_fields): if NARR_FIELD_NAMES[j] in WIND_FIELD_NAMES: this_directory_name = '{0:s}/earth_relative_wind'.format( TOP_NARR_DIRECTORY_NAME) else: this_directory_name = TOP_NARR_DIRECTORY_NAME + '' this_file_name = processed_narr_io.find_file_for_one_time( top_directory_name=this_directory_name, field_name=NARR_FIELD_NAMES[j], pressure_level_mb=PRESSURE_LEVEL_MB, valid_time_unix_sec=valid_time_unix_sec) print 'Reading data from: "{0:s}"...'.format(this_file_name) narr_matrix_by_field[j] = processed_narr_io.read_fields_from_file( this_file_name)[0][0, ...] narr_matrix_by_field[j] = utils.fill_nans(narr_matrix_by_field[j]) if NARR_FIELD_NAMES[j] == processed_narr_io.WET_BULB_THETA_NAME: narr_matrix_by_field[j] = (narr_matrix_by_field[j] - ZERO_CELSIUS_IN_KELVINS) # (_, front_centroid_latitude_deg, front_centroid_longitude_deg # ) = _find_nearest_front( # front_line_table=front_line_table, # query_latitude_deg=APPROX_FRONT_LATITUDE_DEG, # query_longitude_deg=APPROX_FRONT_LONGITUDE_DEG) front_centroid_latitude_deg = APPROX_FRONT_LATITUDE_DEG + 0. front_centroid_longitude_deg = APPROX_FRONT_LONGITUDE_DEG + 0. projection_object = nwp_model_utils.init_model_projection( nwp_model_utils.NARR_MODEL_NAME) these_x_metres, these_y_metres = nwp_model_utils.project_latlng_to_xy( latitudes_deg=numpy.array([front_centroid_latitude_deg]), longitudes_deg=numpy.array([front_centroid_longitude_deg]), projection_object=projection_object, model_name=nwp_model_utils.NARR_MODEL_NAME) front_centroid_x_metres = these_x_metres[0] front_centroid_y_metres = these_y_metres[0] grid_spacing_metres, _ = nwp_model_utils.get_xy_grid_spacing( model_name=nwp_model_utils.NARR_MODEL_NAME) center_narr_row_index = int( numpy.round(front_centroid_y_metres / grid_spacing_metres)) center_narr_column_index = int( numpy.round(front_centroid_x_metres / grid_spacing_metres)) first_narr_row_index = center_narr_row_index - NUM_ROWS_IN_HALF_GRID last_narr_row_index = center_narr_row_index + NUM_ROWS_IN_HALF_GRID first_narr_column_index = (center_narr_column_index - NUM_COLUMNS_IN_HALF_GRID) last_narr_column_index = center_narr_column_index + NUM_COLUMNS_IN_HALF_GRID for j in range(num_narr_fields): narr_matrix_by_field[j] = narr_matrix_by_field[j][ first_narr_row_index:(last_narr_row_index + 1), first_narr_column_index:(last_narr_column_index + 1)] _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=first_narr_row_index, last_row_in_full_grid=last_narr_row_index, first_column_in_full_grid=first_narr_column_index, last_column_in_full_grid=last_narr_column_index, resolution_string='i') plotting_utils.plot_coastlines(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_countries(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_states_and_provinces(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_parallels(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) for j in range(num_narr_fields): if NARR_FIELD_NAMES[j] in WIND_FIELD_NAMES: continue min_colour_value = numpy.percentile(narr_matrix_by_field[j], MIN_COLOUR_PERCENTILE) max_colour_value = numpy.percentile(narr_matrix_by_field[j], MAX_COLOUR_PERCENTILE) nwp_plotting.plot_subgrid( field_matrix=narr_matrix_by_field[j], model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, colour_map=THERMAL_COLOUR_MAP_OBJECT, min_value_in_colour_map=min_colour_value, max_value_in_colour_map=max_colour_value, first_row_in_full_grid=first_narr_row_index, first_column_in_full_grid=first_narr_column_index) plotting_utils.add_linear_colour_bar( axes_object_or_list=axes_object, values_to_colour=narr_matrix_by_field[j], colour_map=THERMAL_COLOUR_MAP_OBJECT, colour_min=min_colour_value, colour_max=max_colour_value, orientation='horizontal', extend_min=True, extend_max=True) u_wind_index = NARR_FIELD_NAMES.index( processed_narr_io.U_WIND_EARTH_RELATIVE_NAME) v_wind_index = NARR_FIELD_NAMES.index( processed_narr_io.V_WIND_EARTH_RELATIVE_NAME) nwp_plotting.plot_wind_barbs_on_subgrid( u_wind_matrix_m_s01=narr_matrix_by_field[u_wind_index], v_wind_matrix_m_s01=narr_matrix_by_field[v_wind_index], model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, first_row_in_full_grid=first_narr_row_index, first_column_in_full_grid=first_narr_column_index, plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB, plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB, barb_length=WIND_BARB_LENGTH, empty_barb_radius=EMPTY_WIND_BARB_RADIUS, colour_map=WIND_COLOUR_MAP_OBJECT, colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT, colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT) num_fronts = len(front_line_table.index) for i in range(num_fronts): this_front_type_string = front_line_table[ front_utils.FRONT_TYPE_COLUMN].values[i] if this_front_type_string == front_utils.WARM_FRONT_STRING_ID: this_colour = WARM_FRONT_COLOUR else: this_colour = COLD_FRONT_COLOUR # front_plotting.plot_polyline( # latitudes_deg=front_line_table[ # front_utils.LATITUDES_COLUMN].values[i], # longitudes_deg=front_line_table[ # front_utils.LONGITUDES_COLUMN].values[i], # basemap_object=basemap_object, axes_object=axes_object, # front_type=front_line_table[ # front_utils.FRONT_TYPE_COLUMN].values[i], # line_width=FRONT_LINE_WIDTH, line_colour=this_colour) print 'Saving figure to: "{0:s}"...'.format(OUTPUT_FILE_NAME) file_system_utils.mkdir_recursive_if_necessary(file_name=OUTPUT_FILE_NAME) pyplot.savefig(OUTPUT_FILE_NAME, dpi=OUTPUT_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=OUTPUT_FILE_NAME, output_file_name=OUTPUT_FILE_NAME)
def _plot_storm_outlines_one_time(storm_object_table, valid_time_unix_sec, warning_table, axes_object, basemap_object, storm_outline_colour, storm_outline_opacity, include_secondary_ids, output_dir_name, primary_id_to_track_colour=None, radar_matrix=None, radar_field_name=None, radar_latitudes_deg=None, radar_longitudes_deg=None, radar_colour_map_object=None): """Plots storm outlines (and may underlay radar data) at one time step. M = number of rows in radar grid N = number of columns in radar grid K = number of storm objects If `primary_id_to_track_colour is None`, all storm tracks will be the same colour. :param storm_object_table: See doc for `storm_plotting.plot_storm_outlines`. :param valid_time_unix_sec: Will plot storm outlines only at this time. Will plot tracks up to and including this time. :param warning_table: None or a pandas table with the following columns. warning_table.start_time_unix_sec: Start time. warning_table.end_time_unix_sec: End time. warning_table.polygon_object_latlng: Polygon (instance of `shapely.geometry.Polygon`) with lat-long coordinates of warning boundary. :param axes_object: See doc for `storm_plotting.plot_storm_outlines`. :param basemap_object: Same. :param storm_outline_colour: Same. :param storm_outline_opacity: Same. :param include_secondary_ids: Same. :param output_dir_name: See documentation at top of file. :param primary_id_to_track_colour: Dictionary created by `_assign_colours_to_storms`. If this is None, all storm tracks will be the same colour. :param radar_matrix: M-by-N numpy array of radar values. If `radar_matrix is None`, radar data will simply not be plotted. :param radar_field_name: [used only if `radar_matrix is not None`] See documentation at top of file. :param radar_latitudes_deg: [used only if `radar_matrix is not None`] length-M numpy array of grid-point latitudes (deg N). :param radar_longitudes_deg: [used only if `radar_matrix is not None`] length-N numpy array of grid-point longitudes (deg E). :param radar_colour_map_object: [used only if `radar_matrix is not None`] Colour map (instance of `matplotlib.pyplot.cm`). If None, will use default for the given field. """ # plot_storm_ids = radar_matrix is None or radar_colour_map_object is None plot_storm_ids = False min_plot_latitude_deg = basemap_object.llcrnrlat max_plot_latitude_deg = basemap_object.urcrnrlat min_plot_longitude_deg = basemap_object.llcrnrlon max_plot_longitude_deg = basemap_object.urcrnrlon 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) if radar_matrix is not None: custom_colour_map = radar_colour_map_object is not None good_indices = numpy.where( numpy.logical_and(radar_latitudes_deg >= min_plot_latitude_deg, radar_latitudes_deg <= max_plot_latitude_deg))[0] radar_latitudes_deg = radar_latitudes_deg[good_indices] radar_matrix = radar_matrix[good_indices, :] good_indices = numpy.where( numpy.logical_and( radar_longitudes_deg >= min_plot_longitude_deg, radar_longitudes_deg <= max_plot_longitude_deg))[0] radar_longitudes_deg = radar_longitudes_deg[good_indices] radar_matrix = radar_matrix[:, good_indices] latitude_spacing_deg = radar_latitudes_deg[1] - radar_latitudes_deg[0] longitude_spacing_deg = (radar_longitudes_deg[1] - radar_longitudes_deg[0]) if radar_colour_map_object is None: colour_map_object, colour_norm_object = ( radar_plotting.get_default_colour_scheme(radar_field_name)) else: colour_map_object = radar_colour_map_object colour_norm_object = radar_plotting.get_default_colour_scheme( radar_field_name)[-1] this_ratio = radar_plotting._field_to_plotting_units( field_matrix=1., field_name=radar_field_name) colour_norm_object = pyplot.Normalize( colour_norm_object.vmin / this_ratio, colour_norm_object.vmax / this_ratio) 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(radar_latitudes_deg), min_grid_point_longitude_deg=numpy.min(radar_longitudes_deg), latitude_spacing_deg=latitude_spacing_deg, longitude_spacing_deg=longitude_spacing_deg, colour_map_object=colour_map_object, colour_norm_object=colour_norm_object) latitude_range_deg = max_plot_latitude_deg - min_plot_latitude_deg longitude_range_deg = max_plot_longitude_deg - min_plot_longitude_deg if latitude_range_deg > longitude_range_deg: orientation_string = 'vertical' else: orientation_string = 'horizontal' colour_bar_object = 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=orientation_string, padding=0.05, extend_min=radar_field_name in radar_plotting.SHEAR_VORT_DIV_NAMES, extend_max=True, fraction_of_axis_length=1.) radar_field_name_verbose = radar_utils.field_name_to_verbose( field_name=radar_field_name, include_units=True) radar_field_name_verbose = radar_field_name_verbose.replace( 'm ASL', 'kft ASL') colour_bar_object.set_label(radar_field_name_verbose) if custom_colour_map: tick_values = colour_bar_object.get_ticks() tick_label_strings = ['{0:.1f}'.format(v) for v in tick_values] colour_bar_object.set_ticks(tick_values) colour_bar_object.set_ticklabels(tick_label_strings) valid_time_rows = numpy.where(storm_object_table[ tracking_utils.VALID_TIME_COLUMN].values == valid_time_unix_sec)[0] this_colour = matplotlib.colors.to_rgba(storm_outline_colour, storm_outline_opacity) storm_plotting.plot_storm_outlines( storm_object_table=storm_object_table.iloc[valid_time_rows], axes_object=axes_object, basemap_object=basemap_object, line_colour=this_colour) if plot_storm_ids: storm_plotting.plot_storm_ids( storm_object_table=storm_object_table.iloc[valid_time_rows], axes_object=axes_object, basemap_object=basemap_object, plot_near_centroids=False, include_secondary_ids=include_secondary_ids, font_colour=storm_plotting.DEFAULT_FONT_COLOUR) if warning_table is not None: warning_indices = numpy.where( numpy.logical_and( warning_table[WARNING_START_TIME_KEY].values <= valid_time_unix_sec, warning_table[WARNING_END_TIME_KEY].values >= valid_time_unix_sec))[0] for k in warning_indices: this_vertex_dict = polygons.polygon_object_to_vertex_arrays( warning_table[WARNING_LATLNG_POLYGON_KEY].values[k]) these_latitudes_deg = this_vertex_dict[polygons.EXTERIOR_Y_COLUMN] these_longitudes_deg = this_vertex_dict[polygons.EXTERIOR_X_COLUMN] these_latitude_flags = numpy.logical_and( these_latitudes_deg >= min_plot_latitude_deg, these_latitudes_deg <= max_plot_latitude_deg) these_longitude_flags = numpy.logical_and( these_longitudes_deg >= min_plot_longitude_deg, these_longitudes_deg <= max_plot_longitude_deg) these_coord_flags = numpy.logical_and(these_latitude_flags, these_longitude_flags) if not numpy.any(these_coord_flags): continue these_x_metres, these_y_metres = basemap_object( these_longitudes_deg, these_latitudes_deg) axes_object.plot(these_x_metres, these_y_metres, color=this_colour, linestyle='dashed', linewidth=storm_plotting.DEFAULT_POLYGON_WIDTH) axes_object.text(numpy.mean(these_x_metres), numpy.mean(these_y_metres), 'W{0:d}'.format(k), fontsize=storm_plotting.DEFAULT_FONT_SIZE, fontweight='bold', color=this_colour, horizontalalignment='center', verticalalignment='center') these_sec_id_strings = ( warning_table[LINKED_SECONDARY_IDS_KEY].values[k]) if len(these_sec_id_strings) == 0: continue these_object_indices = numpy.array([], dtype=int) for this_sec_id_string in these_sec_id_strings: these_subindices = numpy.where( storm_object_table[tracking_utils.SECONDARY_ID_COLUMN]. values[valid_time_rows] == this_sec_id_string)[0] these_object_indices = numpy.concatenate( (these_object_indices, valid_time_rows[these_subindices])) for i in these_object_indices: this_vertex_dict = polygons.polygon_object_to_vertex_arrays( storm_object_table[ tracking_utils.LATLNG_POLYGON_COLUMN].values[i]) these_x_metres, these_y_metres = basemap_object( this_vertex_dict[polygons.EXTERIOR_X_COLUMN], this_vertex_dict[polygons.EXTERIOR_Y_COLUMN]) axes_object.text(numpy.mean(these_x_metres), numpy.mean(these_y_metres), 'W{0:d}'.format(k), fontsize=storm_plotting.DEFAULT_FONT_SIZE, fontweight='bold', color=this_colour, horizontalalignment='center', verticalalignment='center') if primary_id_to_track_colour is None: 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=DEFAULT_TRACK_COLOUR) else: for this_primary_id_string in primary_id_to_track_colour: this_storm_object_table = storm_object_table.loc[ storm_object_table[tracking_utils.PRIMARY_ID_COLUMN] == this_primary_id_string] if len(this_storm_object_table.index) == 0: continue storm_plotting.plot_storm_tracks( storm_object_table=this_storm_object_table, axes_object=axes_object, basemap_object=basemap_object, colour_map_object=None, constant_colour=primary_id_to_track_colour[ this_primary_id_string]) nice_time_string = time_conversion.unix_sec_to_string( valid_time_unix_sec, NICE_TIME_FORMAT) abbrev_time_string = time_conversion.unix_sec_to_string( valid_time_unix_sec, FILE_NAME_TIME_FORMAT) pyplot.title('Storm objects at {0:s}'.format(nice_time_string)) output_file_name = '{0:s}/storm_outlines_{1:s}.jpg'.format( output_dir_name, abbrev_time_string) 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()
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)
def _plot_storm_outlines_one_time(storm_object_table, valid_time_unix_sec, axes_object, basemap_object, storm_colour, storm_opacity, include_secondary_ids, output_dir_name, radar_matrix=None, radar_field_name=None, radar_latitudes_deg=None, radar_longitudes_deg=None): """Plots storm outlines (and may underlay radar data) at one time step. M = number of rows in radar grid N = number of columns in radar grid K = number of storm objects :param storm_object_table: See doc for `storm_plotting.plot_storm_outlines`. :param valid_time_unix_sec: Will plot storm outlines only at this time. Will plot tracks up to and including this time. :param axes_object: Same. :param basemap_object: Same. :param storm_colour: Same. :param storm_opacity: Same. :param include_secondary_ids: Same. :param output_dir_name: See documentation at top of file. :param radar_matrix: M-by-N numpy array of radar values. If `radar_matrix is None`, radar data will simply not be plotted. :param radar_field_name: [used only if `radar_matrix is not None`] See documentation at top of file. :param radar_latitudes_deg: [used only if `radar_matrix is not None`] length-M numpy array of grid-point latitudes (deg N). :param radar_longitudes_deg: [used only if `radar_matrix is not None`] length-N numpy array of grid-point longitudes (deg E). """ min_plot_latitude_deg = basemap_object.llcrnrlat max_plot_latitude_deg = basemap_object.urcrnrlat min_plot_longitude_deg = basemap_object.llcrnrlon max_plot_longitude_deg = basemap_object.urcrnrlon 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) if radar_matrix is not None: good_indices = numpy.where( numpy.logical_and(radar_latitudes_deg >= min_plot_latitude_deg, radar_latitudes_deg <= max_plot_latitude_deg))[0] radar_latitudes_deg = radar_latitudes_deg[good_indices] radar_matrix = radar_matrix[good_indices, :] good_indices = numpy.where( numpy.logical_and( radar_longitudes_deg >= min_plot_longitude_deg, radar_longitudes_deg <= max_plot_longitude_deg))[0] radar_longitudes_deg = radar_longitudes_deg[good_indices] radar_matrix = radar_matrix[:, good_indices] latitude_spacing_deg = radar_latitudes_deg[1] - radar_latitudes_deg[0] longitude_spacing_deg = (radar_longitudes_deg[1] - radar_longitudes_deg[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(radar_latitudes_deg), min_grid_point_longitude_deg=numpy.min(radar_longitudes_deg), latitude_spacing_deg=latitude_spacing_deg, longitude_spacing_deg=longitude_spacing_deg) colour_map_object, colour_norm_object = ( radar_plotting.get_default_colour_scheme(radar_field_name)) latitude_range_deg = max_plot_latitude_deg - min_plot_latitude_deg longitude_range_deg = max_plot_longitude_deg - min_plot_longitude_deg if latitude_range_deg > longitude_range_deg: orientation_string = 'vertical' else: orientation_string = 'horizontal' colour_bar_object = 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=orientation_string, extend_min=radar_field_name in radar_plotting.SHEAR_VORT_DIV_NAMES, extend_max=True, fraction_of_axis_length=0.9) colour_bar_object.set_label( radar_plotting.FIELD_NAME_TO_VERBOSE_DICT[radar_field_name]) valid_time_rows = numpy.where(storm_object_table[ tracking_utils.VALID_TIME_COLUMN].values == valid_time_unix_sec)[0] line_colour = matplotlib.colors.to_rgba(storm_colour, storm_opacity) storm_plotting.plot_storm_outlines( storm_object_table=storm_object_table.iloc[valid_time_rows], axes_object=axes_object, basemap_object=basemap_object, line_colour=line_colour) storm_plotting.plot_storm_ids( storm_object_table=storm_object_table.iloc[valid_time_rows], axes_object=axes_object, basemap_object=basemap_object, plot_near_centroids=False, include_secondary_ids=include_secondary_ids, font_colour=storm_plotting.DEFAULT_FONT_COLOUR) storm_plotting.plot_storm_tracks(storm_object_table=storm_object_table, axes_object=axes_object, basemap_object=basemap_object, colour_map_object=None, line_colour=TRACK_COLOUR) nice_time_string = time_conversion.unix_sec_to_string( valid_time_unix_sec, NICE_TIME_FORMAT) abbrev_time_string = time_conversion.unix_sec_to_string( valid_time_unix_sec, FILE_NAME_TIME_FORMAT) pyplot.title('Storm objects at {0:s}'.format(nice_time_string)) output_file_name = '{0:s}/storm_outlines_{1:s}.jpg'.format( output_dir_name, abbrev_time_string) print('Saving figure to: "{0:s}"...'.format(output_file_name)) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _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()
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 )