def _write_sounding_figure(figure_object, title_string, output_file_name): """Writes sounding figure to file. :param figure_object: Figure handle (instance of `matplotlib.figure.Figure`). :param title_string: Figure title. :param output_file_name: Path to output file (figure will be saved as image here). """ 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) imagemagick_utils.resize_image(input_file_name=output_file_name, output_file_name=output_file_name, output_size_pixels=SOUNDING_FIGURE_SIZE_PX) imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name, border_width_pixels=TITLE_FONT_SIZE + 25) _overlay_text(image_file_name=output_file_name, text_string=title_string, x_offset_from_center_px=0, y_offset_from_top_px=0) imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name, border_width_pixels=10)
def _run(input_dir_name, output_dir_name): """Creates figure showing overall model evaluation. This is effectively the main method. :param input_dir_name: See documentation at top of file. :param output_dir_name: Same. """ file_system_utils.mkdir_recursive_if_necessary( directory_name=output_dir_name) panel_file_names = [ '{0:s}/{1:s}'.format(input_dir_name, p) for p in PATHLESS_INPUT_FILE_NAMES ] resized_panel_file_names = [ '{0:s}/{1:s}'.format(output_dir_name, p) for p in PATHLESS_INPUT_FILE_NAMES ] letter_label = None for i in range(len(panel_file_names)): print('Resizing panel and saving to: "{0:s}"...'.format( resized_panel_file_names[i])) imagemagick_utils.trim_whitespace( input_file_name=panel_file_names[i], output_file_name=resized_panel_file_names[i]) if letter_label is None: letter_label = 'a' else: letter_label = chr(ord(letter_label) + 1) _overlay_text(image_file_name=resized_panel_file_names[i], x_offset_from_left_px=0, y_offset_from_top_px=TITLE_FONT_SIZE, text_string='({0:s})'.format(letter_label)) imagemagick_utils.resize_image( input_file_name=resized_panel_file_names[i], output_file_name=resized_panel_file_names[i], output_size_pixels=PANEL_SIZE_PX) concat_figure_file_name = '{0:s}/overall_evaluation.jpg'.format( output_dir_name) print( 'Concatenating panels to: "{0:s}"...'.format(concat_figure_file_name)) imagemagick_utils.concatenate_images( input_file_names=resized_panel_file_names, output_file_name=concat_figure_file_name, num_panel_rows=NUM_PANEL_ROWS, num_panel_columns=NUM_PANEL_COLUMNS) imagemagick_utils.resize_image(input_file_name=concat_figure_file_name, output_file_name=concat_figure_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX)
def _run(input_dir_name, output_dir_name): """Creates figure showing model performance as a function of hyperparams. This is effectively the main method. :param input_dir_name: See documentation at top of file. :param output_dir_name: Same. """ file_system_utils.mkdir_recursive_if_necessary( directory_name=output_dir_name) num_scores = len(SCORE_NAMES) num_dense_layer_counts = len(DENSE_LAYER_COUNTS) for j in range(num_scores): panel_file_names = [ '{0:s}/num-dense-layers={1:d}_{2:s}_grid.jpg'.format( input_dir_name, d, SCORE_NAMES[j]) for d in DENSE_LAYER_COUNTS ] resized_panel_file_names = [ '{0:s}/num-dense-layers={1:d}_{2:s}_grid.jpg'.format( output_dir_name, d, SCORE_NAMES[j]) for d in DENSE_LAYER_COUNTS ] for i in range(num_dense_layer_counts): imagemagick_utils.trim_whitespace( input_file_name=panel_file_names[i], output_file_name=resized_panel_file_names[i]) imagemagick_utils.resize_image( input_file_name=resized_panel_file_names[i], output_file_name=resized_panel_file_names[i], output_size_pixels=PANEL_SIZE_PX) concat_figure_file_name = '{0:s}/{1:s}_grid.jpg'.format( output_dir_name, SCORE_NAMES[j]) print('Concatenating panels to: "{0:s}"...'.format( concat_figure_file_name)) imagemagick_utils.concatenate_images( input_file_names=resized_panel_file_names, output_file_name=concat_figure_file_name, num_panel_rows=NUM_PANEL_ROWS, num_panel_columns=NUM_PANEL_COLUMNS) imagemagick_utils.resize_image( input_file_name=concat_figure_file_name, output_file_name=concat_figure_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX) imagemagick_utils.trim_whitespace( input_file_name=concat_figure_file_name, output_file_name=concat_figure_file_name)
def _run(): """Plots dilation of WPC fronts. This is effectively the main method. """ print 'Reading data from: "{0:s}"...'.format(FRONT_LINE_FILE_NAME) front_line_table = fronts_io.read_polylines_from_file(FRONT_LINE_FILE_NAME) print 'Reading data from: "{0:s}"...'.format(FRONTAL_GRID_FILE_NAME) frontal_grid_table = fronts_io.read_narr_grids_from_file( FRONTAL_GRID_FILE_NAME) num_grid_rows, num_grid_columns = nwp_model_utils.get_grid_dimensions( model_name=nwp_model_utils.NARR_MODEL_NAME) ternary_front_matrix = ml_utils.front_table_to_images( frontal_grid_table=frontal_grid_table, num_rows_per_image=num_grid_rows, num_columns_per_image=num_grid_columns) _plot_fronts(front_line_table=front_line_table, ternary_front_matrix=ternary_front_matrix, title_string='Observed fronts before dilation', annotation_string='(a)', output_file_name=BEFORE_FILE_NAME) ternary_front_matrix = ml_utils.dilate_ternary_target_images( target_matrix=ternary_front_matrix, dilation_distance_metres=DILATION_DISTANCE_METRES, verbose=False) _plot_fronts(front_line_table=front_line_table, ternary_front_matrix=ternary_front_matrix, title_string='Observed fronts after dilation', annotation_string='(b)', output_file_name=AFTER_FILE_NAME) print 'Concatenating figures to: "{0:s}"...'.format(CONCAT_FILE_NAME) imagemagick_utils.concatenate_images( input_file_names=[BEFORE_FILE_NAME, AFTER_FILE_NAME], output_file_name=CONCAT_FILE_NAME, num_panel_rows=1, num_panel_columns=2) imagemagick_utils.resize_image(input_file_name=CONCAT_FILE_NAME, output_file_name=CONCAT_FILE_NAME, output_size_pixels=CONCAT_SIZE_PIXELS)
def _run(): """Concatenates figures showing dilation procedure and double penalty. This is effectively the main method. """ dilation_image_object = Image.open(DILATION_FILE_NAME) double_penalty_image_object = Image.open(DOUBLE_PENALTY_FILE_NAME) new_dilation_width_px = double_penalty_image_object.size[0] width_ratio = (float(new_dilation_width_px) / dilation_image_object.size[0]) new_dilation_height_px = int( numpy.round(dilation_image_object.size[1] * width_ratio)) small_dilation_file_name = DILATION_FILE_NAME.replace( '.jpg', '_resized.jpg') print 'Resizing dilation figure to: "{0:s}"...'.format( small_dilation_file_name) command_string = ( '/usr/bin/convert "{0:s}" -resize {1:d}x{2:d} "{3:s}"').format( DILATION_FILE_NAME, new_dilation_width_px, new_dilation_height_px, small_dilation_file_name) os.system(command_string) print('Concatenating dilation and double-penalty figures to: "{0:s}"...' ).format(CONCAT_FILE_NAME) imagemagick_utils.concatenate_images( input_file_names=[small_dilation_file_name, DOUBLE_PENALTY_FILE_NAME], output_file_name=CONCAT_FILE_NAME, num_panel_rows=2, num_panel_columns=1) imagemagick_utils.trim_whitespace(input_file_name=CONCAT_FILE_NAME, output_file_name=CONCAT_FILE_NAME) imagemagick_utils.resize_image(input_file_name=CONCAT_FILE_NAME, output_file_name=CONCAT_FILE_NAME, output_size_pixels=CONCAT_SIZE_PIXELS) os.remove(small_dilation_file_name)
def _run(): """Plots determinization of front probabilities. This is effectively the main method. """ prediction_dict = ml_utils.read_gridded_predictions(PREDICTION_FILE_NAME) class_probability_matrix = prediction_dict[ml_utils.PROBABILITY_MATRIX_KEY] for this_id in front_utils.VALID_INTEGER_IDS: if this_id == front_utils.NO_FRONT_INTEGER_ID: class_probability_matrix[..., this_id][numpy.isnan( class_probability_matrix[..., this_id])] = 1. else: class_probability_matrix[..., this_id][numpy.isnan( class_probability_matrix[..., this_id])] = 0. _plot_predictions(output_file_name=BEFORE_FILE_NAME, title_string='Probabilities', annotation_string='(a)', class_probability_matrix=class_probability_matrix) predicted_label_matrix = object_eval.determinize_probabilities( class_probability_matrix=class_probability_matrix, binarization_threshold=BINARIZATION_THRESHOLD) _plot_predictions(output_file_name=AFTER_FILE_NAME, title_string='Deterministic predictions', annotation_string='(b)', predicted_label_matrix=predicted_label_matrix) print 'Concatenating figures to: "{0:s}"...'.format(CONCAT_FILE_NAME) imagemagick_utils.concatenate_images( input_file_names=[BEFORE_FILE_NAME, AFTER_FILE_NAME], output_file_name=CONCAT_FILE_NAME, num_panel_rows=2, num_panel_columns=1) imagemagick_utils.resize_image(input_file_name=CONCAT_FILE_NAME, output_file_name=CONCAT_FILE_NAME, output_size_pixels=CONCAT_SIZE_PIXELS)
def _run(evaluation_dir_name, num_months_per_chunk, num_hours_per_chunk, confidence_level, output_dir_name): """Plots temporally subset model evaluation. This is effectively the main method. :param evaluation_dir_name: See documentation at top of file. :param num_months_per_chunk: Same. :param num_hours_per_chunk: Same. :param confidence_level: Same. :param output_dir_name: Same. """ file_system_utils.mkdir_recursive_if_necessary( directory_name=output_dir_name) panel_file_names = _plot_by_month( evaluation_dir_name=evaluation_dir_name, num_months_per_chunk=num_months_per_chunk, confidence_level=confidence_level, output_dir_name=output_dir_name) panel_file_names += _plot_by_hour(evaluation_dir_name=evaluation_dir_name, num_hours_per_chunk=num_hours_per_chunk, confidence_level=confidence_level, output_dir_name=output_dir_name) concat_file_name = '{0:s}/temporally_subset_eval.jpg'.format( output_dir_name) print('Concatenating panels to: "{0:s}"...'.format(concat_file_name)) imagemagick_utils.concatenate_images(input_file_names=panel_file_names, output_file_name=concat_file_name, num_panel_rows=2, num_panel_columns=2) imagemagick_utils.resize_image(input_file_name=concat_file_name, output_file_name=concat_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX)
def _write_radar_figures(figure_objects, field_names, composite_name, concat_title_string, output_dir_name): """Writes radar figures to file. F = number of radar fields :param figure_objects: length-F list of figure handles (each an instance of `matplotlib.figure.Figure`). :param field_names: length-F list of field names. :param composite_name: Name of composite (e.g., "after" or "difference"). :param concat_title_string: Title for concatenated figure. :param output_dir_name: Name of output directory (figures will be saved here). :return: concat_figure_file_name: Path to image file with concatenated figure. """ num_fields = len(field_names) panel_file_names = [None] * num_fields for k in range(num_fields): panel_file_names[k] = '{0:s}/{1:s}_{2:s}.jpg'.format( output_dir_name, field_names[k].replace('_', '-'), composite_name) print('Saving figure to: "{0:s}"...'.format(panel_file_names[k])) figure_objects[k].savefig(panel_file_names[k], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(figure_objects[k]) concat_figure_file_name = '{0:s}/radar_{1:s}.jpg'.format( output_dir_name, composite_name) print( 'Concatenating panels to: "{0:s}"...'.format(concat_figure_file_name)) imagemagick_utils.concatenate_images( input_file_names=panel_file_names, output_file_name=concat_figure_file_name, num_panel_rows=1, num_panel_columns=num_fields, border_width_pixels=50) imagemagick_utils.resize_image(input_file_name=concat_figure_file_name, output_file_name=concat_figure_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX) imagemagick_utils.trim_whitespace(input_file_name=concat_figure_file_name, output_file_name=concat_figure_file_name, border_width_pixels=TITLE_FONT_SIZE + 25) _overlay_text(image_file_name=concat_figure_file_name, text_string=concat_title_string, x_offset_from_center_px=0, y_offset_from_top_px=0) imagemagick_utils.trim_whitespace(input_file_name=concat_figure_file_name, output_file_name=concat_figure_file_name, border_width_pixels=10) return concat_figure_file_name
def plot_many_soundings(list_of_metpy_dictionaries, title_strings, num_panel_rows, output_file_name, temp_directory_name=None, option_dict=None): """Creates paneled figure with many soundings. N = number of soundings to plot :param list_of_metpy_dictionaries: length-N list of dictionaries. Each dictionary must satisfy the input format for `sounding_dict_for_metpy` in `plot_sounding`. :param title_strings: length-N list of titles. :param num_panel_rows: Number of rows in paneled figure. :param output_file_name: Path to output (image) file. :param temp_directory_name: Name of temporary directory. Each panel will be stored here, then deleted after the panels have been concatenated into the final image. If `temp_directory_name is None`, will use the default temp directory on the local machine. :param option_dict: See doc for `plot_sounding`. """ error_checking.assert_is_numpy_array(numpy.array(title_strings), num_dimensions=1) num_soundings = len(title_strings) error_checking.assert_is_list(list_of_metpy_dictionaries) error_checking.assert_is_geq(len(list_of_metpy_dictionaries), num_soundings) error_checking.assert_is_leq(len(list_of_metpy_dictionaries), num_soundings) error_checking.assert_is_integer(num_panel_rows) error_checking.assert_is_geq(num_panel_rows, 1) error_checking.assert_is_leq(num_panel_rows, num_soundings) file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name) if temp_directory_name is not None: file_system_utils.mkdir_recursive_if_necessary( directory_name=temp_directory_name) temp_file_names = [None] * num_soundings num_panel_columns = int(numpy.ceil(float(num_soundings) / num_panel_rows)) for i in range(num_panel_rows): for j in range(num_panel_columns): this_sounding_index = i * num_panel_columns + j if this_sounding_index >= num_soundings: break plot_sounding(sounding_dict_for_metpy=list_of_metpy_dictionaries[ this_sounding_index], title_string=title_strings[this_sounding_index], option_dict=option_dict) temp_file_names[this_sounding_index] = '{0:s}.jpg'.format( tempfile.NamedTemporaryFile(dir=temp_directory_name, delete=False).name) print('Saving sounding to: "{0:s}"...'.format( temp_file_names[this_sounding_index])) pyplot.savefig(temp_file_names[this_sounding_index], dpi=DOTS_PER_INCH) pyplot.close() imagemagick_utils.trim_whitespace( input_file_name=temp_file_names[this_sounding_index], output_file_name=temp_file_names[this_sounding_index], border_width_pixels=SINGLE_IMAGE_BORDER_WIDTH_PX) imagemagick_utils.resize_image( input_file_name=temp_file_names[this_sounding_index], output_file_name=temp_file_names[this_sounding_index], output_size_pixels=SINGLE_IMAGE_SIZE_PX) print('Concatenating panels into one figure: "{0:s}"...'.format( output_file_name)) imagemagick_utils.concatenate_images( input_file_names=temp_file_names, output_file_name=output_file_name, num_panel_rows=num_panel_rows, num_panel_columns=num_panel_columns, border_width_pixels=PANELED_IMAGE_BORDER_WIDTH_PX) for i in range(num_soundings): os.remove(temp_file_names[i])
def _run(): """Plots weird WPC fronts, along with theta_w and wind barbs from NARR. This is effectively the main method. """ narr_latitude_matrix_deg, narr_longitude_matrix_deg = ( nwp_model_utils.get_latlng_grid_point_matrices( model_name=nwp_model_utils.NARR_MODEL_NAME)) narr_rotation_cos_matrix, narr_rotation_sin_matrix = ( nwp_model_utils.get_wind_rotation_angles( latitudes_deg=narr_latitude_matrix_deg, longitudes_deg=narr_longitude_matrix_deg, model_name=nwp_model_utils.NARR_MODEL_NAME)) num_panels = len(VALID_TIME_STRINGS) panel_file_names = [''] * num_panels this_annotation_string = None for i in range(num_panels): this_time_unix_sec = time_conversion.string_to_unix_sec( VALID_TIME_STRINGS[i], DEFAULT_TIME_FORMAT) this_title_string = time_conversion.unix_sec_to_string( this_time_unix_sec, NICE_TIME_FORMAT) if PRESSURE_LEVELS_MB[i] == 1000: this_title_string += ' at 1000 mb' else: this_title_string += ' at surface' if this_annotation_string is None: this_annotation_string = '(a)' else: this_orig_character = this_annotation_string[1] this_new_character = chr(ord(this_orig_character) + 1) this_annotation_string = this_annotation_string.replace( this_orig_character, this_new_character) this_file_name = _plot_one_time( valid_time_string=VALID_TIME_STRINGS[i], pressure_level_mb=PRESSURE_LEVELS_MB[i], title_string=this_title_string, annotation_string=this_annotation_string, narr_rotation_cos_matrix=narr_rotation_cos_matrix, narr_rotation_sin_matrix=narr_rotation_sin_matrix) panel_file_names[i] = this_file_name print '\n' concat_file_name = '{0:s}/weird_fronts.jpg'.format(OUTPUT_DIR_NAME) print 'Concatenating figures to: "{0:s}"...'.format(concat_file_name) num_panels = len(panel_file_names) num_panel_columns = int(numpy.ceil(float(num_panels) / 2)) imagemagick_utils.concatenate_images(input_file_names=panel_file_names, output_file_name=concat_file_name, num_panel_rows=NUM_PANEL_ROWS, num_panel_columns=num_panel_columns) imagemagick_utils.trim_whitespace(input_file_name=concat_file_name, output_file_name=concat_file_name) imagemagick_utils.resize_image(input_file_name=concat_file_name, output_file_name=concat_file_name, output_size_pixels=CONCAT_SIZE_PIXELS)
def _run(valid_time_string, smoothing_radius_pixels, front_percentile, num_closing_iters, pressure_level_mb, top_narr_directory_name, narr_mask_file_name, output_dir_name): """Plots NFA (numerical frontal analysis) procedure. This is effectively the main method. :param valid_time_string: See documentation at top of file. :param smoothing_radius_pixels: Same. :param front_percentile: Same. :param num_closing_iters: Same. :param pressure_level_mb: Same. :param top_narr_directory_name: Same. :param narr_mask_file_name: Same. :param output_dir_name: Same. """ cutoff_radius_pixels = 4 * smoothing_radius_pixels valid_time_unix_sec = time_conversion.string_to_unix_sec( valid_time_string, INPUT_TIME_FORMAT) file_system_utils.mkdir_recursive_if_necessary( directory_name=output_dir_name) if narr_mask_file_name == '': num_grid_rows, num_grid_columns = nwp_model_utils.get_grid_dimensions( model_name=nwp_model_utils.NARR_MODEL_NAME) narr_mask_matrix = numpy.full( (num_grid_rows, num_grid_columns), 1, dtype=int) else: print 'Reading mask from: "{0:s}"...\n'.format(narr_mask_file_name) narr_mask_matrix = ml_utils.read_narr_mask(narr_mask_file_name) wet_bulb_theta_file_name = processed_narr_io.find_file_for_one_time( top_directory_name=top_narr_directory_name, field_name=processed_narr_io.WET_BULB_THETA_NAME, pressure_level_mb=pressure_level_mb, valid_time_unix_sec=valid_time_unix_sec) print 'Reading data from: "{0:s}"...'.format(wet_bulb_theta_file_name) wet_bulb_theta_matrix_kelvins = processed_narr_io.read_fields_from_file( wet_bulb_theta_file_name)[0][0, ...] wet_bulb_theta_matrix_kelvins = general_utils.fill_nans( wet_bulb_theta_matrix_kelvins) u_wind_file_name = processed_narr_io.find_file_for_one_time( top_directory_name=top_narr_directory_name, field_name=processed_narr_io.U_WIND_GRID_RELATIVE_NAME, pressure_level_mb=pressure_level_mb, valid_time_unix_sec=valid_time_unix_sec) print 'Reading data from: "{0:s}"...'.format(u_wind_file_name) u_wind_matrix_m_s01 = processed_narr_io.read_fields_from_file( u_wind_file_name)[0][0, ...] u_wind_matrix_m_s01 = general_utils.fill_nans(u_wind_matrix_m_s01) v_wind_file_name = processed_narr_io.find_file_for_one_time( top_directory_name=top_narr_directory_name, field_name=processed_narr_io.V_WIND_GRID_RELATIVE_NAME, pressure_level_mb=pressure_level_mb, valid_time_unix_sec=valid_time_unix_sec) print 'Reading data from: "{0:s}"...'.format(v_wind_file_name) v_wind_matrix_m_s01 = processed_narr_io.read_fields_from_file( v_wind_file_name)[0][0, ...] v_wind_matrix_m_s01 = general_utils.fill_nans(v_wind_matrix_m_s01) unsmoothed_narr_file_name = '{0:s}/unsmoothed_narr_fields.jpg'.format( output_dir_name) _plot_narr_fields( wet_bulb_theta_matrix_kelvins=wet_bulb_theta_matrix_kelvins, u_wind_matrix_m_s01=u_wind_matrix_m_s01, v_wind_matrix_m_s01=v_wind_matrix_m_s01, title_string='Predictors before smoothing', annotation_string='(a)', output_file_name=unsmoothed_narr_file_name) wet_bulb_theta_matrix_kelvins = nfa.gaussian_smooth_2d_field( field_matrix=wet_bulb_theta_matrix_kelvins, standard_deviation_pixels=smoothing_radius_pixels, cutoff_radius_pixels=cutoff_radius_pixels) u_wind_matrix_m_s01 = nfa.gaussian_smooth_2d_field( field_matrix=u_wind_matrix_m_s01, standard_deviation_pixels=smoothing_radius_pixels, cutoff_radius_pixels=cutoff_radius_pixels) v_wind_matrix_m_s01 = nfa.gaussian_smooth_2d_field( field_matrix=v_wind_matrix_m_s01, standard_deviation_pixels=smoothing_radius_pixels, cutoff_radius_pixels=cutoff_radius_pixels) smoothed_narr_file_name = '{0:s}/smoothed_narr_fields.jpg'.format( output_dir_name) _plot_narr_fields( wet_bulb_theta_matrix_kelvins=wet_bulb_theta_matrix_kelvins, u_wind_matrix_m_s01=u_wind_matrix_m_s01, v_wind_matrix_m_s01=v_wind_matrix_m_s01, title_string='Predictors after smoothing', annotation_string='(b)', output_file_name=smoothed_narr_file_name) x_spacing_metres, y_spacing_metres = nwp_model_utils.get_xy_grid_spacing( model_name=nwp_model_utils.NARR_MODEL_NAME) tfp_matrix_kelvins_m02 = nfa.get_thermal_front_param( thermal_field_matrix_kelvins=wet_bulb_theta_matrix_kelvins, x_spacing_metres=x_spacing_metres, y_spacing_metres=y_spacing_metres) tfp_matrix_kelvins_m02[narr_mask_matrix == 0] = 0. tfp_file_name = '{0:s}/tfp.jpg'.format(output_dir_name) tfp_title_string = ( r'Thermal front parameter ($\times$ 10$^{-10}$ K m$^{-2}$)') _plot_tfp(tfp_matrix_kelvins_m02=tfp_matrix_kelvins_m02, title_string=tfp_title_string, annotation_string='(c)', output_file_name=tfp_file_name) proj_velocity_matrix_m_s01 = nfa.project_wind_to_thermal_gradient( u_matrix_grid_relative_m_s01=u_wind_matrix_m_s01, v_matrix_grid_relative_m_s01=v_wind_matrix_m_s01, thermal_field_matrix_kelvins=wet_bulb_theta_matrix_kelvins, x_spacing_metres=x_spacing_metres, y_spacing_metres=y_spacing_metres) locating_var_matrix_m01_s01 = nfa.get_locating_variable( tfp_matrix_kelvins_m02=tfp_matrix_kelvins_m02, projected_velocity_matrix_m_s01=proj_velocity_matrix_m_s01) locating_var_file_name = '{0:s}/locating_variable.jpg'.format( output_dir_name) locating_var_title_string = ( r'Locating variable ($\times$ 10$^{-9}$ K m$^{-1}$ s$^{-1}$)') _plot_locating_variable( locating_var_matrix_m01_s01=locating_var_matrix_m01_s01, title_string=locating_var_title_string, annotation_string='(d)', output_file_name=locating_var_file_name) predicted_label_matrix = nfa.get_front_types( locating_var_matrix_m01_s01=locating_var_matrix_m01_s01, warm_front_percentile=front_percentile, cold_front_percentile=front_percentile) unclosed_fronts_file_name = '{0:s}/unclosed_fronts.jpg'.format( output_dir_name) _plot_front_types( predicted_label_matrix=predicted_label_matrix, title_string='Frontal regions before closing', annotation_string='(e)', output_file_name=unclosed_fronts_file_name) predicted_label_matrix = front_utils.close_frontal_image( ternary_image_matrix=predicted_label_matrix, num_iterations=num_closing_iters) closed_fronts_file_name = '{0:s}/closed_fronts.jpg'.format(output_dir_name) _plot_front_types( predicted_label_matrix=predicted_label_matrix, title_string='Frontal regions after closing', annotation_string='(f)', output_file_name=closed_fronts_file_name) concat_file_name = '{0:s}/nfa_procedure.jpg'.format(output_dir_name) print 'Concatenating figures to: "{0:s}"...'.format(concat_file_name) panel_file_names = [ unsmoothed_narr_file_name, smoothed_narr_file_name, tfp_file_name, locating_var_file_name, unclosed_fronts_file_name, closed_fronts_file_name ] imagemagick_utils.concatenate_images( input_file_names=panel_file_names, output_file_name=concat_file_name, num_panel_rows=3, num_panel_columns=2) imagemagick_utils.resize_image( input_file_name=concat_file_name, output_file_name=concat_file_name, output_size_pixels=CONCAT_SIZE_PIXELS)
def _plot_one_composite(gradcam_file_name, monte_carlo_file_name, composite_name_abbrev, composite_name_verbose, colour_map_object, min_colour_value, max_colour_value, num_contours, smoothing_radius_grid_cells, monte_carlo_max_fdr, output_dir_name): """Plots class-activation map for one composite. :param gradcam_file_name: Path to input file (will be read by `gradcam.read_file`). :param monte_carlo_file_name: Path to Monte Carlo file (will be read by `_read_monte_carlo_file`). :param composite_name_abbrev: Abbrev composite name (will be used in file names). :param composite_name_verbose: Verbose composite name (will be used in figure title). :param colour_map_object: See documentation at top of file. :param min_colour_value: Minimum value in colour bar (may be NaN). :param max_colour_value: Max value in colour bar (may be NaN). :param num_contours: See documentation at top of file. :param smoothing_radius_grid_cells: Same. :param monte_carlo_max_fdr: Same. :param output_dir_name: Name of output directory (figures will be saved here). :return: main_figure_file_name: Path to main image file created by this method. :return: min_colour_value: Same as input but cannot be None. :return: max_colour_value: Same as input but cannot be None. """ (mean_radar_matrix, mean_class_activn_matrix, significance_matrix, model_metadata_dict) = _read_one_composite( gradcam_file_name=gradcam_file_name, smoothing_radius_grid_cells=smoothing_radius_grid_cells, monte_carlo_file_name=monte_carlo_file_name, monte_carlo_max_fdr=monte_carlo_max_fdr) if numpy.isnan(min_colour_value) or numpy.isnan(max_colour_value): min_colour_value_log10 = numpy.log10( numpy.percentile(mean_class_activn_matrix, 1.)) max_colour_value_log10 = numpy.log10( numpy.percentile(mean_class_activn_matrix, 99.)) min_colour_value_log10 = max([min_colour_value_log10, -2.]) max_colour_value_log10 = max([max_colour_value_log10, -1.]) min_colour_value_log10 = min([min_colour_value_log10, 1.]) max_colour_value_log10 = min([max_colour_value_log10, 2.]) min_colour_value = 10**min_colour_value_log10 max_colour_value = 10**max_colour_value_log10 else: min_colour_value_log10 = numpy.log10(min_colour_value) max_colour_value_log10 = numpy.log10(max_colour_value) contour_interval_log10 = ( (max_colour_value_log10 - min_colour_value_log10) / (num_contours - 1)) mean_activn_matrix_log10 = numpy.log10(mean_class_activn_matrix) training_option_dict = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY] field_names = training_option_dict[trainval_io.RADAR_FIELDS_KEY] num_fields = mean_radar_matrix.shape[-1] num_heights = mean_radar_matrix.shape[-2] handle_dict = plot_examples.plot_one_example( list_of_predictor_matrices=[mean_radar_matrix], model_metadata_dict=model_metadata_dict, pmm_flag=True, allow_whitespace=True, plot_panel_names=True, panel_name_font_size=PANEL_NAME_FONT_SIZE, add_titles=False, label_colour_bars=True, colour_bar_length=COLOUR_BAR_LENGTH, colour_bar_font_size=COLOUR_BAR_FONT_SIZE, num_panel_rows=num_heights) figure_objects = handle_dict[plot_examples.RADAR_FIGURES_KEY] axes_object_matrices = handle_dict[plot_examples.RADAR_AXES_KEY] for k in range(num_fields): cam_plotting.plot_many_2d_grids( class_activation_matrix_3d=numpy.flip( mean_activn_matrix_log10[0, ...], axis=0), axes_object_matrix=axes_object_matrices[k], colour_map_object=colour_map_object, min_contour_level=min_colour_value_log10, max_contour_level=max_colour_value_log10, contour_interval=contour_interval_log10) significance_plotting.plot_many_2d_grids_without_coords( significance_matrix=numpy.flip(significance_matrix[0, ...], axis=0), axes_object_matrix=axes_object_matrices[k]) panel_file_names = [None] * num_fields for k in range(num_fields): panel_file_names[k] = '{0:s}/{1:s}_{2:s}.jpg'.format( output_dir_name, composite_name_abbrev, field_names[k].replace('_', '-')) print('Saving figure to: "{0:s}"...'.format(panel_file_names[k])) figure_objects[k].savefig(panel_file_names[k], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(figure_objects[k]) main_figure_file_name = '{0:s}/{1:s}_gradcam.jpg'.format( output_dir_name, composite_name_abbrev) print('Concatenating panels to: "{0:s}"...'.format(main_figure_file_name)) imagemagick_utils.concatenate_images( input_file_names=panel_file_names, output_file_name=main_figure_file_name, num_panel_rows=1, num_panel_columns=num_fields, border_width_pixels=50) imagemagick_utils.resize_image(input_file_name=main_figure_file_name, output_file_name=main_figure_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX) imagemagick_utils.trim_whitespace(input_file_name=main_figure_file_name, output_file_name=main_figure_file_name, border_width_pixels=TITLE_FONT_SIZE + 25) _overlay_text(image_file_name=main_figure_file_name, x_offset_from_center_px=0, y_offset_from_top_px=0, text_string=composite_name_verbose) imagemagick_utils.trim_whitespace(input_file_name=main_figure_file_name, output_file_name=main_figure_file_name, border_width_pixels=10) return main_figure_file_name, min_colour_value, max_colour_value
def _run(): """Plots conversion of gridded probabilities into objects. This is effectively the main method. """ prediction_dict = ml_utils.read_gridded_predictions(PREDICTION_FILE_NAME) class_probability_matrix = prediction_dict[ml_utils.PROBABILITY_MATRIX_KEY] for this_id in front_utils.VALID_INTEGER_IDS: if this_id == front_utils.NO_FRONT_INTEGER_ID: class_probability_matrix[..., this_id][numpy.isnan( class_probability_matrix[..., this_id])] = 1. else: class_probability_matrix[..., this_id][numpy.isnan( class_probability_matrix[..., this_id])] = 0. predicted_label_matrix = object_eval.determinize_probabilities( class_probability_matrix=class_probability_matrix, binarization_threshold=BINARIZATION_THRESHOLD) _plot_predictions(predicted_label_matrix=predicted_label_matrix, title_string='All frontal regions', annotation_string='(b)', output_file_name=ALL_REGIONS_FILE_NAME) valid_time_unix_sec = time_conversion.string_to_unix_sec( VALID_TIME_STRING, TIME_FORMAT) valid_times_unix_sec = numpy.array([valid_time_unix_sec], dtype=int) predicted_region_table = object_eval.images_to_regions( predicted_label_matrix=predicted_label_matrix, image_times_unix_sec=valid_times_unix_sec) num_grid_rows, num_grid_columns = nwp_model_utils.get_grid_dimensions( model_name=nwp_model_utils.NARR_MODEL_NAME) grid_spacing_metres = nwp_model_utils.get_xy_grid_spacing( model_name=nwp_model_utils.NARR_MODEL_NAME)[0] predicted_region_table = object_eval.discard_regions_with_small_area( predicted_region_table=predicted_region_table, x_grid_spacing_metres=grid_spacing_metres, y_grid_spacing_metres=grid_spacing_metres, min_area_metres2=MIN_REGION_AREA_METRES2) predicted_label_matrix = object_eval.regions_to_images( predicted_region_table=predicted_region_table, num_grid_rows=num_grid_rows, num_grid_columns=num_grid_columns) _plot_predictions(predicted_label_matrix=predicted_label_matrix, title_string='Large frontal regions', annotation_string='(c)', output_file_name=LARGE_REGIONS_FILE_NAME) predicted_region_table = object_eval.skeletonize_frontal_regions( predicted_region_table=predicted_region_table, num_grid_rows=num_grid_rows, num_grid_columns=num_grid_columns) predicted_label_matrix = object_eval.regions_to_images( predicted_region_table=predicted_region_table, num_grid_rows=num_grid_rows, num_grid_columns=num_grid_columns) _plot_predictions(predicted_label_matrix=predicted_label_matrix, title_string='All skeleton lines', annotation_string='(d)', output_file_name=ALL_SKELETONS_FILE_NAME) predicted_region_table = object_eval.find_main_skeletons( predicted_region_table=predicted_region_table, image_times_unix_sec=valid_times_unix_sec, num_grid_rows=num_grid_rows, num_grid_columns=num_grid_columns, x_grid_spacing_metres=grid_spacing_metres, y_grid_spacing_metres=grid_spacing_metres, min_endpoint_length_metres=MIN_ENDPOINT_LENGTH_METRES) predicted_label_matrix = object_eval.regions_to_images( predicted_region_table=predicted_region_table, num_grid_rows=num_grid_rows, num_grid_columns=num_grid_columns) _plot_predictions(predicted_label_matrix=predicted_label_matrix, title_string='Main skeleton lines', annotation_string='(e)', output_file_name=MAIN_SKELETONS_FILE_NAME) print 'Concatenating figures to: "{0:s}"...'.format(CONCAT_FILE_NAME) panel_file_names = [ PROBABILITY_FILE_NAME, ALL_REGIONS_FILE_NAME, LARGE_REGIONS_FILE_NAME, ALL_SKELETONS_FILE_NAME, MAIN_SKELETONS_FILE_NAME ] imagemagick_utils.concatenate_images(input_file_names=panel_file_names, output_file_name=CONCAT_FILE_NAME, num_panel_rows=2, num_panel_columns=3) imagemagick_utils.resize_image(input_file_name=CONCAT_FILE_NAME, output_file_name=CONCAT_FILE_NAME, output_size_pixels=CONCAT_SIZE_PIXELS)
def _plot_histogram_one_target(target_values, target_name, num_bins, letter_label, output_dir_name): """Plots histogram for one target variable. :param target_values: 1-D numpy array of values. :param target_name: Name of target variable. :param num_bins: Number of bins in histogram. :param letter_label: Letter label (will be used to label panel). :param output_dir_name: Name of output directory. Figure will be saved here. :return: output_file_name: Path to output file. """ min_value = (numpy.min(target_values) if target_name == SHORTWAVE_NET_FLUX_NAME else 0.) max_value = numpy.max(target_values) num_examples_by_bin = histograms.create_histogram( input_values=target_values, num_bins=num_bins, min_value=min_value, max_value=max_value)[1] frequency_by_bin = (num_examples_by_bin.astype(float) / numpy.sum(num_examples_by_bin)) bin_edges = numpy.linspace(min_value, max_value, num=num_bins + 1) bin_centers = numpy.array( [numpy.mean(bin_edges[[k, k + 1]]) for k in range(num_bins)]) x_tick_coords = 0.5 + numpy.linspace( 0, num_bins - 1, num=num_bins, dtype=float) if target_name == example_utils.SHORTWAVE_HEATING_RATE_NAME: x_tick_labels = ['{0:.1f}'.format(c) for c in bin_centers] else: x_tick_labels = [ '{0:d}'.format(int(numpy.round(c))) for c in bin_centers ] x_tick_labels = [ x_tick_labels[k] if numpy.mod(k, 3) == 0 else ' ' for k in range(num_bins) ] figure_object, axes_object = pyplot.subplots( 1, 1, figsize=(FIGURE_WIDTH_INCHES, FIGURE_HEIGHT_INCHES)) axes_object.bar(x=x_tick_coords, height=frequency_by_bin, width=1., color=FACE_COLOUR, edgecolor=EDGE_COLOUR, linewidth=EDGE_WIDTH) axes_object.set_xlim([x_tick_coords[0] - 0.5, x_tick_coords[-1] + 0.5]) axes_object.set_xticks(x_tick_coords) axes_object.set_xticklabels(x_tick_labels, rotation=90.) axes_object.set_ylabel('Frequency') axes_object.set_xlabel(TARGET_NAME_TO_VERBOSE[target_name]) plotting_utils.label_axes(axes_object=axes_object, label_string='({0:s})'.format(letter_label)) output_file_name = '{0:s}/histogram_{1:s}.jpg'.format( output_dir_name, target_name.replace('_', '-')) 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) imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name) imagemagick_utils.resize_image(input_file_name=output_file_name, output_file_name=output_file_name, output_size_pixels=int(2.5e6)) return output_file_name
def _run(input_dir_name, site_names_for_reliability, site_name_for_histogram, output_dir_name): """Creates figure showing overall model evaluation. This is effectively the main method. :param input_dir_name: See documentation at top of file. :param site_names_for_reliability: Same. :param site_name_for_histogram: Same. :param output_dir_name: Same. """ file_system_utils.mkdir_recursive_if_necessary( directory_name=output_dir_name) pathless_input_file_names = [ 'shortwave-surface-down-flux-w-m02_attributes_{0:s}.jpg'.format( site_name_for_histogram), 'shortwave-toa-up-flux-w-m02_attributes_{0:s}.jpg'.format( site_name_for_histogram), 'net-shortwave-flux-w-m02_attributes_{0:s}.jpg'.format( site_name_for_histogram), 'shortwave-heating-rate-k-day01_bias_profile.jpg', 'shortwave-heating-rate-k-day01_mean-absolute-error_profile.jpg', 'shortwave-heating-rate-k-day01_mae-skill-score_profile.jpg' ] num_sites_for_relia = len(site_names_for_reliability) for j in range(num_sites_for_relia): this_file_name = ( 'shortwave-heating-rate-k-day01_reliability_{0:s}.jpg').format( site_names_for_reliability[j]) pathless_input_file_names.append(this_file_name) panel_file_names = [ '{0:s}/{1:s}'.format(input_dir_name, p) for p in pathless_input_file_names ] resized_panel_file_names = [ '{0:s}/{1:s}'.format(output_dir_name, p) for p in pathless_input_file_names ] letter_label = None for i in range(len(panel_file_names)): print('Resizing panel and saving to: "{0:s}"...'.format( resized_panel_file_names[i])) imagemagick_utils.trim_whitespace( input_file_name=panel_file_names[i], output_file_name=resized_panel_file_names[i]) if letter_label is None: letter_label = 'a' else: letter_label = chr(ord(letter_label) + 1) _overlay_text(image_file_name=resized_panel_file_names[i], x_offset_from_left_px=0, y_offset_from_top_px=TITLE_FONT_SIZE, text_string='({0:s})'.format(letter_label)) imagemagick_utils.resize_image( input_file_name=resized_panel_file_names[i], output_file_name=resized_panel_file_names[i], output_size_pixels=PANEL_SIZE_PX) concat_figure_file_name = '{0:s}/evaluation_by_site.jpg'.format( output_dir_name) print( 'Concatenating panels to: "{0:s}"...'.format(concat_figure_file_name)) imagemagick_utils.concatenate_images( input_file_names=resized_panel_file_names, output_file_name=concat_figure_file_name, num_panel_rows=NUM_PANEL_ROWS, num_panel_columns=NUM_PANEL_COLUMNS) imagemagick_utils.resize_image(input_file_name=concat_figure_file_name, output_file_name=concat_figure_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX)
def _run(saliency_file_names, monte_carlo_file_names, composite_names, colour_map_name, max_colour_values, half_num_contours, smoothing_radius_grid_cells, output_dir_name): """Makes figure with sanity checks for saliency maps. This is effectively the main method. :param saliency_file_names: See documentation at top of file. :param monte_carlo_file_names: Same. :param composite_names: Same. :param colour_map_name: Same. :param max_colour_values: Same. :param half_num_contours: Same. :param smoothing_radius_grid_cells: Same. :param output_dir_name: Same. """ # Process input args. file_system_utils.mkdir_recursive_if_necessary( directory_name=output_dir_name) if smoothing_radius_grid_cells <= 0: smoothing_radius_grid_cells = None colour_map_object = pyplot.cm.get_cmap(colour_map_name) error_checking.assert_is_geq(half_num_contours, 5) num_composites = len(saliency_file_names) expected_dim = numpy.array([num_composites], dtype=int) error_checking.assert_is_numpy_array(numpy.array(composite_names), exact_dimensions=expected_dim) error_checking.assert_is_numpy_array(numpy.array(monte_carlo_file_names), exact_dimensions=expected_dim) monte_carlo_file_names = [ None if f in NONE_STRINGS else f for f in monte_carlo_file_names ] max_colour_values[max_colour_values <= 0] = numpy.nan error_checking.assert_is_numpy_array(max_colour_values, exact_dimensions=expected_dim) composite_names_abbrev = [ n.replace('_', '-').lower() for n in composite_names ] composite_names_verbose = [ '({0:s}) {1:s}'.format(chr(ord('a') + i), composite_names[i].replace('_', ' ')) for i in range(num_composites) ] panel_file_names = [None] * num_composites for i in range(num_composites): panel_file_names[i], max_colour_values[i] = _plot_one_composite( saliency_file_name=saliency_file_names[i], monte_carlo_file_name=monte_carlo_file_names[i], composite_name_abbrev=composite_names_abbrev[i], composite_name_verbose=composite_names_verbose[i], colour_map_object=colour_map_object, max_colour_value=max_colour_values[i], half_num_contours=half_num_contours, smoothing_radius_grid_cells=smoothing_radius_grid_cells, output_dir_name=output_dir_name) _add_colour_bar(figure_file_name=panel_file_names[i], colour_map_object=colour_map_object, max_colour_value=max_colour_values[i], temporary_dir_name=output_dir_name) print('\n') figure_file_name = '{0:s}/saliency_concat.jpg'.format(output_dir_name) print('Concatenating panels to: "{0:s}"...'.format(figure_file_name)) num_panel_rows = int(numpy.ceil(numpy.sqrt(num_composites))) num_panel_columns = int(numpy.floor( float(num_composites) / num_panel_rows)) imagemagick_utils.concatenate_images(input_file_names=panel_file_names, output_file_name=figure_file_name, border_width_pixels=100, num_panel_rows=num_panel_rows, num_panel_columns=num_panel_columns) imagemagick_utils.trim_whitespace(input_file_name=figure_file_name, output_file_name=figure_file_name, border_width_pixels=10) imagemagick_utils.resize_image(input_file_name=figure_file_name, output_file_name=figure_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX)
def _plot_sounding_saliency( saliency_matrix, colour_map_object, max_colour_value, sounding_matrix, saliency_dict, model_metadata_dict, output_dir_name, pmm_flag, example_index=None): """Plots saliency for sounding. H = number of sounding heights F = number of sounding fields If plotting a composite rather than one example, `full_storm_id_string` and `storm_time_unix_sec` can be None. :param saliency_matrix: H-by-F numpy array of saliency values. :param colour_map_object: See documentation at top of file. :param max_colour_value: Max value in colour scheme for saliency. :param sounding_matrix: H-by-F numpy array of actual sounding values. :param saliency_dict: Dictionary returned from `saliency_maps.read_standard_file` or `saliency_maps.read_pmm_file`. :param model_metadata_dict: Dictionary returned by `cnn.read_model_metadata`. :param output_dir_name: Path to output directory. Figure will be saved here. :param pmm_flag: Boolean flag. If True, will plot composite rather than one example. :param example_index: [used only if `pmm_flag == False`] Will plot the [i]th example, where i = `example_index`. """ if pmm_flag: example_index = 0 training_option_dict = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY] sounding_field_names = training_option_dict[trainval_io.SOUNDING_FIELDS_KEY] sounding_heights_m_agl = training_option_dict[ trainval_io.SOUNDING_HEIGHTS_KEY] sounding_matrix = numpy.expand_dims(sounding_matrix, axis=0) if saliency_maps.SOUNDING_PRESSURES_KEY in saliency_dict: pressure_matrix_pascals = numpy.expand_dims( saliency_dict[saliency_maps.SOUNDING_PRESSURES_KEY], axis=-1 ) pressure_matrix_pascals = pressure_matrix_pascals[[example_index], ...] sounding_matrix = numpy.concatenate( (sounding_matrix, pressure_matrix_pascals), axis=-1 ) sounding_dict_for_metpy = dl_utils.soundings_to_metpy_dictionaries( sounding_matrix=sounding_matrix, field_names=sounding_field_names + [soundings.PRESSURE_NAME] )[0] else: sounding_dict_for_metpy = dl_utils.soundings_to_metpy_dictionaries( sounding_matrix=sounding_matrix, field_names=sounding_field_names, height_levels_m_agl=sounding_heights_m_agl, storm_elevations_m_asl=numpy.array([0.]) )[0] if pmm_flag: full_storm_id_string = None storm_time_unix_sec = None title_string = 'PMM composite' else: full_storm_id_string = saliency_dict[saliency_maps.FULL_IDS_KEY][ example_index] storm_time_unix_sec = saliency_dict[saliency_maps.STORM_TIMES_KEY][ example_index] title_string = 'Storm "{0:s}" at {1:s}'.format( full_storm_id_string, time_conversion.unix_sec_to_string( storm_time_unix_sec, plot_input_examples.TIME_FORMAT) ) sounding_plotting.plot_sounding( sounding_dict_for_metpy=sounding_dict_for_metpy, title_string=title_string) left_panel_file_name = plot_input_examples.metadata_to_file_name( output_dir_name=output_dir_name, is_sounding=False, pmm_flag=pmm_flag, full_storm_id_string=full_storm_id_string, storm_time_unix_sec=storm_time_unix_sec, radar_field_name='sounding-actual') print('Saving figure to file: "{0:s}"...'.format(left_panel_file_name)) pyplot.savefig(left_panel_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace( input_file_name=left_panel_file_name, output_file_name=left_panel_file_name) saliency_plotting.plot_saliency_for_sounding( saliency_matrix=saliency_matrix, sounding_field_names=sounding_field_names, pressure_levels_mb=sounding_dict_for_metpy[ soundings.PRESSURE_COLUMN_METPY], colour_map_object=colour_map_object, max_absolute_colour_value=max_colour_value) right_panel_file_name = plot_input_examples.metadata_to_file_name( output_dir_name=output_dir_name, is_sounding=False, pmm_flag=pmm_flag, full_storm_id_string=full_storm_id_string, storm_time_unix_sec=storm_time_unix_sec, radar_field_name='sounding-saliency') print('Saving figure to file: "{0:s}"...'.format(right_panel_file_name)) pyplot.savefig(right_panel_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace( input_file_name=right_panel_file_name, output_file_name=right_panel_file_name) concat_file_name = plot_input_examples.metadata_to_file_name( output_dir_name=output_dir_name, is_sounding=True, pmm_flag=pmm_flag, full_storm_id_string=full_storm_id_string, storm_time_unix_sec=storm_time_unix_sec) print('Concatenating figures to: "{0:s}"...\n'.format(concat_file_name)) imagemagick_utils.concatenate_images( input_file_names=[left_panel_file_name, right_panel_file_name], output_file_name=concat_file_name, num_panel_rows=1, num_panel_columns=2) imagemagick_utils.resize_image( input_file_name=concat_file_name, output_file_name=concat_file_name, output_size_pixels=SOUNDING_IMAGE_SIZE_PX) os.remove(left_panel_file_name) os.remove(right_panel_file_name)
def _run(input_dir_name, heights_m_agl, output_dir_name): """Creates figure showing overall model evaluation. This is effectively the main method. :param input_dir_name: See documentation at top of file. :param heights_m_agl: Same. :param output_dir_name: Same. """ file_system_utils.mkdir_recursive_if_necessary( directory_name=output_dir_name) num_heights = len(heights_m_agl) pathless_input_file_names = [] for j in range(num_heights): first_file_name = ( 'shortwave-heating-rate-k-day01_{0:05d}metres_scores_without_units' '.jpg').format(heights_m_agl[j]) second_file_name = ( 'shortwave-heating-rate-k-day01_{0:05d}metres_scores_with_units.jpg' ).format(heights_m_agl[j]) pathless_input_file_names += [first_file_name, second_file_name] pathless_input_file_names += [ 'net-shortwave-flux-w-m02_scores_without_units.jpg', 'net-shortwave-flux-w-m02_scores_with_units.jpg' ] panel_file_names = [ '{0:s}/{1:s}'.format(input_dir_name, p) for p in pathless_input_file_names ] resized_panel_file_names = [ '{0:s}/{1:s}'.format(output_dir_name, p) for p in pathless_input_file_names ] letter_label = None for i in range(len(panel_file_names)): print('Resizing panel and saving to: "{0:s}"...'.format( resized_panel_file_names[i])) imagemagick_utils.trim_whitespace( input_file_name=panel_file_names[i], output_file_name=resized_panel_file_names[i]) if letter_label is None: letter_label = 'a' else: letter_label = chr(ord(letter_label) + 1) image_matrix = Image.open(resized_panel_file_names[i]) _, figure_height_px = image_matrix.size _overlay_text(image_file_name=resized_panel_file_names[i], x_offset_from_left_px=0, y_offset_from_top_px=figure_height_px - 50, text_string='({0:s})'.format(letter_label)) imagemagick_utils.resize_image( input_file_name=resized_panel_file_names[i], output_file_name=resized_panel_file_names[i], output_size_pixels=PANEL_SIZE_PX) concat_figure_file_name = '{0:s}/evaluation_by_time.jpg'.format( output_dir_name) print( 'Concatenating panels to: "{0:s}"...'.format(concat_figure_file_name)) imagemagick_utils.concatenate_images( input_file_names=resized_panel_file_names, output_file_name=concat_figure_file_name, num_panel_rows=num_heights + 1, num_panel_columns=NUM_PANEL_COLUMNS) imagemagick_utils.resize_image(input_file_name=concat_figure_file_name, output_file_name=concat_figure_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX)
def _plot_one_example( radar_matrix, sounding_matrix, sounding_pressures_pascals, full_storm_id_string, storm_time_unix_sec, model_metadata_dict, output_dir_name): """Plots predictors for one example. M = number of rows in radar grid N = number of columns in radar grid H_r = number of heights in radar grid F_r = number of radar fields H_s = number of sounding heights F_s = number of sounding fields :param radar_matrix: numpy array (1 x M x N x H_r x F_r) of radar values. :param sounding_matrix: numpy array (1 x H_s x F_s) of sounding values. :param sounding_pressures_pascals: numpy array (length H_s) of sounding pressures. :param full_storm_id_string: Full storm ID. :param storm_time_unix_sec: Valid time. :param model_metadata_dict: Dictionary returned by `cnn.read_model_metadata`. :param output_dir_name: Name of output directory (figures will be saved here). :return: radar_figure_file_name: Path to radar figure created by this method. """ training_option_dict = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY] radar_field_names = training_option_dict[trainval_io.RADAR_FIELDS_KEY] num_radar_fields = radar_matrix.shape[-1] num_radar_heights = radar_matrix.shape[-2] handle_dict = plot_examples.plot_one_example( list_of_predictor_matrices=[radar_matrix, sounding_matrix], model_metadata_dict=model_metadata_dict, pmm_flag=False, example_index=0, plot_sounding=True, sounding_pressures_pascals=sounding_pressures_pascals, allow_whitespace=True, plot_panel_names=True, panel_name_font_size=PANEL_NAME_FONT_SIZE, add_titles=False, label_colour_bars=True, colour_bar_length=COLOUR_BAR_LENGTH, colour_bar_font_size=COLOUR_BAR_FONT_SIZE, num_panel_rows=num_radar_heights ) sounding_file_name = plot_examples.metadata_to_file_name( output_dir_name=output_dir_name, is_sounding=True, pmm_flag=False, full_storm_id_string=full_storm_id_string, storm_time_unix_sec=storm_time_unix_sec ) print('Saving figure to: "{0:s}"...'.format(sounding_file_name)) sounding_figure_object = handle_dict[plot_examples.SOUNDING_FIGURE_KEY] sounding_figure_object.savefig( sounding_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight' ) pyplot.close(sounding_figure_object) figure_objects = handle_dict[plot_examples.RADAR_FIGURES_KEY] panel_file_names = [None] * num_radar_fields for k in range(num_radar_fields): panel_file_names[k] = plot_examples.metadata_to_file_name( output_dir_name=output_dir_name, is_sounding=False, pmm_flag=False, full_storm_id_string=full_storm_id_string, storm_time_unix_sec=storm_time_unix_sec, radar_field_name=radar_field_names[k] ) print('Saving figure to: "{0:s}"...'.format(panel_file_names[k])) figure_objects[k].savefig( panel_file_names[k], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight' ) pyplot.close(figure_objects[k]) radar_figure_file_name = plot_examples.metadata_to_file_name( output_dir_name=output_dir_name, is_sounding=False, pmm_flag=False, full_storm_id_string=full_storm_id_string, storm_time_unix_sec=storm_time_unix_sec ) print('Concatenating panels to: "{0:s}"...'.format(radar_figure_file_name)) imagemagick_utils.concatenate_images( input_file_names=panel_file_names, output_file_name=radar_figure_file_name, num_panel_rows=1, num_panel_columns=num_radar_fields, border_width_pixels=50 ) imagemagick_utils.resize_image( input_file_name=radar_figure_file_name, output_file_name=radar_figure_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX ) imagemagick_utils.trim_whitespace( input_file_name=radar_figure_file_name, output_file_name=radar_figure_file_name, border_width_pixels=10 ) for this_file_name in panel_file_names: os.remove(this_file_name) return radar_figure_file_name
def _run(gradcam_file_names, monte_carlo_file_names, composite_names, colour_map_name, min_colour_values, max_colour_values, num_contours, smoothing_radius_grid_cells, monte_carlo_max_fdr, output_dir_name): """Makes figure with gradient-weighted class-activation maps (Grad-CAM). This is effectively the main method. :param gradcam_file_names: See documentation at top of file. :param monte_carlo_file_names: Same. :param composite_names: Same. :param colour_map_name: Same. :param min_colour_values: Same. :param max_colour_values: Same. :param num_contours: Same. :param smoothing_radius_grid_cells: Same. :param output_dir_name: Same. """ if smoothing_radius_grid_cells <= 0: smoothing_radius_grid_cells = None if monte_carlo_max_fdr <= 0: monte_carlo_max_fdr = None file_system_utils.mkdir_recursive_if_necessary( directory_name=output_dir_name) colour_map_object = pyplot.cm.get_cmap(colour_map_name) error_checking.assert_is_geq(num_contours, 10) num_composites = len(gradcam_file_names) expected_dim = numpy.array([num_composites], dtype=int) error_checking.assert_is_numpy_array(numpy.array(composite_names), exact_dimensions=expected_dim) error_checking.assert_is_numpy_array(numpy.array(monte_carlo_file_names), exact_dimensions=expected_dim) monte_carlo_file_names = [ None if f in NONE_STRINGS else f for f in monte_carlo_file_names ] nan_indices = numpy.where( numpy.logical_or(max_colour_values < 0, min_colour_values < 0))[0] min_colour_values[nan_indices] = numpy.nan max_colour_values[nan_indices] = numpy.nan error_checking.assert_is_numpy_array(min_colour_values, exact_dimensions=expected_dim) error_checking.assert_is_numpy_array(max_colour_values, exact_dimensions=expected_dim) assert not numpy.any(max_colour_values <= min_colour_values) composite_names_abbrev = [ n.replace('_', '-').lower() for n in composite_names ] composite_names_verbose = [ '({0:s}) {1:s}'.format(chr(ord('a') + i), composite_names[i].replace('_', ' ')) for i in range(num_composites) ] panel_file_names = [None] * num_composites for i in range(num_composites): (panel_file_names[i], min_colour_values[i], max_colour_values[i]) = _plot_one_composite( gradcam_file_name=gradcam_file_names[i], monte_carlo_file_name=monte_carlo_file_names[i], composite_name_abbrev=composite_names_abbrev[i], composite_name_verbose=composite_names_verbose[i], colour_map_object=colour_map_object, min_colour_value=min_colour_values[i], max_colour_value=max_colour_values[i], num_contours=num_contours, smoothing_radius_grid_cells=smoothing_radius_grid_cells, monte_carlo_max_fdr=monte_carlo_max_fdr, output_dir_name=output_dir_name) _add_colour_bar(figure_file_name=panel_file_names[i], colour_map_object=colour_map_object, min_colour_value=min_colour_values[i], max_colour_value=max_colour_values[i], temporary_dir_name=output_dir_name) print('\n') figure_file_name = '{0:s}/gradcam_concat.jpg'.format(output_dir_name) print('Concatenating panels to: "{0:s}"...'.format(figure_file_name)) num_panel_rows = int(numpy.ceil(numpy.sqrt(num_composites))) num_panel_columns = int(numpy.floor( float(num_composites) / num_panel_rows)) imagemagick_utils.concatenate_images(input_file_names=panel_file_names, output_file_name=figure_file_name, border_width_pixels=25, num_panel_rows=num_panel_rows, num_panel_columns=num_panel_columns) imagemagick_utils.trim_whitespace(input_file_name=figure_file_name, output_file_name=figure_file_name, border_width_pixels=10) imagemagick_utils.resize_image(input_file_name=figure_file_name, output_file_name=figure_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX)
def _plot_one_composite(saliency_file_name, monte_carlo_file_name, composite_name_abbrev, composite_name_verbose, colour_map_object, max_colour_value, half_num_contours, smoothing_radius_grid_cells, output_dir_name): """Plots saliency map for one composite. :param saliency_file_name: Path to saliency file (will be read by `saliency.read_file`). :param monte_carlo_file_name: Path to Monte Carlo file (will be read by `_read_monte_carlo_file`). :param composite_name_abbrev: Abbrev composite name (will be used in file names). :param composite_name_verbose: Verbose composite name (will be used in figure title). :param colour_map_object: See documentation at top of file. :param max_colour_value: Same. :param half_num_contours: Same. :param smoothing_radius_grid_cells: Same. :param output_dir_name: Name of output directory (figures will be saved here). :return: main_figure_file_name: Path to main image file created by this method. """ (mean_radar_matrices, mean_saliency_matrices, significance_matrices, model_metadata_dict) = _read_one_composite( saliency_file_name=saliency_file_name, smoothing_radius_grid_cells=smoothing_radius_grid_cells, monte_carlo_file_name=monte_carlo_file_name) refl_heights_m_agl = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY][ trainval_io.RADAR_HEIGHTS_KEY] num_refl_heights = len(refl_heights_m_agl) handle_dict = plot_examples.plot_one_example( list_of_predictor_matrices=mean_radar_matrices, model_metadata_dict=model_metadata_dict, pmm_flag=True, plot_sounding=False, allow_whitespace=True, plot_panel_names=True, panel_name_font_size=PANEL_NAME_FONT_SIZE, add_titles=False, label_colour_bars=True, colour_bar_length=COLOUR_BAR_LENGTH, colour_bar_font_size=COLOUR_BAR_FONT_SIZE, num_panel_rows=num_refl_heights) axes_object_matrices = handle_dict[plot_examples.RADAR_AXES_KEY] this_saliency_matrix = numpy.flip(mean_saliency_matrices[0][0, ..., 0], axis=0) saliency_plotting.plot_many_2d_grids_with_contours( saliency_matrix_3d=this_saliency_matrix, axes_object_matrix=axes_object_matrices[0], colour_map_object=colour_map_object, max_absolute_contour_level=max_colour_value, contour_interval=max_colour_value / half_num_contours, row_major=True) this_sig_matrix = numpy.flip(significance_matrices[0][0, ..., 0], axis=0) significance_plotting.plot_many_2d_grids_without_coords( significance_matrix=this_sig_matrix, axes_object_matrix=axes_object_matrices[0], marker_size=2, row_major=True) this_saliency_matrix = numpy.flip(mean_saliency_matrices[1][0, ...], axis=0) saliency_plotting.plot_many_2d_grids_with_contours( saliency_matrix_3d=this_saliency_matrix, axes_object_matrix=axes_object_matrices[1], colour_map_object=colour_map_object, max_absolute_contour_level=max_colour_value, contour_interval=max_colour_value / half_num_contours, row_major=False) this_sig_matrix = numpy.flip(significance_matrices[1][0, ...], axis=0) significance_plotting.plot_many_2d_grids_without_coords( significance_matrix=this_sig_matrix, axes_object_matrix=axes_object_matrices[1], marker_size=2, row_major=False) refl_figure_object = handle_dict[plot_examples.RADAR_FIGURES_KEY][0] refl_figure_file_name = '{0:s}/{1:s}_reflectivity.jpg'.format( output_dir_name, composite_name_abbrev) print('Saving figure to: "{0:s}"...'.format(refl_figure_file_name)) refl_figure_object.savefig(refl_figure_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(refl_figure_object) shear_figure_object = handle_dict[plot_examples.RADAR_FIGURES_KEY][1] shear_figure_file_name = '{0:s}/{1:s}_shear.jpg'.format( output_dir_name, composite_name_abbrev) print('Saving figure to: "{0:s}"...'.format(shear_figure_file_name)) shear_figure_object.savefig(shear_figure_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(shear_figure_object) main_figure_file_name = '{0:s}/{1:s}_saliency.jpg'.format( output_dir_name, composite_name_abbrev) print('Concatenating panels to: "{0:s}"...'.format(main_figure_file_name)) imagemagick_utils.concatenate_images( input_file_names=[refl_figure_file_name, shear_figure_file_name], output_file_name=main_figure_file_name, num_panel_rows=1, num_panel_columns=2, border_width_pixels=50, extra_args_string='-gravity south') imagemagick_utils.resize_image(input_file_name=main_figure_file_name, output_file_name=main_figure_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX) imagemagick_utils.trim_whitespace(input_file_name=main_figure_file_name, output_file_name=main_figure_file_name, border_width_pixels=TITLE_FONT_SIZE + 25) _overlay_text(image_file_name=main_figure_file_name, x_offset_from_center_px=0, y_offset_from_top_px=0, text_string=composite_name_verbose) imagemagick_utils.trim_whitespace(input_file_name=main_figure_file_name, output_file_name=main_figure_file_name, border_width_pixels=10) return main_figure_file_name
def _plot_composite(composite_file_name, composite_name_abbrev, composite_name_verbose, output_dir_name): """Plots one composite. :param composite_file_name: Path to input file. Will be read by `_read_composite`. :param composite_name_abbrev: Abbreviated name for composite. Will be used in names of output files. :param composite_name_verbose: Verbose name for composite. Will be used as figure title. :param output_dir_name: Path to output directory. Figures will be saved here. :return: radar_figure_file_name: Path to file with radar figure for this composite. :return: sounding_figure_file_name: Path to file with sounding figure for this composite. """ mean_predictor_matrices, model_metadata_dict, mean_sounding_pressures_pa = ( _read_composite(composite_file_name)) radar_field_names = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY][ trainval_io.RADAR_FIELDS_KEY] radar_heights_m_agl = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY][ trainval_io.RADAR_HEIGHTS_KEY] num_radar_fields = len(radar_field_names) num_radar_heights = len(radar_heights_m_agl) handle_dict = plot_examples.plot_one_example( list_of_predictor_matrices=mean_predictor_matrices, model_metadata_dict=model_metadata_dict, pmm_flag=True, plot_sounding=True, sounding_pressures_pascals=mean_sounding_pressures_pa, allow_whitespace=True, plot_panel_names=True, panel_name_font_size=PANEL_NAME_FONT_SIZE, add_titles=False, label_colour_bars=True, colour_bar_length=COLOUR_BAR_LENGTH, colour_bar_font_size=COLOUR_BAR_FONT_SIZE, sounding_font_size=SOUNDING_FONT_SIZE, num_panel_rows=num_radar_heights) sounding_figure_file_name = '{0:s}/{1:s}_sounding.jpg'.format( output_dir_name, composite_name_abbrev) print('Saving figure to: "{0:s}"...'.format(sounding_figure_file_name)) sounding_figure_object = handle_dict[plot_examples.SOUNDING_FIGURE_KEY] sounding_figure_object.savefig(sounding_figure_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(sounding_figure_object) imagemagick_utils.resize_image(input_file_name=sounding_figure_file_name, output_file_name=sounding_figure_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX) imagemagick_utils.trim_whitespace( input_file_name=sounding_figure_file_name, output_file_name=sounding_figure_file_name, border_width_pixels=TITLE_FONT_SIZE + 25) _overlay_text(image_file_name=sounding_figure_file_name, x_offset_from_center_px=0, y_offset_from_top_px=0, text_string=composite_name_verbose) imagemagick_utils.trim_whitespace( input_file_name=sounding_figure_file_name, output_file_name=sounding_figure_file_name, border_width_pixels=10) radar_figure_objects = handle_dict[plot_examples.RADAR_FIGURES_KEY] panel_file_names = [None] * num_radar_fields for j in range(num_radar_fields): panel_file_names[j] = '{0:s}/{1:s}_{2:s}.jpg'.format( output_dir_name, composite_name_abbrev, radar_field_names[j].replace('_', '-')) print('Saving figure to: "{0:s}"...'.format(panel_file_names[j])) radar_figure_objects[j].savefig(panel_file_names[j], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(radar_figure_objects[j]) radar_figure_file_name = '{0:s}/{1:s}_radar.jpg'.format( output_dir_name, composite_name_abbrev) print('Concatenating panels to: "{0:s}"...'.format(radar_figure_file_name)) imagemagick_utils.concatenate_images( input_file_names=panel_file_names, output_file_name=radar_figure_file_name, num_panel_rows=1, num_panel_columns=num_radar_fields, border_width_pixels=50) imagemagick_utils.resize_image(input_file_name=radar_figure_file_name, output_file_name=radar_figure_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX) imagemagick_utils.trim_whitespace(input_file_name=radar_figure_file_name, output_file_name=radar_figure_file_name, border_width_pixels=TITLE_FONT_SIZE + 25) _overlay_text(image_file_name=radar_figure_file_name, x_offset_from_center_px=0, y_offset_from_top_px=0, text_string=composite_name_verbose) imagemagick_utils.trim_whitespace(input_file_name=radar_figure_file_name, output_file_name=radar_figure_file_name, border_width_pixels=10) return radar_figure_file_name, sounding_figure_file_name
def _run(input_file_name, output_dir_name): """Plots mean example created by average_examples.py. This is effectively the main method. :param input_file_name: See documentation at top of file. :param output_dir_name: Same. """ file_system_utils.mkdir_recursive_if_necessary( directory_name=output_dir_name) pickle_file_handle = open(input_file_name, 'rb') mean_example_dict = pickle.load(pickle_file_handle) pickle_file_handle.close() # Plot predictors with liquid-water content (LWC). figure_object = profile_plotting.plot_predictors( example_dict=mean_example_dict, example_index=0, plot_ice=False, use_log_scale=True)[0] panel_file_names = ['foo'] * 3 panel_file_names[0] = '{0:s}/predictors_with_lwc.jpg'.format( output_dir_name) print('Saving figure to: "{0:s}"...'.format(panel_file_names[0])) figure_object.savefig(panel_file_names[0], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(figure_object) # Plot predictors with ice-water content (IWC). figure_object = profile_plotting.plot_predictors( example_dict=mean_example_dict, example_index=0, plot_ice=True, use_log_scale=True)[0] panel_file_names[1] = '{0:s}/predictors_with_iwc.jpg'.format( output_dir_name) print('Saving figure to: "{0:s}"...'.format(panel_file_names[1])) figure_object.savefig(panel_file_names[1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(figure_object) # Plot targets. figure_object = profile_plotting.plot_targets( example_dict=mean_example_dict, example_index=0, use_log_scale=True)[0] panel_file_names[2] = '{0:s}/targets.jpg'.format(output_dir_name) print('Saving figure to: "{0:s}"...'.format(panel_file_names[2])) figure_object.savefig(panel_file_names[2], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(figure_object) # Concatenate panels. concat_figure_file_name = '{0:s}/predictors_and_targets.jpg'.format( output_dir_name) print( 'Concatenating panels to: "{0:s}"...'.format(concat_figure_file_name)) imagemagick_utils.concatenate_images( input_file_names=panel_file_names, output_file_name=concat_figure_file_name, num_panel_rows=2, num_panel_columns=2, border_width_pixels=50) imagemagick_utils.resize_image(input_file_name=concat_figure_file_name, output_file_name=concat_figure_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX)
def _run(evaluation_dir_name, smoothing_radius_grid_cells, score_colour_map_name, num_ex_colour_map_name, max_colour_percentile, output_dir_name): """Plots spatially subset model evaluation. This is effectively the main method. :param evaluation_dir_name: See documentation at top of file. :param smoothing_radius_grid_cells: Same. :param score_colour_map_name: Same. :param num_ex_colour_map_name: Same. :param max_colour_percentile: Same. :param output_dir_name: Same. """ if smoothing_radius_grid_cells <= 0: smoothing_radius_grid_cells = None score_colour_map_object = pyplot.get_cmap(score_colour_map_name) num_ex_colour_map_object = pyplot.get_cmap(num_ex_colour_map_name) error_checking.assert_is_geq(max_colour_percentile, 90.) error_checking.assert_is_leq(max_colour_percentile, 100.) grid_metafile_name = grids.find_equidistant_metafile( directory_name=evaluation_dir_name, raise_error_if_missing=True) print('Reading grid metadata from: "{0:s}"...'.format(grid_metafile_name)) grid_metadata_dict = grids.read_equidistant_metafile(grid_metafile_name) print(SEPARATOR_STRING) num_grid_rows = len(grid_metadata_dict[grids.Y_COORDS_KEY]) num_grid_columns = len(grid_metadata_dict[grids.X_COORDS_KEY]) auc_matrix = numpy.full((num_grid_rows, num_grid_columns), numpy.nan) csi_matrix = numpy.full((num_grid_rows, num_grid_columns), numpy.nan) pod_matrix = numpy.full((num_grid_rows, num_grid_columns), numpy.nan) far_matrix = numpy.full((num_grid_rows, num_grid_columns), numpy.nan) num_examples_matrix = numpy.full((num_grid_rows, num_grid_columns), 0, dtype=int) num_positive_examples_matrix = numpy.full( (num_grid_rows, num_grid_columns), 0, dtype=int) for i in range(num_grid_rows): for j in range(num_grid_columns): this_eval_file_name = model_eval.find_file( directory_name=evaluation_dir_name, grid_row=i, grid_column=j, raise_error_if_missing=False) if not os.path.isfile(this_eval_file_name): warning_string = ( 'Cannot find file (this may or may not be a problem). ' 'Expected at: "{0:s}"').format(this_eval_file_name) warnings.warn(warning_string) continue print('Reading data from: "{0:s}"...'.format(this_eval_file_name)) this_evaluation_dict = model_eval.read_evaluation( this_eval_file_name) num_examples_matrix[i, j] = len( this_evaluation_dict[model_eval.OBSERVED_LABELS_KEY]) num_positive_examples_matrix[i, j] = numpy.sum( this_evaluation_dict[model_eval.OBSERVED_LABELS_KEY]) this_evaluation_table = this_evaluation_dict[ model_eval.EVALUATION_TABLE_KEY] auc_matrix[i, j] = numpy.nanmean( this_evaluation_table[model_eval.AUC_KEY].values) csi_matrix[i, j] = numpy.nanmean( this_evaluation_table[model_eval.CSI_KEY].values) pod_matrix[i, j] = numpy.nanmean( this_evaluation_table[model_eval.POD_KEY].values) far_matrix[i, j] = 1. - numpy.nanmean( this_evaluation_table[model_eval.SUCCESS_RATIO_KEY].values) print(SEPARATOR_STRING) auc_matrix[num_positive_examples_matrix == 0] = numpy.nan csi_matrix[num_positive_examples_matrix == 0] = numpy.nan pod_matrix[num_positive_examples_matrix == 0] = numpy.nan far_matrix[num_positive_examples_matrix == 0] = numpy.nan if smoothing_radius_grid_cells is not None: print(( 'Applying Gaussian smoother with e-folding radius of {0:.1f} grid ' 'cells...').format(smoothing_radius_grid_cells)) orig_num_examples_matrix = num_examples_matrix + 0 num_examples_matrix = general_utils.apply_gaussian_filter( input_matrix=num_examples_matrix.astype(float), e_folding_radius_grid_cells=smoothing_radius_grid_cells) num_examples_matrix = numpy.round(num_examples_matrix).astype(int) num_examples_matrix[orig_num_examples_matrix == 0] = 0 # HACK num_positive_examples_matrix = general_utils.apply_gaussian_filter( input_matrix=num_positive_examples_matrix.astype(float), e_folding_radius_grid_cells=smoothing_radius_grid_cells) num_positive_examples_matrix = ( numpy.round(num_positive_examples_matrix).astype(int)) num_positive_examples_matrix[num_examples_matrix == 0] = 0 auc_matrix = general_utils.apply_gaussian_filter( input_matrix=ge_utils.fill_nans(auc_matrix), e_folding_radius_grid_cells=smoothing_radius_grid_cells) csi_matrix = general_utils.apply_gaussian_filter( input_matrix=ge_utils.fill_nans(csi_matrix), e_folding_radius_grid_cells=smoothing_radius_grid_cells) pod_matrix = general_utils.apply_gaussian_filter( input_matrix=ge_utils.fill_nans(pod_matrix), e_folding_radius_grid_cells=smoothing_radius_grid_cells) far_matrix = general_utils.apply_gaussian_filter( input_matrix=ge_utils.fill_nans(far_matrix), e_folding_radius_grid_cells=smoothing_radius_grid_cells) auc_matrix[num_positive_examples_matrix == 0] = numpy.nan csi_matrix[num_positive_examples_matrix == 0] = numpy.nan pod_matrix[num_positive_examples_matrix == 0] = numpy.nan far_matrix[num_positive_examples_matrix == 0] = numpy.nan panel_file_names = [] file_system_utils.mkdir_recursive_if_necessary( directory_name=output_dir_name) # Plot number of examples. this_data_matrix = numpy.maximum(numpy.log10(num_examples_matrix), 0.) this_data_matrix[this_data_matrix == 0] = numpy.nan max_colour_value = numpy.nanpercentile(this_data_matrix, max_colour_percentile) figure_object, axes_object = _plot_one_value( data_matrix=this_data_matrix, grid_metadata_dict=grid_metadata_dict, colour_map_object=num_ex_colour_map_object, min_colour_value=0., max_colour_value=max_colour_value, plot_cbar_min_arrow=False, plot_cbar_max_arrow=True, log_scale=True) axes_object.set_title(r'Number of examples') plotting_utils.label_axes(axes_object=axes_object, label_string='(a)') panel_file_names.append('{0:s}/num_examples.jpg'.format(output_dir_name)) print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1])) figure_object.savefig(panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(figure_object) # Plot number of positive examples. this_data_matrix = num_positive_examples_matrix.astype(float) this_data_matrix[this_data_matrix == 0] = numpy.nan max_colour_value = numpy.nanpercentile(this_data_matrix, max_colour_percentile) min_colour_value = numpy.nanpercentile(this_data_matrix, 100. - max_colour_percentile) figure_object, axes_object = _plot_one_value( data_matrix=this_data_matrix, grid_metadata_dict=grid_metadata_dict, colour_map_object=num_ex_colour_map_object, min_colour_value=min_colour_value, max_colour_value=max_colour_value, plot_cbar_min_arrow=True, plot_cbar_max_arrow=True) axes_object.set_title('Number of tornadic examples') plotting_utils.label_axes(axes_object=axes_object, label_string='(b)') panel_file_names.append( '{0:s}/num_positive_examples.jpg'.format(output_dir_name)) print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1])) figure_object.savefig(panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(figure_object) # Plot AUC. max_colour_value = numpy.nanpercentile(auc_matrix, max_colour_percentile) min_colour_value = numpy.maximum( numpy.nanpercentile(auc_matrix, 100. - max_colour_percentile), 0.5) figure_object, axes_object = _plot_one_value( data_matrix=auc_matrix, grid_metadata_dict=grid_metadata_dict, colour_map_object=score_colour_map_object, min_colour_value=min_colour_value, max_colour_value=max_colour_value, plot_cbar_min_arrow=True, plot_cbar_max_arrow=max_colour_value < 1.) axes_object.set_title('AUC (area under ROC curve)') plotting_utils.label_axes(axes_object=axes_object, label_string='(c)') panel_file_names.append('{0:s}/auc.jpg'.format(output_dir_name)) print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1])) figure_object.savefig(panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(figure_object) # Plot CSI. max_colour_value = numpy.nanpercentile(csi_matrix, max_colour_percentile) min_colour_value = numpy.nanpercentile(csi_matrix, 100. - max_colour_percentile) figure_object, axes_object = _plot_one_value( data_matrix=csi_matrix, grid_metadata_dict=grid_metadata_dict, colour_map_object=score_colour_map_object, min_colour_value=min_colour_value, max_colour_value=max_colour_value, plot_cbar_min_arrow=min_colour_value > 0., plot_cbar_max_arrow=max_colour_value < 1.) axes_object.set_title('CSI (critical success index)') plotting_utils.label_axes(axes_object=axes_object, label_string='(d)') panel_file_names.append('{0:s}/csi.jpg'.format(output_dir_name)) print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1])) figure_object.savefig(panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(figure_object) # Plot POD. max_colour_value = numpy.nanpercentile(pod_matrix, max_colour_percentile) min_colour_value = numpy.nanpercentile(pod_matrix, 100. - max_colour_percentile) figure_object, axes_object = _plot_one_value( data_matrix=pod_matrix, grid_metadata_dict=grid_metadata_dict, colour_map_object=score_colour_map_object, min_colour_value=min_colour_value, max_colour_value=max_colour_value, plot_cbar_min_arrow=min_colour_value > 0., plot_cbar_max_arrow=max_colour_value < 1.) axes_object.set_title('POD (probability of detection)') plotting_utils.label_axes(axes_object=axes_object, label_string='(e)') panel_file_names.append('{0:s}/pod.jpg'.format(output_dir_name)) print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1])) figure_object.savefig(panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(figure_object) # Plot FAR. max_colour_value = numpy.nanpercentile(far_matrix, max_colour_percentile) min_colour_value = numpy.nanpercentile(far_matrix, 100. - max_colour_percentile) figure_object, axes_object = _plot_one_value( data_matrix=far_matrix, grid_metadata_dict=grid_metadata_dict, colour_map_object=score_colour_map_object, min_colour_value=min_colour_value, max_colour_value=max_colour_value, plot_cbar_min_arrow=min_colour_value > 0., plot_cbar_max_arrow=max_colour_value < 1.) axes_object.set_title('FAR (false-alarm ratio)') plotting_utils.label_axes(axes_object=axes_object, label_string='(f)') panel_file_names.append('{0:s}/far.jpg'.format(output_dir_name)) print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1])) figure_object.savefig(panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(figure_object) # Concatenate panels. concat_file_name = '{0:s}/spatially_subset_evaluation.jpg'.format( output_dir_name) print('Concatenating panels to: "{0:s}"...'.format(concat_file_name)) imagemagick_utils.concatenate_images(input_file_names=panel_file_names, output_file_name=concat_file_name, num_panel_rows=NUM_PANEL_ROWS, num_panel_columns=NUM_PANEL_COLUMNS) imagemagick_utils.resize_image(input_file_name=concat_file_name, output_file_name=concat_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX)
def _run(): """Makes event-attribution schematics for 2019 tornado-prediction paper. This is effectively the main method. """ file_system_utils.mkdir_recursive_if_necessary( directory_name=OUTPUT_DIR_NAME) # Interpolation with merger. figure_object, axes_object = _plot_interp_two_times( storm_object_table=_get_data_for_interp_with_merger()[0], tornado_table=_get_data_for_interp_with_merger()[1], legend_font_size=SMALL_LEGEND_FONT_SIZE, legend_position_string='upper right' ) axes_object.set_title('Interpolation with merger') this_file_name = '{0:s}/interp_with_merger_standalone.jpg'.format( OUTPUT_DIR_NAME) print('Saving figure to: "{0:s}"...'.format(this_file_name)) figure_object.savefig( this_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight' ) plotting_utils.label_axes(axes_object=axes_object, label_string='(a)') panel_file_names = ['{0:s}/interp_with_merger.jpg'.format(OUTPUT_DIR_NAME)] print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1])) figure_object.savefig( panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight' ) pyplot.close(figure_object) # Interpolation with split. figure_object, axes_object = _plot_interp_two_times( storm_object_table=_get_data_for_interp_with_split()[0], tornado_table=_get_data_for_interp_with_split()[1], legend_font_size=DEFAULT_FONT_SIZE, legend_position_string='upper left' ) axes_object.set_title('Interpolation with split') this_file_name = '{0:s}/interp_with_split_standalone.jpg'.format( OUTPUT_DIR_NAME) print('Saving figure to: "{0:s}"...'.format(this_file_name)) figure_object.savefig( this_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight' ) plotting_utils.label_axes(axes_object=axes_object, label_string='(b)') panel_file_names.append( '{0:s}/interp_with_split.jpg'.format(OUTPUT_DIR_NAME) ) print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1])) figure_object.savefig( panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight' ) pyplot.close(figure_object) # Simple successors. figure_object, axes_object = _plot_attribution_one_track( storm_object_table=_get_track_for_simple_succ(), plot_legend=True, plot_x_ticks=True, legend_font_size=SMALL_LEGEND_FONT_SIZE, legend_location='lower right' ) this_file_name = '{0:s}/simple_successors_standalone.jpg'.format( OUTPUT_DIR_NAME) print('Saving figure to: "{0:s}"...'.format(this_file_name)) figure_object.savefig( this_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight' ) plotting_utils.label_axes(axes_object=axes_object, label_string='(c)') axes_object.set_title('Linking to simple successors') panel_file_names.append( '{0:s}/simple_successors.jpg'.format(OUTPUT_DIR_NAME) ) print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1])) figure_object.savefig( panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight' ) pyplot.close(figure_object) # Simple predecessors, example 1. figure_object, axes_object = _plot_attribution_one_track( storm_object_table=_get_track1_for_simple_pred(), plot_legend=True, plot_x_ticks=False, legend_font_size=DEFAULT_FONT_SIZE, legend_location=(0.28, 0.1) ) axes_object.set_title('Simple predecessors, example 1') this_file_name = '{0:s}/simple_predecessors_track1_standalone.jpg'.format( OUTPUT_DIR_NAME) print('Saving figure to: "{0:s}"...'.format(this_file_name)) figure_object.savefig( this_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight' ) plotting_utils.label_axes(axes_object=axes_object, label_string='(d)') axes_object.set_title('Linking to simple predecessors, example 1') panel_file_names.append( '{0:s}/simple_predecessors_track1.jpg'.format(OUTPUT_DIR_NAME) ) print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1])) figure_object.savefig( panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight' ) pyplot.close(figure_object) # Simple predecessors, example 2. figure_object, axes_object = _plot_attribution_one_track( storm_object_table=_get_track2_for_simple_pred(), plot_legend=False, plot_x_ticks=False ) axes_object.set_title('Simple predecessors, example 2') this_file_name = '{0:s}/simple_predecessors_track2_standalone.jpg'.format( OUTPUT_DIR_NAME) print('Saving figure to: "{0:s}"...'.format(this_file_name)) figure_object.savefig( this_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight' ) plotting_utils.label_axes(axes_object=axes_object, label_string='(e)') axes_object.set_title('Linking to simple predecessors, example 2') panel_file_names.append( '{0:s}/simple_predecessors_track2.jpg'.format(OUTPUT_DIR_NAME) ) print('Saving figure to: "{0:s}"...'.format(panel_file_names[-1])) figure_object.savefig( panel_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight' ) pyplot.close(figure_object) # Concatenate all panels into one figure. concat_file_name = '{0:s}/attribution_schemas.jpg'.format(OUTPUT_DIR_NAME) print('Concatenating panels to: "{0:s}"...'.format(concat_file_name)) imagemagick_utils.concatenate_images( input_file_names=panel_file_names, output_file_name=concat_file_name, num_panel_rows=2, num_panel_columns=3) imagemagick_utils.resize_image( input_file_name=concat_file_name, output_file_name=concat_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX)
def _run(): """Plots results of CNN experiment. This is effectively the main method. :raises: ValueError: if any Unix command fails. """ num_predictor_combos = len(UNIQUE_PREDICTOR_COMBO_STRINGS) num_image_sizes = len(UNIQUE_HALF_IMAGE_SIZES) num_dropout_fractions = len(UNIQUE_DROPOUT_FRACTIONS) gerrity_score_matrix = numpy.full( (num_predictor_combos, num_image_sizes, num_dropout_fractions), numpy.nan) peirce_score_matrix = gerrity_score_matrix + 0. hss_matrix = gerrity_score_matrix + 0. accuracy_matrix = gerrity_score_matrix + 0. for i in range(num_predictor_combos): for j in range(num_image_sizes): for k in range(num_dropout_fractions): this_num_predictors = len( UNIQUE_PREDICTOR_COMBO_STRINGS[i].split()) this_eval_file_name = ( '{0:s}/{1:s}_init-num-filters={2:d}_half-image-size-px=' '{3:d}_num-conv-layer-sets={4:d}_dropout={5:.2f}/validation' '/model_evaluation.p' ).format( TOP_EXPERIMENT_DIR_NAME, UNIQUE_PREDICTOR_COMBO_STRINGS[i].replace( '_', '-').replace(' ', '_'), this_num_predictors * 8, UNIQUE_HALF_IMAGE_SIZES[j], 2 + int(UNIQUE_HALF_IMAGE_SIZES[j] > 8), UNIQUE_DROPOUT_FRACTIONS[k] ) if not os.path.isfile(this_eval_file_name): warning_string = ( 'POTENTIAL PROBLEM. Cannot find file expected at: ' '"{0:s}"' ).format(this_eval_file_name) warnings.warn(warning_string) continue print 'Reading data from: "{0:s}"...'.format( this_eval_file_name) this_evaluation_dict = eval_utils.read_evaluation_results( this_eval_file_name) gerrity_score_matrix[i, j, k] = this_evaluation_dict[ eval_utils.GERRITY_SCORE_KEY] peirce_score_matrix[i, j, k] = this_evaluation_dict[ eval_utils.PEIRCE_SCORE_KEY] hss_matrix[i, j, k] = this_evaluation_dict[ eval_utils.HEIDKE_SCORE_KEY] accuracy_matrix[i, j, k] = this_evaluation_dict[ eval_utils.ACCURACY_KEY] print SEPARATOR_STRING panel_file_names = numpy.full((4, num_dropout_fractions), '', dtype=object) for k in range(num_dropout_fractions): if k == 0: this_y_axis_text_colour = BLACK_COLOUR + 0. else: this_y_axis_text_colour = WHITE_COLOUR + 0. this_title_string = 'Gerrity score; dropout = {0:.2f}'.format( UNIQUE_DROPOUT_FRACTIONS[k]) panel_file_names[0, k] = ( '{0:s}/gerrity_score_dropout-fraction={1:.2f}.jpg' ).format(TOP_EXPERIMENT_DIR_NAME, UNIQUE_DROPOUT_FRACTIONS[k]) print gerrity_score_matrix[..., k] _plot_scores_as_grid( score_matrix=gerrity_score_matrix[..., k], colour_map_object=COLOUR_MAP_OBJECT, min_colour_value=numpy.nanpercentile( gerrity_score_matrix, MIN_COLOUR_PERCENTILE), max_colour_value=numpy.nanpercentile( gerrity_score_matrix, MAX_COLOUR_PERCENTILE), x_tick_labels=UNIQUE_IMAGE_SIZE_STRINGS, x_axis_label=IMAGE_SIZE_AXIS_LABEL, x_axis_text_colour=WHITE_COLOUR, y_tick_labels=UNIQUE_PREDICTOR_ABBREV_STRINGS, y_axis_label='', y_axis_text_colour=this_y_axis_text_colour, title_string=this_title_string, output_file_name=panel_file_names[0, k]) this_title_string = 'Peirce score; dropout = {0:.2f}'.format( UNIQUE_DROPOUT_FRACTIONS[k]) panel_file_names[1, k] = ( '{0:s}/peirce_score_dropout-fraction={1:.2f}.jpg' ).format(TOP_EXPERIMENT_DIR_NAME, UNIQUE_DROPOUT_FRACTIONS[k]) _plot_scores_as_grid( score_matrix=peirce_score_matrix[..., k], colour_map_object=COLOUR_MAP_OBJECT, min_colour_value=numpy.nanpercentile( peirce_score_matrix, MIN_COLOUR_PERCENTILE), max_colour_value=numpy.nanpercentile( peirce_score_matrix, MAX_COLOUR_PERCENTILE), x_tick_labels=UNIQUE_IMAGE_SIZE_STRINGS, x_axis_label=IMAGE_SIZE_AXIS_LABEL, x_axis_text_colour=WHITE_COLOUR, y_tick_labels=UNIQUE_PREDICTOR_ABBREV_STRINGS, y_axis_label='', y_axis_text_colour=this_y_axis_text_colour, title_string=this_title_string, output_file_name=panel_file_names[1, k]) this_title_string = 'Heidke skill score; dropout = {0:.2f}'.format( UNIQUE_DROPOUT_FRACTIONS[k]) panel_file_names[2, k] = ( '{0:s}/hss_dropout-fraction={1:.2f}.jpg' ).format(TOP_EXPERIMENT_DIR_NAME, UNIQUE_DROPOUT_FRACTIONS[k]) _plot_scores_as_grid( score_matrix=hss_matrix[..., k], colour_map_object=COLOUR_MAP_OBJECT, min_colour_value=numpy.nanpercentile( hss_matrix, MIN_COLOUR_PERCENTILE), max_colour_value=numpy.nanpercentile( hss_matrix, MAX_COLOUR_PERCENTILE), x_tick_labels=UNIQUE_IMAGE_SIZE_STRINGS, x_axis_label=IMAGE_SIZE_AXIS_LABEL, x_axis_text_colour=WHITE_COLOUR, y_tick_labels=UNIQUE_PREDICTOR_ABBREV_STRINGS, y_axis_label='', y_axis_text_colour=this_y_axis_text_colour, title_string=this_title_string, output_file_name=panel_file_names[2, k]) this_title_string = 'Accuracy; dropout = {0:.2f}'.format( UNIQUE_DROPOUT_FRACTIONS[k]) panel_file_names[3, k] = ( '{0:s}/accuracy_dropout-fraction={1:.2f}.jpg' ).format(TOP_EXPERIMENT_DIR_NAME, UNIQUE_DROPOUT_FRACTIONS[k]) _plot_scores_as_grid( score_matrix=accuracy_matrix[..., k], colour_map_object=COLOUR_MAP_OBJECT, min_colour_value=numpy.nanpercentile( accuracy_matrix, MIN_COLOUR_PERCENTILE), max_colour_value=numpy.nanpercentile( accuracy_matrix, MAX_COLOUR_PERCENTILE), x_tick_labels=UNIQUE_IMAGE_SIZE_STRINGS, x_axis_label=IMAGE_SIZE_AXIS_LABEL, x_axis_text_colour=BLACK_COLOUR, y_tick_labels=UNIQUE_PREDICTOR_ABBREV_STRINGS, y_axis_label='', y_axis_text_colour=this_y_axis_text_colour, title_string=this_title_string, output_file_name=panel_file_names[3, k]) for m in range(4): second_image_object = Image.open(panel_file_names[m, 1]) command_string = '"{0:s}" "{1:s}" -resize {2:d}x{3:d}\! "{1:s}"'.format( imagemagick_utils.DEFAULT_CONVERT_EXE_NAME, panel_file_names[m, 0], second_image_object.size[0], second_image_object.size[1]) print 'Resizing image: "{0:s}"...'.format(panel_file_names[m, 0]) exit_code = os.system(command_string) if exit_code != 0: raise ValueError('\nUnix command failed (log messages shown ' 'above should explain why).') concat_file_name = '{0:s}/validation.jpg'.format(TOP_EXPERIMENT_DIR_NAME) print 'Concatenating panels to: "{0:s}"...'.format(concat_file_name) imagemagick_utils.concatenate_images( input_file_names=numpy.ravel(panel_file_names).tolist(), output_file_name=concat_file_name, num_panel_rows=4, num_panel_columns=num_dropout_fractions) imagemagick_utils.resize_image( input_file_name=concat_file_name, output_file_name=concat_file_name, output_size_pixels=FIGURE_SIZE_PIXELS)
def _run(): """Plots example of double penalty. This is effectively the main method. """ print 'Reading data from: "{0:s}"...'.format(INPUT_FILE_NAME) actual_grid_point_table = fronts_io.read_narr_grids_from_file( INPUT_FILE_NAME) predicted_grid_point_table = copy.deepcopy(actual_grid_point_table) predicted_grid_point_table[ front_utils.WARM_FRONT_COLUMN_INDICES_COLUMN] += 1 predicted_grid_point_table[ front_utils.COLD_FRONT_COLUMN_INDICES_COLUMN] += 1 predicted_grid_point_table[front_utils.WARM_FRONT_ROW_INDICES_COLUMN] += 1 predicted_grid_point_table[front_utils.COLD_FRONT_ROW_INDICES_COLUMN] += 1 num_grid_rows, num_grid_columns = nwp_model_utils.get_grid_dimensions( model_name=nwp_model_utils.NARR_MODEL_NAME) actual_binary_matrix = ml_utils.front_table_to_images( frontal_grid_table=actual_grid_point_table, num_rows_per_image=num_grid_rows, num_columns_per_image=num_grid_columns) actual_binary_matrix = ml_utils.binarize_front_images(actual_binary_matrix) predicted_binary_matrix = ml_utils.front_table_to_images( frontal_grid_table=predicted_grid_point_table, num_rows_per_image=num_grid_rows, num_columns_per_image=num_grid_columns) predicted_binary_matrix = ml_utils.binarize_front_images( predicted_binary_matrix) _plot_fronts(actual_binary_matrix=actual_binary_matrix, predicted_binary_matrix=predicted_binary_matrix, title_string='Observed and predicted front\nwithout dilation', annotation_string='(c)', output_file_name=NO_DILATION_FILE_NAME) actual_binary_matrix = ml_utils.dilate_binary_target_images( target_matrix=actual_binary_matrix, dilation_distance_metres=DILATION_DISTANCE_METRES, verbose=False) predicted_binary_matrix = ml_utils.dilate_binary_target_images( target_matrix=predicted_binary_matrix, dilation_distance_metres=DILATION_DISTANCE_METRES, verbose=False) _plot_fronts(actual_binary_matrix=actual_binary_matrix, predicted_binary_matrix=predicted_binary_matrix, title_string='Observed and predicted front\nwith dilation', annotation_string='(d)', output_file_name=WITH_DILATION_FILE_NAME) print 'Concatenating figures to: "{0:s}"...'.format(CONCAT_FILE_NAME) imagemagick_utils.concatenate_images( input_file_names=[NO_DILATION_FILE_NAME, WITH_DILATION_FILE_NAME], output_file_name=CONCAT_FILE_NAME, num_panel_rows=1, num_panel_columns=2) imagemagick_utils.resize_image(input_file_name=CONCAT_FILE_NAME, output_file_name=CONCAT_FILE_NAME, output_size_pixels=CONCAT_SIZE_PIXELS)
def _plot_sounding_saliency( saliency_matrix, colour_map_object, max_colour_value, sounding_figure_object, sounding_axes_object, sounding_pressures_pascals, saliency_dict, model_metadata_dict, add_title, output_dir_name, pmm_flag, example_index=None): """Plots saliency for sounding. H = number of sounding heights F = number of sounding fields :param saliency_matrix: H-by-F numpy array of saliency values. :param colour_map_object: See documentation at top of file. :param max_colour_value: Same. :param sounding_figure_object: Figure handle (instance of `matplotlib.figure.Figure`) for sounding itself. :param sounding_axes_object: Axes handle (instance of `matplotlib.axes._subplots.AxesSubplot`) for sounding itself. :param sounding_pressures_pascals: length-H numpy array of sounding pressures. :param saliency_dict: Dictionary returned by `saliency_maps.read_file`. :param model_metadata_dict: Dictionary returned by `cnn.read_model_metadata`. :param add_title: Boolean flag. :param output_dir_name: Name of output directory. Figures will be saved here. :param pmm_flag: Boolean flag. If True, plotting PMM composite rather than one example. :param example_index: [used only if `pmm_flag == False`] Plotting the [i]th example, where i = `example_index`. """ if max_colour_value is None: max_colour_value = numpy.percentile( numpy.absolute(saliency_matrix), MAX_COLOUR_PERCENTILE ) training_option_dict = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY] sounding_field_names = training_option_dict[trainval_io.SOUNDING_FIELDS_KEY] if pmm_flag: full_storm_id_string = None storm_time_unix_sec = None else: full_storm_id_string = saliency_dict[saliency_maps.FULL_STORM_IDS_KEY][ example_index] storm_time_unix_sec = saliency_dict[saliency_maps.STORM_TIMES_KEY][ example_index] if add_title: title_string = 'Max absolute saliency = {0:.2e}'.format( max_colour_value) sounding_axes_object.set_title(title_string) left_panel_file_name = plot_examples.metadata_to_file_name( output_dir_name=output_dir_name, is_sounding=False, pmm_flag=pmm_flag, full_storm_id_string=full_storm_id_string, storm_time_unix_sec=storm_time_unix_sec, radar_field_name='sounding-actual') print('Saving figure to file: "{0:s}"...'.format(left_panel_file_name)) sounding_figure_object.savefig( left_panel_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(sounding_figure_object) saliency_plotting.plot_saliency_for_sounding( saliency_matrix=saliency_matrix, sounding_field_names=sounding_field_names, pressure_levels_mb=PASCALS_TO_MB * sounding_pressures_pascals, colour_map_object=colour_map_object, max_absolute_colour_value=max_colour_value) right_panel_file_name = plot_examples.metadata_to_file_name( output_dir_name=output_dir_name, is_sounding=False, pmm_flag=pmm_flag, full_storm_id_string=full_storm_id_string, storm_time_unix_sec=storm_time_unix_sec, radar_field_name='sounding-saliency') print('Saving figure to file: "{0:s}"...'.format(right_panel_file_name)) pyplot.savefig(right_panel_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close() concat_file_name = plot_examples.metadata_to_file_name( output_dir_name=output_dir_name, is_sounding=True, pmm_flag=pmm_flag, full_storm_id_string=full_storm_id_string, storm_time_unix_sec=storm_time_unix_sec) print('Concatenating figures to: "{0:s}"...\n'.format(concat_file_name)) imagemagick_utils.concatenate_images( input_file_names=[left_panel_file_name, right_panel_file_name], output_file_name=concat_file_name, num_panel_rows=1, num_panel_columns=2 ) imagemagick_utils.resize_image( input_file_name=concat_file_name, output_file_name=concat_file_name, output_size_pixels=SOUNDING_IMAGE_SIZE_PX) os.remove(left_panel_file_name) os.remove(right_panel_file_name)
def _plot_one_composite(saliency_file_name, composite_name_abbrev, composite_name_verbose, colour_map_object, max_colour_value, half_num_contours, smoothing_radius_grid_cells, output_dir_name): """Plots saliency map for one composite. :param saliency_file_name: Path to input file (will be read by `saliency.read_file`). :param composite_name_abbrev: Abbrev composite name (will be used in file names). :param composite_name_verbose: Verbose composite name (will be used in figure title). :param colour_map_object: See documentation at top of file. :param max_colour_value: Same. :param half_num_contours: Same. :param smoothing_radius_grid_cells: Same. :param output_dir_name: Name of output directory (figures will be saved here). :return: main_figure_file_name: Path to main image file created by this method. :return: max_colour_value: See input doc. """ mean_radar_matrix, mean_saliency_matrix, model_metadata_dict = ( _read_one_composite( saliency_file_name=saliency_file_name, smoothing_radius_grid_cells=smoothing_radius_grid_cells)) if numpy.isnan(max_colour_value): max_colour_value = numpy.percentile(mean_saliency_matrix, MAX_COLOUR_PERCENTILE) training_option_dict = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY] field_names = training_option_dict[trainval_io.RADAR_FIELDS_KEY] num_fields = mean_radar_matrix.shape[-1] num_heights = mean_radar_matrix.shape[-2] handle_dict = plot_examples.plot_one_example( list_of_predictor_matrices=[mean_radar_matrix], model_metadata_dict=model_metadata_dict, pmm_flag=True, allow_whitespace=True, plot_panel_names=True, panel_name_font_size=PANEL_NAME_FONT_SIZE, add_titles=False, label_colour_bars=True, colour_bar_length=COLOUR_BAR_LENGTH, colour_bar_font_size=COLOUR_BAR_FONT_SIZE, num_panel_rows=num_heights) figure_objects = handle_dict[plot_examples.RADAR_FIGURES_KEY] axes_object_matrices = handle_dict[plot_examples.RADAR_AXES_KEY] for k in range(num_fields): this_saliency_matrix = mean_saliency_matrix[0, ..., k] saliency_plotting.plot_many_2d_grids_with_contours( saliency_matrix_3d=numpy.flip(this_saliency_matrix, axis=0), axes_object_matrix=axes_object_matrices[k], colour_map_object=colour_map_object, max_absolute_contour_level=max_colour_value, contour_interval=max_colour_value / half_num_contours) panel_file_names = [None] * num_fields for k in range(num_fields): panel_file_names[k] = '{0:s}/{1:s}_{2:s}.jpg'.format( output_dir_name, composite_name_abbrev, field_names[k].replace('_', '-')) print('Saving figure to: "{0:s}"...'.format(panel_file_names[k])) figure_objects[k].savefig(panel_file_names[k], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(figure_objects[k]) main_figure_file_name = '{0:s}/{1:s}_saliency.jpg'.format( output_dir_name, composite_name_abbrev) print('Concatenating panels to: "{0:s}"...'.format(main_figure_file_name)) imagemagick_utils.concatenate_images( input_file_names=panel_file_names, output_file_name=main_figure_file_name, num_panel_rows=1, num_panel_columns=num_fields, border_width_pixels=50) imagemagick_utils.resize_image(input_file_name=main_figure_file_name, output_file_name=main_figure_file_name, output_size_pixels=CONCAT_FIGURE_SIZE_PX) imagemagick_utils.trim_whitespace(input_file_name=main_figure_file_name, output_file_name=main_figure_file_name, border_width_pixels=TITLE_FONT_SIZE + 25) _overlay_text(image_file_name=main_figure_file_name, x_offset_from_center_px=0, y_offset_from_top_px=0, text_string=composite_name_verbose) imagemagick_utils.trim_whitespace(input_file_name=main_figure_file_name, output_file_name=main_figure_file_name, border_width_pixels=10) return main_figure_file_name, max_colour_value
def _plot_sounding_saliency( sounding_matrix, sounding_saliency_matrix, sounding_field_names, saliency_metadata_dict, colour_map_object, max_colour_value_by_example, output_dir_name): """Plots soundings along with their saliency maps. E = number of examples H = number of sounding heights F = number of sounding fields :param sounding_matrix: E-by-H-by-F numpy array of sounding values. :param sounding_saliency_matrix: E-by-H-by-F numpy array of corresponding saliency values. :param sounding_field_names: length-F list of field names. :param saliency_metadata_dict: Dictionary returned by `saliency_maps.read_standard_file`. :param colour_map_object: See doc for `_plot_2d3d_radar_saliency`. :param max_colour_value_by_example: Same. :param output_dir_name: Name of output directory (figures will be saved here). """ # TODO(thunderhoser): Generalize this method to deal with # probability-matched means. num_examples = sounding_matrix.shape[0] try: metpy_dict_by_example = dl_utils.soundings_to_metpy_dictionaries( sounding_matrix=sounding_matrix, field_names=sounding_field_names) except: sounding_pressure_matrix_pa = numpy.expand_dims( saliency_metadata_dict[saliency_maps.SOUNDING_PRESSURES_KEY], axis=-1) this_sounding_matrix = numpy.concatenate( (sounding_matrix, sounding_pressure_matrix_pa), axis=-1) metpy_dict_by_example = dl_utils.soundings_to_metpy_dictionaries( sounding_matrix=this_sounding_matrix, field_names=sounding_field_names + [soundings.PRESSURE_NAME]) for i in range(num_examples): this_storm_id = saliency_metadata_dict[ saliency_maps.STORM_IDS_KEY][i] this_storm_time_string = time_conversion.unix_sec_to_string( saliency_metadata_dict[saliency_maps.STORM_TIMES_KEY][i], TIME_FORMAT) this_title_string = 'Storm "{0:s}" at {1:s}'.format( this_storm_id, this_storm_time_string) sounding_plotting.plot_sounding( sounding_dict_for_metpy=metpy_dict_by_example[i], title_string=this_title_string) this_left_file_name = ( '{0:s}/{1:s}_{2:s}_sounding-actual.jpg' ).format( output_dir_name, this_storm_id.replace('_', '-'), this_storm_time_string ) print 'Saving figure to file: "{0:s}"...'.format( this_left_file_name) pyplot.savefig(this_left_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace( input_file_name=this_left_file_name, output_file_name=this_left_file_name) saliency_plotting.plot_saliency_for_sounding( saliency_matrix=sounding_saliency_matrix[i, ...], sounding_field_names=sounding_field_names, pressure_levels_mb=metpy_dict_by_example[i][ soundings.PRESSURE_COLUMN_METPY], colour_map_object=colour_map_object, max_absolute_colour_value=max_colour_value_by_example[i]) this_right_file_name = ( '{0:s}/{1:s}_{2:s}_sounding-saliency.jpg' ).format( output_dir_name, this_storm_id.replace('_', '-'), this_storm_time_string ) print 'Saving figure to file: "{0:s}"...'.format( this_right_file_name) pyplot.savefig(this_right_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace( input_file_name=this_right_file_name, output_file_name=this_right_file_name) this_file_name = ( '{0:s}/saliency_{1:s}_{2:s}_sounding.jpg' ).format( output_dir_name, this_storm_id.replace('_', '-'), this_storm_time_string ) print 'Concatenating panels into file: "{0:s}"...\n'.format( this_file_name) imagemagick_utils.concatenate_images( input_file_names=[this_left_file_name, this_right_file_name], output_file_name=this_file_name, num_panel_rows=1, num_panel_columns=2) imagemagick_utils.resize_image( input_file_name=this_file_name, output_file_name=this_file_name, output_size_pixels=SOUNDING_IMAGE_SIZE_PX) os.remove(this_left_file_name) os.remove(this_right_file_name)