Example #1
0
def _prepare_default_regions_json():
    regs = {}
    for regname in get_all_default_region_ids():
        reg = Region(regname)
        regs[regname] = r = {}
        latr = reg.lat_range
        r['minLat'] = latr[0]
        r['maxLat'] = latr[1]
        lonr = reg.lon_range
        r['minLon'] = lonr[0]
        r['maxLon'] = lonr[1]
    return regs
Example #2
0
    def set_region(self, region):
        if isinstance(region, str):
            region = Region(region)
        if not isinstance(region, Region):
            raise IOError('Invalid input for region, need string or '
                          'instance of Region class, got {}'.format(region))
        self.lon_range = region.lon_range
        self.lat_range = region.lat_range
        self._region = region

        spl = self.name.split('-')
        self._name = '{}-{}'.format(region.name, spl[1])
Example #3
0
def plot_map_aerocom(data, region=None, fig=None, **kwargs):
    """High level map plotting function for Aerocom default plotting
    
    Note
    ----
    This function does not iterate over a cube in time, but uses the
    first available time index in the data.
    
    Parameters
    ----------
    data : :obj:`GriddedData`
        input data from one timestamp (if data contains more than one time 
        stamp, the first index is used)
        
    TODO 
        finish docstring
    
        
    """
    #kwargs["fix_aspect"] = 1.6
    from pyaerocom import GriddedData
    if not isinstance(data, GriddedData):
        raise TypeError("This plotting method needs an instance of pyaerocom "
                        "GriddedData on input, got: %s" % type(data))
    if region:
        if isinstance(region, str):
            region = Region(region)
        if not isinstance(region, Region):
            raise TypeError(
                "Invalid input for region, need None, str or Region")
        data = data.crop(region=region)
    if not data.suppl_info["region"]:
        data = data.crop(region="WORLD")
    region = data.suppl_info["region"]
    s = data.plot_settings
    fig = plot_griddeddata_on_map(data,
                                  xlim=region.lon_range_plot,
                                  ylim=region.lat_range_plot,
                                  vmin=s.map_vmin,
                                  vmax=s.map_vmax,
                                  c_over=s.map_c_over,
                                  c_under=s.map_c_under,
                                  cbar_levels=s.map_cbar_levels,
                                  xticks=region.lon_ticks,
                                  yticks=region.lat_ticks,
                                  cbar_ticks=s.map_cbar_ticks,
                                  **kwargs)
    ax = fig.axes[0]

    # annotate model in lower left corner
    lonr, latr = region.lon_range_plot, region.lat_range_plot
    ax.annotate(data.name,
                xy=(lonr[0] + (lonr[1] - lonr[0]) * .03,
                    latr[0] + (latr[1] - latr[0]) * .03),
                xycoords='data',
                horizontalalignment='left',
                color='black',
                fontsize=MPL_PARAMS['axes.titlesize'] + 2,
                bbox=dict(boxstyle='square',
                          facecolor='white',
                          edgecolor='none',
                          alpha=0.7))
    ax.annotate('source: AEROCOM',
                xy=(0.97, 0.03),
                xycoords='figure fraction',
                horizontalalignment='right',
                fontsize=MPL_PARAMS['xtick.labelsize'],
                bbox=dict(boxstyle='square',
                          facecolor='none',
                          edgecolor='black'))
    ax.set_title("{} {} mean {:.3f}".format(
        data.var_name.upper(),
        to_datetime(data.start).strftime("%Y%m%d"), data.area_weighted_mean()))
    return fig
Example #4
0
    def apply_latlon_filter(self, lat_range=None, lon_range=None,
                            region_id=None, inplace=False):
        """Apply regional filter

        Returns new object filtered for input coordinate range

        Parameters
        ----------
        lat_range : list, optional
            latitude range that is supposed to be applied. If specified, then
            also lon_range need to be specified, else, region_id is checked
            against AeroCom default regions (and used if applicable)
        lon_range : list, optional
            longitude range that is supposed to be applied. If specified, then
            also lat_range need to be specified, else, region_id is checked
            against AeroCom default regions (and used if applicable)
        region_id : str
            name of region to be applied. If provided (i.e. not None) then
            input args `lat_range` and `lon_range` are ignored

        Returns
        -------
        ColocatedData
            filtered data object
        """
        is_2d = self._check_latlon_coords()

        if region_id is not None:
            reg = Region(region_id)
            lon_range = reg.lon_range
            lat_range = reg.lat_range
            region_id = reg.name

        if all([x is None for x in (lat_range, lon_range)]):
            raise ValueError('Please provide input, either for lat_range or '
                             'lon_range or region_id')
        if lon_range is None:
            lon_range = [-180, 180]
        if lat_range is None:
            lat_range = [-90, 90]

        latr, lonr = self.data.attrs['lat_range'], self.data.attrs['lon_range']
        if np.equal(latr, lat_range).all() and np.equal(lonr, lon_range).all():
            const.print_log.info('Filtering of lat_range={} and lon_range={} '
                                 'results in unchanged object, returning self'
                                 .format(lon_range, lat_range))
            return self

        if lat_range[0] < latr[0]:
            lat_range[0] = latr[0]
        if lat_range[1] > latr[1]:
            lat_range[1] = latr[1]
        if lon_range[0] < lonr[0]:
            lon_range[0] = lonr[0]
        if lon_range[1] > lonr[1]:
            lon_range[1] = lonr[1]

        if is_2d:
            filtered = self._filter_latlon_2d(self.data, lat_range, lon_range)
        else:
            filtered = self._filter_latlon_3d(self.data, lat_range, lon_range)

        if not isinstance(region_id, str):
            region_id = 'CUSTOM'
        try:
            alt_info = filtered.attrs['filter_name'].split('-', 1)[-1]
        except Exception:
            alt_info = 'CUSTOM'

        filtered.attrs['filter_name'] = '{}-{}'.format(region_id, alt_info)
        filtered.attrs['region'] = region_id
        filtered.attrs['lon_range'] = lon_range
        filtered.attrs['lat_range'] = lat_range
        if inplace:
            self.data = filtered
            return self
        return ColocatedData(filtered)
Example #5
0
    def apply_latlon_filter(self,
                            lat_range=None,
                            lon_range=None,
                            region_id=None):
        """Apply regional filter 
        
        Returns new object filtered for input coordinate range
        
        Parameters
        ----------
        lat_range : list, optional
            latitude range that is supposed to be applied. If specified, then
            also lon_range need to be specified, else, region_id is checked 
            against AeroCom default regions (and used if applicable)
        lon_range : list, optional
            longitude range that is supposed to be applied. If specified, then
            also lat_range need to be specified, else, region_id is checked 
            against AeroCom default regions (and used if applicable)
        region_id : str
            name of region to be applied 
        
        Returns
        -------
        ColocatedData
            filtered data object
        """
        is_2d = self._check_latlon_coords()
        if valid_region(region_id):
            reg = Region(region_id)
            if lon_range is not None and lon_range != reg.lon_range:
                raise ValueError('Conflict: receieved region ID {}, which has '
                                 'a different longitude range ({}) than input '
                                 'lon_range {}'.format(region_id,
                                                       reg.lon_range,
                                                       lon_range))
            if lat_range is not None and lat_range != reg.lat_range:
                raise ValueError('Conflict: receieved region ID {}, which has '
                                 'a different longitude range ({}) than input '
                                 'lat_range {}'.format(region_id,
                                                       reg.lat_range,
                                                       lat_range))
            lon_range = reg.lon_range
            lat_range = reg.lat_range
            region_id = reg.name

        if lon_range is None and lat_range is None:
            raise ValueError('Need either lon_range or lat_range or valid '
                             'region_id')
        if lon_range is None:
            lon_range = [-180, 180]
        if lat_range is None:
            lat_range = [-90, 90]

        latr, lonr = self.data.attrs['lat_range'], self.data.attrs['lon_range']
        if np.equal(latr, lat_range).all() and np.equal(lonr, lon_range).all():
            const.print_log.info(
                'Filtering of lat_range={} and lon_range={} '
                'results in unchanged object, returning self'.format(
                    lon_range, lat_range))
            return self

        if lat_range[0] < latr[0]:
            lat_range[0] = latr[0]
        if lat_range[1] > latr[1]:
            lat_range[1] = latr[1]
        if lon_range[0] < lonr[0]:
            lon_range[0] = lonr[0]
        if lon_range[1] > lonr[1]:
            lon_range[1] = lonr[1]

        if is_2d:
            filtered = self._filter_latlon_2d(lat_range, lon_range)
        else:
            filtered = self._filter_latlon_3d(lat_range, lon_range)

        if not isinstance(region_id, str):
            region_id = 'CUSTOM'
        try:
            alt_info = filtered.attrs['filter_name'].split('-', 1)[-1]
        except:
            alt_info = 'CUSTOM'

        filtered.attrs['filter_name'] = '{}-{}'.format(region_id, alt_info)
        filtered.attrs['region'] = region_id
        filtered.attrs['lon_range'] = lon_range
        filtered.attrs['lat_range'] = lat_range

        return ColocatedData(filtered)
Example #6
0
 def region(self):
     """Region associated with this filter (instance of :class:`Region`)"""
     r = self._region
     if not isinstance(r, Region) or not r.name == self.region_name:
         self._region = Region(self.region_name)
     return self._region