예제 #1
0
def interp_temperature_sfc_from_nwp(
        radar_grid_point_lats_deg=None, radar_grid_point_lngs_deg=None,
        unix_time_sec=None, temperature_kelvins=None, model_name=None,
        grid_id=None, top_grib_directory_name=None,
        wgrib_exe_name=grib_io.WGRIB_EXE_NAME_DEFAULT,
        wgrib2_exe_name=grib_io.WGRIB2_EXE_NAME_DEFAULT):
    """Interpolates temperature isosurface from NWP model.

    M = number of rows (unique grid-point latitudes) in radar grid
    N = number of columns (unique grid-point longitudes) in radar grid

    :param radar_grid_point_lats_deg: length-M numpy array of grid-point
        latitudes (deg N).
    :param radar_grid_point_lngs_deg: length-N numpy array of grid-point
        longitudes (deg E).
    :param unix_time_sec: Target time.
    :param temperature_kelvins: Target temperature.
    :param model_name: Name of model.
    :param grid_id: String ID for model grid.
    :param top_grib_directory_name: Name of top-level directory with grib files
        for the given model.
    :param wgrib_exe_name: Path to wgrib executable.
    :param wgrib2_exe_name: Path to wgrib2 executable.
    :return: isosurface_height_matrix_m_asl: length-Q numpy array with heights
        of temperature isosurface (metres above sea level).
    """

    error_checking.assert_is_numpy_array(
        radar_grid_point_lats_deg, num_dimensions=1)
    error_checking.assert_is_valid_lat_numpy_array(radar_grid_point_lats_deg)

    error_checking.assert_is_numpy_array(
        radar_grid_point_lngs_deg, num_dimensions=1)
    lng_conversion.convert_lng_positive_in_west(
        radar_grid_point_lngs_deg, allow_nan=False)

    radar_lat_matrix_deg, radar_lng_matrix_deg = (
        grids.latlng_vectors_to_matrices(
            radar_grid_point_lats_deg, radar_grid_point_lngs_deg))

    num_grid_rows = len(radar_grid_point_lats_deg)
    num_grid_columns = len(radar_grid_point_lngs_deg)
    radar_lat_vector_deg = numpy.reshape(
        radar_lat_matrix_deg, num_grid_rows * num_grid_columns)
    radar_lng_vector_deg = numpy.reshape(
        radar_lng_matrix_deg, num_grid_rows * num_grid_columns)

    query_point_dict = {interp.QUERY_LAT_COLUMN: radar_lat_vector_deg,
                        interp.QUERY_LNG_COLUMN: radar_lng_vector_deg}
    query_point_table = pandas.DataFrame.from_dict(query_point_dict)

    isosurface_height_vector_m_asl = interp.interp_temperature_sfc_from_nwp(
        query_point_table, unix_time_sec=unix_time_sec,
        temperature_kelvins=temperature_kelvins, model_name=model_name,
        grid_id=grid_id, top_grib_directory_name=top_grib_directory_name,
        wgrib_exe_name=wgrib_exe_name, wgrib2_exe_name=wgrib2_exe_name,
        raise_error_if_missing=True)

    return numpy.reshape(
        isosurface_height_vector_m_asl, (num_grid_rows, num_grid_columns))
예제 #2
0
    def test_latlng_vectors_to_matrices(self):
        """Ensures correct output from latlng_vectors_to_matrices."""

        (grid_point_lat_matrix_deg,
         grid_point_lng_matrix_deg) = grids.latlng_vectors_to_matrices(
             EXPECTED_GRID_POINT_LATITUDES_DEG,
             EXPECTED_GRID_POINT_LONGITUDES_DEG)

        self.assertTrue(
            numpy.allclose(grid_point_lat_matrix_deg,
                           EXPECTED_GRID_POINT_LAT_MATRIX_DEG,
                           atol=TOLERANCE))
        self.assertTrue(
            numpy.allclose(grid_point_lng_matrix_deg,
                           EXPECTED_GRID_POINT_LNG_MATRIX_DEG,
                           atol=TOLERANCE))
예제 #3
0
    def test_latlng_vectors_to_matrices(self):
        """Ensures correct output from latlng_vectors_to_matrices."""

        this_latitude_matrix_deg, this_longitude_matrix_deg = (
            grids.latlng_vectors_to_matrices(
                unique_latitudes_deg=POINT_LATITUDES_DEG,
                unique_longitudes_deg=POINT_LONGITUDES_DEG))

        self.assertTrue(
            numpy.allclose(this_latitude_matrix_deg,
                           POINT_LATITUDE_MATRIX_DEG,
                           atol=TOLERANCE))
        self.assertTrue(
            numpy.allclose(this_longitude_matrix_deg,
                           POINT_LONGITUDE_MATRIX_DEG,
                           atol=TOLERANCE))
예제 #4
0
def interp_temperature_surface_from_nwp(
        radar_grid_point_latitudes_deg,
        radar_grid_point_longitudes_deg,
        radar_time_unix_sec,
        critical_temperature_kelvins,
        model_name,
        top_grib_directory_name,
        use_all_grids=True,
        grid_id=None,
        wgrib_exe_name=grib_io.WGRIB_EXE_NAME_DEFAULT,
        wgrib2_exe_name=grib_io.WGRIB2_EXE_NAME_DEFAULT):
    """Interpolates temperature (isothermal) surface from NWP model.

    M = number of rows (unique grid-point latitudes) in radar grid
    N = number of columns (unique grid-point longitudes) in radar grid

    :param radar_grid_point_latitudes_deg: length-M numpy array of grid-point
        latitudes (deg N).
    :param radar_grid_point_longitudes_deg: length-N numpy array of grid-point
        longitudes (deg E).
    :param radar_time_unix_sec: Radar time.
    :param critical_temperature_kelvins: Temperature of isosurface.
    :param model_name: See doc for `interp.interp_temperature_surface_from_nwp`.
    :param top_grib_directory_name: Same.
    :param use_all_grids: Same.
    :param grid_id: Same.
    :param wgrib_exe_name: Same.
    :param wgrib2_exe_name: Same.
    :return: isosurface_height_matrix_m_asl: M-by-N numpy array with heights of
        temperature isosurface (metres above sea level).
    """

    error_checking.assert_is_numpy_array(radar_grid_point_latitudes_deg,
                                         num_dimensions=1)
    error_checking.assert_is_valid_lat_numpy_array(
        radar_grid_point_latitudes_deg)

    error_checking.assert_is_numpy_array(radar_grid_point_longitudes_deg,
                                         num_dimensions=1)
    lng_conversion.convert_lng_positive_in_west(
        radar_grid_point_longitudes_deg, allow_nan=False)

    (radar_latitude_matrix_deg,
     radar_longitude_matrix_deg) = grids.latlng_vectors_to_matrices(
         unique_latitudes_deg=radar_grid_point_latitudes_deg,
         unique_longitudes_deg=radar_grid_point_longitudes_deg)

    num_grid_rows = len(radar_grid_point_latitudes_deg)
    num_grid_columns = len(radar_grid_point_longitudes_deg)
    radar_latitude_vector_deg = numpy.reshape(radar_latitude_matrix_deg,
                                              num_grid_rows * num_grid_columns)
    radar_longitude_vector_deg = numpy.reshape(
        radar_longitude_matrix_deg, num_grid_rows * num_grid_columns)

    query_point_dict = {
        interp.QUERY_LAT_COLUMN: radar_latitude_vector_deg,
        interp.QUERY_LNG_COLUMN: radar_longitude_vector_deg
    }
    query_point_table = pandas.DataFrame.from_dict(query_point_dict)

    isosurface_height_vector_m_asl = interp.interp_temperature_surface_from_nwp(
        query_point_table=query_point_table,
        query_time_unix_sec=radar_time_unix_sec,
        critical_temperature_kelvins=critical_temperature_kelvins,
        model_name=model_name,
        top_grib_directory_name=top_grib_directory_name,
        use_all_grids=use_all_grids,
        grid_id=grid_id,
        wgrib_exe_name=wgrib_exe_name,
        wgrib2_exe_name=wgrib2_exe_name,
        raise_error_if_missing=True)

    return numpy.reshape(isosurface_height_vector_m_asl,
                         (num_grid_rows, num_grid_columns))
예제 #5
0
def write_field_to_myrorss_file(field_matrix,
                                netcdf_file_name,
                                field_name,
                                metadata_dict,
                                height_m_asl=None):
    """Writes field to MYRORSS-formatted file.

    M = number of rows (unique grid-point latitudes)
    N = number of columns (unique grid-point longitudes)

    :param field_matrix: M-by-N numpy array with one radar variable at one time.
        Latitude should increase down each column, and longitude should increase
        to the right along each row.
    :param netcdf_file_name: Path to output file.
    :param field_name: Name of radar field in GewitterGefahr format.
    :param metadata_dict: Dictionary created by either
        `gridrad_io.read_metadata_from_full_grid_file` or
        `read_metadata_from_raw_file`.
    :param height_m_asl: Height of radar field (metres above sea level).
    """

    if field_name == radar_utils.REFL_NAME:
        field_to_heights_dict_m_asl = (
            myrorss_and_mrms_utils.fields_and_refl_heights_to_dict(
                field_names=[field_name],
                data_source=radar_utils.MYRORSS_SOURCE_ID,
                refl_heights_m_asl=numpy.array([height_m_asl])))

    else:
        field_to_heights_dict_m_asl = (
            myrorss_and_mrms_utils.fields_and_refl_heights_to_dict(
                field_names=[field_name],
                data_source=radar_utils.MYRORSS_SOURCE_ID))

    field_name = list(field_to_heights_dict_m_asl.keys())[0]
    radar_height_m_asl = field_to_heights_dict_m_asl[field_name][0]

    if field_name in radar_utils.ECHO_TOP_NAMES:
        field_matrix = METRES_TO_KM * field_matrix
    field_name_myrorss = radar_utils.field_name_new_to_orig(
        field_name=field_name, data_source_name=radar_utils.MYRORSS_SOURCE_ID)

    file_system_utils.mkdir_recursive_if_necessary(file_name=netcdf_file_name)
    netcdf_dataset = Dataset(netcdf_file_name,
                             'w',
                             format='NETCDF3_64BIT_OFFSET')

    netcdf_dataset.setncattr(FIELD_NAME_COLUMN_ORIG, field_name_myrorss)
    netcdf_dataset.setncattr('DataType', 'SparseLatLonGrid')

    netcdf_dataset.setncattr(
        NW_GRID_POINT_LAT_COLUMN_ORIG,
        rounder.round_to_nearest(
            metadata_dict[radar_utils.NW_GRID_POINT_LAT_COLUMN],
            LATLNG_MULTIPLE_DEG))
    netcdf_dataset.setncattr(
        NW_GRID_POINT_LNG_COLUMN_ORIG,
        rounder.round_to_nearest(
            metadata_dict[radar_utils.NW_GRID_POINT_LNG_COLUMN],
            LATLNG_MULTIPLE_DEG))
    netcdf_dataset.setncattr(HEIGHT_COLUMN_ORIG,
                             METRES_TO_KM * numpy.float(radar_height_m_asl))
    netcdf_dataset.setncattr(
        UNIX_TIME_COLUMN_ORIG,
        numpy.int32(metadata_dict[radar_utils.UNIX_TIME_COLUMN]))
    netcdf_dataset.setncattr('FractionalTime', 0.)

    netcdf_dataset.setncattr('attributes', ' ColorMap SubType Unit')
    netcdf_dataset.setncattr('ColorMap-unit', 'dimensionless')
    netcdf_dataset.setncattr('ColorMap-value', '')
    netcdf_dataset.setncattr('SubType-unit', 'dimensionless')
    netcdf_dataset.setncattr('SubType-value', numpy.float(radar_height_m_asl))
    netcdf_dataset.setncattr('Unit-unit', 'dimensionless')
    netcdf_dataset.setncattr('Unit-value', 'dimensionless')

    netcdf_dataset.setncattr(
        LAT_SPACING_COLUMN_ORIG,
        rounder.round_to_nearest(metadata_dict[radar_utils.LAT_SPACING_COLUMN],
                                 LATLNG_MULTIPLE_DEG))
    netcdf_dataset.setncattr(
        LNG_SPACING_COLUMN_ORIG,
        rounder.round_to_nearest(metadata_dict[radar_utils.LNG_SPACING_COLUMN],
                                 LATLNG_MULTIPLE_DEG))
    netcdf_dataset.setncattr(SENTINEL_VALUE_COLUMNS_ORIG[0],
                             numpy.double(-99000.))
    netcdf_dataset.setncattr(SENTINEL_VALUE_COLUMNS_ORIG[1],
                             numpy.double(-99001.))

    min_latitude_deg = metadata_dict[radar_utils.NW_GRID_POINT_LAT_COLUMN] - (
        metadata_dict[radar_utils.LAT_SPACING_COLUMN] *
        (metadata_dict[radar_utils.NUM_LAT_COLUMN] - 1))
    unique_grid_point_lats_deg, unique_grid_point_lngs_deg = (
        grids.get_latlng_grid_points(
            min_latitude_deg=min_latitude_deg,
            min_longitude_deg=metadata_dict[
                radar_utils.NW_GRID_POINT_LNG_COLUMN],
            lat_spacing_deg=metadata_dict[radar_utils.LAT_SPACING_COLUMN],
            lng_spacing_deg=metadata_dict[radar_utils.LNG_SPACING_COLUMN],
            num_rows=metadata_dict[radar_utils.NUM_LAT_COLUMN],
            num_columns=metadata_dict[radar_utils.NUM_LNG_COLUMN]))

    num_grid_rows = len(unique_grid_point_lats_deg)
    num_grid_columns = len(unique_grid_point_lngs_deg)
    field_vector = numpy.reshape(field_matrix,
                                 num_grid_rows * num_grid_columns)

    grid_point_lat_matrix, grid_point_lng_matrix = (
        grids.latlng_vectors_to_matrices(unique_grid_point_lats_deg,
                                         unique_grid_point_lngs_deg))
    grid_point_lat_vector = numpy.reshape(grid_point_lat_matrix,
                                          num_grid_rows * num_grid_columns)
    grid_point_lng_vector = numpy.reshape(grid_point_lng_matrix,
                                          num_grid_rows * num_grid_columns)

    real_value_indices = numpy.where(numpy.invert(
        numpy.isnan(field_vector)))[0]
    netcdf_dataset.createDimension(NUM_LAT_COLUMN_ORIG, num_grid_rows - 1)
    netcdf_dataset.createDimension(NUM_LNG_COLUMN_ORIG, num_grid_columns - 1)
    netcdf_dataset.createDimension(NUM_PIXELS_COLUMN_ORIG,
                                   len(real_value_indices))

    row_index_vector, column_index_vector = radar_utils.latlng_to_rowcol(
        grid_point_lat_vector,
        grid_point_lng_vector,
        nw_grid_point_lat_deg=metadata_dict[
            radar_utils.NW_GRID_POINT_LAT_COLUMN],
        nw_grid_point_lng_deg=metadata_dict[
            radar_utils.NW_GRID_POINT_LNG_COLUMN],
        lat_spacing_deg=metadata_dict[radar_utils.LAT_SPACING_COLUMN],
        lng_spacing_deg=metadata_dict[radar_utils.LNG_SPACING_COLUMN])

    netcdf_dataset.createVariable(field_name_myrorss, numpy.single,
                                  (NUM_PIXELS_COLUMN_ORIG, ))
    netcdf_dataset.createVariable(GRID_ROW_COLUMN_ORIG, numpy.int16,
                                  (NUM_PIXELS_COLUMN_ORIG, ))
    netcdf_dataset.createVariable(GRID_COLUMN_COLUMN_ORIG, numpy.int16,
                                  (NUM_PIXELS_COLUMN_ORIG, ))
    netcdf_dataset.createVariable(NUM_GRID_CELL_COLUMN_ORIG, numpy.int32,
                                  (NUM_PIXELS_COLUMN_ORIG, ))

    netcdf_dataset.variables[field_name_myrorss].setncattr(
        'BackgroundValue', numpy.int32(-99900))
    netcdf_dataset.variables[field_name_myrorss].setncattr(
        'units', 'dimensionless')
    netcdf_dataset.variables[field_name_myrorss].setncattr(
        'NumValidRuns', numpy.int32(len(real_value_indices)))

    netcdf_dataset.variables[field_name_myrorss][:] = field_vector[
        real_value_indices]
    netcdf_dataset.variables[GRID_ROW_COLUMN_ORIG][:] = (
        row_index_vector[real_value_indices])
    netcdf_dataset.variables[GRID_COLUMN_COLUMN_ORIG][:] = (
        column_index_vector[real_value_indices])
    netcdf_dataset.variables[NUM_GRID_CELL_COLUMN_ORIG][:] = (numpy.full(
        len(real_value_indices), 1, dtype=int))

    netcdf_dataset.close()
예제 #6
0
def _run(evaluation_dir_name, grid_metafile_name, output_dir_name):
    """Plots evaluation scores by spatial region.

    This is effectively the main method.

    :param evaluation_dir_name: See documentation at top of file.
    :param grid_metafile_name: Same.
    :param output_dir_name: Same.
    """

    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    # Read metadata for grid.
    print('Reading grid metadata from: "{0:s}"...'.format(grid_metafile_name))
    grid_point_latitudes_deg, grid_point_longitudes_deg = (
        prediction_io.read_grid_metafile(grid_metafile_name))

    num_grid_rows = len(grid_point_latitudes_deg)
    num_grid_columns = len(grid_point_longitudes_deg)

    latitude_matrix_deg, longitude_matrix_deg = (
        grids.latlng_vectors_to_matrices(
            unique_latitudes_deg=grid_point_latitudes_deg,
            unique_longitudes_deg=grid_point_longitudes_deg))

    # Read evaluation files.
    eval_table_matrix_xarray = numpy.full((num_grid_rows, num_grid_columns),
                                          None,
                                          dtype=object)

    scalar_field_names = None
    aux_field_names = None
    vector_field_names = None
    heights_m_agl = None

    for i in range(num_grid_rows):
        for j in range(num_grid_columns):
            this_file_name = evaluation.find_file(
                directory_name=evaluation_dir_name,
                grid_row=i,
                grid_column=j,
                raise_error_if_missing=False)

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

            print('Reading data from: "{0:s}"...'.format(this_file_name))
            eval_table_matrix_xarray[i,
                                     j] = evaluation.read_file(this_file_name)
            eval_table_matrix_xarray[i, j] = _augment_eval_table(
                eval_table_matrix_xarray[i, j])

            if scalar_field_names is None:
                t = eval_table_matrix_xarray[i, j]

                scalar_field_names = (
                    t.coords[evaluation.SCALAR_FIELD_DIM].values)
                vector_field_names = (
                    t.coords[evaluation.VECTOR_FIELD_DIM].values)
                heights_m_agl = numpy.round(
                    t.coords[evaluation.HEIGHT_DIM].values).astype(int)

                try:
                    aux_field_names = (
                        t.coords[evaluation.AUX_TARGET_FIELD_DIM].values)
                except KeyError:
                    aux_field_names = []

    print(SEPARATOR_STRING)

    evaluation_tables_xarray = numpy.reshape(eval_table_matrix_xarray,
                                             num_grid_rows * num_grid_columns)
    nan_array = numpy.full(len(scalar_field_names), numpy.nan)

    scalar_mae_matrix = numpy.vstack([
        nan_array if t is None else t[evaluation.SCALAR_MAE_KEY].values
        for t in evaluation_tables_xarray
    ])
    scalar_rmse_matrix = numpy.sqrt(
        numpy.vstack([
            nan_array if t is None else t[evaluation.SCALAR_MSE_KEY].values
            for t in evaluation_tables_xarray
        ]))
    scalar_bias_matrix = numpy.vstack([
        nan_array if t is None else t[evaluation.SCALAR_BIAS_KEY].values
        for t in evaluation_tables_xarray
    ])
    scalar_mae_skill_matrix = numpy.vstack([
        nan_array if t is None else t[evaluation.SCALAR_MAE_SKILL_KEY].values
        for t in evaluation_tables_xarray
    ])
    scalar_mse_skill_matrix = numpy.vstack([
        nan_array if t is None else t[evaluation.SCALAR_MSE_SKILL_KEY].values
        for t in evaluation_tables_xarray
    ])
    scalar_correlation_matrix = numpy.vstack([
        nan_array if t is None else t[evaluation.SCALAR_CORRELATION_KEY].values
        for t in evaluation_tables_xarray
    ])
    scalar_kge_matrix = numpy.vstack([
        nan_array if t is None else t[evaluation.SCALAR_KGE_KEY].values
        for t in evaluation_tables_xarray
    ])
    scalar_skewness_matrix = numpy.vstack([
        nan_array if t is None else t[SCALAR_SKEWNESS_KEY].values
        for t in evaluation_tables_xarray
    ])

    grid_dim_tuple = (num_grid_rows, num_grid_columns)

    for k in range(len(scalar_field_names)):
        _plot_all_scores_one_field(
            latitude_matrix_deg=latitude_matrix_deg,
            longitude_matrix_deg=longitude_matrix_deg,
            mae_matrix=numpy.reshape(scalar_mae_matrix[:, k], grid_dim_tuple),
            rmse_matrix=numpy.reshape(scalar_rmse_matrix[:, k],
                                      grid_dim_tuple),
            bias_matrix=numpy.reshape(scalar_bias_matrix[:, k],
                                      grid_dim_tuple),
            mae_skill_score_matrix=numpy.reshape(scalar_mae_skill_matrix[:, k],
                                                 grid_dim_tuple),
            mse_skill_score_matrix=numpy.reshape(scalar_mse_skill_matrix[:, k],
                                                 grid_dim_tuple),
            correlation_matrix=numpy.reshape(scalar_correlation_matrix[:, k],
                                             grid_dim_tuple),
            kge_matrix=numpy.reshape(scalar_kge_matrix[:, k], grid_dim_tuple),
            skewness_matrix=numpy.reshape(scalar_skewness_matrix[:, k],
                                          grid_dim_tuple),
            field_name=scalar_field_names[k],
            output_dir_name=output_dir_name)

        if k == len(scalar_field_names) - 1:
            print(SEPARATOR_STRING)
        else:
            print('\n')

    if len(aux_field_names) > 0:
        nan_array = numpy.full(len(aux_field_names), numpy.nan)

        aux_mae_matrix = numpy.vstack([
            nan_array if t is None else t[evaluation.AUX_MAE_KEY].values
            for t in evaluation_tables_xarray
        ])
        aux_rmse_matrix = numpy.sqrt(
            numpy.vstack([
                nan_array if t is None else t[evaluation.AUX_MSE_KEY].values
                for t in evaluation_tables_xarray
            ]))
        aux_bias_matrix = numpy.vstack([
            nan_array if t is None else t[evaluation.AUX_BIAS_KEY].values
            for t in evaluation_tables_xarray
        ])
        aux_mae_skill_matrix = numpy.vstack([
            nan_array if t is None else t[evaluation.AUX_MAE_SKILL_KEY].values
            for t in evaluation_tables_xarray
        ])
        aux_mse_skill_matrix = numpy.vstack([
            nan_array if t is None else t[evaluation.AUX_MSE_SKILL_KEY].values
            for t in evaluation_tables_xarray
        ])
        aux_correlation_matrix = numpy.vstack([
            nan_array
            if t is None else t[evaluation.AUX_CORRELATION_KEY].values
            for t in evaluation_tables_xarray
        ])
        aux_kge_matrix = numpy.vstack([
            nan_array if t is None else t[evaluation.AUX_KGE_KEY].values
            for t in evaluation_tables_xarray
        ])
        aux_skewness_matrix = numpy.vstack([
            nan_array if t is None else t[AUX_SKEWNESS_KEY].values
            for t in evaluation_tables_xarray
        ])

    for k in range(len(aux_field_names)):
        _plot_all_scores_one_field(
            latitude_matrix_deg=latitude_matrix_deg,
            longitude_matrix_deg=longitude_matrix_deg,
            mae_matrix=numpy.reshape(aux_mae_matrix[:, k], grid_dim_tuple),
            rmse_matrix=numpy.reshape(aux_rmse_matrix[:, k], grid_dim_tuple),
            bias_matrix=numpy.reshape(aux_bias_matrix[:, k], grid_dim_tuple),
            mae_skill_score_matrix=numpy.reshape(aux_mae_skill_matrix[:, k],
                                                 grid_dim_tuple),
            mse_skill_score_matrix=numpy.reshape(aux_mse_skill_matrix[:, k],
                                                 grid_dim_tuple),
            correlation_matrix=numpy.reshape(aux_correlation_matrix[:, k],
                                             grid_dim_tuple),
            kge_matrix=numpy.reshape(aux_kge_matrix[:, k], grid_dim_tuple),
            skewness_matrix=numpy.reshape(aux_skewness_matrix[:, k],
                                          grid_dim_tuple),
            field_name=aux_field_names[k],
            output_dir_name=output_dir_name)

        if k == len(aux_field_names) - 1:
            print(SEPARATOR_STRING)
        else:
            print('\n')

    nan_array = numpy.full((len(heights_m_agl), len(vector_field_names)),
                           numpy.nan)

    vector_mae_matrix = numpy.stack([
        nan_array if t is None else t[evaluation.VECTOR_MAE_KEY].values
        for t in evaluation_tables_xarray
    ],
                                    axis=0)
    vector_rmse_matrix = numpy.sqrt(
        numpy.stack([
            nan_array if t is None else t[evaluation.VECTOR_MSE_KEY].values
            for t in evaluation_tables_xarray
        ],
                    axis=0))
    vector_bias_matrix = numpy.stack([
        nan_array if t is None else t[evaluation.VECTOR_BIAS_KEY].values
        for t in evaluation_tables_xarray
    ],
                                     axis=0)
    vector_mae_skill_matrix = numpy.stack([
        nan_array if t is None else t[evaluation.VECTOR_MAE_SKILL_KEY].values
        for t in evaluation_tables_xarray
    ],
                                          axis=0)
    vector_mse_skill_matrix = numpy.stack([
        nan_array if t is None else t[evaluation.VECTOR_MSE_SKILL_KEY].values
        for t in evaluation_tables_xarray
    ],
                                          axis=0)
    vector_correlation_matrix = numpy.stack([
        nan_array if t is None else t[evaluation.VECTOR_CORRELATION_KEY].values
        for t in evaluation_tables_xarray
    ],
                                            axis=0)
    vector_kge_matrix = numpy.stack([
        nan_array if t is None else t[evaluation.VECTOR_KGE_KEY].values
        for t in evaluation_tables_xarray
    ],
                                    axis=0)
    vector_skewness_matrix = numpy.stack([
        nan_array if t is None else t[VECTOR_SKEWNESS_KEY].values
        for t in evaluation_tables_xarray
    ],
                                         axis=0)

    for k in range(len(vector_field_names)):
        for j in range(len(heights_m_agl)):
            _plot_all_scores_one_field(
                latitude_matrix_deg=latitude_matrix_deg,
                longitude_matrix_deg=longitude_matrix_deg,
                mae_matrix=numpy.reshape(vector_mae_matrix[:, j, k],
                                         grid_dim_tuple),
                rmse_matrix=numpy.reshape(vector_rmse_matrix[:, j, k],
                                          grid_dim_tuple),
                bias_matrix=numpy.reshape(vector_bias_matrix[:, j, k],
                                          grid_dim_tuple),
                mae_skill_score_matrix=numpy.reshape(
                    vector_mae_skill_matrix[:, j, k], grid_dim_tuple),
                mse_skill_score_matrix=numpy.reshape(
                    vector_mse_skill_matrix[:, j, k], grid_dim_tuple),
                correlation_matrix=numpy.reshape(
                    vector_correlation_matrix[:, j, k], grid_dim_tuple),
                kge_matrix=numpy.reshape(vector_kge_matrix[:, j, k],
                                         grid_dim_tuple),
                skewness_matrix=numpy.reshape(vector_skewness_matrix[:, j, k],
                                              grid_dim_tuple),
                field_name=vector_field_names[k],
                height_m_agl=heights_m_agl[j],
                output_dir_name=output_dir_name)

        if k == len(vector_field_names) - 1:
            print(SEPARATOR_STRING)
        else:
            print('\n')

    num_examples_array = numpy.array([
        numpy.nan if t is None else t.attrs[NUM_EXAMPLES_KEY]
        for t in evaluation_tables_xarray
    ])
    num_examples_matrix = numpy.reshape(num_examples_array, grid_dim_tuple)
    max_colour_value = numpy.nanpercentile(num_examples_matrix,
                                           MAX_COLOUR_PERCENTILE)

    figure_object, axes_object = _plot_score_one_field(
        latitude_matrix_deg=latitude_matrix_deg,
        longitude_matrix_deg=longitude_matrix_deg,
        score_matrix=num_examples_matrix,
        colour_map_object=COUNT_COLOUR_MAP_OBJECT,
        min_colour_value=0.,
        max_colour_value=max_colour_value,
        taper_cbar_top=True,
        taper_cbar_bottom=False,
        log_scale=False)

    axes_object.set_title('Number of examples', fontsize=TITLE_FONT_SIZE)
    figure_file_name = '{0:s}/num_examples.jpg'.format(output_dir_name)

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