def _plot_feature_map_after_conv(feature_matrix): """Plots new feature map (after convolution). M = number of rows in grid N = number of columns in grid :param feature_matrix: Feature map as M-by-N numpy array. """ dummy_matrix = numpy.full(feature_matrix.shape, numpy.nan) dummy_matrix[:2, :2] = HIGHLIGHTED_VALUE _, axes_object = pyplot.subplots(1, 1, figsize=(FIGURE_WIDTH_INCHES, FIGURE_HEIGHT_INCHES)) pyplot.imshow(dummy_matrix, cmap=COLOUR_MAP_OBJECT, vmin=HIGHLIGHTED_VALUE - 1, vmax=HIGHLIGHTED_VALUE, axes=axes_object, origin='upper') pyplot.xticks([], []) pyplot.yticks([], []) for i in range(feature_matrix.shape[1]): for j in range(feature_matrix.shape[0]): if i == j == 1: this_colour = SPECIAL_COLOUR + 0. else: this_colour = MAIN_COLOUR + 0. axes_object.text(i, j, '{0:.1f}'.format(feature_matrix[j, i]), fontsize=OVERLAY_FONT_SIZE, color=this_colour, horizontalalignment='center', verticalalignment='center') # polygon_x_coords = numpy.array([0, 2, 2, 0, 0], dtype=float) - 0.5 # polygon_y_coords = numpy.array([2, 2, 0, 0, 2], dtype=float) - 0.5 # axes_object.plot( # polygon_x_coords, polygon_y_coords, color=LINE_COLOUR, # linewidth=LINE_WIDTH) plotting_utils.annotate_axes(axes_object=axes_object, annotation_string='(c)', font_colour=ANNOTATION_COLOUR) print 'Saving figure to: "{0:s}"...'.format(AFTER_CONV_FILE_NAME) file_system_utils.mkdir_recursive_if_necessary( file_name=AFTER_CONV_FILE_NAME) pyplot.savefig(AFTER_CONV_FILE_NAME, dpi=OUTPUT_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=AFTER_CONV_FILE_NAME, output_file_name=AFTER_CONV_FILE_NAME) return feature_matrix
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 _plot_scores_as_grid( score_matrix, colour_map_object, min_colour_value, max_colour_value, x_tick_labels, x_axis_label, x_axis_text_colour, y_tick_labels, y_axis_label, y_axis_text_colour, title_string, output_file_name): """Plots model scores as 2-D grid. M = number of rows in grid N = number of columns in grid :param score_matrix: M-by-N numpy array of model scores. :param colour_map_object: Instance of `matplotlib.colors.ListedColormap`. :param min_colour_value: Minimum value in colour map. :param max_colour_value: Max value in colour map. :param x_tick_labels: length-N list of string labels. :param x_axis_label: String label for the entire x-axis. :param x_axis_text_colour: Colour for all text labels along x-axis. :param y_tick_labels: length-M list of string labels. :param y_axis_label: String label for the entire y-axis. :param y_axis_text_colour: Colour for all text labels along y-axis. :param title_string: Figure title. :param output_file_name: Path to output file (the figure will be saved here). """ _, axes_object = pyplot.subplots( 1, 1, figsize=(FIGURE_WIDTH_INCHES, FIGURE_HEIGHT_INCHES)) score_matrix_to_plot = score_matrix + 0. score_matrix_to_plot[numpy.isnan(score_matrix_to_plot)] = 0. pyplot.imshow( score_matrix_to_plot, cmap=colour_map_object, origin='lower', vmin=min_colour_value, vmax=max_colour_value) x_tick_values = numpy.linspace( 0, score_matrix_to_plot.shape[1] - 1, num=score_matrix_to_plot.shape[1], dtype=float) pyplot.xticks(x_tick_values, x_tick_labels, color=x_axis_text_colour) pyplot.xlabel(x_axis_label, color=x_axis_text_colour) y_tick_values = numpy.linspace( 0, score_matrix_to_plot.shape[0] - 1, num=score_matrix_to_plot.shape[0], dtype=float) pyplot.yticks(y_tick_values, y_tick_labels, color=y_axis_text_colour) pyplot.ylabel(y_axis_label, color=y_axis_text_colour) pyplot.title(title_string) plotting_utils.add_linear_colour_bar( axes_object_or_list=axes_object, values_to_colour=score_matrix_to_plot, colour_map=colour_map_object, colour_min=min_colour_value, colour_max=max_colour_value, orientation='vertical', extend_min=True, extend_max=True, font_size=FONT_SIZE) print 'Saving figure to: "{0:s}"...'.format(output_file_name) file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace( input_file_name=output_file_name, output_file_name=output_file_name)
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 _plot_locating_variable( locating_var_matrix_m01_s01, title_string, annotation_string, output_file_name): """Plots locating variable. M = number of rows in grid N = number of columns in grid :param locating_var_matrix_m01_s01: M-by-N numpy array with values of locating variable. :param title_string: Title (will be placed above figure). :param annotation_string: Text annotation (will be placed in top left of figure). :param output_file_name: Path to output file (figure will be saved here). """ (narr_row_limits, narr_column_limits, axes_object, basemap_object ) = _init_basemap(BORDER_COLOUR) matrix_to_plot = locating_var_matrix_m01_s01[ narr_row_limits[0]:(narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1) ] * LOCATING_VAR_MULTIPLIER max_colour_value = numpy.nanpercentile( numpy.absolute(matrix_to_plot), MAX_COLOUR_PERCENTILE) min_colour_value = -1 * max_colour_value nwp_plotting.plot_subgrid( field_matrix=matrix_to_plot, model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, colour_map=LOCATING_VAR_COLOUR_MAP_OBJECT, min_value_in_colour_map=min_colour_value, max_value_in_colour_map=max_colour_value, first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0]) plotting_utils.add_linear_colour_bar( axes_object_or_list=axes_object, values_to_colour=matrix_to_plot, colour_map=LOCATING_VAR_COLOUR_MAP_OBJECT, colour_min=min_colour_value, colour_max=max_colour_value, orientation='vertical', extend_min=True, extend_max=True, fraction_of_axis_length=COLOUR_BAR_LENGTH_FRACTION) pyplot.title(title_string) plotting_utils.annotate_axes( axes_object=axes_object, annotation_string=annotation_string) print 'Saving figure to: "{0:s}"...'.format(output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _plot_kernel(): """Plots convolutional kernel. J = number of rows in kernel K = number of columns in kernel :return: kernel_matrix: Kernel as J-by-K numpy array. """ kernel_matrix = numpy.random.choice(a=POSSIBLE_KERNEL_VALUES, size=(NUM_ROWS_IN_KERNEL, NUM_COLUMNS_IN_KERNEL), replace=True) dummy_matrix = numpy.full((NUM_ROWS_IN_KERNEL, NUM_COLUMNS_IN_KERNEL), HIGHLIGHTED_VALUE) _, axes_object = pyplot.subplots(1, 1, figsize=(FIGURE_WIDTH_INCHES, FIGURE_HEIGHT_INCHES)) pyplot.imshow(dummy_matrix, cmap=COLOUR_MAP_OBJECT, vmin=HIGHLIGHTED_VALUE - 1, vmax=HIGHLIGHTED_VALUE, axes=axes_object, origin='upper') pyplot.xticks([], []) pyplot.yticks([], []) for i in range(kernel_matrix.shape[1]): for j in range(kernel_matrix.shape[0]): axes_object.text(i, j, '{0:.1f}'.format(kernel_matrix[j, i]), fontsize=OVERLAY_FONT_SIZE, color=MAIN_COLOUR, horizontalalignment='center', verticalalignment='center') plotting_utils.annotate_axes(axes_object=axes_object, annotation_string='(b)', font_colour=ANNOTATION_COLOUR) print 'Saving figure to: "{0:s}"...'.format(KERNEL_FILE_NAME) file_system_utils.mkdir_recursive_if_necessary(file_name=KERNEL_FILE_NAME) pyplot.savefig(KERNEL_FILE_NAME, dpi=OUTPUT_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=KERNEL_FILE_NAME, output_file_name=KERNEL_FILE_NAME) return kernel_matrix
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(): """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 _plot_ternary_table(): """Plots ternary contingency table.""" _, axes_object = pyplot.subplots(1, 1, figsize=(FIGURE_WIDTH_INCHES, FIGURE_HEIGHT_INCHES)) pyplot.imshow(numpy.zeros((3, 3)), cmap=COLOUR_MAP_OBJECT, vmin=LARGE_NUMBER, vmax=LARGE_NUMBER + 1, axes=axes_object, origin='upper') tick_locations = numpy.array([0, 1, 2], dtype=int) tick_labels = ['NF', 'WF', 'CF'] pyplot.xticks(tick_locations, tick_labels) pyplot.xlabel('Actual') pyplot.yticks(tick_locations, tick_labels) pyplot.ylabel('Predicted') for i in range(3): for j in range(3): axes_object.text(i, j, str(TERNARY_VARIABLE_NAME_MATRIX[i, j]), fontsize=OVERLAY_FONT_SIZE, color=MAIN_COLOUR, horizontalalignment='center', verticalalignment='center') # plotting_utils.annotate_axes( # axes_object=axes_object, annotation_string='(b)', # font_colour=ANNOTATION_COLOUR) print 'Saving figure to: "{0:s}"...'.format(TERNARY_CT_FILE_NAME) file_system_utils.mkdir_recursive_if_necessary( file_name=TERNARY_CT_FILE_NAME) pyplot.savefig(TERNARY_CT_FILE_NAME, dpi=OUTPUT_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=TERNARY_CT_FILE_NAME, output_file_name=TERNARY_CT_FILE_NAME)
def _plot_front_types(predicted_label_matrix, title_string, annotation_string, output_file_name): """Plots front type at each grid cell. M = number of rows in grid N = number of columns in grid :param predicted_label_matrix: M-by-N numpy array with predicted front type at each grid cell. Each front type is from the list `front_utils.VALID_INTEGER_IDS`. :param title_string: Title (will be placed above figure). :param annotation_string: Text annotation (will be placed in top left of figure). :param output_file_name: Path to output file (figure will be saved here). """ (narr_row_limits, narr_column_limits, axes_object, basemap_object ) = _init_basemap(BORDER_COLOUR) matrix_to_plot = predicted_label_matrix[ narr_row_limits[0]:(narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1) ] front_plotting.plot_narr_grid( frontal_grid_matrix=matrix_to_plot, axes_object=axes_object, basemap_object=basemap_object, first_row_in_narr_grid=narr_row_limits[0], first_column_in_narr_grid=narr_column_limits[0]) pyplot.title(title_string) plotting_utils.annotate_axes( axes_object=axes_object, annotation_string=annotation_string) print 'Saving figure to: "{0:s}"...'.format(output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _run(tropical_example_dir_name, non_tropical_example_dir_name, num_histogram_bins, output_dir_name): """Plots distribution of each target variable. This is effectively the main method. :param tropical_example_dir_name: See documentation at top of file. :param non_tropical_example_dir_name: Same. :param num_histogram_bins: Same. :param output_dir_name: Same. """ file_system_utils.mkdir_recursive_if_necessary( directory_name=output_dir_name) first_time_unix_sec = ( time_conversion.first_and_last_times_in_year(FIRST_YEAR)[0]) last_time_unix_sec = ( time_conversion.first_and_last_times_in_year(LAST_YEAR)[-1]) example_file_names = example_io.find_many_files( directory_name=tropical_example_dir_name, first_time_unix_sec=first_time_unix_sec, last_time_unix_sec=last_time_unix_sec, raise_error_if_all_missing=True, raise_error_if_any_missing=True) example_file_names += example_io.find_many_files( directory_name=non_tropical_example_dir_name, first_time_unix_sec=first_time_unix_sec, last_time_unix_sec=last_time_unix_sec, raise_error_if_all_missing=True, raise_error_if_any_missing=True) example_dicts = [] for this_file_name in example_file_names: print('Reading data from: "{0:s}"...'.format(this_file_name)) this_example_dict = example_io.read_file(this_file_name) this_example_dict = example_utils.subset_by_field( example_dict=this_example_dict, field_names=TARGET_NAMES_IN_FILE) example_dicts.append(this_example_dict) example_dict = example_utils.concat_examples(example_dicts) del example_dicts letter_label = None panel_file_names = [] for this_target_name in TARGET_NAMES: if this_target_name in TARGET_NAMES_IN_FILE: these_target_values = example_utils.get_field_from_dict( example_dict=example_dict, field_name=this_target_name) else: down_fluxes_w_m02 = example_utils.get_field_from_dict( example_dict=example_dict, field_name=example_utils.SHORTWAVE_SURFACE_DOWN_FLUX_NAME) up_fluxes_w_m02 = example_utils.get_field_from_dict( example_dict=example_dict, field_name=example_utils.SHORTWAVE_TOA_UP_FLUX_NAME) these_target_values = down_fluxes_w_m02 - up_fluxes_w_m02 these_target_values = numpy.ravel(these_target_values) if letter_label is None: letter_label = 'a' else: letter_label = chr(ord(letter_label) + 1) this_file_name = _plot_histogram_one_target( target_values=these_target_values, target_name=this_target_name, num_bins=num_histogram_bins, letter_label=letter_label, output_dir_name=output_dir_name) panel_file_names.append(this_file_name) concat_file_name = '{0:s}/target_distributions.jpg'.format(output_dir_name) print('Concatenating panels to: "{0:s}"...'.format(concat_file_name)) imagemagick_utils.concatenate_images(input_file_names=panel_file_names, output_file_name=concat_file_name, num_panel_rows=2, num_panel_columns=2, border_width_pixels=25) imagemagick_utils.trim_whitespace(input_file_name=concat_file_name, output_file_name=concat_file_name)
def _plot_fronts(actual_binary_matrix, predicted_binary_matrix, title_string, annotation_string, output_file_name): """Plots actual and predicted fronts. M = number of rows in grid N = number of columns in grid :param actual_binary_matrix: M-by-N numpy array. If actual_binary_matrix[i, j] = 1, there is an actual front passing through grid cell [i, j]. :param predicted_binary_matrix: Same but for predicted fronts. :param title_string: Title (will be placed above figure). :param annotation_string: Text annotation (will be placed in top left of figure). :param output_file_name: Path to output file (figure will be saved here). """ (narr_row_limits, narr_column_limits) = nwp_plotting.latlng_limits_to_rowcol_limits( min_latitude_deg=MIN_LATITUDE_DEG, max_latitude_deg=MAX_LATITUDE_DEG, min_longitude_deg=MIN_LONGITUDE_DEG, max_longitude_deg=MAX_LONGITUDE_DEG, model_name=nwp_model_utils.NARR_MODEL_NAME) _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=narr_row_limits[0], last_row_in_full_grid=narr_row_limits[1], first_column_in_full_grid=narr_column_limits[0], last_column_in_full_grid=narr_column_limits[1], resolution_string='i') plotting_utils.plot_coastlines(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_countries(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_states_and_provinces(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_parallels(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) this_colour_map_object, this_colour_norm_object = _get_colour_map(True) this_matrix = actual_binary_matrix[0, narr_row_limits[0]:( narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1)] nwp_plotting.plot_subgrid( field_matrix=this_matrix, model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, colour_map=this_colour_map_object, min_value_in_colour_map=this_colour_norm_object.boundaries[0], max_value_in_colour_map=this_colour_norm_object.boundaries[-1], first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0], opacity=ACTUAL_FRONT_OPACITY) this_colour_map_object, this_colour_norm_object = _get_colour_map(False) this_matrix = predicted_binary_matrix[0, narr_row_limits[0]:( narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1)] nwp_plotting.plot_subgrid( field_matrix=this_matrix, model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, colour_map=this_colour_map_object, min_value_in_colour_map=this_colour_norm_object.boundaries[0], max_value_in_colour_map=this_colour_norm_object.boundaries[-1], first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0], opacity=PREDICTED_FRONT_OPACITY) pyplot.title(title_string) plotting_utils.annotate_axes(axes_object=axes_object, annotation_string=annotation_string) print 'Saving figure to: "{0:s}"...'.format(output_file_name) file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _plot_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 _plot_one_time( predictor_matrix, predictor_names, front_polyline_table, high_low_table, thermal_colour_map_object, max_thermal_prctile_for_colours, narr_row_limits, narr_column_limits, title_string, letter_label, output_file_name): """Plots predictors at one time. M = number of rows in grid N = number of columns in grid C = number of channels (predictors) :param predictor_matrix: M-by-N-by-C numpy array of predictor values. :param predictor_names: length-C list of predictor names. :param front_polyline_table: pandas DataFrame returned by `fronts_io.read_polylines_from_file`. :param high_low_table: pandas DataFrame returned by `wpc_bulletin_io.read_highs_and_lows`. :param thermal_colour_map_object: See documentation at top of file. :param max_thermal_prctile_for_colours: Same. :param narr_row_limits: length-2 numpy array, indicating the first and last NARR rows in `predictor_matrix`. If narr_row_limits = [i, k], `predictor_matrix` spans rows i...k of the full NARR grid. :param narr_column_limits: Same but for columns. :param title_string: Title (will be placed above figure). :param letter_label: Letter label. If this is "a", the label "(a)" will be printed at the top left of the figure. :param output_file_name: Path to output file (figure will be saved here). """ _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=narr_row_limits[0], last_row_in_full_grid=narr_row_limits[1], first_column_in_full_grid=narr_column_limits[0], last_column_in_full_grid=narr_column_limits[1] ) plotting_utils.plot_coastlines( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR ) plotting_utils.plot_countries( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR ) plotting_utils.plot_states_and_provinces( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR ) plotting_utils.plot_parallels( basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG ) plotting_utils.plot_meridians( basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG ) num_predictors = len(predictor_names) for j in range(num_predictors): if predictor_names[j] in WIND_FIELD_NAMES: continue min_colour_value = numpy.percentile( predictor_matrix[..., j], 100. - max_thermal_prctile_for_colours) max_colour_value = numpy.percentile( predictor_matrix[..., j], max_thermal_prctile_for_colours) nwp_plotting.plot_subgrid( field_matrix=predictor_matrix[..., j], model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, colour_map=thermal_colour_map_object, min_value_in_colour_map=min_colour_value, max_value_in_colour_map=max_colour_value, first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0] ) plotting_utils.add_linear_colour_bar( axes_object_or_list=axes_object, values_to_colour=predictor_matrix[..., j], colour_map=thermal_colour_map_object, colour_min=min_colour_value, colour_max=max_colour_value, orientation='horizontal', extend_min=True, extend_max=True, fraction_of_axis_length=0.9) u_wind_index = predictor_names.index( processed_narr_io.U_WIND_GRID_RELATIVE_NAME) v_wind_index = predictor_names.index( processed_narr_io.V_WIND_GRID_RELATIVE_NAME) nwp_plotting.plot_wind_barbs_on_subgrid( u_wind_matrix_m_s01=predictor_matrix[..., u_wind_index], v_wind_matrix_m_s01=predictor_matrix[..., v_wind_index], model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0], plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB, plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB, barb_length=WIND_BARB_LENGTH, empty_barb_radius=EMPTY_WIND_BARB_RADIUS, fill_empty_barb=False, colour_map=WIND_COLOUR_MAP_OBJECT, colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT, colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT) if high_low_table is None: num_pressure_systems = 0 else: num_pressure_systems = len(high_low_table.index) for i in range(num_pressure_systems): this_system_type_string = high_low_table[ wpc_bulletin_io.SYSTEM_TYPE_COLUMN].values[i] if this_system_type_string == wpc_bulletin_io.HIGH_PRESSURE_STRING: this_string = 'H' else: this_string = 'L' this_x_coord_metres, this_y_coord_metres = basemap_object( high_low_table[wpc_bulletin_io.LONGITUDE_COLUMN].values[i], high_low_table[wpc_bulletin_io.LATITUDE_COLUMN].values[i] ) axes_object.text( this_x_coord_metres, this_y_coord_metres, this_string, fontsize=PRESSURE_SYSTEM_FONT_SIZE, color=PRESSURE_SYSTEM_COLOUR, fontweight='bold', horizontalalignment='center', verticalalignment='center') num_fronts = len(front_polyline_table.index) for i in range(num_fronts): this_front_type_string = front_polyline_table[ front_utils.FRONT_TYPE_COLUMN].values[i] if this_front_type_string == front_utils.WARM_FRONT_STRING_ID: this_colour = WARM_FRONT_COLOUR else: this_colour = COLD_FRONT_COLOUR front_plotting.plot_front_with_markers( line_latitudes_deg=front_polyline_table[ front_utils.LATITUDES_COLUMN].values[i], line_longitudes_deg=front_polyline_table[ front_utils.LONGITUDES_COLUMN].values[i], axes_object=axes_object, basemap_object=basemap_object, front_type_string=front_polyline_table[ front_utils.FRONT_TYPE_COLUMN].values[i], marker_colour=this_colour) pyplot.title(title_string) if letter_label is not None: plotting_utils.annotate_axes( axes_object=axes_object, annotation_string='({0:s})'.format(letter_label) ) print 'Saving figure to: "{0:s}"...'.format(output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _plot_one_time(valid_time_string, pressure_level_mb, title_string, annotation_string, narr_rotation_cos_matrix, narr_rotation_sin_matrix): """Plots WPC fronts and NARR fields at one time. M = number of grid rows in the full NARR N = number of grid columns in the full NARR :param valid_time_string: Valid time (format "yyyy-mm-dd-HH"). :param pressure_level_mb: Pressure level (millibars). :param title_string: Title (will be placed above figure). :param annotation_string: Annotation (will be placed above and left of figure). :param narr_rotation_cos_matrix: M-by-N numpy array of cosines for wind- rotation angles. :param narr_rotation_sin_matrix: M-by-N numpy array of sines for wind- rotation angles. """ narr_row_limits, narr_column_limits = ( nwp_plotting.latlng_limits_to_rowcol_limits( min_latitude_deg=MIN_LATITUDE_DEG, max_latitude_deg=MAX_LATITUDE_DEG, min_longitude_deg=MIN_LONGITUDE_DEG, max_longitude_deg=MAX_LONGITUDE_DEG, model_name=nwp_model_utils.NARR_MODEL_NAME)) valid_time_unix_sec = time_conversion.string_to_unix_sec( valid_time_string, DEFAULT_TIME_FORMAT) front_file_name = fronts_io.find_file_for_one_time( top_directory_name=TOP_FRONT_DIR_NAME, file_type=fronts_io.POLYLINE_FILE_TYPE, valid_time_unix_sec=valid_time_unix_sec) print 'Reading data from: "{0:s}"...'.format(front_file_name) front_line_table = fronts_io.read_polylines_from_file(front_file_name) num_narr_fields = len(NARR_FIELD_NAMES) narr_matrix_by_field = [numpy.array([])] * num_narr_fields for j in range(num_narr_fields): this_file_name = processed_narr_io.find_file_for_one_time( top_directory_name=TOP_NARR_DIRECTORY_NAME, field_name=NARR_FIELD_NAMES[j], pressure_level_mb=pressure_level_mb, valid_time_unix_sec=valid_time_unix_sec) print 'Reading data from: "{0:s}"...'.format(this_file_name) narr_matrix_by_field[j] = processed_narr_io.read_fields_from_file( this_file_name)[0][0, ...] narr_matrix_by_field[j] = utils.fill_nans(narr_matrix_by_field[j]) narr_matrix_by_field[j] = narr_matrix_by_field[j][narr_row_limits[0]:( narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1)] if NARR_FIELD_NAMES[j] == processed_narr_io.WET_BULB_THETA_NAME: narr_matrix_by_field[j] = (narr_matrix_by_field[j] - ZERO_CELSIUS_IN_KELVINS) _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=narr_row_limits[0], last_row_in_full_grid=narr_row_limits[1], first_column_in_full_grid=narr_column_limits[0], last_column_in_full_grid=narr_column_limits[1]) plotting_utils.plot_coastlines(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_countries(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_states_and_provinces(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_parallels(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) for j in range(num_narr_fields): if NARR_FIELD_NAMES[j] in WIND_FIELD_NAMES: continue min_colour_value = numpy.percentile(narr_matrix_by_field[j], MIN_COLOUR_PERCENTILE) max_colour_value = numpy.percentile(narr_matrix_by_field[j], MAX_COLOUR_PERCENTILE) nwp_plotting.plot_subgrid( field_matrix=narr_matrix_by_field[j], model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, colour_map=THERMAL_COLOUR_MAP_OBJECT, min_value_in_colour_map=min_colour_value, max_value_in_colour_map=max_colour_value, first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0]) plotting_utils.add_linear_colour_bar( axes_object_or_list=axes_object, values_to_colour=narr_matrix_by_field[j], colour_map=THERMAL_COLOUR_MAP_OBJECT, colour_min=min_colour_value, colour_max=max_colour_value, orientation='horizontal', extend_min=True, extend_max=True, fraction_of_axis_length=0.9) this_cos_matrix = narr_rotation_cos_matrix[narr_row_limits[0]:( narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1)] this_sin_matrix = narr_rotation_sin_matrix[narr_row_limits[0]:( narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1)] u_wind_index = NARR_FIELD_NAMES.index( processed_narr_io.U_WIND_GRID_RELATIVE_NAME) v_wind_index = NARR_FIELD_NAMES.index( processed_narr_io.V_WIND_GRID_RELATIVE_NAME) narr_matrix_by_field[u_wind_index], narr_matrix_by_field[v_wind_index] = ( nwp_model_utils.rotate_winds_to_earth_relative( u_winds_grid_relative_m_s01=narr_matrix_by_field[u_wind_index], v_winds_grid_relative_m_s01=narr_matrix_by_field[v_wind_index], rotation_angle_cosines=this_cos_matrix, rotation_angle_sines=this_sin_matrix)) nwp_plotting.plot_wind_barbs_on_subgrid( u_wind_matrix_m_s01=narr_matrix_by_field[u_wind_index], v_wind_matrix_m_s01=narr_matrix_by_field[v_wind_index], model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0], plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB, plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB, barb_length=WIND_BARB_LENGTH, empty_barb_radius=EMPTY_WIND_BARB_RADIUS, fill_empty_barb=False, colour_map=WIND_COLOUR_MAP_OBJECT, colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT, colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT) num_fronts = len(front_line_table.index) for i in range(num_fronts): this_front_type_string = front_line_table[ front_utils.FRONT_TYPE_COLUMN].values[i] if this_front_type_string == front_utils.WARM_FRONT_STRING_ID: this_colour = WARM_FRONT_COLOUR else: this_colour = COLD_FRONT_COLOUR front_plotting.plot_front_with_markers( line_latitudes_deg=front_line_table[ front_utils.LATITUDES_COLUMN].values[i], line_longitudes_deg=front_line_table[ front_utils.LONGITUDES_COLUMN].values[i], axes_object=axes_object, basemap_object=basemap_object, front_type_string=front_line_table[ front_utils.FRONT_TYPE_COLUMN].values[i], marker_colour=this_colour) pyplot.title(title_string) plotting_utils.annotate_axes(axes_object=axes_object, annotation_string=annotation_string) file_system_utils.mkdir_recursive_if_necessary( directory_name=OUTPUT_DIR_NAME) figure_file_name = '{0:s}/fronts_{1:04d}mb_{2:s}.jpg'.format( OUTPUT_DIR_NAME, pressure_level_mb, valid_time_string) print 'Saving figure to: "{0:s}"...'.format(figure_file_name) pyplot.savefig(figure_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=figure_file_name, output_file_name=figure_file_name) return figure_file_name
def _run(): """Plots performance diagram on testing data. This is effectively the main method. """ _, axes_object = pyplot.subplots( 1, 1, figsize=(FIGURE_WIDTH_INCHES, FIGURE_HEIGHT_INCHES) ) model_eval_plotting.plot_performance_diagram( axes_object=axes_object, pod_by_threshold=numpy.full(2, numpy.nan), success_ratio_by_threshold=numpy.full(2, numpy.nan) ) num_datasets = len(METHOD_NAME_BY_DATASET) for i in range(num_datasets): this_file_name = '{0:s}/obe_{1:d}km_min.p'.format( METHOD_NAME_TO_DIRECTORY[METHOD_NAME_BY_DATASET[i]], MATCHING_DIST_BY_DATASET_KM[i] ) print 'Reading data from: "{0:s}"...'.format(this_file_name) this_evaluation_dict = object_eval.read_evaluation_results( this_file_name) this_min_pod = this_evaluation_dict[object_eval.BINARY_POD_KEY] this_min_success_ratio = this_evaluation_dict[ object_eval.BINARY_SUCCESS_RATIO_KEY] this_file_name = '{0:s}/obe_{1:d}km_max.p'.format( METHOD_NAME_TO_DIRECTORY[METHOD_NAME_BY_DATASET[i]], MATCHING_DIST_BY_DATASET_KM[i] ) print 'Reading data from: "{0:s}"...'.format(this_file_name) this_evaluation_dict = object_eval.read_evaluation_results( this_file_name) this_max_pod = this_evaluation_dict[object_eval.BINARY_POD_KEY] this_max_success_ratio = this_evaluation_dict[ object_eval.BINARY_SUCCESS_RATIO_KEY] this_file_name = '{0:s}/obe_{1:d}km_mean.p'.format( METHOD_NAME_TO_DIRECTORY[METHOD_NAME_BY_DATASET[i]], MATCHING_DIST_BY_DATASET_KM[i] ) print 'Reading data from: "{0:s}"...'.format(this_file_name) this_evaluation_dict = object_eval.read_evaluation_results( this_file_name) this_mean_pod = this_evaluation_dict[object_eval.BINARY_POD_KEY] this_mean_success_ratio = this_evaluation_dict[ object_eval.BINARY_SUCCESS_RATIO_KEY] these_x_errors = numpy.array([ this_mean_success_ratio - this_min_success_ratio, this_max_success_ratio - this_mean_success_ratio ]) these_y_errors = numpy.array([ this_mean_pod - this_min_pod, this_max_pod - this_mean_pod ]) these_x_errors = numpy.reshape(these_x_errors, (these_x_errors.size, 1)) these_y_errors = numpy.reshape(these_y_errors, (these_y_errors.size, 1)) axes_object.errorbar( this_mean_success_ratio, this_mean_pod, xerr=these_x_errors, yerr=these_y_errors, ecolor=METHOD_NAME_TO_COLOUR[METHOD_NAME_BY_DATASET[i]], elinewidth=LINE_WIDTH, capsize=ERROR_BAR_CAP_SIZE, capthick=LINE_WIDTH) this_label_string = '{0:s} ({1:d} km)'.format( METHOD_NAME_BY_DATASET[i], MATCHING_DIST_BY_DATASET_KM[i]) this_x_coord = this_mean_success_ratio + 0.01 this_horiz_alignment_string = 'left' if METHOD_NAME_BY_DATASET[i] == CNN_METHOD_NAME: this_y_coord = this_mean_pod + 0.01 this_vert_alignment_string = 'bottom' else: this_y_coord = this_mean_pod - 0.01 this_vert_alignment_string = 'top' if MATCHING_DIST_BY_DATASET_KM[i] == 250: this_x_coord = this_mean_success_ratio - 0.01 this_horiz_alignment_string = 'right' axes_object.text( this_x_coord, this_y_coord, this_label_string, fontsize=FONT_SIZE, fontweight='bold', color=METHOD_NAME_TO_COLOUR[METHOD_NAME_BY_DATASET[i]], horizontalalignment=this_horiz_alignment_string, verticalalignment=this_vert_alignment_string, zorder=1e6) file_system_utils.mkdir_recursive_if_necessary(file_name=OUTPUT_FILE_NAME) print 'Saving figure to: "{0:s}"...'.format(OUTPUT_FILE_NAME) pyplot.savefig(OUTPUT_FILE_NAME, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=OUTPUT_FILE_NAME, output_file_name=OUTPUT_FILE_NAME)
def _add_colour_bar(figure_file_name, colour_map_object, max_colour_value, temporary_dir_name): """Adds colour bar to saved image file. :param figure_file_name: Path to saved image file. Colour bar will be added to this image. :param colour_map_object: Colour scheme (instance of `matplotlib.pyplot.cm` or similar). :param max_colour_value: Max value in colour scheme. :param temporary_dir_name: Name of temporary output directory. """ this_image_matrix = Image.open(figure_file_name) figure_width_px, figure_height_px = this_image_matrix.size figure_width_inches = float(figure_width_px) / FIGURE_RESOLUTION_DPI figure_height_inches = float(figure_height_px) / FIGURE_RESOLUTION_DPI extra_figure_object, extra_axes_object = pyplot.subplots( 1, 1, figsize=(figure_width_inches, figure_height_inches)) extra_axes_object.axis('off') dummy_values = numpy.array([0., max_colour_value]) colour_bar_object = plotting_utils.plot_linear_colour_bar( axes_object_or_matrix=extra_axes_object, data_matrix=dummy_values, colour_map_object=colour_map_object, min_value=0., max_value=max_colour_value, orientation_string='vertical', fraction_of_axis_length=1.25, extend_min=False, extend_max=True, font_size=COLOUR_BAR_FONT_SIZE, aspect_ratio=50.) tick_values = colour_bar_object.get_ticks() if max_colour_value <= 0.005: tick_strings = ['{0:.4f}'.format(v) for v in tick_values] elif max_colour_value <= 0.05: tick_strings = ['{0:.3f}'.format(v) for v in tick_values] else: tick_strings = ['{0:.2f}'.format(v) for v in tick_values] colour_bar_object.set_ticks(tick_values) colour_bar_object.set_ticklabels(tick_strings) extra_file_name = '{0:s}/saliency_colour-bar.jpg'.format( temporary_dir_name) print('Saving colour bar to: "{0:s}"...'.format(extra_file_name)) extra_figure_object.savefig(extra_file_name, dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(extra_figure_object) print('Concatenating colour bar to: "{0:s}"...'.format(figure_file_name)) imagemagick_utils.concatenate_images( input_file_names=[figure_file_name, extra_file_name], output_file_name=figure_file_name, num_panel_rows=1, num_panel_columns=2, extra_args_string='-gravity Center') os.remove(extra_file_name) imagemagick_utils.trim_whitespace(input_file_name=figure_file_name, output_file_name=figure_file_name)
def _plot_predictions_one_time( output_file_name, title_string, annotation_string, predicted_label_matrix=None, class_probability_matrix=None, plot_warm_colour_bar=True, plot_cold_colour_bar=True): """Plots predictions (objects or probability grid) for one valid time. :param output_file_name: Path to output file (figure will be saved here). :param title_string: Title (will be placed above figure). :param annotation_string: Text annotation (will be placed in top left of figure). :param predicted_label_matrix: See doc for `target_matrix` in `machine_learning_utils.write_gridded_predictions`. :param class_probability_matrix: [used iff `predicted_label_matrix is None`] See doc for `machine_learning_utils.write_gridded_predictions`. :param plot_warm_colour_bar: [used iff `predicted_label_matrix is None`] Boolean flag, indicating whether or not to plot colour bar for warm- front probability. :param plot_cold_colour_bar: Same but for cold-front probability. """ (narr_row_limits, narr_column_limits ) = nwp_plotting.latlng_limits_to_rowcol_limits( min_latitude_deg=MIN_LATITUDE_DEG, max_latitude_deg=MAX_LATITUDE_DEG, min_longitude_deg=MIN_LONGITUDE_DEG, max_longitude_deg=MAX_LONGITUDE_DEG, model_name=nwp_model_utils.NARR_MODEL_NAME) _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=narr_row_limits[0], last_row_in_full_grid=narr_row_limits[1], first_column_in_full_grid=narr_column_limits[0], last_column_in_full_grid=narr_column_limits[1]) plotting_utils.plot_coastlines( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_countries( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_states_and_provinces( basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_parallels( basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians( basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) if class_probability_matrix is None: this_matrix = predicted_label_matrix[ 0, narr_row_limits[0]:(narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1) ] front_plotting.plot_narr_grid( frontal_grid_matrix=this_matrix, axes_object=axes_object, basemap_object=basemap_object, first_row_in_narr_grid=narr_row_limits[0], first_column_in_narr_grid=narr_column_limits[0], opacity=DETERMINISTIC_OPACITY) else: this_matrix = class_probability_matrix[ 0, narr_row_limits[0]:(narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1), front_utils.WARM_FRONT_INTEGER_ID ] prediction_plotting.plot_narr_grid( probability_matrix=this_matrix, front_string_id=front_utils.WARM_FRONT_STRING_ID, axes_object=axes_object, basemap_object=basemap_object, first_row_in_narr_grid=narr_row_limits[0], first_column_in_narr_grid=narr_column_limits[0], opacity=PROBABILISTIC_OPACITY) this_matrix = class_probability_matrix[ 0, narr_row_limits[0]:(narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1), front_utils.COLD_FRONT_INTEGER_ID ] prediction_plotting.plot_narr_grid( probability_matrix=this_matrix, front_string_id=front_utils.COLD_FRONT_STRING_ID, axes_object=axes_object, basemap_object=basemap_object, first_row_in_narr_grid=narr_row_limits[0], first_column_in_narr_grid=narr_column_limits[0], opacity=PROBABILISTIC_OPACITY) if plot_warm_colour_bar: (this_colour_map_object, this_colour_norm_object ) = prediction_plotting.get_warm_front_colour_map()[:2] plotting_utils.add_colour_bar( axes_object_or_list=axes_object, colour_map=this_colour_map_object, colour_norm_object=this_colour_norm_object, values_to_colour=class_probability_matrix[ ..., front_utils.WARM_FRONT_INTEGER_ID], orientation='vertical', extend_min=True, extend_max=False, fraction_of_axis_length=LENGTH_FRACTION_FOR_PROB_COLOUR_BAR) if plot_cold_colour_bar: (this_colour_map_object, this_colour_norm_object ) = prediction_plotting.get_cold_front_colour_map()[:2] plotting_utils.add_colour_bar( axes_object_or_list=axes_object, colour_map=this_colour_map_object, colour_norm_object=this_colour_norm_object, values_to_colour=class_probability_matrix[ ..., front_utils.COLD_FRONT_INTEGER_ID], orientation='vertical', extend_min=True, extend_max=False, fraction_of_axis_length=LENGTH_FRACTION_FOR_PROB_COLOUR_BAR) pyplot.title(title_string) plotting_utils.annotate_axes( axes_object=axes_object, annotation_string=annotation_string) print 'Saving figure to: "{0:s}"...'.format(output_file_name) file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace( input_file_name=output_file_name, output_file_name=output_file_name)
def plot_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 _plot_predictions(predicted_label_matrix, title_string, annotation_string, output_file_name): """Plots predicted front locations. :param predicted_label_matrix: See doc for `target_matrix` in `machine_learning_utils.write_gridded_predictions`. :param title_string: Title (will be placed above figure). :param annotation_string: Text annotation (will be placed in top left of figure). :param output_file_name: Path to output file (figure will be saved here). """ (narr_row_limits, narr_column_limits) = nwp_plotting.latlng_limits_to_rowcol_limits( min_latitude_deg=MIN_LATITUDE_DEG, max_latitude_deg=MAX_LATITUDE_DEG, min_longitude_deg=MIN_LONGITUDE_DEG, max_longitude_deg=MAX_LONGITUDE_DEG, model_name=nwp_model_utils.NARR_MODEL_NAME) _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=narr_row_limits[0], last_row_in_full_grid=narr_row_limits[1], first_column_in_full_grid=narr_column_limits[0], last_column_in_full_grid=narr_column_limits[1]) plotting_utils.plot_coastlines(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_countries(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_states_and_provinces(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_parallels(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) this_matrix = predicted_label_matrix[0, narr_row_limits[0]:( narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1)] front_plotting.plot_narr_grid( frontal_grid_matrix=this_matrix, axes_object=axes_object, basemap_object=basemap_object, first_row_in_narr_grid=narr_row_limits[0], first_column_in_narr_grid=narr_column_limits[0], opacity=1.) pyplot.title(title_string) plotting_utils.annotate_axes(axes_object=axes_object, annotation_string=annotation_string) print 'Saving figure to: "{0:s}"...'.format(output_file_name) file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _plot_narr_fields( wet_bulb_theta_matrix_kelvins, u_wind_matrix_m_s01, v_wind_matrix_m_s01, title_string, annotation_string, output_file_name): """Plots NARR fields. M = number of rows in grid N = number of columns in grid :param wet_bulb_theta_matrix_kelvins: M-by-N numpy array of wet-bulb potential temperatures. :param u_wind_matrix_m_s01: M-by-N numpy array of u-wind components (metres per second). :param v_wind_matrix_m_s01: Same but for v-wind. :param title_string: Title (will be placed above figure). :param annotation_string: Text annotation (will be placed in top left of figure). :param output_file_name: Path to output file (figure will be saved here). """ (narr_row_limits, narr_column_limits, axes_object, basemap_object ) = _init_basemap(BORDER_COLOUR) wet_bulb_theta_matrix_to_plot = wet_bulb_theta_matrix_kelvins[ narr_row_limits[0]:(narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1) ] - ZERO_CELSIUS_IN_KELVINS u_wind_matrix_to_plot = u_wind_matrix_m_s01[ narr_row_limits[0]:(narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1) ] v_wind_matrix_to_plot = v_wind_matrix_m_s01[ narr_row_limits[0]:(narr_row_limits[1] + 1), narr_column_limits[0]:(narr_column_limits[1] + 1) ] nwp_plotting.plot_subgrid( field_matrix=wet_bulb_theta_matrix_to_plot, model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, colour_map=THERMAL_COLOUR_MAP_OBJECT, min_value_in_colour_map=numpy.nanpercentile( wet_bulb_theta_matrix_to_plot, MIN_COLOUR_PERCENTILE), max_value_in_colour_map=numpy.nanpercentile( wet_bulb_theta_matrix_to_plot, MAX_COLOUR_PERCENTILE), first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0]) plotting_utils.add_linear_colour_bar( axes_object_or_list=axes_object, values_to_colour=wet_bulb_theta_matrix_to_plot, colour_map=THERMAL_COLOUR_MAP_OBJECT, colour_min=numpy.nanpercentile( wet_bulb_theta_matrix_to_plot, MIN_COLOUR_PERCENTILE), colour_max=numpy.nanpercentile( wet_bulb_theta_matrix_to_plot, MAX_COLOUR_PERCENTILE), orientation='vertical', extend_min=True, extend_max=True, fraction_of_axis_length=COLOUR_BAR_LENGTH_FRACTION) nwp_plotting.plot_wind_barbs_on_subgrid( u_wind_matrix_m_s01=u_wind_matrix_to_plot, v_wind_matrix_m_s01=v_wind_matrix_to_plot, model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, first_row_in_full_grid=narr_row_limits[0], first_column_in_full_grid=narr_column_limits[0], plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB, plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB, barb_length=WIND_BARB_LENGTH, empty_barb_radius=EMPTY_WIND_BARB_RADIUS, fill_empty_barb=False, colour_map=WIND_COLOUR_MAP_OBJECT, colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT, colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT) pyplot.title(title_string) plotting_utils.annotate_axes( axes_object=axes_object, annotation_string=annotation_string) print 'Saving figure to: "{0:s}"...'.format(output_file_name) pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=output_file_name, output_file_name=output_file_name)
def _plot_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 _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 _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, composite_names, colour_map_name, max_colour_values, half_num_contours, smoothing_radius_grid_cells, output_dir_name): """Makes figure with saliency maps for MYRORSS model. This is effectively the main method. :param saliency_file_names: See documentation at top of file. :param composite_names: Same. :param colour_map_name: Same. :param max_colour_values: Same. :param half_num_contours: Same. :param smoothing_radius_grid_cells: Same. :param output_dir_name: Same. """ # Process input args. file_system_utils.mkdir_recursive_if_necessary( directory_name=output_dir_name) if smoothing_radius_grid_cells <= 0: smoothing_radius_grid_cells = None colour_map_object = pyplot.cm.get_cmap(colour_map_name) error_checking.assert_is_geq(half_num_contours, 5) num_composites = len(saliency_file_names) expected_dim = numpy.array([num_composites], dtype=int) error_checking.assert_is_numpy_array(numpy.array(composite_names), exact_dimensions=expected_dim) max_colour_values[max_colour_values <= 0] = numpy.nan error_checking.assert_is_numpy_array(max_colour_values, exact_dimensions=expected_dim) composite_names_abbrev = [ n.replace('_', '-').lower() for n in composite_names ] composite_names_verbose = [ '({0:s}) {1:s}'.format(chr(ord('a') + i), composite_names[i].replace('_', ' ')) for i in range(num_composites) ] panel_file_names = [None] * num_composites for i in range(num_composites): panel_file_names[i], max_colour_values[i] = _plot_one_composite( saliency_file_name=saliency_file_names[i], composite_name_abbrev=composite_names_abbrev[i], composite_name_verbose=composite_names_verbose[i], colour_map_object=colour_map_object, max_colour_value=max_colour_values[i], half_num_contours=half_num_contours, smoothing_radius_grid_cells=smoothing_radius_grid_cells, output_dir_name=output_dir_name) _add_colour_bar(figure_file_name=panel_file_names[i], colour_map_object=colour_map_object, max_colour_value=max_colour_values[i], temporary_dir_name=output_dir_name) print('\n') figure_file_name = '{0:s}/saliency_concat.jpg'.format(output_dir_name) print('Concatenating panels to: "{0:s}"...'.format(figure_file_name)) num_panel_rows = int(numpy.floor(numpy.sqrt(num_composites))) num_panel_columns = int(numpy.ceil(float(num_composites) / num_panel_rows)) imagemagick_utils.concatenate_images(input_file_names=panel_file_names, output_file_name=figure_file_name, border_width_pixels=25, num_panel_rows=num_panel_rows, num_panel_columns=num_panel_columns) imagemagick_utils.trim_whitespace(input_file_name=figure_file_name, output_file_name=figure_file_name, border_width_pixels=10)
def _run(): """Plots input example. This is effectively the main method. :return: figure_file_name: Path to output file (where the figure was saved). """ valid_time_unix_sec = time_conversion.string_to_unix_sec( VALID_TIME_STRING, TIME_FORMAT) front_file_name = fronts_io.find_file_for_one_time( top_directory_name=TOP_FRONT_DIR_NAME, file_type=fronts_io.POLYLINE_FILE_TYPE, valid_time_unix_sec=valid_time_unix_sec) print 'Reading data from: "{0:s}"...'.format(front_file_name) front_line_table = fronts_io.read_polylines_from_file(front_file_name) num_narr_fields = len(NARR_FIELD_NAMES) narr_matrix_by_field = [numpy.array([])] * num_narr_fields for j in range(num_narr_fields): if NARR_FIELD_NAMES[j] in WIND_FIELD_NAMES: this_directory_name = '{0:s}/earth_relative_wind'.format( TOP_NARR_DIRECTORY_NAME) else: this_directory_name = TOP_NARR_DIRECTORY_NAME + '' this_file_name = processed_narr_io.find_file_for_one_time( top_directory_name=this_directory_name, field_name=NARR_FIELD_NAMES[j], pressure_level_mb=PRESSURE_LEVEL_MB, valid_time_unix_sec=valid_time_unix_sec) print 'Reading data from: "{0:s}"...'.format(this_file_name) narr_matrix_by_field[j] = processed_narr_io.read_fields_from_file( this_file_name)[0][0, ...] narr_matrix_by_field[j] = utils.fill_nans(narr_matrix_by_field[j]) if NARR_FIELD_NAMES[j] == processed_narr_io.WET_BULB_THETA_NAME: narr_matrix_by_field[j] = (narr_matrix_by_field[j] - ZERO_CELSIUS_IN_KELVINS) # (_, front_centroid_latitude_deg, front_centroid_longitude_deg # ) = _find_nearest_front( # front_line_table=front_line_table, # query_latitude_deg=APPROX_FRONT_LATITUDE_DEG, # query_longitude_deg=APPROX_FRONT_LONGITUDE_DEG) front_centroid_latitude_deg = APPROX_FRONT_LATITUDE_DEG + 0. front_centroid_longitude_deg = APPROX_FRONT_LONGITUDE_DEG + 0. projection_object = nwp_model_utils.init_model_projection( nwp_model_utils.NARR_MODEL_NAME) these_x_metres, these_y_metres = nwp_model_utils.project_latlng_to_xy( latitudes_deg=numpy.array([front_centroid_latitude_deg]), longitudes_deg=numpy.array([front_centroid_longitude_deg]), projection_object=projection_object, model_name=nwp_model_utils.NARR_MODEL_NAME) front_centroid_x_metres = these_x_metres[0] front_centroid_y_metres = these_y_metres[0] grid_spacing_metres, _ = nwp_model_utils.get_xy_grid_spacing( model_name=nwp_model_utils.NARR_MODEL_NAME) center_narr_row_index = int( numpy.round(front_centroid_y_metres / grid_spacing_metres)) center_narr_column_index = int( numpy.round(front_centroid_x_metres / grid_spacing_metres)) first_narr_row_index = center_narr_row_index - NUM_ROWS_IN_HALF_GRID last_narr_row_index = center_narr_row_index + NUM_ROWS_IN_HALF_GRID first_narr_column_index = (center_narr_column_index - NUM_COLUMNS_IN_HALF_GRID) last_narr_column_index = center_narr_column_index + NUM_COLUMNS_IN_HALF_GRID for j in range(num_narr_fields): narr_matrix_by_field[j] = narr_matrix_by_field[j][ first_narr_row_index:(last_narr_row_index + 1), first_narr_column_index:(last_narr_column_index + 1)] _, axes_object, basemap_object = nwp_plotting.init_basemap( model_name=nwp_model_utils.NARR_MODEL_NAME, first_row_in_full_grid=first_narr_row_index, last_row_in_full_grid=last_narr_row_index, first_column_in_full_grid=first_narr_column_index, last_column_in_full_grid=last_narr_column_index, resolution_string='i') plotting_utils.plot_coastlines(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_countries(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_states_and_provinces(basemap_object=basemap_object, axes_object=axes_object, line_colour=BORDER_COLOUR) plotting_utils.plot_parallels(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lat_deg=-90., upper_right_lat_deg=90., parallel_spacing_deg=PARALLEL_SPACING_DEG) plotting_utils.plot_meridians(basemap_object=basemap_object, axes_object=axes_object, bottom_left_lng_deg=0., upper_right_lng_deg=360., meridian_spacing_deg=MERIDIAN_SPACING_DEG) for j in range(num_narr_fields): if NARR_FIELD_NAMES[j] in WIND_FIELD_NAMES: continue min_colour_value = numpy.percentile(narr_matrix_by_field[j], MIN_COLOUR_PERCENTILE) max_colour_value = numpy.percentile(narr_matrix_by_field[j], MAX_COLOUR_PERCENTILE) nwp_plotting.plot_subgrid( field_matrix=narr_matrix_by_field[j], model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, colour_map=THERMAL_COLOUR_MAP_OBJECT, min_value_in_colour_map=min_colour_value, max_value_in_colour_map=max_colour_value, first_row_in_full_grid=first_narr_row_index, first_column_in_full_grid=first_narr_column_index) plotting_utils.add_linear_colour_bar( axes_object_or_list=axes_object, values_to_colour=narr_matrix_by_field[j], colour_map=THERMAL_COLOUR_MAP_OBJECT, colour_min=min_colour_value, colour_max=max_colour_value, orientation='horizontal', extend_min=True, extend_max=True) u_wind_index = NARR_FIELD_NAMES.index( processed_narr_io.U_WIND_EARTH_RELATIVE_NAME) v_wind_index = NARR_FIELD_NAMES.index( processed_narr_io.V_WIND_EARTH_RELATIVE_NAME) nwp_plotting.plot_wind_barbs_on_subgrid( u_wind_matrix_m_s01=narr_matrix_by_field[u_wind_index], v_wind_matrix_m_s01=narr_matrix_by_field[v_wind_index], model_name=nwp_model_utils.NARR_MODEL_NAME, axes_object=axes_object, basemap_object=basemap_object, first_row_in_full_grid=first_narr_row_index, first_column_in_full_grid=first_narr_column_index, plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB, plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB, barb_length=WIND_BARB_LENGTH, empty_barb_radius=EMPTY_WIND_BARB_RADIUS, colour_map=WIND_COLOUR_MAP_OBJECT, colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT, colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT) num_fronts = len(front_line_table.index) for i in range(num_fronts): this_front_type_string = front_line_table[ front_utils.FRONT_TYPE_COLUMN].values[i] if this_front_type_string == front_utils.WARM_FRONT_STRING_ID: this_colour = WARM_FRONT_COLOUR else: this_colour = COLD_FRONT_COLOUR # front_plotting.plot_polyline( # latitudes_deg=front_line_table[ # front_utils.LATITUDES_COLUMN].values[i], # longitudes_deg=front_line_table[ # front_utils.LONGITUDES_COLUMN].values[i], # basemap_object=basemap_object, axes_object=axes_object, # front_type=front_line_table[ # front_utils.FRONT_TYPE_COLUMN].values[i], # line_width=FRONT_LINE_WIDTH, line_colour=this_colour) print 'Saving figure to: "{0:s}"...'.format(OUTPUT_FILE_NAME) file_system_utils.mkdir_recursive_if_necessary(file_name=OUTPUT_FILE_NAME) pyplot.savefig(OUTPUT_FILE_NAME, dpi=OUTPUT_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=OUTPUT_FILE_NAME, output_file_name=OUTPUT_FILE_NAME)
def _plot_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 _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 _plot_feature_map_before_conv(): """Plots original feature map (before convolution). M = number of rows in grid N = number of columns in grid :return: feature_matrix: Feature map as M-by-N numpy array. """ feature_matrix = numpy.random.random_integers( low=MIN_FEATURE_VALUE, high=MAX_FEATURE_VALUE, size=(NUM_ROWS_BEFORE_POOLING, NUM_COLUMNS_BEFORE_POOLING)) dummy_matrix = numpy.full( (NUM_ROWS_BEFORE_POOLING, NUM_COLUMNS_BEFORE_POOLING), numpy.nan) dummy_matrix[:3, :3] = HIGHLIGHTED_VALUE dummy_matrix = numpy.ma.masked_where(numpy.isnan(dummy_matrix), dummy_matrix) _, axes_object = pyplot.subplots(1, 1, figsize=(FIGURE_WIDTH_INCHES, FIGURE_HEIGHT_INCHES)) pyplot.imshow(dummy_matrix, cmap=COLOUR_MAP_OBJECT, vmin=HIGHLIGHTED_VALUE - 1, vmax=HIGHLIGHTED_VALUE, axes=axes_object, origin='upper') pyplot.xticks([], []) pyplot.yticks([], []) for i in range(feature_matrix.shape[1]): for j in range(feature_matrix.shape[0]): if i == j == 1: this_colour = SPECIAL_COLOUR + 0. else: this_colour = MAIN_COLOUR + 0. axes_object.text(i, j, '{0:d}'.format(feature_matrix[j, i]), fontsize=OVERLAY_FONT_SIZE, color=this_colour, horizontalalignment='center', verticalalignment='center') # polygon_x_coords = numpy.array([0, 3, 3, 0, 0], dtype=float) - 0.5 # polygon_y_coords = numpy.array([3, 3, 0, 0, 3], dtype=float) - 0.5 # axes_object.plot( # polygon_x_coords, polygon_y_coords, color=LINE_COLOUR, # linewidth=LINE_WIDTH) plotting_utils.annotate_axes(axes_object=axes_object, annotation_string='(a)', font_colour=ANNOTATION_COLOUR) print 'Saving figure to: "{0:s}"...'.format(BEFORE_CONV_FILE_NAME) file_system_utils.mkdir_recursive_if_necessary( file_name=BEFORE_CONV_FILE_NAME) pyplot.savefig(BEFORE_CONV_FILE_NAME, dpi=OUTPUT_RESOLUTION_DPI) pyplot.close() imagemagick_utils.trim_whitespace(input_file_name=BEFORE_CONV_FILE_NAME, output_file_name=BEFORE_CONV_FILE_NAME) return feature_matrix
def _run(include_caption, output_dir_name): """Makes animation to explain multivariate convolution. This is effectively the main method. :param include_caption: See documentation at top of file. :param output_dir_name: Same. """ file_system_utils.mkdir_recursive_if_necessary( directory_name=output_dir_name) output_feature_matrix = standalone_utils.do_2d_convolution( feature_matrix=INPUT_FEATURE_MATRIX, kernel_matrix=KERNEL_MATRIX, pad_edges=True, stride_length_px=1) output_feature_matrix = output_feature_matrix[0, ..., 0] num_grid_rows = INPUT_FEATURE_MATRIX.shape[0] num_grid_columns = INPUT_FEATURE_MATRIX.shape[1] num_input_channels = INPUT_FEATURE_MATRIX.shape[2] image_file_names = [] kernel_width_ratio = float(KERNEL_MATRIX.shape[1]) / num_grid_columns kernel_height_ratio = float(KERNEL_MATRIX.shape[0]) / num_grid_rows for i in range(num_grid_rows): for j in range(num_grid_columns): this_figure_object, this_axes_object_matrix = ( plotting_utils.create_paneled_figure( num_rows=NUM_PANEL_ROWS, num_columns=NUM_PANEL_COLUMNS, horizontal_spacing=0.2, vertical_spacing=0., shared_x_axis=False, shared_y_axis=False, keep_aspect_ratio=True)) this_axes_object_matrix[0, 2].axis('off') this_axes_object_matrix[2, 2].axis('off') letter_label = None for k in range(num_input_channels): _plot_feature_map(feature_matrix_2d=INPUT_FEATURE_MATRIX[..., k], kernel_row=i, kernel_column=j, is_output_map=False, axes_object=this_axes_object_matrix[k, 0]) if letter_label is None: letter_label = 'a' else: letter_label = chr(ord(letter_label) + 1) plotting_utils.label_axes( axes_object=this_axes_object_matrix[k, 0], label_string='({0:s})'.format(letter_label), font_size=PANEL_LETTER_FONT_SIZE, y_coord_normalized=1.04, x_coord_normalized=0.1) _plot_feature_map(feature_matrix_2d=output_feature_matrix, kernel_row=i, kernel_column=j, is_output_map=True, axes_object=this_axes_object_matrix[1, 2]) for k in range(num_input_channels): this_bbox_object = this_axes_object_matrix[k, 1].get_position() this_width = kernel_width_ratio * (this_bbox_object.x1 - this_bbox_object.x0) this_height = kernel_height_ratio * (this_bbox_object.y1 - this_bbox_object.y0) this_bbox_object.x0 += 0.5 * this_width this_bbox_object.y0 += 0.005 this_bbox_object.x1 = this_bbox_object.x0 + this_width this_bbox_object.y1 = this_bbox_object.y0 + this_height this_axes_object_matrix[k, 1].set_position(this_bbox_object) _plot_kernel(kernel_matrix_2d=KERNEL_MATRIX[..., k, 0], feature_matrix_2d=INPUT_FEATURE_MATRIX[..., k], feature_row_at_center=i, feature_column_at_center=j, axes_object=this_axes_object_matrix[k, 1]) letter_label = chr(ord(letter_label) + 1) plotting_utils.label_axes( axes_object=this_axes_object_matrix[k, 1], label_string='({0:s})'.format(letter_label), font_size=PANEL_LETTER_FONT_SIZE, y_coord_normalized=1.04, x_coord_normalized=0.2) _plot_feature_to_kernel_lines( kernel_matrix_2d=KERNEL_MATRIX[..., k, 0], feature_matrix_2d=INPUT_FEATURE_MATRIX[..., k], feature_row_at_center=i, feature_column_at_center=j, kernel_axes_object=this_axes_object_matrix[k, 1], feature_axes_object=this_axes_object_matrix[k, 0]) letter_label = chr(ord(letter_label) + 1) plotting_utils.label_axes( axes_object=this_axes_object_matrix[1, 2], label_string='({0:s})'.format(letter_label), font_size=PANEL_LETTER_FONT_SIZE, y_coord_normalized=1.04, x_coord_normalized=0.1) if include_caption: this_figure_object.text(0.5, 0., FIGURE_CAPTION, fontsize=DEFAULT_FONT_SIZE, color='k', horizontalalignment='center', verticalalignment='top') image_file_names.append( '{0:s}/conv_animation_row{1:d}_column{2:d}.jpg'.format( output_dir_name, i, j)) print('Saving figure to: "{0:s}"...'.format(image_file_names[-1])) this_figure_object.savefig(image_file_names[-1], dpi=FIGURE_RESOLUTION_DPI, pad_inches=0, bbox_inches='tight') pyplot.close(this_figure_object) imagemagick_utils.trim_whitespace( input_file_name=image_file_names[-1], output_file_name=image_file_names[-1]) animation_file_name = '{0:s}/conv_animation.gif'.format(output_dir_name) print('Creating animation: "{0:s}"...'.format(animation_file_name)) imagemagick_utils.create_gif(input_file_names=image_file_names, output_file_name=animation_file_name, num_seconds_per_frame=0.5, resize_factor=0.5)