예제 #1
0
    def test_is_regular_pass(self):
        """ Test is_regular function. """
        coord = np.array([[1, 2], [4.4, 5.4], [4, 5]])
        self.assertFalse(grid_is_regular(coord))

        coord = np.array([[1, 2], [4.4, 5], [4, 5]])
        self.assertFalse(grid_is_regular(coord))

        coord = np.array([[1, 2], [4, 5]])
        self.assertFalse(grid_is_regular(coord))

        coord = np.array([[1, 2], [4, 5], [1, 5], [4, 3]])
        self.assertFalse(grid_is_regular(coord))

        coord = np.array([[1, 2], [4, 5], [1, 5], [4, 2]])
        self.assertTrue(grid_is_regular(coord))

        grid_x, grid_y = np.mgrid[10:100:complex(0, 5), 0:10:complex(0, 5)]
        grid_x = grid_x.reshape(-1, )
        grid_y = grid_y.reshape(-1, )
        coord = np.array([grid_x, grid_y]).transpose()
        self.assertTrue(grid_is_regular(coord))

        grid_x, grid_y = np.mgrid[10:100:complex(0, 4), 0:10:complex(0, 5)]
        grid_x = grid_x.reshape(-1, )
        grid_y = grid_y.reshape(-1, )
        coord = np.array([grid_x, grid_y]).transpose()
        self.assertTrue(grid_is_regular(coord))
예제 #2
0
    def resolution(self):
        """ Returns a tuple of the resolution in the same unit as the coords.
        """
        if self._resolution is None:
            assert grid_is_regular(self.coord), 'Centroids not a regular grid'
            lats = np.unique(self.lat)
            lons = np.unique(self.lon)
            res_lat = lats[1] - lats[0]
            res_lon = lons[1] - lons[0]
            self._resolution = (res_lat, res_lon)

        return self._resolution
예제 #3
0
    def test_is_regular_pass(self):
        """ Test is_regular function. """
        coord = np.array([[1, 2], [4.4, 5.4], [4, 5]])
        reg, hei, wid = grid_is_regular(coord)
        self.assertFalse(reg)
        self.assertEqual(hei, 1)
        self.assertEqual(wid, 1)

        coord = np.array([[1, 2], [4.4, 5], [4, 5]])
        reg, hei, wid = grid_is_regular(coord)
        self.assertFalse(reg)
        self.assertEqual(hei, 1)
        self.assertEqual(wid, 1)

        coord = np.array([[1, 2], [4, 5]])
        reg, hei, wid = grid_is_regular(coord)
        self.assertFalse(reg)
        self.assertEqual(hei, 1)
        self.assertEqual(wid, 1)

        coord = np.array([[1, 2], [4, 5], [1, 5], [4, 3]])
        reg, hei, wid = grid_is_regular(coord)
        self.assertFalse(reg)
        self.assertEqual(hei, 2)
        self.assertEqual(wid, 1)

        coord = np.array([[1, 2], [4, 5], [1, 5], [4, 2]])
        reg, hei, wid = grid_is_regular(coord)
        self.assertTrue(reg)
        self.assertEqual(hei, 2)
        self.assertEqual(wid, 2)

        grid_x, grid_y = np.mgrid[10 : 100 : complex(0, 5),
                                  0 : 10 : complex(0, 5)]
        grid_x = grid_x.reshape(-1,)
        grid_y = grid_y.reshape(-1,)
        coord = np.array([grid_x, grid_y]).transpose()
        reg, hei, wid = grid_is_regular(coord)
        self.assertTrue(reg)
        self.assertEqual(hei, 5)
        self.assertEqual(wid, 5)

        grid_x, grid_y = np.mgrid[10 : 100 : complex(0, 4),
                                  0 : 10 : complex(0, 5)]
        grid_x = grid_x.reshape(-1,)
        grid_y = grid_y.reshape(-1,)
        coord = np.array([grid_x, grid_y]).transpose()
        reg, hei, wid = grid_is_regular(coord)
        self.assertTrue(reg)
        self.assertEqual(hei, 5)
        self.assertEqual(wid, 4)
예제 #4
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
예제 #5
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
예제 #6
0
 def shape_grid(self):
     """If the centroids lie on a regular grid, return its shape as a tuple
     of the form (n_lat, n_lon), that is, (height, width) """
     assert grid_is_regular(self.coord), 'Coords are not on a regular grid'
     return (np.unique(self.lat).size, np.unique(self.lon).size)