def test_list_wrong_length_fail(self):
        """When input is list of neither expected size nor one, fail."""
        num_exp = 3
        values = ['1', '2']
        val_name = 'values'

        with self.assertRaises(ValueError) as cm:
            to_list(num_exp, values, val_name)
        self.assertIn("Provide one or 3 values.", str(cm.exception))
Esempio n. 2
0
    def test_list_wrong_length_fail(self):
        """When input is list of neither expected size nor one, fail."""
        num_exp = 3
        values = ['1', '2']
        val_name = 'values'

        with self.assertLogs('climada.util.files_handler', level='ERROR') as cm:
            to_list(num_exp, values, val_name)
        self.assertIn("Provide one or 3 values.", cm.output[0])
Esempio n. 3
0
    def test_one_to_list(self):
        """When input is a string or list with one element, it returns a list
        with the expected number of elments repeated"""
        num_exp = 3
        values = 'hi'
        val_name = 'values'
        out = to_list(num_exp, values, val_name)
        self.assertEqual(['hi', 'hi', 'hi'], out)

        values = ['ha']
        out = to_list(num_exp, values, val_name)
        self.assertEqual(['ha', 'ha', 'ha'], out)
Esempio n. 4
0
 def test_identity_pass(self):
     """Returns the same list if its length is correct."""
     num_exp = 3
     values = ['hi', 'ho', 'ha']
     val_name = 'values'
     out = to_list(num_exp, values, val_name)
     self.assertEqual(values, out)
Esempio n. 5
0
    def read(self, files, descriptions='', var_names=None):
        """ Read and check centroids.

        Parameters:
            files (str or list(str)): absolute file name(s) or folder name
                containing the files to read
            descriptions (str or list(str), optional): one description of the
                data or a description of each data file
            var_names (dict or list(dict), default): name of the variables in
                the file (default: check def_source_vars() function)

        Raises:
            TypeError, ValueError
        """
        all_files = get_file_names(files)
        desc_list = to_list(len(all_files), descriptions, 'descriptions')
        var_list = to_list(len(all_files), var_names, 'var_names')
        self.clear()
        for file, desc, var in zip(all_files, desc_list, var_list):
            self.append(Centroids._read_one(file, desc, var))
Esempio n. 6
0
def geo_bin_from_array(array_sub, geo_coord, var_name, title, pop_name=True,\
                       buffer=BUFFER, extend='neither', \
                       proj=ccrs.PlateCarree(), axes=None, **kwargs):
    """Plot array values binned over input coordinates.

    Parameters:
        array_sub (np.array(1d or 2d) or list(np.array)): Each array (in a row
            or in  the list) are values at each point in corresponding
            geo_coord that are binned in one subplot.
        geo_coord (2d np.array or list(2d np.array)): (lat, lon) for each
            point in a row. If one provided, the same grid is used for all
            subplots. Otherwise provide as many as subplots in array_sub.
        var_name (str or list(str)): label to be shown in the colorbar. If one
            provided, the same is used for all subplots. Otherwise provide as
            many as subplots in array_sub.
        title (str or list(str)): subplot title. If one provided, the same is
            used for all subplots. Otherwise provide as many as subplots in
            array_sub.
        pop_name (bool, optional): add names of the populated places.
        buffer (float, optional): border to add to coordinates
        extend (str, optional): extend border colorbar with arrows.
            [ 'neither' | 'both' | 'min' | 'max' ]
        proj (ccrs): coordinate reference system used in coordinates
        kwargs (optional): arguments for hexbin matplotlib function

    Returns:
        cartopy.mpl.geoaxes.GeoAxesSubplot

    Raises:
        ValueError
    """
    # Generate array of values used in each subplot
    num_im, list_arr = _get_collection_arrays(array_sub)
    list_tit = to_list(num_im, title, 'title')
    list_name = to_list(num_im, var_name, 'var_name')
    list_coord = to_list(num_im, geo_coord, 'geo_coord')

    if 'cmap' not in kwargs:
        kwargs['cmap'] = 'Wistia'
    if axes is None:
        _, axes = make_map(num_im, proj=proj)
    if not isinstance(axes, np.ndarray):
        axes_iter = np.array([[axes]])

    # Generate each subplot
    for array_im, axis, tit, name, coord in \
    zip(list_arr, axes_iter.flatten(), list_tit, list_name, list_coord):
        if coord.shape[0] != array_im.size:
            raise ValueError("Size mismatch in input array: %s != %s." % \
                             (coord.shape[0], array_im.size))

        # Binned image with coastlines
        extent = _get_borders(coord, buffer, proj)
        axis.set_extent((extent), proj)
        add_shapes(axis)
        if pop_name:
            add_populated_places(axis, extent, proj)

        if 'gridsize' not in kwargs:
            kwargs['gridsize'] = min(int(array_im.size/2), MAX_BINS)
        hex_bin = axis.hexbin(coord[:, 1], coord[:, 0], C=array_im, \
            transform=proj, **kwargs)

        # Create colorbar in this axis
        cbax = make_axes_locatable(axis).append_axes('right', size="6.5%", \
            pad=0.1, axes_class=plt.Axes)
        cbar = plt.colorbar(hex_bin, cax=cbax, orientation='vertical',
                            extend=extend)
        cbar.set_label(name)
        axis.set_title(tit)

    return axes
Esempio n. 7
0
def geo_im_from_array(array_sub, geo_coord, var_name, title,
                      proj=ccrs.PlateCarree(), smooth=True, axes=None, **kwargs):
    """Image(s) plot defined in array(s) over input coordinates.

    Parameters:
        array_sub (np.array(1d or 2d) or list(np.array)): Each array (in a row
            or in  the list) are values at each point in corresponding
            geo_coord that are ploted in one subplot.
        geo_coord (2d np.array or list(2d np.array)): (lat, lon) for each
            point in a row. If one provided, the same grid is used for all
            subplots. Otherwise provide as many as subplots in array_sub.
        var_name (str or list(str)): label to be shown in the colorbar. If one
            provided, the same is used for all subplots. Otherwise provide as
            many as subplots in array_sub.
        title (str or list(str)): subplot title. If one provided, the same is
            used for all subplots. Otherwise provide as many as subplots in
            array_sub.
        proj (ccrs): coordinate reference system used in coordinates
        smooth (bool, optional): smooth plot to RESOLUTIONxRESOLUTION. Default:
            True.
        kwargs (optional): arguments for pcolormesh matplotlib function.

    Returns:
        cartopy.mpl.geoaxes.GeoAxesSubplot

    Raises:
        ValueError
    """
    # Generate array of values used in each subplot
    num_im, list_arr = _get_collection_arrays(array_sub)
    list_tit = to_list(num_im, title, 'title')
    list_name = to_list(num_im, var_name, 'var_name')
    list_coord = to_list(num_im, geo_coord, 'geo_coord')

    if 'vmin' not in kwargs:
        kwargs['vmin'] = np.min(array_sub)
    if 'vmax' not in kwargs:
        kwargs['vmax'] = np.max(array_sub)
    if axes is None:
        _, axes = make_map(num_im, proj=proj)
    axes_iter = axes
    if not isinstance(axes, np.ndarray):
        axes_iter = np.array([[axes]])

    # Generate each subplot
    for array_im, axis, tit, name, coord in \
    zip(list_arr, axes_iter.flatten(), list_tit, list_name, list_coord):
        if coord.shape[0] != array_im.size:
            raise ValueError("Size mismatch in input array: %s != %s." % \
                             (coord.shape[0], array_im.size))
        is_reg, height, width = grid_is_regular(coord)
        extent = _get_borders(coord, proj=proj)
        if smooth or not is_reg:
            # Create regular grid where to interpolate the array
            grid_x, grid_y = np.mgrid[
                extent[0] : extent[1] : complex(0, RESOLUTION),
                extent[2] : extent[3] : complex(0, RESOLUTION)]
            grid_im = griddata((coord[:, 1], coord[:, 0]), array_im, \
                               (grid_x, grid_y))
        else:
            grid_x = coord[:, 1].reshape((width, height)).transpose()
            grid_y = coord[:, 0].reshape((width, height)).transpose()
            grid_im = np.array(array_im.reshape((width, height)).transpose())
            if grid_y[0, 0] > grid_y[0, -1]:
                grid_y = np.flip(grid_y)
                grid_im = np.flip(grid_im, 1)
            grid_im = np.resize(grid_im, (height, width, 1))

        # Add coastline to axis
        axis.set_extent((extent), proj)
        add_shapes(axis)
        # Create colormesh, colorbar and labels in axis
        cbax = make_axes_locatable(axis).append_axes('right', size="6.5%", \
            pad=0.1, axes_class=plt.Axes)
        cbar = plt.colorbar(axis.pcolormesh(grid_x, grid_y, np.squeeze(grid_im), \
            transform=proj, **kwargs), cax=cbax, orientation='vertical')
        cbar.set_label(name)
        axis.set_title(tit)

    return axes
Esempio n. 8
0
def geo_im_from_array(array_sub,
                      coord,
                      var_name,
                      title,
                      proj=None,
                      smooth=True,
                      axes=None,
                      figsize=(9, 13),
                      adapt_fontsize=True,
                      **kwargs):
    """Image(s) plot defined in array(s) over input coordinates.

    Parameters
    ----------
    array_sub : np.array(1d or 2d) or list(np.array)
        Each array (in a row or in  the list) are values at each point in corresponding
        geo_coord that are ploted in one subplot.
    coord : 2d np.array
        (lat, lon) for each point in a row. The same grid is used for all subplots.
    var_name : str or list(str)
        label to be shown in the colorbar. If one provided, the same is used for all subplots.
        Otherwise provide as many as subplots in array_sub.
    title : str or list(str)
        subplot title. If one provided, the same is used for all subplots.
        Otherwise provide as many as subplots in array_sub.
    proj : ccrs, optional
        coordinate reference system used in coordinates, by default None
    smooth : bool, optional
        smooth plot to RESOLUTIONxRESOLUTION, by default True
    axes : Axes or ndarray(Axes), optional
        by default None
    figsize : tuple, optional
        figure size for plt.subplots, by default (9, 13)
    adapt_fontsize : bool, optional
        If set to true, the size of the fonts will be adapted to the size of the figure. Otherwise
        the default matplotlib font size is used. Default is True.
    **kwargs
        arbitrary keyword arguments for pcolormesh matplotlib function

    Returns
    -------
    cartopy.mpl.geoaxes.GeoAxesSubplot

    Raises
    ------
    ValueError
    """

    # Generate array of values used in each subplot
    num_im, list_arr = _get_collection_arrays(array_sub)
    list_tit = to_list(num_im, title, 'title')
    list_name = to_list(num_im, var_name, 'var_name')
    list_coord = to_list(num_im, coord, 'geo_coord')

    is_reg, height, width = u_coord.grid_is_regular(coord)
    extent = _get_borders(coord, proj_limits=(-360, 360, -90, 90))
    mid_lon = 0
    if not proj:
        mid_lon = 0.5 * sum(extent[:2])
        proj = ccrs.PlateCarree(central_longitude=mid_lon)
    if 'vmin' not in kwargs:
        kwargs['vmin'] = np.nanmin(array_sub)
    if 'vmax' not in kwargs:
        kwargs['vmax'] = np.nanmax(array_sub)
    if axes is None:
        if isinstance(proj, ccrs.PlateCarree):
            # use different projections for plot and data to shift the central lon in the plot
            xmin, xmax = u_coord.lon_bounds(
                np.concatenate([c[:, 1] for c in list_coord]))
            proj_plot = ccrs.PlateCarree(central_longitude=0.5 * (xmin + xmax))
        _, axes, fontsize = make_map(num_im,
                                     proj=proj_plot,
                                     figsize=figsize,
                                     adapt_fontsize=adapt_fontsize)
    else:
        fontsize = None
    axes_iter = axes
    if not isinstance(axes, np.ndarray):
        axes_iter = np.array([[axes]])

    if 'cmap' not in kwargs:
        kwargs['cmap'] = CMAP_RASTER

    # Generate each subplot
    for array_im, axis, tit, name in zip(list_arr, axes_iter.flatten(),
                                         list_tit, list_name):
        if coord.shape[0] != array_im.size:
            raise ValueError("Size mismatch in input array: %s != %s." %
                             (coord.shape[0], array_im.size))
        if smooth or not is_reg:
            # Create regular grid where to interpolate the array
            grid_x, grid_y = np.mgrid[
                extent[0]:extent[1]:complex(0, RESOLUTION),
                extent[2]:extent[3]:complex(0, RESOLUTION)]
            grid_im = griddata((coord[:, 1], coord[:, 0]), array_im,
                               (grid_x, grid_y))
        else:
            grid_x = coord[:, 1].reshape((width, height)).transpose()
            grid_y = coord[:, 0].reshape((width, height)).transpose()
            grid_im = np.array(array_im.reshape((width, height)).transpose())
            if grid_y[0, 0] > grid_y[0, -1]:
                grid_y = np.flip(grid_y)
                grid_im = np.flip(grid_im, 1)
            grid_im = np.resize(grid_im, (height, width, 1))
        axis.set_extent(
            (extent[0] - mid_lon, extent[1] - mid_lon, extent[2], extent[3]),
            crs=proj)

        # Add coastline to axis
        add_shapes(axis)
        # Create colormesh, colorbar and labels in axis
        cbax = make_axes_locatable(axis).append_axes('right',
                                                     size="6.5%",
                                                     pad=0.1,
                                                     axes_class=plt.Axes)
        img = axis.pcolormesh(grid_x - mid_lon,
                              grid_y,
                              np.squeeze(grid_im),
                              transform=proj,
                              **kwargs)
        cbar = plt.colorbar(img, cax=cbax, orientation='vertical')
        cbar.set_label(name)
        axis.set_title("\n".join(wrap(tit)))
        if fontsize:
            cbar.ax.tick_params(labelsize=fontsize)
            cbar.ax.yaxis.get_offset_text().set_fontsize(fontsize)
            for item in [axis.title, cbar.ax.xaxis.label, cbar.ax.yaxis.label]:
                item.set_fontsize(fontsize)

    plt.tight_layout()
    return axes
Esempio n. 9
0
def _plot_scattered_data(method,
                         array_sub,
                         geo_coord,
                         var_name,
                         title,
                         pop_name=False,
                         buffer=BUFFER,
                         extend='neither',
                         proj=ccrs.PlateCarree(),
                         shapes=True,
                         axes=None,
                         figsize=(9, 13),
                         adapt_fontsize=True,
                         **kwargs):
    """Function for internal use in `geo_scatter_from_array` (when called with method="scatter")
    and `geo_bin_from_array` (when called with method="hexbin"). See the docstrings of the
    respective functions for more information on the parameters."""

    # Generate array of values used in each subplot
    num_im, list_arr = _get_collection_arrays(array_sub)
    list_tit = to_list(num_im, title, 'title')
    list_name = to_list(num_im, var_name, 'var_name')
    list_coord = to_list(num_im, geo_coord, 'geo_coord')

    if 'cmap' not in kwargs:
        kwargs['cmap'] = CMAP_EXPOSURES

    if axes is None:
        proj_plot = proj
        if isinstance(proj, ccrs.PlateCarree):
            # use different projections for plot and data to shift the central lon in the plot
            xmin, xmax = u_coord.lon_bounds(
                np.concatenate([c[:, 1] for c in list_coord]))
            proj_plot = ccrs.PlateCarree(central_longitude=0.5 * (xmin + xmax))
        _, axes, fontsize = make_map(num_im,
                                     proj=proj_plot,
                                     figsize=figsize,
                                     adapt_fontsize=adapt_fontsize)
    else:
        fontsize = None
    axes_iter = axes
    if not isinstance(axes, np.ndarray):
        axes_iter = np.array([[axes]])

    # Generate each subplot
    for array_im, axis, tit, name, coord in \
    zip(list_arr, axes_iter.flatten(), list_tit, list_name, list_coord):
        if coord.shape[0] != array_im.size:
            raise ValueError("Size mismatch in input array: %s != %s." %
                             (coord.shape[0], array_im.size))

        # Binned image with coastlines
        if isinstance(proj, ccrs.PlateCarree):
            xmin, ymin, xmax, ymax = u_coord.latlon_bounds(coord[:, 0],
                                                           coord[:, 1],
                                                           buffer=buffer)
            extent = (xmin, xmax, ymin, ymax)
        else:
            extent = _get_borders(coord,
                                  buffer=buffer,
                                  proj_limits=proj.x_limits + proj.y_limits)
        axis.set_extent((extent), proj)

        if shapes:
            add_shapes(axis)
        if pop_name:
            add_populated_places(axis, extent, proj, fontsize)

        if method == "hexbin":
            if 'gridsize' not in kwargs:
                kwargs['gridsize'] = min(int(array_im.size / 2), MAX_BINS)
            mappable = axis.hexbin(coord[:, 1],
                                   coord[:, 0],
                                   C=array_im,
                                   transform=proj,
                                   **kwargs)
        else:
            mappable = axis.scatter(coord[:, 1],
                                    coord[:, 0],
                                    c=array_im,
                                    transform=proj,
                                    **kwargs)

        # Create colorbar in this axis
        cbax = make_axes_locatable(axis).append_axes('right',
                                                     size="6.5%",
                                                     pad=0.1,
                                                     axes_class=plt.Axes)
        cbar = plt.colorbar(mappable,
                            cax=cbax,
                            orientation='vertical',
                            extend=extend)
        cbar.set_label(name)
        axis.set_title("\n".join(wrap(tit)))
        if fontsize:
            cbar.ax.tick_params(labelsize=fontsize)
            cbar.ax.yaxis.get_offset_text().set_fontsize(fontsize)
            for item in [axis.title, cbar.ax.xaxis.label, cbar.ax.yaxis.label]:
                item.set_fontsize(fontsize)
    plt.tight_layout()
    return axes
Esempio n. 10
0
    def _plot_exc_prob(
            self,
            run_datetime,
            threshold,
            title,
            cbar_label,
            proj=ccrs.PlateCarree(),
            polygon_file=None,
            polygon_file_crs="epsg:4326",
            mask=None,
            figsize=(9, 13),
            adapt_fontsize=True,
    ):
        """plot the probability of reaching a threshold"""
        # select hazard with run_datetime
        # pylint: disable=protected-access
        if run_datetime is None:
            run_datetime = self.run_datetime[0]
        haz_ind = np.argwhere(np.isin(self.run_datetime, run_datetime))[0][0]
        extend = "neither"
        value = np.squeeze(
            np.asarray(
                (self._impact[haz_ind].imp_mat > threshold).sum(axis=0) /
                self._impact[haz_ind].event_id.size))
        if mask is not None:
            value[np.invert(mask)] = np.nan
        coord = self._impact[haz_ind].coord_exp
        # Generate array of values used in each subplot
        array_sub = value
        shapes = True
        if not polygon_file:
            shapes = False
        var_name = cbar_label
        geo_coord = coord
        num_im, list_arr = u_plot._get_collection_arrays(array_sub)
        list_tit = to_list(num_im, title, "title")
        list_name = to_list(num_im, var_name, "var_name")
        list_coord = to_list(num_im, geo_coord, "geo_coord")

        kwargs = dict()
        kwargs["cmap"] = CMAP_WARNPROB
        kwargs["s"] = 5
        kwargs["marker"] = ","
        kwargs["norm"] = BoundaryNorm(np.linspace(0, 1, 11),
                                      CMAP_WARNPROB.N,
                                      clip=True)

        # Generate each subplot
        fig, axis_sub, _fontsize = u_plot.make_map(
            num_im, proj=proj, figsize=figsize, adapt_fontsize=adapt_fontsize)
        if not isinstance(axis_sub, np.ndarray):
            axis_sub = np.array([[axis_sub]])
        fig.set_size_inches(9, 8)
        for array_im, axis, tit, name, coord in zip(list_arr,
                                                    axis_sub.flatten(),
                                                    list_tit, list_name,
                                                    list_coord):
            if coord.shape[0] != array_im.size:
                raise ValueError("Size mismatch in input array: %s != %s." %
                                 (coord.shape[0], array_im.size))

            hex_bin = axis.scatter(coord[:, 1],
                                   coord[:, 0],
                                   c=array_im,
                                   transform=ccrs.PlateCarree(),
                                   **kwargs)
            if shapes:
                # add warning regions
                shp = shapereader.Reader(polygon_file)
                transformer = pyproj.Transformer.from_crs(
                    polygon_file_crs,
                    self._impact[haz_ind].crs,
                    always_xy=True)
                for geometry, _ in zip(shp.geometries(), shp.records()):
                    geom2 = shapely.ops.transform(transformer.transform,
                                                  geometry)
                    axis.add_geometries(
                        [geom2],
                        crs=ccrs.PlateCarree(),
                        facecolor="none",
                        edgecolor="gray",
                    )

            # Create colorbar in this axis
            cbax = make_axes_locatable(axis).append_axes("bottom",
                                                         size="6.5%",
                                                         pad=0.3,
                                                         axes_class=plt.Axes)
            cbar = plt.colorbar(hex_bin,
                                cax=cbax,
                                orientation="horizontal",
                                extend=extend)
            cbar.set_label(name)
            title_position = {
                "model_text": [0.02, 0.94],
                "explain_text": [0.02, 0.9],
                "event_day": [0.98, 0.94],
                "run_start": [0.98, 0.9],
            }
            left_right = {
                "model_text": "left",
                "explain_text": "left",
                "event_day": "right",
                "run_start": "right",
            }
            color = {
                "model_text": "k",
                "explain_text": "k",
                "event_day": "r",
                "run_start": "k",
            }
            for t_i in tit:
                plt.figtext(
                    title_position[t_i][0],
                    title_position[t_i][1],
                    tit[t_i],
                    fontsize="xx-large",
                    color=color[t_i],
                    ha=left_right[t_i],
                )
            extent = u_plot._get_borders(coord)
            axis.set_extent((extent), ccrs.PlateCarree())
        fig.tight_layout()
        return fig, axis_sub
Esempio n. 11
0
    def _plot_imp_map(
            self,
            run_datetime,
            title,
            cbar_label,
            polygon_file=None,
            polygon_file_crs="epsg:4326",
            proj=ccrs.PlateCarree(),
            figsize=(9, 13),
            adapt_fontsize=True,
    ):
        # select hazard with run_datetime
        # pylint: disable=protected-access
        if run_datetime is None:
            run_datetime = self.run_datetime[0]
        haz_ind = np.argwhere(np.isin(self.run_datetime, run_datetime))[0][0]
        # tryout new plot with right projection
        extend = "neither"
        value = self._impact[haz_ind].eai_exp
        #    value[np.invert(mask)] = np.nan
        coord = self._impact[haz_ind].coord_exp

        # Generate array of values used in each subplot
        array_sub = value
        shapes = True
        if not polygon_file:
            shapes = False
        var_name = cbar_label
        geo_coord = coord
        num_im, list_arr = u_plot._get_collection_arrays(array_sub)
        list_tit = to_list(num_im, title, "title")
        list_name = to_list(num_im, var_name, "var_name")
        list_coord = to_list(num_im, geo_coord, "geo_coord")

        kwargs = dict()
        kwargs["cmap"] = CMAP_IMPACT
        kwargs["s"] = 5
        kwargs["marker"] = ","
        kwargs["norm"] = BoundaryNorm(
            np.append(
                np.append([0], [10**x for x in np.arange(0, 2.9, 2.9 / 9)]),
                [10**x for x in np.arange(3, 7, 4 / 90)],
            ),
            CMAP_IMPACT.N,
            clip=True,
        )

        # Generate each subplot
        fig, axis_sub, _fontsize = u_plot.make_map(
            num_im, proj=proj, figsize=figsize, adapt_fontsize=adapt_fontsize)
        if not isinstance(axis_sub, np.ndarray):
            axis_sub = np.array([[axis_sub]])
        fig.set_size_inches(9, 8)
        for array_im, axis, tit, name, coord in zip(list_arr,
                                                    axis_sub.flatten(),
                                                    list_tit, list_name,
                                                    list_coord):
            if coord.shape[0] != array_im.size:
                raise ValueError("Size mismatch in input array: %s != %s." %
                                 (coord.shape[0], array_im.size))
            # Binned image with coastlines
            extent = u_plot._get_borders(coord)
            axis.set_extent((extent), ccrs.PlateCarree())
            hex_bin = axis.scatter(coord[:, 1],
                                   coord[:, 0],
                                   c=array_im,
                                   transform=ccrs.PlateCarree(),
                                   **kwargs)
            if shapes:
                # add warning regions
                shp = shapereader.Reader(polygon_file)
                transformer = pyproj.Transformer.from_crs(
                    polygon_file_crs,
                    self._impact[haz_ind].crs,
                    always_xy=True)
                for geometry, _ in zip(shp.geometries(), shp.records()):
                    geom2 = shapely.ops.transform(transformer.transform,
                                                  geometry)
                    axis.add_geometries(
                        [geom2],
                        crs=ccrs.PlateCarree(),
                        facecolor="none",
                        edgecolor="gray",
                    )
            else:  # add country boundaries
                u_plot.add_shapes(axis)
            # Create colorbar in this axis
            cbax = make_axes_locatable(axis).append_axes("bottom",
                                                         size="6.5%",
                                                         pad=0.3,
                                                         axes_class=plt.Axes)
            cbar = plt.colorbar(hex_bin,
                                cax=cbax,
                                orientation="horizontal",
                                extend=extend)
            cbar.set_label(name)
            cbar.formatter.set_scientific(False)
            cbar.set_ticks([0, 1000, 10000, 100000, 1000000])
            cbar.set_ticklabels(
                ["0", "1 000", "10 000", "100 000", "1 000 000"])
            title_position = {
                "model_text": [0.02, 0.85],
                "explain_text": [0.02, 0.81],
                "event_day": [0.98, 0.85],
                "run_start": [0.98, 0.81],
            }
            left_right = {
                "model_text": "left",
                "explain_text": "left",
                "event_day": "right",
                "run_start": "right",
            }
            color = {
                "model_text": "k",
                "explain_text": "k",
                "event_day": "r",
                "run_start": "k",
            }
            for t_i in tit:
                plt.figtext(
                    title_position[t_i][0],
                    title_position[t_i][1],
                    tit[t_i],
                    fontsize="xx-large",
                    color=color[t_i],
                    ha=left_right[t_i],
                )

        fig.tight_layout()
        fig.subplots_adjust(top=0.8)
        return fig, axis_sub
Esempio n. 12
0
    def _plot_exc_prob(self,
                       run_datetime,
                       threshold,
                       title,
                       cbar_label,
                       proj=ccrs.PlateCarree(),
                       polygon_file=None,
                       polygon_file_crs='epsg:4326',
                       mask=None,
                       figsize=(9, 13)):
        """  plot the probability of reaching a threshold """
        # select hazard with run_datetime
        if run_datetime is None:
            run_datetime = self.run_datetime[0]
        haz_ind = np.argwhere(np.isin(self.run_datetime, run_datetime))[0][0]
        extend = 'neither'
        value = np.squeeze(
            np.asarray(
                (self._impact[haz_ind].imp_mat > threshold).sum(axis=0) /
                self._impact[haz_ind].event_id.size))
        if mask is not None:
            value[np.invert(mask)] = np.nan
        coord = self._impact[haz_ind].coord_exp
        # Generate array of values used in each subplot
        array_sub = value
        shapes = True
        if not polygon_file:
            shapes = False
        var_name = cbar_label
        geo_coord = coord
        num_im, list_arr = u_plot._get_collection_arrays(array_sub)
        list_tit = to_list(num_im, title, 'title')
        list_name = to_list(num_im, var_name, 'var_name')
        list_coord = to_list(num_im, geo_coord, 'geo_coord')

        kwargs = dict()
        kwargs['cmap'] = CMAP_WARNPROB
        kwargs['s'] = 5
        kwargs['marker'] = ','
        kwargs['norm'] = BoundaryNorm(np.linspace(0, 1, 11),
                                      CMAP_WARNPROB.N,
                                      clip=True)

        # Generate each subplot
        fig, axis_sub = u_plot.make_map(num_im, proj=proj, figsize=figsize)
        if not isinstance(axis_sub, np.ndarray):
            axis_sub = np.array([[axis_sub]])
        fig.set_size_inches(9, 8)
        for array_im, axis, tit, name, coord in zip(list_arr,
                                                    axis_sub.flatten(),
                                                    list_tit, list_name,
                                                    list_coord):
            if coord.shape[0] != array_im.size:
                raise ValueError("Size mismatch in input array: %s != %s." % \
                                 (coord.shape[0], array_im.size))

            hex_bin = axis.scatter(coord[:, 1], coord[:, 0], c=array_im, \
                                   transform=ccrs.PlateCarree(), **kwargs)
            if shapes:
                # add warning regions
                shp = shapereader.Reader(polygon_file)
                transformer = pyproj.Transformer.from_crs(
                    polygon_file_crs,
                    self._impact[haz_ind].crs,
                    always_xy=True)
                for geometry, _ in zip(shp.geometries(), shp.records()):
                    geom2 = shapely.ops.transform(transformer.transform,
                                                  geometry)
                    axis.add_geometries([geom2], crs=ccrs.PlateCarree(), facecolor='', \
                                        edgecolor='gray')

            # Create colorbar in this axis
            cbax = make_axes_locatable(axis).append_axes('bottom', size="6.5%", \
                                                         pad=0.3, axes_class=plt.Axes)
            cbar = plt.colorbar(hex_bin,
                                cax=cbax,
                                orientation='horizontal',
                                extend=extend)
            cbar.set_label(name)
            title_position = {
                'model_text': [0.02, 0.94],
                'explain_text': [0.02, 0.9],
                'event_day': [0.98, 0.94],
                'run_start': [0.98, 0.9]
            }
            left_right = {
                'model_text': 'left',
                'explain_text': 'left',
                'event_day': 'right',
                'run_start': 'right'
            }
            color = {
                'model_text': 'k',
                'explain_text': 'k',
                'event_day': 'r',
                'run_start': 'k'
            }
            for t_i in tit:
                plt.figtext(title_position[t_i][0],
                            title_position[t_i][1],
                            tit[t_i],
                            fontsize='xx-large',
                            color=color[t_i],
                            ha=left_right[t_i])
            extent = u_plot._get_borders(coord)
            axis.set_extent((extent), ccrs.PlateCarree())

        return fig, axis_sub
Esempio n. 13
0
def geo_bin_from_array(array_sub,
                       geo_coord,
                       var_name,
                       title,
                       pop_name=True,
                       buffer=BUFFER,
                       extend='neither',
                       proj=ccrs.PlateCarree(),
                       axes=None,
                       figsize=(9, 13),
                       **kwargs):
    """Plot array values binned over input coordinates.

    Parameters
    ----------
    array_sub : np.array(1d or 2d) or list(np.array)
        Each array (in a row or in  the list) are values at each point in corresponding
        geo_coord that are binned in one subplot.
    geo_coord : 2d np.array or list(2d np.array)
        (lat, lon) for each point in a row. If one provided, the same grid is used for all
        subplots. Otherwise provide as many as subplots in array_sub.
    var_name : str or list(str)
        label to be shown in the colorbar. If one provided, the same is used for all subplots.
        Otherwise provide as many as subplots in array_sub.
    title : str or list(str)
        subplot title. If one provided, the same is used for all subplots.
        Otherwise provide as many as subplots in array_sub.
    pop_name : bool, optional
        add names of the populated places, by default True
    buffer : float, optional
        border to add to coordinates, by default BUFFER
    extend : str, optional
        extend border colorbar with arrows.
        [ 'neither' | 'both' | 'min' | 'max' ], by default 'neither'
    proj : ccrs, optional
        coordinate reference system of the given data, by default ccrs.PlateCarree()
    axes : Axes or ndarray(Axes), optional
        by default None
    figsize : tuple, optional
        figure size for plt.subplots, by default (9, 13)
    **kwargs
        arbitrary keyword arguments for hexbin matplotlib function

    Returns
    -------
    cartopy.mpl.geoaxes.GeoAxesSubplot

    Raises
    ------
    ValueError
    """

    # Generate array of values used in each subplot
    num_im, list_arr = _get_collection_arrays(array_sub)
    list_tit = to_list(num_im, title, 'title')
    list_name = to_list(num_im, var_name, 'var_name')
    list_coord = to_list(num_im, geo_coord, 'geo_coord')

    if 'cmap' not in kwargs:
        kwargs['cmap'] = 'Wistia'

    if axes is None:
        proj_plot = proj
        if isinstance(proj, ccrs.PlateCarree):
            # use different projections for plot and data to shift the central lon in the plot
            xmin, xmax = u_coord.lon_bounds(
                np.concatenate([c[:, 1] for c in list_coord]))
            proj_plot = ccrs.PlateCarree(central_longitude=0.5 * (xmin + xmax))
        _, axes = make_map(num_im, proj=proj_plot, figsize=figsize)

    if not isinstance(axes, np.ndarray):
        axes_iter = np.array([[axes]])

    # Generate each subplot
    for array_im, axis, tit, name, coord in \
    zip(list_arr, axes_iter.flatten(), list_tit, list_name, list_coord):
        if coord.shape[0] != array_im.size:
            raise ValueError("Size mismatch in input array: %s != %s." %
                             (coord.shape[0], array_im.size))

        # Binned image with coastlines
        if isinstance(proj, ccrs.PlateCarree):
            xmin, ymin, xmax, ymax = u_coord.latlon_bounds(coord[:, 0],
                                                           coord[:, 1],
                                                           buffer=buffer)
            extent = (xmin, xmax, ymin, ymax)
        else:
            extent = _get_borders(coord,
                                  buffer=buffer,
                                  proj_limits=proj.x_limits + proj.y_limits)
        axis.set_extent((extent), proj)
        add_shapes(axis)
        if pop_name:
            add_populated_places(axis, extent, proj)

        if 'gridsize' not in kwargs:
            kwargs['gridsize'] = min(int(array_im.size / 2), MAX_BINS)
        hex_bin = axis.hexbin(coord[:, 1],
                              coord[:, 0],
                              C=array_im,
                              transform=proj,
                              **kwargs)

        # Create colorbar in this axis
        cbax = make_axes_locatable(axis).append_axes('right',
                                                     size="6.5%",
                                                     pad=0.1,
                                                     axes_class=plt.Axes)
        cbar = plt.colorbar(hex_bin,
                            cax=cbax,
                            orientation='vertical',
                            extend=extend)
        cbar.set_label(name)
        axis.set_title(tit)

    return axes