Beispiel #1
0
 def test_legs_col_arr_one_col_grey_txt(self):
     #one color as a text string
     blue_mapping = legs.PalObj(color_arr = 'grey_175')
     data = [0.00, 1.00]
     rgb_img = blue_mapping.to_rgb(data)      
     #                           data value  color
     ans =  [[175, 175, 175],  #    1.00     grey 175
             [175, 175, 175]]  #    0.66     grey 175
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #2
0
 def test_legs_col_arr_one_col_txt(self):
     #one color as a text string
     blue_mapping = legs.PalObj(color_arr = 'blue')
     data = [0.00, 1.00]
     rgb_img = blue_mapping.to_rgb(data)      
     #                           data value  color
     ans =  [[169, 222, 255],  #    1.00     light blue
             [  0,  81, 237]]  #    0.66     dark_blue
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #3
0
 def test_legs_col_arr_one_col_txt_solid_supplied(self):
     #or any color you like by passing RGB values to color_arr
     orange_mapping = legs.PalObj(color_arr = [255, 194, 124], solid='supplied')  #light orange
                                                    
     data = [0.00, 1.00]
     rgb_img = orange_mapping.to_rgb(data)      
     #                           data value  color
     ans =  [[255, 194, 124],  #    0.00     light orange
             [255, 194, 124]]  #    1.00     light orange
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #4
0
 def test_legs_range(self):
     #one solution is to adjust range of palette so that is encompasses the data
     black_white_mapping = legs.PalObj(range_arr=[0.,1.1])
     data = [0.000, 0.366, 0.733, 1.100]
     rgb_img = black_white_mapping.to_rgb(data)           
     #                           data value  color
     ans = [[255, 255, 255],    #   0.000    white
            [170, 170, 170],    #   0.366    grey 
            [ 85,  85,  85],    #   0.733    grey
            [  0,   0,   0]]    #   1.100    black
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #5
0
 def test_legs_no_args(self):
     #default map is a black and white palette for data values in the interval [0,1]
     black_white_mapping = legs.PalObj()
     data = [0.00, 0.33, 0.66, 1.00]
     rgb_img = black_white_mapping.to_rgb(data)
     #                           data value  color
     ans = [[255, 255, 255],   #    0.00     white    
            [170, 170, 170],   #    0.33     grey     
            [ 86,  86,  86],   #    0.66     grey     
            [  0,   0,   0]]   #    1.00     black    
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #6
0
 def test_legs_col_arr_two_col_txt_solid_light(self):
     #solid can also be set to col_light
     orange_blue_mapping = legs.PalObj(color_arr = ['orange','blue'], solid='col_light')
     data = [0.00, 0.33, 0.66, 1.00]
     rgb_img = orange_blue_mapping.to_rgb(data)      
     #                           data value  color
     ans =  [[255, 194, 124],  #    0.00     light orange
             [255, 194, 124],  #    0.33     light orange
             [169, 222, 255],  #    0.66     light blue
             [169, 222, 255]]  #    1.00     light blue
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #7
0
 def test_legs_col_arr_two_col_txt(self):
     #any number of colors can be specified
     orange_blue_mapping = legs.PalObj(color_arr = ['orange','blue'])
     data = [0.00, 0.33, 0.66, 1.00]
     rgb_img = orange_blue_mapping.to_rgb(data)      
     #                           data value  color
     ans = [[255, 194, 124],   #    0.00     light orange
            [255, 122,  42],   #    0.33     dark orange 
            [114, 176, 249],   #    0.66     light blue
            [  0,  81, 237]]   #    1.00     dark_blue
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #8
0
 def test_legs_range_over_high_under_low(self):
     #end points can be handled separately 
     #this is done with the "over_high" and "under_low" keywords
     black_white_mapping = legs.PalObj(range_arr=[0.,1],over_high='extend',under_low='exact')
     data = [0.000, 0.366, 0.733, 1.100] #    1.1 is above [0,1] range of the palette
     rgb_img = black_white_mapping.to_rgb(data) #No error is raised
     #                           data value  color
     ans = [[255, 255, 255],   #    0.000    white 
            [161, 161, 161],   #    0.366    grey 
            [ 68,  68,  68],   #    0.733    grey
            [  0,   0,   0]]   #    1.100    black
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #9
0
 def test_legs_range_over_under(self):
     #another possibility is to extend the first and last color of the palette beyond the range of the palette
     #this is done with the "over_under" keyword
     black_white_mapping = legs.PalObj(range_arr=[0.,1],over_under='extend')
     data = [0.000, 0.366, 0.733, 1.100]#     1.1 is above [0,1] range of the palette
     rgb_img = black_white_mapping.to_rgb(data)
     #                           data value  color
     ans = [[255, 255, 255],   #    0.000    white
            [161, 161, 161],   #    0.366    grey 
            [ 68,  68,  68],   #    0.733    grey
            [  0,   0,   0]]   #    1.100    black
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #10
0
 def test_legs_col_arr_two_col_txt_solid_dark(self):
     #for categorical color palettes we need conly one color per legs
     #this is done with the "solid" keyword
     orange_blue_mapping = legs.PalObj(color_arr = ['orange','blue'], solid='col_dark')
     data = [0.00, 0.33, 0.66, 1.00]
     rgb_img = orange_blue_mapping.to_rgb(data)      
     #                           data value  color
     ans =  [[255,  86,   0],  #    0.00     dark orange
             [255,  86,   0],  #    0.33     dark orange
             [  0,  81, 237],  #    0.66     dark blue
             [  0,  81, 237]]  #    1.00     dark blue
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #11
0
 def test_legs_col_arr_two_col_txt_dark_pos(self):
     #by default, dark colors are associated to high data values
     #this can be changed for all color legs with the "dark_pos" keyword
     orange_blue_mapping = legs.PalObj(color_arr = ['orange','blue'], dark_pos='low')
     data = [0.00, 0.33, 0.66, 1.00]
     rgb_img = orange_blue_mapping.to_rgb(data)      
     #                           data value  color
     ans =  [[255,  86,   0],  #    0.00     dark orange
             [255, 157,  81],  #    0.33     light orange
             [ 54, 126, 242],  #    0.66     dark_blue
             [169, 222, 255]]  #    1.00     light blue
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #12
0
 def test_legs_n_col(self):
     #keyword n_col makes for easy semi-continuous palettes
     #default color order: ['brown','blue','green','orange','red','pink','purple','yellow']
     two_color_mapping = legs.PalObj(n_col=2)
     data = [0.00, 0.33, 0.66, 1.00]
     rgb_img = two_color_mapping.to_rgb(data)      
     #                           data value  color
     ans = [[223, 215, 208],   #    0.00     light brown
           [ 139, 110,  83],   #    0.33     dark brown
           [ 114, 176, 249],   #    0.66     light blue
           [   0,  81, 237]]   #    1.00     dark blue
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #13
0
 def test_legs_col_arr_one_col_txt(self):
     #if you don't like the default order, colors can be speficied directly
     #see color dictionary in col_utils for the list of available colors
     orange_mapping = legs.PalObj(color_arr = 'orange')
     data = [0.00, 0.33, 0.66, 1.00]
     rgb_img = orange_mapping.to_rgb(data)      
     #                           data value  color
     ans = [[255, 194, 124],   #    0.00     light orange
            [255, 158,  83],   #    0.33     
            [255, 122,  42],   #    0.66     
            [255,  86,   0]]   #    1.00     dark orange
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #14
0
 def test_legs_col_arr_two_col_rgb(self):
     #for exact color control, RGB values can be specified directly
     orange_blue_mapping = legs.PalObj(color_arr = [[[255, 194, 124],[255,  86,   0]],      #[light orange],[dark orange]
                                                    [[169, 222, 255],[000,  81, 237]]])     #[light blue]  ,[dark blue  ]
     data = [0.00, 0.33, 0.66, 1.00]
     rgb_img = orange_blue_mapping.to_rgb(data)      
     #                           data value  color
     ans = [[255, 194, 124],   #    0.00     light orange
            [255, 122,  42],   #    0.33     dark orange 
            [114, 176, 249],   #    0.66     light blue
            [  0,  81, 237]]   #    1.00     dark_blue
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #15
0
 def test_legs_col_arr_two_col_txt_dark_pos_diff(self):
     #for diverging palette
     #we need dark color to be associated with high and low values 
     #for different color legs
     orange_blue_mapping = legs.PalObj(color_arr = ['orange','blue'], dark_pos=['low','high'])
     data = [0.00, 0.33, 0.66, 1.00]
     rgb_img = orange_blue_mapping.to_rgb(data)      
     #                           data value  color
     ans =  [[255,  86,   0],  #    0.00     dark orange
             [255, 157,  81],  #    0.33     light orange
             [114, 176, 249],  #    0.66     light blue
             [  0,  81, 237]]  #    1.00     dark_blue
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #16
0
 def test_legs_col_excep_1(self):
     #data value with special meaning (nodata, zero, etc) can be assigned special colors 
     #using exceptions
     black_white_mapping = legs.PalObj(range_arr=[1,6],excep_val=-999.) 
     data = [1.,2,3,-999,5,6]
     rgb_img = black_white_mapping.to_rgb(data)      
     #                           data value  color
     ans =  [[255, 255, 255],  #     1       white
             [204, 204, 204],  #     2       grey
             [153, 153, 153],  #     3       grey
             [158,   0,  13],  #     -999 -> special value in red
             [ 51,  51,  51],  #     5       grey
             [  0,   0,   0]]  #     6       black
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #17
0
 def test_legs_excep_2(self):
     black_white_mapping = legs.PalObj(range_arr=[1,6],excep_val=[0, -999.],
                                                       excep_tol=[.7, 1e-3],
                                                       excep_col=['dark_blue','dark_red'])
     data = [1,-.5, 0, .5, 2, 3, 4, -999, 5, 6]
     rgb_img = black_white_mapping.to_rgb(data)      
     #                           data value  color
     ans = [[255, 255, 255],   #     1       white
            [  0,  81, 237],   #     .-5  -> special value in dark_blue
            [  0,  81, 237],   #     0    -> special value in dark_blue
            [  0,  81, 237],   #     .5   -> special value in dark_blue
            [204, 204, 204],   #     2       grey
            [153, 153, 153],   #     3       grey
            [102, 102, 102],   #     4       grey
            [158,   0,  13],   #     -999 -> special value in dark_blue
            [ 51,  51,  51],   #     5       grey
            [  0,   0,   0]]   #     6       black
     self.assertEqual(rgb_img.tolist(),ans)
Beispiel #18
0
    def test_general_lam_projection(self):
        import os, inspect
        import pickle
        import numpy as np
        import matplotlib as mpl
        import matplotlib.pyplot as plt
        import cartopy.crs as ccrs
        import cartopy.feature as cfeature
        import domutils
        import domutils._py_tools as py_tools

        # In your scripts use something like :
        import domutils.legs as legs
        import domutils.geo_tools as geo_tools
        #recover previously prepared data
        domutils_dir = os.path.dirname(domutils.__file__)
        package_dir = os.path.dirname(domutils_dir) + '/'
        source_file = package_dir + '/test_data/pal_demo_data.pickle'
        with open(source_file, 'rb') as f:
            data_dict = pickle.load(f)
        longitudes = data_dict['longitudes']  #2D longitudes [deg]
        latitudes = data_dict['latitudes']  #2D latitudes  [deg]
        ground_mask = data_dict[
            'groundMask']  #2D land fraction [0-1]; 1 = all land
        terrain_height = data_dict[
            'terrainHeight']  #2D terrain height of model [m ASL]

        #flag non-terrain (ocean and lakes) as -3333.
        inds = np.asarray((ground_mask.ravel() <= .01)).nonzero()
        if inds[0].size != 0:
            terrain_height.flat[inds] = -3333.

        #missing value
        missing = -9999.

        #pixel density of image to plot
        ratio = 0.8
        hpix = 600.  #number of horizontal pixels
        vpix = ratio * hpix  #number of vertical pixels
        img_res = (int(hpix), int(vpix))

        ##define Albers projection and extend of map
        #Obtained through trial and error for good fit of the mdel grid being plotted
        proj_aea = ccrs.AlbersEqualArea(central_longitude=-94.,
                                        central_latitude=35.,
                                        standard_parallels=(30., 40.))
        map_extent = [-104.8, -75.2, 27.8, 48.5]

        #point density for figure
        mpl.rcParams['figure.dpi'] = 400
        #larger characters
        mpl.rcParams.update({'font.size': 15})

        #instantiate figure
        fig = plt.figure(figsize=(7.5, 6.))

        #instantiate object to handle geographical projection of data
        proj_inds = geo_tools.ProjInds(src_lon=longitudes,
                                       src_lat=latitudes,
                                       extent=map_extent,
                                       dest_crs=proj_aea,
                                       image_res=img_res,
                                       missing=missing)

        #axes for this plot
        ax = fig.add_axes([.01, .1, .8, .8], projection=proj_aea)
        ax.set_extent(map_extent)

        # Set up colormapping object
        #
        # Two color segments for this palette
        red_green = [
            [[227, 209, 130], [20, 89,
                               69]],  # bottom color leg : yellow , dark green
            [[227, 209, 130], [140, 10, 10]]
        ]  #    top color leg : yellow , dark red

        map_terrain = legs.PalObj(
            range_arr=[0., 750, 1500.],
            color_arr=red_green,
            dark_pos=['low', 'high'],
            excep_val=[-3333., missing],
            excep_col=[[170, 200, 250], [120, 120, 120]],  #blue , grey_120
            over_high='extend')

        #geographical projection of data into axes space
        proj_data = proj_inds.project_data(terrain_height)

        #plot data & palette
        map_terrain.plot_data(ax=ax,
                              data=proj_data,
                              zorder=0,
                              palette='right',
                              pal_units='[meters]',
                              pal_format='{:4.0f}')  #palette options

        #add political boundaries
        ax.add_feature(cfeature.STATES.with_scale('50m'),
                       linewidth=0.5,
                       edgecolor='0.2',
                       zorder=1)

        #plot border and mask everything outside model domain
        proj_inds.plot_border(ax, mask_outside=True, linewidth=.5)

        #uncomment to save figure
        output_dir = package_dir + 'test_results/'
        if not os.path.isdir(output_dir):
            os.mkdir(output_dir)
        image_name = output_dir + 'test_general_lam_projection.svg'
        plt.savefig(image_name)
        plt.close(fig)
        print('saved: ' + image_name)

        #compare image with saved reference
        #copy reference image to testdir
        reference_image = package_dir + '/test_data/_static/' + os.path.basename(
            image_name)
        images_are_similar = py_tools.render_similarly(image_name,
                                                       reference_image)

        #test fails if images are not similar
        self.assertEqual(images_are_similar, True)
Beispiel #19
0
    def test_no_extent_in_cartopy_projection(self):
        '''
        make sure ProjInds works with projections requiring no extent
        '''

        import os
        import numpy as np
        import cartopy.crs as ccrs
        import cartopy.feature as cfeature
        import matplotlib.pyplot as plt
        import domutils
        import domutils.legs as legs
        import domutils.geo_tools as geo_tools
        import domutils._py_tools as py_tools

        regular_lons = [[-100., -100, -100], [-90., -90, -90],
                        [-80., -80, -80]]
        regular_lats = [[30, 40, 50], [30, 40, 50], [30, 40, 50]]
        data_vals = [[6.5, 3.5, .5], [7.5, 4.5, 1.5], [8.5, 5.5, 2.5]]
        missing = -9999.
        image_ratio = .5
        rec_w = 6.4  #inches!
        rec_h = image_ratio * rec_w  #inches!
        grid_w_pts = 2000.
        image_res = [grid_w_pts, image_ratio * grid_w_pts]  #100 x 50

        #cartopy projection with no extent
        proj_rob = ccrs.Robinson()

        #instantiate object to handle geographical projection of data
        # onto geoAxes with this specific crs
        ProjInds = geo_tools.ProjInds(src_lon=regular_lons,
                                      src_lat=regular_lats,
                                      dest_crs=proj_rob,
                                      image_res=image_res,
                                      extend_x=False,
                                      extend_y=False)

        #geographical projection of data into axes space
        projected_data = ProjInds.project_data(data_vals)

        #plot data to make sure it works
        #the image that is generated can be looked at to insure proper functionning of the test
        #it is not currently tested
        color_map = legs.PalObj(range_arr=[0., 9.],
                                color_arr=[
                                    'brown', 'blue', 'green', 'orange', 'red',
                                    'pink', 'purple', 'yellow', 'b_w'
                                ],
                                excep_val=missing,
                                excep_col='grey_220')
        fig_w = 9.
        fig_h = image_ratio * fig_w
        fig = plt.figure(figsize=(fig_w, fig_h))
        pos = [.1, .1, rec_w / fig_w, rec_h / fig_h]
        ax = fig.add_axes(pos, projection=proj_rob)
        x1, x2, y1, y2 = ax.get_extent()
        ax.outline_patch.set_linewidth(.3)
        projected_rgb = color_map.to_rgb(projected_data)
        ax.imshow(projected_rgb,
                  interpolation='nearest',
                  aspect='auto',
                  extent=[x1, x2, y1, y2],
                  origin='upper')
        ax.coastlines(resolution='110m',
                      linewidth=0.3,
                      edgecolor='0.3',
                      zorder=10)
        color_map.plot_palette(data_ax=ax)
        domutils_dir = os.path.dirname(domutils.__file__)
        package_dir = os.path.dirname(domutils_dir)
        test_results_dir = package_dir + '/test_results/'
        if not os.path.isdir(test_results_dir):
            os.mkdir(test_results_dir)
        svg_name = test_results_dir + '/test_no_extent_in_cartopy_projection.svg'

        plt.savefig(svg_name, dpi=500)
        plt.close(fig)
        print('saved: ' + svg_name)

        #compare image with saved reference
        #copy reference image to testdir
        reference_image = package_dir + '/test_data/_static/' + os.path.basename(
            svg_name)
        images_are_similar = py_tools.render_similarly(svg_name,
                                                       reference_image)

        #test fails if images are not similar
        self.assertEqual(images_are_similar, True)
Beispiel #20
0
def main():
    #recover previously prepared data
    currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
    parentdir  = os.path.dirname(currentdir) #directory where this package lives
    source_file = parentdir + '/test_data/pal_demo_data.pickle'
    with open(source_file, 'rb') as f:
        data_dict = pickle.load(f)
    longitudes     = data_dict['longitudes']    #2D longitudes [deg]
    latitudes      = data_dict['latitudes']     #2D latitudes  [deg]
    ground_mask    = data_dict['groundMask']    #2D land fraction [0-1]; 1 = all land
    terrain_height = data_dict['terrainHeight'] #2D terrain height of model [m ASL]
    
    #flag non-terrain (ocean and lakes) as -3333.
    inds = np.asarray( (ground_mask.ravel() <= .01) ).nonzero()
    if inds[0].size != 0:
        terrain_height.flat[inds] = -3333.

    #missing value
    missing = -9999.
    
    #pixel density of image to plot
    ratio = 0.8
    hpix = 600.       #number of horizontal pixels E-W
    vpix = ratio*hpix #number of vertical pixels   S-N
    img_res = (int(hpix),int(vpix))
    
    ##define Albers projection and extend of map
    #Obtained through trial and error for good fit of the mdel grid being plotted
    proj_aea = ccrs.AlbersEqualArea(central_longitude=-94.,
                                    central_latitude=35.,
                                    standard_parallels=(30.,40.))
    map_extent=[-104.8,-75.2,27.8,48.5]

    #point density for figure
    mpl.rcParams['figure.dpi'] = 400
    #larger characters
    mpl.rcParams.update({'font.size': 15})

    #instantiate figure
    fig = plt.figure(figsize=(7.5,6.))

    #instantiate object to handle geographical projection of data
    proj_inds = geo_tools.ProjInds(src_lon=longitudes, src_lat=latitudes,
                                   extent=map_extent,  dest_crs=proj_aea,
                                   image_res=img_res,  missing=missing)
    
    #axes for this plot
    ax = fig.add_axes([.01,.1,.8,.8], projection=proj_aea)
    ax.set_extent(map_extent)
    
    # Set up colormapping object
    #
    # Two color segments for this palette
    red_green = [[[227,209,130],[ 20, 89, 69]],    # bottom color leg : yellow , dark green
                 [[227,209,130],[140, 10, 10]]]    #    top color leg : yellow , dark red

    map_terrain = legs.PalObj(range_arr=[0., 750, 1500.],
                              color_arr=red_green, dark_pos=['low','high'],
                              excep_val=[-3333.       ,missing],
                              excep_col=[[170,200,250],[120,120,120]],  #blue , grey_120
                              over_high='extend')
    
    #geographical projection of data into axes space
    proj_data = proj_inds.project_data(terrain_height)
    
    #plot data & palette
    map_terrain.plot_data(ax=ax,data=proj_data, zorder=0,
                         palette='right', pal_units='[meters]', pal_format='{:4.0f}')   #palette options
    
    #add political boundaries
    ax.add_feature(cfeature.STATES.with_scale('50m'), linewidth=0.5, edgecolor='0.2',zorder=1)
    
    #plot border and mask everything outside model domain
    proj_inds.plot_border(ax, mask_outside=True, linewidth=.5)
Beispiel #21
0
def plot_rdpr_rdqi(fst_file: str = None,
                   this_date: Any = None,
                   fig_dir: Optional[str] = None,
                   fig_format: Optional[str] = 'gif',
                   args=None):
    """ plot RDPR and RDQI from a rpn "standard" file 

    Data needs to be at correct valid time

    If the file does not exist, the image will display "Non existing file"

    Args:

        fst_file:   full path of standard file to read
        this_date:  validity time of data to plot
        fig_dir:    directory where figures will be written

    
    Returns:

        Nothing, only plot a figure

    """

    import os
    from os import linesep as newline
    import datetime
    import logging
    import numpy as np
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    from packaging import version
    import cartopy
    import cartopy.crs as ccrs
    import cartopy.feature as cfeature
    import domutils.legs as legs
    import domcmc.fst_tools as fst_tools
    import domutils.geo_tools as geo_tools
    import domutils._py_tools as dpy

    #logging
    logger = logging.getLogger(__name__)

    #use provided data path for cartiopy shapefiles
    #TODO there has got to be a better way to do this!
    if args is not None:
        if hasattr(args, 'cartopy_dir'):
            if args.cartopy_dir is not None:
                cartopy.config['pre_existing_data_dir'] = args.cartopy_dir

    #Read data
    logger.info('Reading RDPR and RDQI from: ' + fst_file)
    pr_dict = fst_tools.get_data(file_name=fst_file,
                                 var_name='RDPR',
                                 datev=this_date,
                                 latlon=True)
    qi_dict = fst_tools.get_data(file_name=fst_file,
                                 var_name='RDQI',
                                 datev=this_date)

    #value assigned to missing data
    missing = -9999.

    #make figure directory if it does not exist
    dpy.parallel_mkdir(fig_dir)

    #setup figure properties
    ratio = 0.5
    fig_name_recipe = '%Y%m%d_%H%M.svg'
    # all sizes are inches for consistency with matplotlib
    rec_w = 6.  # Horizontal size of a panel  /2.54 for dimensions in cm
    rec_h = ratio * rec_w  # Vertical size of a panel
    sp_w = .1  # horizontal space between panels
    sp_h = .5  # vertical space between panels
    pal_sp = .1  # spavce between panel and palette
    pal_w = .25  # width of palette
    tit_h = 1.  # height of title
    xp = .04  # axes relative x position of image caption
    yp = 1.05  # axes relative y position of image caption
    dpi = 500  # density of pixel for figure
    #size of figure
    fig_w = 3. + 2 * (sp_w + rec_w + pal_w + pal_sp)
    fig_h = 2. * sp_h + sp_h + rec_h + tit_h
    #normalize all dimensions
    rec_w /= fig_w
    rec_h /= fig_h
    sp_w /= fig_w
    sp_h /= fig_h
    pal_sp /= fig_w
    pal_w /= fig_w
    tit_h /= fig_h
    # matplotlib global settings
    mpl.rcParams.update({'font.size': 24})
    # Use this for editable text in svg
    mpl.rcParams['text.usetex'] = False
    mpl.rcParams['svg.fonttype'] = 'none'
    # Hi def figure
    mpl.rcParams['figure.dpi'] = dpi
    # instantiate figure
    fig = plt.figure(figsize=(fig_w, fig_h))

    ax = fig.add_axes([0, 0, 1, 1], zorder=0)
    ax.axis('off')
    ax.annotate(this_date.strftime('%Y-%m-%d %H:%M'),
                size=35,
                xy=(0.015, 0.92),
                xycoords='figure fraction',
                bbox=dict(boxstyle="round", fc=[1, 1, 1, .9], ec=[1, 1, 1, 0]))

    if pr_dict is None:
        #data not found or not available at desired date
        #print warning and make empty image
        message = ('RDPR not available in file: ' + newline + fst_file +
                   newline + 'at date' + newline + str(this_date))
        logger.warning(message)
        ax = fig.add_axes([0, 0, 1, 1])
        ax.axis('off')
        ax.annotate(message, size=18, xy=(.1, .5), xycoords='axes fraction')
    else:
        #PR found in file, proceed to plot it

        #setup color mapping objects:
        #
        #Precip rate
        map_pr = legs.PalObj(range_arr=[.1, 3., 6., 12., 25., 50., 100.],
                             n_col=6,
                             over_high='extend',
                             under_low='white',
                             excep_val=missing,
                             excep_col='grey_200')
        #custom pastel color segments for QI index
        pastel = [
            [[255, 190, 187], [230, 104, 96]],  #pale/dark red
            [[255, 185, 255], [147, 78, 172]],  #pale/dark purple
            [[255, 227, 215], [205, 144, 73]],  #pale/dark brown
            [[210, 235, 255], [58, 134, 237]],  #pale/dark blue
            [[223, 255, 232], [61, 189, 63]]
        ]  #pale/dark green
        map_qi = legs.PalObj(range_arr=[0., 1.],
                             dark_pos='high',
                             color_arr=pastel,
                             excep_val=[missing, 0.],
                             excep_col=['grey_220', 'white'])

        #Setup geographical projection
        # Full HRDPS grid
        pole_latitude = 35.7
        pole_longitude = 65.5
        lat_0 = 48.8
        delta_lat = 10.
        lon_0 = 266.00
        delta_lon = 40.
        map_extent = [
            lon_0 - delta_lon, lon_0 + delta_lon, lat_0 - delta_lat,
            lat_0 + delta_lat
        ]
        proj_aea = ccrs.RotatedPole(pole_latitude=pole_latitude,
                                    pole_longitude=pole_longitude)
        logger.info('Making projection object')
        proj_obj = geo_tools.ProjInds(src_lon=pr_dict['lon'],
                                      src_lat=pr_dict['lat'],
                                      extent=map_extent,
                                      dest_crs=proj_aea,
                                      image_res=(800, 400))

        #plot precip rate
        #
        #position of this fig
        x0 = sp_w + 0. * (rec_w + sp_w)
        y0 = sp_h + 0. * (rec_h + sp_h)
        pos = [x0, y0, rec_w, rec_h]
        #setup axes
        ax = fig.add_axes(pos, projection=proj_aea)
        ax.set_extent(map_extent)
        #thinner lines
        if version.parse(cartopy.__version__) >= version.parse("0.18.0"):
            ax.spines['geo'].set_linewidth(0.3)
        else:
            ax.outline_patch.set_linewidth(0.3)
        #plot image caption
        ax.annotate('RDPR', size=30, xy=(xp, yp), xycoords='axes fraction')
        #geographical projection of data
        projected_pr = proj_obj.project_data(pr_dict['values'])
        #apply color mapping n plot data
        map_pr.plot_data(ax,
                         projected_pr,
                         palette='right',
                         pal_linewidth=0.3,
                         pal_units='[mm/h]',
                         pal_format='{:5.1f}',
                         equal_legs=True)
        #force axes to respect ratio we previously indicated...
        ax.set_aspect('auto')
        #plot geographical contours
        ax.add_feature(cfeature.STATES.with_scale('50m'),
                       linewidth=0.3,
                       edgecolor='0.3',
                       zorder=1)
        #plot border
        proj_obj.plot_border(ax, mask_outside=True, linewidth=.3)

        #plot quality index
        #
        #position of this fig
        x0 = sp_w + 1. * (rec_w + sp_w + pal_sp + pal_w + 1.5 / fig_w)
        y0 = sp_h + 0. * (rec_h + sp_h)
        pos = [x0, y0, rec_w, rec_h]
        #setup axes
        ax = fig.add_axes(pos, projection=proj_aea)
        ax.set_extent(map_extent)
        #thinner lines
        if version.parse(cartopy.__version__) >= version.parse("0.18.0"):
            ax.spines['geo'].set_linewidth(0.3)
        else:
            ax.outline_patch.set_linewidth(0.3)
        #plot image caption
        ax.annotate('RDQI', size=30, xy=(xp, yp), xycoords='axes fraction')
        if qi_dict is None:
            #QI not available indicate it on figure
            message = 'RDQI not available in file: ' + newline + fst_file
            logger.warning.warn(message)
            ax.annotate(message,
                        size=10,
                        xy=(.0, .5),
                        xycoords='axes fraction')
        else:
            #QI is available, plot it
            #
            #geographical projection of data
            projected_qi = proj_obj.project_data(qi_dict['values'])
            #apply color mapping n plot data
            map_qi.plot_data(ax,
                             projected_qi,
                             palette='right',
                             pal_linewidth=0.3,
                             pal_units='[unitless]',
                             pal_format='{:2.1f}')
            #force axes to respect ratio we previously indicated...
            ax.set_aspect('auto')
            #plot geographical contours
            ax.add_feature(cfeature.STATES.with_scale('50m'),
                           linewidth=0.3,
                           edgecolor='0.3',
                           zorder=1)
            #plot border
            proj_obj.plot_border(ax, mask_outside=True, linewidth=.3)

    #save figure
    svg_name = fig_dir + this_date.strftime(fig_name_recipe)
    logger.info('Saving figure:' + svg_name +
                ', changing typeface and converting format if needed.')
    plt.savefig(svg_name)
    plt.close(fig)

    dpy.lmroman(svg_name)
    if fig_format != 'svg':
        dpy.convert(svg_name,
                    fig_format,
                    del_orig=True,
                    density=500,
                    geometry='50%')

    #not sure what is accumulating but adding this garbage collection step
    #prevents jobs from aborting when a large number of files are made
    #gc.collect()
    #not sure if needed anymore... keeping commented command here just in case.

    logger.info('plot_rdpr_rdqi Done')
Beispiel #22
0
def main():

    #recover previously prepared data
    currentdir = os.path.dirname(
        os.path.abspath(inspect.getfile(inspect.currentframe())))
    parentdir = os.path.dirname(
        currentdir)  #directory where this package lives
    source_file = parentdir + '/test_data/goes_gpm_data.pickle'
    with open(source_file, 'rb') as f:
        data_dict = pickle.load(f)
    dpr_lats = data_dict['dprLats']
    dpr_lons = data_dict['dprLons']
    dpr_pr = data_dict['dprPrecipRate']
    goes_lats = data_dict['goesLats']
    goes_lons = data_dict['goesLons']
    goes_albedo = data_dict['goesAlbedo']

    #missing value
    missing = -9999.

    #Figure position stuff
    pic_h = 5.4
    pic_w = 8.8
    pal_sp = .1 / pic_w
    pal_w = .25 / pic_w
    ratio = .8
    sq_sz = 6.
    rec_w = sq_sz / pic_w
    rec_h = ratio * sq_sz / pic_h
    sp_w = .1 / pic_w
    sp_h = 1.0 / pic_h
    x1 = .1 / pic_w
    y1 = .2 / pic_h

    #number of pixels of the image that will be shown
    hpix = 400.  #number of horizontal pixels E-W
    vpix = ratio * hpix  #number of vertical pixels   S-N
    img_res = (int(hpix), int(vpix))

    #point density for figure
    mpl.rcParams.update({'font.size': 17})
    #Use this to make text editable in svg files
    mpl.rcParams['text.usetex'] = False
    mpl.rcParams['svg.fonttype'] = 'none'
    #Hi def figure
    mpl.rcParams['figure.dpi'] = 400

    #instantiate figure
    fig = plt.figure(figsize=(pic_w, pic_h))

    # Set up colormapping objects

    #For precip rates
    ranges = [0., .4, .8, 1.5, 3., 6., 12.]
    map_pr = legs.PalObj(range_arr=ranges,
                         n_col=6,
                         over_high='extend',
                         under_low='white',
                         excep_val=[missing, 0.],
                         excep_col=['grey_230', 'white'])

    #For Goes albedo
    map_goes = legs.PalObj(range_arr=[0., .6],
                           over_high='extend',
                           color_arr='b_w',
                           dark_pos='low',
                           excep_val=[-1, missing],
                           excep_col=['grey_130', 'grey_130'])

    #Plot data on a domain covering North-America
    #
    #
    map_extent = [-141.0, -16., -7.0, 44.0]
    #position
    x0 = x1
    y0 = y1
    pos = [x0, y0, rec_w, rec_h]
    #border of smaller domain to plot on large figure
    map_extent_small = [-78., -68., 12., 22.]
    #
    make_panel(fig,
               pos,
               img_res,
               map_extent,
               missing,
               dpr_lats,
               dpr_lons,
               dpr_pr,
               goes_lats,
               goes_lons,
               goes_albedo,
               map_pr,
               map_goes,
               map_extent_small,
               average_dpr=True)

    #instantiate 2nd figure
    fig2 = plt.figure(figsize=(pic_w, pic_h))
    # sphinx_gallery_thumbnail_number = 2

    #Closeup on a domain in the viscinity of Haiti
    #
    #
    map_extent = map_extent_small
    #position
    x0 = x1
    y0 = y1
    pos = [x0, y0, rec_w, rec_h]
    #
    make_panel(fig2,
               pos,
               img_res,
               map_extent,
               missing,
               dpr_lats,
               dpr_lons,
               dpr_pr,
               goes_lats,
               goes_lons,
               goes_albedo,
               map_pr,
               map_goes,
               include_zero=False)

    #plot palettes
    x0 = x0 + rec_w + pal_w
    y0 = y0
    map_pr.plot_palette(pal_pos=[x0, y0, pal_w, rec_h],
                        pal_units='[mm/h]',
                        pal_format='{:2.1f}',
                        equal_legs=True)

    x0 = x0 + 5. * pal_w
    y0 = y0
    map_goes.plot_palette(pal_pos=[x0, y0, pal_w, rec_h],
                          pal_units='unitless',
                          pal_format='{:2.1f}')
def main():
    #recover previously prepared data
    currentdir = os.path.dirname(
        os.path.abspath(inspect.getfile(inspect.currentframe())))
    parentdir = os.path.dirname(
        currentdir)  #directory where this package lives
    source_file = parentdir + '/test_data/pal_demo_data.pickle'
    with open(source_file, 'rb') as f:
        data_dict = pickle.load(f)
    longitudes = data_dict['longitudes']  #2D longitudes [deg]
    latitudes = data_dict['latitudes']  #2D latitudes  [deg]
    quality_index = data_dict[
        'qualityIndex']  #2D quality index of a radar mosaic [0-1]; 1 = best quality

    #missing value
    missing = -9999.

    #pixel density of image to plot
    ratio = 0.8
    hpix = 600.  #number of horizontal pixels  E-W
    vpix = ratio * hpix  #number of vertical pixels    S-N
    img_res = (int(hpix), int(vpix))

    ##define Albers projection and extend of map
    #Obtained through trial and error for good fit of the mdel grid being plotted
    proj_aea = ccrs.AlbersEqualArea(central_longitude=-94.,
                                    central_latitude=35.,
                                    standard_parallels=(30., 40.))
    map_extent = [-104.8, -75.2, 27.8, 48.5]

    #point density for figure
    mpl.rcParams['figure.dpi'] = 400
    #larger characters
    mpl.rcParams.update({'font.size': 15})

    #instantiate figure
    fig = plt.figure(figsize=(7.5, 6.))

    #instantiate object to handle geographical projection of data
    proj_inds = geo_tools.ProjInds(src_lon=longitudes,
                                   src_lat=latitudes,
                                   extent=map_extent,
                                   dest_crs=proj_aea,
                                   image_res=img_res,
                                   missing=missing)

    #axes for this plot
    ax = fig.add_axes([.01, .1, .8, .8], projection=proj_aea)
    ax.set_extent(map_extent)

    # Set up colormapping object
    #
    #custom pastel color segments
    pastel = [
        [[255, 190, 187], [230, 104, 96]],  #pale/dark red
        [[255, 185, 255], [147, 78, 172]],  #pale/dark purple
        [[255, 227, 215], [205, 144, 73]],  #pale/dark brown
        [[210, 235, 255], [58, 134, 237]],  #pale/dark blue
        [[223, 255, 232], [61, 189, 63]]
    ]  #pale/dark green

    #init color mapping object
    map_qi = legs.PalObj(range_arr=[0., 1.],
                         dark_pos='high',
                         color_arr=pastel,
                         excep_val=[missing],
                         excep_col='grey_120')

    #geographical projection of data into axes space
    proj_data = proj_inds.project_data(quality_index)

    #plot data & palette
    map_qi.plot_data(ax=ax,
                     data=proj_data,
                     zorder=0,
                     palette='right',
                     pal_units='[unitless]',
                     pal_format='{:2.1f}')  #palette options

    #add political boundaries
    ax.add_feature(cfeature.STATES.with_scale('50m'),
                   linewidth=0.5,
                   edgecolor='0.2',
                   zorder=1)

    #plot border and mask everything outside model domain
    proj_inds.plot_border(ax, mask_outside=True, linewidth=.5)
Beispiel #24
0
def main():

    import os, inspect
    import copy
    import numpy as np
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    import cartopy.crs as ccrs
    
    # imports from domutils
    import domutils.legs as legs
    import domutils.geo_tools   as geo_tools
    import domutils.radar_tools as radar_tools

    #missing values ane the associated color
    missing  = -9999.
    missing_color = 'grey_160'
    undetect = -3333.
    undetect_color = 'grey_180'

    #file to read
    currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
    parentdir  = os.path.dirname(currentdir) #directory where this package lives
    odim_file = parentdir + '/test_data/odimh5_radar_volume_scans/2019071120_24_ODIMH5_PVOL6S_VOL.qc.casbv.h5'

    #Read a PPI from a volume scan in the ODIM H5 format
    #we want the PPI with a nominal elevation of 0.4 degree
    #we retrieve reflectivity (dbzh) and Doppler velocity (vradh) and the Depolarization ratio (dr)
    #the reader computes the lat/lon of data points in the PPI for you
    out_dict = radar_tools.read_h5_vol(odim_file=odim_file, 
                                       elevations=[0.4], 
                                       quantities=['dbzh','vradh','dr'],
                                       no_data=missing, undetect=undetect,
                                       include_quality=True,
                                       latlon=True)
    #radar properties
    radar_lat    = out_dict['radar_lat']
    radar_lon    = out_dict['radar_lon']
    #PPIs
    # You can see the quantities available in the dict with 
    # print(out_dict['0.4'].keys())
    reflectivity = out_dict['0.4']['dbzh']
    doppvelocity = out_dict['0.4']['vradh']
    dr           = out_dict['0.4']['dr']
    tot_qi       = out_dict['0.4']['quality_qi_total']
    latitudes    = out_dict['0.4']['latitudes']
    longitudes   = out_dict['0.4']['longitudes']


    #
    #Quality controls on Doppler velocity
    #pixel is considered weather is DR < 12 dB
    weather_target = np.where( dr < -12., 1, 0) 
    #not a weather target when DR is missing
    weather_target = np.where( np.isclose(dr, missing),  0, weather_target)  
    #not a weather target when DR is undetect
    weather_target = np.where( np.isclose(dr, undetect), 0, weather_target)  
    #a 3D representation of a boxcar filter see radar_tools API for docs on this function
    #5x5 search area in polar coordinates
    remapped_data_5 = radar_tools.median_filter.remap_data(weather_target, window=5, mode='wrap')
    #if less than 12 points (half the points in a 5x5 window) have good dr, pixel is marked as clutter
    is_clutter = np.where(np.sum(remapped_data_5, axis=2) <= 12, True, False)
    #3x3 search area in polar coordinates
    remapped_data_3 = radar_tools.median_filter.remap_data(weather_target, window=3, mode='wrap')
    #if less than 9 points (all the points in a 3x3 window) have good dr, pixel is marked as clutter
    is_clutter = np.where(np.sum(remapped_data_3, axis=2) < 9, True, is_clutter)
    #
    doppvelocity_qc = copy.deepcopy(doppvelocity)
    #DR filtering only applied to points with reflectivities < 35 dB
    doppvelocity_qc = np.where( np.logical_and(is_clutter , reflectivity < 35.) , undetect, doppvelocity_qc)
    #add filtering using total quality index
    doppvelocity_qc = np.where( tot_qi <  0.2 ,                                   undetect, doppvelocity_qc)


    #pixel density of panels in figure
    ratio = 1.
    hpix = 800.       #number of horizontal pixels E-W
    vpix = ratio*hpix #number of vertical pixels   S-N
    img_res = (int(hpix),int(vpix))
    
    #cartopy Rotated Pole projection
    pole_latitude=90.
    pole_longitude=0.
    proj_rp = ccrs.RotatedPole(pole_latitude=pole_latitude, pole_longitude=pole_longitude)
    #plate carree 
    proj_pc = ccrs.PlateCarree()

    #a domain ~250km around the Montreal area where the radar is
    lat_0 = 45.7063
    delta_lat = 2.18
    lon_0 = -73.85
    delta_lon = 3.12
    map_extent=[lon_0-delta_lon, lon_0+delta_lon, lat_0-delta_lat, lat_0+delta_lat]  

    #a smaller domain for a closeup that will be inlaid in figure
    lat_0 = 46.4329666
    delta_lat = 0.072666
    lon_0 = -75.00555
    delta_lon = 0.104
    map_extent_close=[lon_0-delta_lon, lon_0+delta_lon, lat_0-delta_lat, lat_0+delta_lat]  
    #a circular clipping mask for the closeup axes
    x = np.linspace(-1., 1, int(hpix))
    y = np.linspace(-1., 1, int(vpix))
    xx, yy = np.meshgrid(x, y, indexing='ij')
    clip_alpha = np.where( np.sqrt(xx**2.+yy**2.) < 1., 1., 0. )
    #a circular line around the center of the closeup window
    radius=8. #km
    azimuths = np.arange(0,361.)#360 degree will be included for full circles
    closeup_lons, closeup_lats = geo_tools.lat_lon_range_az(lon_0, lat_0, radius, azimuths)
    #a line 5km long for showing scale in closeup insert
    azimuth = 90 #meteorological angle
    distance = np.linspace(0,5.,50)#360 degree will be included for full circles
    scale_lons, scale_lats = geo_tools.lat_lon_range_az(lon_0-0.07, lat_0-0.04, distance, azimuth)
    

    #point density for figure
    mpl.rcParams['figure.dpi'] = 100.   #crank this up for high def images
    # Use this for editable text in svg (eg with Inkscape)
    mpl.rcParams['text.usetex']  = False
    mpl.rcParams['svg.fonttype'] = 'none'
    #larger characters
    mpl.rcParams.update({'font.size': 25})


    # dimensions for figure panels and spaces
    # all sizes are inches for consistency with matplotlib
    fig_w = 13.5           # Width of figure
    fig_h = 12.5           # Height of figure
    rec_w = 5.             # Horizontal size of a panel
    rec_h = ratio * rec_w  # Vertical size of a panel
    sp_w = .5              # horizontal space between panels
    sp_h = .8              # vertical space between panels
    fig = plt.figure(figsize=(fig_w,fig_h))
    xp = .02               #coords of title (axes normalized coordinates)
    yp = 1.02
    #coords for the closeup  that is overlayed 
    x0 = .55               #x-coord of bottom left position of closeup (axes coords)
    y0 = .55               #y-coord of bottom left position of closeup (axes coords)
    dx = .4                #x-size of closeup axes (fraction of a "regular" panel)
    dy = .4                #y-size of closeup axes (fraction of a "regular" panel)
    #normalize sizes to obtain figure coordinates (0-1 both horizontally and vertically)
    rec_w = rec_w / fig_w
    rec_h = rec_h / fig_h
    sp_w  = sp_w  / fig_w
    sp_h  = sp_h  / fig_h

    #instantiate objects to handle geographical projection of data
    proj_inds = geo_tools.ProjInds(src_lon=longitudes, src_lat=latitudes,
                                   extent=map_extent,  dest_crs=proj_rp,
                                   extend_x=False, extend_y=True,
                                   image_res=img_res,  missing=missing)
    #for closeup image
    proj_inds_close = geo_tools.ProjInds(src_lon=longitudes, src_lat=latitudes,
                                         extent=map_extent_close,  dest_crs=proj_rp,
                                         extend_x=False, extend_y=True,
                                         image_res=img_res,  missing=missing)


    #
    #Reflectivity
    #
    #axes for this plot
    pos = [sp_w, sp_h+(sp_h+rec_h), rec_w, rec_h]
    ax = fig.add_axes(pos, projection=proj_rp)
    ax.spines['geo'].set_linewidth(0.3)
    ax.set_extent(map_extent)
    ax.set_aspect('auto')

    ax.annotate('Qced Reflectivity', size=30,
                xy=(xp, yp), xycoords='axes fraction')
    
    # colormapping object for reflectivity
    map_reflectivity = legs.PalObj(range_arr=[0.,60], 
                                   n_col=6,
                                   over_high='extend',
                                   under_low='white', 
                                   excep_val=[missing,       undetect], 
                                   excep_col=[missing_color, undetect_color])

    #geographical projection of data into axes space
    proj_data = proj_inds.project_data(reflectivity)
    
    #plot data & palette
    map_reflectivity.plot_data(ax=ax, data=proj_data, zorder=0,
                               palette='right', 
                               pal_units='[dBZ]', pal_format='{:3.0f}')  
    
    #add political boundaries
    add_feature(ax)

    #radar circles and azimuths
    radar_ax_circ(ax, radar_lat, radar_lon)

    #circle indicating closeup area
    ax.plot(closeup_lons, closeup_lats, transform=proj_pc, c=(0.,0.,0.), zorder=300, linewidth=.8)

    #arrow pointing to closeup
    ax.annotate("", xy=(0.33, 0.67), xytext=(.55, .74),  xycoords='axes fraction', 
                arrowprops=dict(arrowstyle="<-"))

    #
    #Closeup of reflectivity 
    #
    pos = [sp_w+x0*rec_w, sp_h+(sp_h+rec_h)+y0*rec_h, dx*rec_w, dy*rec_h]
    ax2 = fig.add_axes(pos, projection=proj_rp, label='reflectivity overlay')
    ax2.set_extent(map_extent_close)
    ax2.spines['geo'].set_linewidth(0.0)  #no border line
    ax2.set_facecolor((1.,1.,1.,0.))      #transparent background
    
    #geographical projection of data into axes space
    proj_data = proj_inds_close.project_data(reflectivity)
    
    #RGB values for data to plot
    closeup_rgb = map_reflectivity.to_rgb(proj_data)

    #get corners of image in data space
    extent_data_space = ax2.get_extent()

    ## another way of doing the same thing is to get an object that convers axes coords to data coords
    ## this method is more powerfull as it will return data coords of any points in axes space
    #transform_data_to_axes = ax2.transData + ax2.transAxes.inverted()
    #transform_axes_to_data = transform_data_to_axes.inverted()
    #pts = ((0.,0.),(1.,1.)) #axes space coords
    #pt1, pt2 = transform_axes_to_data.transform(pts)
    #extent_data_space = [pt1[0],pt2[0],pt1[1],pt2[1]]
    
    #add alpha channel (transparency) to closeup image 
    rgba = np.concatenate([closeup_rgb/255.,clip_alpha[...,np.newaxis]], axis=2)

    #plot image
    ax2.imshow(rgba, interpolation='nearest', 
               origin='upper', extent=extent_data_space, zorder=100)
    ax2.set_aspect('auto')

    #circle indicating closeup area
    circle = ax2.plot(closeup_lons, closeup_lats, transform=proj_pc, c=(0.,0.,0.), zorder=300, linewidth=1.5)
    #prevent clipping of the circle we just drawn
    for line in ax2.lines:
        line.set_clip_on(False)


    #
    #Quality Controlled Doppler velocity
    #
    #axes for this plot
    pos = [sp_w+(sp_w+rec_w+1./fig_w), sp_h+(sp_h+rec_h), rec_w, rec_h]
    ax = fig.add_axes(pos, projection=proj_rp)
    ax.set_extent(map_extent)
    ax.set_aspect('auto')

    ax.annotate('Qced Doppler velocity', size=30,
                xy=(xp, yp), xycoords='axes fraction')

    #from https://colorbrewer2.org
    brown_purple=[[ 45,  0, 75],
                  [ 84, 39,136],
                  [128,115,172],
                  [178,171,210],
                  [216,218,235],
                  [247,247,247],
                  [254,224,182],
                  [253,184, 99],
                  [224,130, 20],
                  [179, 88,  6],
                  [127, 59,  8]]
    range_arr = [-48.,-40.,-30.,-20,-10.,-1.,1.,10.,20.,30.,40.,48.]

    map_dvel = legs.PalObj(range_arr=range_arr, 
                           color_arr = brown_purple,
                           solid='supplied',
                           excep_val=[missing, undetect], 
                           excep_col=[missing_color, undetect_color])

    #geographical projection of data into axes space
    proj_data = proj_inds.project_data(doppvelocity_qc)

    #plot data & palette
    map_dvel.plot_data(ax=ax,data=proj_data, zorder=0,
                       palette='right', pal_units='[m/s]', pal_format='{:3.0f}')   #palette options
    
    #add political boundaries
    add_feature(ax)

    #radar circles and azimuths
    radar_ax_circ(ax, radar_lat, radar_lon)

    #circle indicating closeup area
    ax.plot(closeup_lons, closeup_lats, transform=proj_pc, c=(0.,0.,0.), zorder=300, linewidth=.8)

    #arrow pointing to closeup
    ax.annotate("", xy=(0.33, 0.67), xytext=(.55, .74),  xycoords='axes fraction', 
                arrowprops=dict(arrowstyle="<-"))

    #
    #Closeup of Doppler velocity 
    #
    pos = [sp_w+1.*(sp_w+rec_w+1./fig_w)+x0*rec_w, sp_h+(sp_h+rec_h)+y0*rec_h, dx*rec_w, dy*rec_h]
    ax2 = fig.add_axes(pos, projection=proj_rp, label='overlay')
    ax2.set_extent(map_extent_close)
    ax2.spines['geo'].set_linewidth(0.0) #no border line
    ax2.set_facecolor((1.,1.,1.,0.))     #transparent background
    
    #geographical projection of data into axes space
    proj_data = proj_inds_close.project_data(doppvelocity_qc)
    
    #RGB values for data to plot
    closeup_rgb = map_dvel.to_rgb(proj_data)

    #get corners of image in data space
    extent_data_space = ax2.get_extent()
    
    #add alpha channel (transparency) to closeup image 
    rgba = np.concatenate([closeup_rgb/255.,clip_alpha[...,np.newaxis]], axis=2)

    #plot image
    ax2.imshow(rgba, interpolation='nearest', 
               origin='upper', extent=extent_data_space, zorder=100)
    ax2.set_aspect('auto')

    #line indicating closeup area
    circle = ax2.plot(closeup_lons, closeup_lats, transform=proj_pc, c=(0.,0.,0.), zorder=300, linewidth=1.5)
    for line in ax2.lines:
        line.set_clip_on(False)

    #Show scale in inlay
    ax2.plot(scale_lons, scale_lats, transform=proj_pc, c=(0.,0.,0.), zorder=300, linewidth=.8)
    ax2.annotate("5 km", size=18, xy=(.16, .25),  xycoords='axes fraction', zorder=310)


    #
    #DR
    #
    #axes for this plot
    pos = [sp_w, sp_h, rec_w, rec_h]
    ax = fig.add_axes(pos, projection=proj_rp)
    ax.set_extent(map_extent)
    ax.set_aspect('auto')

    ax.annotate('Depolarization ratio', size=30,
                xy=(xp, yp), xycoords='axes fraction')

    # Set up colormapping object
    map_dr = legs.PalObj(range_arr=[-36.,-24.,-12., 0.],
                         color_arr=['purple','blue','orange'],
                         dark_pos =['high',  'high','low'],
                         excep_val=[missing,       undetect], 
                         excep_col=[missing_color, undetect_color])

    #geographical projection of data into axes space
    proj_data = proj_inds.project_data(dr)
    
    #plot data & palette
    map_dr.plot_data(ax=ax,data=proj_data, zorder=0,
                     palette='right', pal_units='[dB]', pal_format='{:3.0f}')  
    
    #add political boundaries
    add_feature(ax)

    #radar circles and azimuths
    radar_ax_circ(ax, radar_lat, radar_lon)


    #
    #Total quality index
    #
    #axes for this plot
    pos = [sp_w+(sp_w+rec_w+1./fig_w), sp_h, rec_w, rec_h]
    ax = fig.add_axes(pos, projection=proj_rp)
    ax.set_extent(map_extent)
    ax.set_aspect('auto')

    ax.annotate('Total quality index', size=30,
                xy=(xp, yp), xycoords='axes fraction')
    
    # Set up colormapping object
    pastel = [ [[255,190,187],[230,104, 96]],  #pale/dark red
               [[255,185,255],[147, 78,172]],  #pale/dark purple
               [[255,227,215],[205,144, 73]],  #pale/dark brown
               [[210,235,255],[ 58,134,237]],  #pale/dark blue
               [[223,255,232],[ 61,189, 63]] ] #pale/dark green
    map_qi = legs.PalObj(range_arr=[0., 1.],
                         dark_pos='high',
                         color_arr=pastel,
                         excep_val=[missing,       undetect], 
                         excep_col=[missing_color, undetect_color])

    #geographical projection of data into axes space
    proj_data = proj_inds.project_data(tot_qi)
    
    #plot data & palette
    map_qi.plot_data(ax=ax,data=proj_data, zorder=0,
                       palette='right', pal_units='[unitless]', pal_format='{:3.1f}')   #palette options
    
    #add political boundaries
    add_feature(ax)

    #radar circles and azimuths
    radar_ax_circ(ax, radar_lat, radar_lon)
Beispiel #25
0
 def test_apply_wrong_low_oper(self):
     with self.assertRaises(ValueError):
         map_obj = legs.PalObj()
         map_obj.lows.oper = '='
         validate.continuity_of_mapping(map_obj)
Beispiel #26
0
 def test_apply_wrong_value_discontinuous_high_oper2(self):
     with self.assertRaises(ValueError):
         map_obj = legs.PalObj()
         map_obj.lows.oper = '>'
         map_obj.cols[0].oper_low = '<'
         validate.continuity_of_mapping(map_obj)
Beispiel #27
0
 def test_apply_wrong_value_discontinuous_high_oper1(self):
     with self.assertRaises(ValueError):
         map_obj = legs.PalObj()
         map_obj.highs.oper = '>='
         map_obj.cols[-1].oper_high = '<='
         validate.continuity_of_mapping(map_obj)
Beispiel #28
0
 def test_apply_wrong_value_discontinuous_high(self):
     with self.assertRaises(ValueError):
         map_obj = legs.PalObj(n_col=2)
         map_obj.highs.val = 0.1
         validate.continuity_of_mapping(map_obj)
Beispiel #29
0
 def test_apply_bounds_mismatch(self):
     with self.assertRaises(ValueError):
         map_obj = legs.PalObj(color_arr=['red', 'blue', 'green'])
         map_obj.cols[1].val_high = 1.0
         map_obj.cols[2].val_low = 1.1
         validate.continuity_of_mapping(map_obj)
Beispiel #30
0
 def test_apply_wrong_value_oper_low(self):
     with self.assertRaises(ValueError):
         map_obj = legs.PalObj(color_arr=['red', 'blue'])
         map_obj.cols[1].oper_low = '<'
         validate.continuity_of_mapping(map_obj)