def map_lakepct(var,
                lon,
                lat,
                levels,
                title_str,
                clrmap,
                fig_name,
                alone=True,
                ax=False):

    # figure creation
    if alone:
        fig, ax = plt.subplots(1,
                               1,
                               figsize=(13, 8),
                               subplot_kw={'projection': ccrs.PlateCarree()})

    ax.add_feature(ctp.feature.OCEAN, color='gainsboro')
    ax.coastlines(color='darkgrey')

    #ax.coastlines(color="grey")

    LON, LAT = mpu.infer_interval_breaks(lon, lat)

    # add the data to the map (more info on colormaps: https://matplotlib.org/users/colormaps.html)
    cmap, norm = mpu.from_levels_and_cmap(levels, clrmap)

    # do not show zeros
    var[var == 0] = np.nan
    cmap.set_over(cmap(0.99))
    h = ax.pcolormesh(LON, LAT, var, cmap=cmap, norm=norm)
    # set the extent of the cartopy geoAxes to "global"
    ax.set_global()
    ax.set_title(title_str, pad=10, loc='right')

    # remove the frame
    ax.outline_patch.set_visible(False)

    # plot the colorbar
    cbar = mpu.colorbar(h, ax, orientation='horizontal', pad=0.1, extend='max')
    cbar.ax.set_xlabel('Natural lake area fraction [%]', size=16)
    cbar.set_ticks(np.arange(0, 110, 10))  # horizontal colorbar
    #cbar.ax.set_xticklabels(['Low', 'Medium', 'High'])  # horizontal colorbar
    # if so, save the figure
    if fig_name != 0 and alone:
        plt.savefig(fig_name + '.jpeg', dpi=1000, bbox_inches='tight')
    def plot_region_hc_map(var, region_props, lakes_path, indir_lakedata):

        # get region specific info from dictionary
        extent = region_props['extent']
        continent_extent = region_props['continent_extent']
        name = region_props['name']
        name_str = region_props['name_str']
        ax_location = region_props['ax_location']
        levels = region_props['levels']
        fig_size = region_props['fig_size']
        cb_orientation = region_props['cb_orientation']

        path_lakes = lakes_path + name + '.shp'

        # settings
        clb_label = 'Joule'
        title_str = name_str + ' heat content anomaly'
        fig_name = 'Heat_content_' + name
        cmap = 'YlOrBr'

        cmap, norm = mpu.from_levels_and_cmap(levels, cmap, extend='max')
        lon, lat = get_lonlat(indir_lakedata)
        LON, LAT = mpu.infer_interval_breaks(lon, lat)
        lakes = gpd.read_file(path_lakes)

        # plotting
        fig, ax = plt.subplots(1,
                               1,
                               figsize=fig_size,
                               subplot_kw={'projection': ccrs.PlateCarree()})

        ax.add_feature(ctp.feature.OCEAN, color='gainsboro')
        ax.coastlines(color="grey")
        # add the data to the map (more info on colormaps: https://matplotlib.org/users/colormaps.html)
        h = ax.pcolormesh(LON, LAT, var, cmap=cmap, norm=norm)
        # load the lake shapefile

        lakes.plot(ax=ax, edgecolor='gray', facecolor='none')

        # set grid lines
        gl = ax.gridlines(crs=ccrs.PlateCarree(),
                          draw_labels=True,
                          linewidth=0.5,
                          color='gainsboro',
                          alpha=0.5)
        gl.xlines = True
        gl.xformatter = LONGITUDE_FORMATTER
        gl.yformatter = LATITUDE_FORMATTER
        gl.xlabels_bottom = None
        gl.ylabels_right = None

        # set extent (in right way)
        extent[1], extent[2] = extent[2], extent[1]
        ax.set_extent(extent)

        # create effect for map borders:
        effect = Stroke(linewidth=1.5, foreground='darkgray')
        # set effect for main ax
        ax.outline_patch.set_path_effects([effect])

        # Create an inset GeoAxes showing the location of the lakes region
        #x0 y0 width height
        sub_ax = fig.add_axes(ax_location, projection=ccrs.PlateCarree())
        sub_ax.set_extent(continent_extent)
        #lakes.plot(ax=sub_ax)

        sub_ax.outline_patch.set_path_effects([effect])
        extent_box = sgeom.box(extent[0], extent[2], extent[1], extent[3])
        sub_ax.add_geometries([extent_box],
                              ccrs.PlateCarree(),
                              facecolor='none',
                              edgecolor='red',
                              linewidth=2)

        # Add the land, coastlines and the extent of the inset axis
        sub_ax.add_feature(cfeature.LAND, edgecolor='gray')
        sub_ax.coastlines(color='gray')
        extent_box = sgeom.box(extent[0], extent[2], extent[1], extent[3])
        sub_ax.add_geometries([extent_box],
                              ccrs.PlateCarree(),
                              facecolor='none',
                              edgecolor='black',
                              linewidth=2)

        # plot the colorbar
        cbar = mpu.colorbar(h,
                            ax,
                            extend='max',
                            orientation=cb_orientation,
                            pad=0.05)
        if cb_orientation == 'vertical':
            cbar.ax.set_ylabel(clb_label, size=16)
        elif cb_orientation == 'horizontal':
            cbar.ax.set_xlabel(clb_label, size=16)

        #ax.set_title(title_str, pad=10)

        plotdir = '/home/inne/documents/phd/data/processed/isimip_lakeheat/plots/'
        plt.savefig(plotdir + fig_name + '.png', dpi=500)
    def plot_global_hc_map(name_str, var, lakes_path, indir_lakedata):

        # get region specific info from dictionary
        if name_str == 'global_absolute':
            levels = np.arange(-1e17, 1.1e17, 0.1e17)
        elif name_str == 'global':
            levels = np.arange(-1e19, 1.1e19, 0.1e19)

        cb_orientation = 'horizontal'
        path_lakes = lakes_path + name_str + '.shp'

        # settings
        clb_label = 'Joule'
        title_str = name_str + ' heat content anomaly'
        fig_name = 'Heat_content_' + name_str
        cmap = 'RdBu_r'  #, 'YlOrBr'

        cmap, norm = mpu.from_levels_and_cmap(levels, cmap, extend='max')
        lon, lat = get_lonlat(indir_lakedata)
        LON, LAT = mpu.infer_interval_breaks(lon, lat)

        # plotting
        fig, ax = plt.subplots(1,
                               1,
                               figsize=(13, 8),
                               subplot_kw={'projection': ccrs.PlateCarree()})

        ax.add_feature(ctp.feature.OCEAN, color='gainsboro')
        ax.coastlines(color="grey")
        # add the data to the map (more info on colormaps: https://matplotlib.org/users/colormaps.html)
        h = ax.pcolormesh(LON, LAT, var, cmap=cmap, norm=norm)

        # set grid lines
        gl = ax.gridlines(crs=ccrs.PlateCarree(),
                          draw_labels=True,
                          linewidth=0.5,
                          color='gainsboro',
                          alpha=0.5)
        gl.xlines = True
        gl.xformatter = LONGITUDE_FORMATTER
        gl.yformatter = LATITUDE_FORMATTER
        gl.xlabels_bottom = None
        gl.ylabels_right = None

        effect = Stroke(linewidth=1.5, foreground='darkgray')
        # set effect for main ax
        ax.outline_patch.set_path_effects([effect])

        # plot the colorbar
        cbar = mpu.colorbar(h,
                            ax,
                            extend='max',
                            orientation=cb_orientation,
                            pad=0.05)
        if cb_orientation == 'vertical':
            cbar.ax.set_ylabel(clb_label, size=16)
        elif cb_orientation == 'horizontal':
            cbar.ax.set_xlabel(clb_label, size=16)

        #ax.set_title(title_str, pad=10)

        plotdir = '/home/inne/documents/phd/data/processed/isimip_lakeheat/plots/'
        plt.savefig(plotdir + fig_name + '.png')
f, ax = plt.subplots(1, 1, subplot_kw=dict(projection=ccrs.Robinson()))

h = data.plot.pcolormesh(ax=ax,
                         transform=ccrs.PlateCarree(),
                         vmin=-2,
                         vmax=2,
                         cmap="RdBu_r",
                         add_colorbar=False,
                         rasterized=True)

ax.coastlines()
ax.set_global()
ax.set_title("")

f.subplots_adjust(left=0.025, right=0.875, bottom=0.05, top=0.95)
mpu.colorbar(h, ax, extend='both')
#mpu.colorbar(h, ax, extend='max')
plt.draw()
plt.savefig(out_file, dpi=400, bbox_inches="tight")

#calculate BGP/BGC ratio
file_B17 = f'{in_dir}TSrec_{scen}_B17_{season}_850-2015sum.nc'
file_D18 = f'{in_dir}TSrec_{scen}_D18_{season}_850-2015sum.nc'

rec = (xr.open_dataset(file_B17).TSrec + xr.open_dataset(file_D18).TSrec) / 2.
BGP = rec.sum(dim=["conversion"])

ratio = (BGP / ts_map.where(ts_map > 0.01)) * 100.

#plot map of BGP/BGC ratio
data = ratio
Exemplo n.º 5
0
def horizontal_map(variable_name, date, start_hour, 
                                  end_hour, pressure_level=False, 
                                  subset=False, initiation=False, 
                                  save=False, gif=False):
    
    '''This function plots the chosen variable for the analysis 
    of the initiation environment on a horizontal (2D) map. Supported variables for plotting 
    procedure are updraft, reflectivity, helicity, pw, cape, cin, ctt, temperature_surface, 
    wind_shear, updraft_reflectivity, rh, omega, pvo, avo, theta_e, water_vapor, uv_wind and 
    divergence.'''
    
    ### Predefine some variables ###
    
    # Get the list of all needed wrf files
    data_dir = '/scratch3/thomasl/work/data/casestudy_baden/'
    
    # Define save directory
    save_dir = '/scratch3/thomasl/work/retrospective_part'                '/casestudy_baden/horizontal_maps/'

    # Change extent of plot
    subset_extent = [6.2, 9.4, 46.5, 48.5]
    
    # Set the location of the initiation of the thunderstorm
    initiation_location = CoordPair(lat=47.25, lon=7.85)

    # 2D variables:
    if variable_name == 'updraft':
        variable_name = 'W_UP_MAX'
        title_name = 'Maximum Z-Wind Updraft'
        colorbar_label = 'Max Z-Wind Updraft [$m$ $s^-$$^1$]'
        save_name = 'updraft'
        variable_min = 0
        variable_max = 30
        
        # Check if a certain pressure_level was defined.
        if pressure_level != False: 
            sys.exit('The variable {} is a 2D variable. '                      'Definition of a pressure_level for '                      'plotting process is not required.'.format(variable_name))
        
    elif variable_name == 'reflectivity':
        variable_name = 'REFD_MAX'
        title_name = 'Maximum Derived Radar Reflectivity'
        colorbar_label = 'Maximum Derived Radar Reflectivity [$dBZ$]'
        save_name = 'reflectivity'
        variable_min = 0
        variable_max = 75
        
        # Check if a certain pressure_level was defined.
        if pressure_level != False: 
            sys.exit('The variable {} is a 2D variable. '                      'Definition of a pressure_level for '                      'plotting process is not required.'.format(variable_name))
        
    elif variable_name == 'helicity':
        variable_name = 'UP_HELI_MAX'
        title_name = 'Maximum Updraft Helicity'
        colorbar_label = 'Maximum Updraft Helicity [$m^{2}$ $s^{-2}$]'
        save_name = 'helicity'
        variable_min = 0 
        variable_max = 140
        
        # Check if a certain pressure_level was defined.
        if pressure_level != False: 
            sys.exit('The variable {} is a 2D variable. '                      'Definition of a pressure_level for '                      'plotting process is not required.'.format(variable_name))
        
    elif variable_name == 'pw':
        title_name = 'Precipitable Water'
        colorbar_label = 'Precipitable Water [$kg$ $m^{-2}$]'
        save_name = 'pw'
        variable_min = 0 
        variable_max = 50 
        
        # Check if a certain pressure_level was defined.
        if pressure_level != False: 
            sys.exit('The variable {} is a 2D variable. '                      'Definition of a pressure_level for '                      'plotting process is not required.'.format(variable_name))
    
    elif variable_name == 'cape':
        variable_name = 'cape_2d'
        title_name = 'CAPE'
        colorbar_label = 'Convective Available Potential Energy'                             '[$J$ $kg^{-1}$]'
        save_name = 'cape'
        variable_min = 0 
        variable_max = 3000 
        
        # Check if a certain pressure_level was defined.
        if pressure_level != False: 
            sys.exit('The variable {} is a 2D variable. '                      'Definition of a pressure_level for '                      'plotting process is not required.'.format(variable_name))
        
    elif variable_name == 'cin':
        variable_name = 'cape_2d'
        title_name = 'CIN'
        colorbar_label = 'Convective Inhibition [$J$ $kg^{-1}$]'
        save_name = 'cin'
        variable_min = 0
        variable_max = 100 

        # Check if a certain pressure_level was defined.
        if pressure_level != False: 
            sys.exit('The variable {} is a 2D variable. '                      'Definition of a pressure_level for '                      'plotting process is not required.'.format(variable_name))
        
    elif variable_name == 'ctt':
        title_name = 'Cloud Top Temperature'
        colorbar_label = 'Cloud Top Temperature [$K$]'
        save_name = 'cct'
        variable_min = 210 
        variable_max = 300 
        
        # Check if a certain pressure_level was defined.
        if pressure_level != False: 
            sys.exit('The variable {} is a 2D variable. '                      'Definition of a pressure_level for '                      'plotting process is not required.'.format(variable_name))
    
    elif variable_name == 'temperature_surface':
        variable_name = 'T2'
        title_name = 'Temperature @ 2 m'
        colorbar_label = 'Temperature [$K$]'
        save_name = 'temperature_surface'
        variable_min = 285
        variable_max = 305

        # Check if a certain pressure_level was defined.
        if pressure_level != False: 
            sys.exit('The variable {} is a 2D variable. '                      'Definition of a pressure_level for '                      'plotting process is not required.'.format(variable_name))
            
    elif variable_name == 'wind_shear':
        variable_name = 'slp'
        title_name = 'SLP, Wind @ 850hPa, Wind @ 500hPa\n'                         'and 500-850hPa Vertical Wind Shear'
        save_name = 'wind_shear'
        variable_min = 1000
        variable_max = 1020

        # Check if a certain pressure_level was defined.
        if pressure_level != False: 
            sys.exit('The variable {} is a 2D variable. '                      'Definition of a pressure_level for '                      'plotting process is not required.'.format(variable_name))
            
    elif variable_name == 'updraft_reflectivity':
        variable_name = 'W_UP_MAX'
        title_name = 'Updraft and Reflectivity'
        colorbar_label = 'Max Z-Wind Updraft [$m$ $s^-$$^1$]'
        save_name = 'updraft_reflectivity'
        variable_min = 0
        variable_max = 30
        
        # Check if a certain pressure_level was defined.
        if pressure_level != False: 
            sys.exit('The variable {} is a 2D variable. '                      'Definition of a pressure_level for '                      'plotting process is not required.'.format(variable_name))
            
    # 3D variables:
    elif variable_name == 'rh':
        title_name = 'Relative Humidity'
        colorbar_label = 'Relative Humidity [$pct$]'
        save_name = 'rh'
        variable_min = 0
        variable_max = 100
        
        # Check if a certain pressure_level was defined.
        if pressure_level == False: 
            sys.exit('The variable {} is a 3D variable. '                      'Definition of a pressure_level for '                      'plotting process is required.'.format(variable_name))
        
    elif variable_name == 'omega':
        title_name = 'Vertical Motion'
        colorbar_label = 'Omega [$Pa$ $s^-$$^1$]'
        save_name = 'omega'
        variable_min = -50
        variable_max = 50
        
        # Check if a certain pressure_level was defined.
        if pressure_level == False: 
            sys.exit('The variable {} is a 3D variable. '                      'Definition of a pressure_level for '                      'plotting process is required.'.format(variable_name))
            
    elif variable_name == 'pvo':
        title_name = 'Potential Vorticity'
        colorbar_label = 'Potential Vorticity [$PVU$]'
        save_name = 'pvo'
        variable_min = -1 
        variable_max = 9 
        
        # Check if a certain pressure_level was defined.
        if pressure_level == False: 
            sys.exit('The variable {} is a 3D variable. '                      'Definition of a pressure_level for '                      'plotting process is required.'.format(variable_name))
            
    elif variable_name == 'avo':
        title_name = 'Absolute Vorticity'
        colorbar_label = 'Absolute Vorticity [$10^{-5}$'                             '$s^{-1}$]'
        save_name = 'avo'
        variable_min = -250
        variable_max = 250 
        
        # Check if a certain pressure_level was defined.
        if pressure_level == False: 
            sys.exit('The variable {} is a 3D variable. '                      'Definition of a pressure_level for '                      'plotting process is required.'.format(variable_name))
    
    elif variable_name == 'theta_e':
        title_name = 'Theta-E'
        colorbar_label = 'Theta-E [$K$]'
        save_name = 'theta_e'
        variable_min = 315
        variable_max = 335 
        
        # Check if a certain pressure_level was defined.
        if pressure_level == False: 
            sys.exit('The variable {} is a 3D variable. '                      'Definition of a pressure_level for '                      'plotting process is required.'.format(variable_name))
            
    elif variable_name == 'water_vapor':
        variable_name = 'QVAPOR'
        title_name = 'Water Vapor Mixing Ratio'
        colorbar_label = 'Water Vapor Mixing Ratio [$g$ $kg^{-1}$]'
        save_name = 'water_vapor'
        variable_min = 5
        variable_max = 15
        
        # Check if a certain pressure_level was defined.
        if pressure_level == False: 
            sys.exit('The variable {} is a 3D variable. '                      'Definition of a pressure_level for '                      'plotting process is required.'.format(variable_name))
    
    elif variable_name == 'uv_wind':
        variable_name = 'wspd_wdir'
        title_name = 'Wind Speed and Direction'
        colorbar_label = 'Wind Speed [$m$ $s^{-1}$]'
        save_name = 'uv_wind'
        variable_min = 0
        variable_max = 10 

        # Check if a certain pressure_level was defined.
        if pressure_level == False: 
            sys.exit('The variable {} is a 3D variable. '                      'Definition of a pressure_level for '                      'plotting process is required.'.format(variable_name))
        
    elif variable_name == 'divergence':
        variable_name = 'ua'
        title_name = 'Horizontal Wind Divergence'
        colorbar_label = 'Divergence [$10^{-6}$ $s^{-1}$]'
        save_name = 'divergence'
        variable_min = -2.5
        variable_max = 2.5
            
        # Check if a certain pressure_level was defined.
        if pressure_level == False: 
            sys.exit('The variable {} is a 3D variable. '                      'Definition of a pressure_level for '                      'plotting process is required.'.format(variable_name))
    
    # Make a list of all wrf files in data directory
    wrflist = list()
    for (dirpath, dirnames, filenames) in os.walk(data_dir):
        wrflist += [os.path.join(dirpath, file) for file in filenames]
    
    ### Plotting Iteration ###
    
    # Iterate over a list of hourly timesteps
    time = list()
    for i in range(start_hour, end_hour):
        time = str(i).zfill(2)

        # Iterate over all 5 minutes steps of hour
        for j in range(0, 60, 5):
            minutes = str(j).zfill(2)
                
            # Load the netCDF files out of the wrflist
            ncfile = [Dataset(x) for x in wrflist
                if x.endswith('{}_{}:{}:00'.format(date, time, minutes))]
            
            # Load variable(s)
            if title_name == 'CAPE':
                variable = getvar(ncfile, variable_name)[0,:]
                
            elif title_name == 'CIN':
                variable = getvar(ncfile, variable_name)[1,:]
                
            elif variable_name == 'ctt':
                variable = getvar(ncfile, variable_name, units='K')
                
            elif variable_name == 'wspd_wdir':
                variable = getvar(ncfile, variable_name)[0,:]
            
            elif variable_name == 'QVAPOR':
                variable = getvar(ncfile, variable_name)*1000 # convert to g/kg
                    
            else:
                variable = getvar(ncfile, variable_name)

            if variable_name == 'slp':
                slp = variable.squeeze()
                
                ua = getvar(ncfile, 'ua')
                va = getvar(ncfile, 'va')

                p = getvar(ncfile, 'pressure')

                u_wind850 = interplevel(ua, p, 850)
                v_wind850 = interplevel(va, p, 850)

                u_wind850 = u_wind850.squeeze()
                v_wind850 = v_wind850.squeeze()

                u_wind500 = interplevel(ua, p, 500)
                v_wind500 = interplevel(va, p, 500)

                u_wind500 = u_wind500.squeeze()
                v_wind500 = v_wind500.squeeze()

                slp = ndimage.gaussian_filter(slp, sigma=3, order=0)
            
            # Interpolating 3d data to a horizontal pressure level
            if pressure_level != False:
                p = getvar(ncfile, 'pressure')
                variable_pressure = interplevel(variable, p, 
                                                pressure_level)
                variable = variable_pressure
                
            if variable_name == 'wspd_wdir':
                ua = getvar(ncfile, 'ua')
                va = getvar(ncfile, 'va')
                u_pressure = interplevel(ua, p, pressure_level)
                v_pressure = interplevel(va, p, pressure_level)
                
            elif title_name == 'Updraft and Reflectivity':
                reflectivity = getvar(ncfile, 'REFD_MAX')
                
            elif title_name == 'Difference in Theta-E values':
                variable = getvar(ncfile, variable_name)
                
                p = getvar(ncfile, 'pressure')
                variable_pressure1 = interplevel(variable, p, '950')
                variable_pressure2 = interplevel(variable, p, '950')
                
            elif variable_name == 'ua':
                va = getvar(ncfile, 'va')

                p = getvar(ncfile, 'pressure')

                v_pressure = interplevel(va, p, pressure_level)

                u_wind = variable.squeeze()
                v_wind = v_pressure.squeeze()

                u_wind.attrs['units']='meters/second'
                v_wind.attrs['units']='meters/second'
                
                lats, lons = latlon_coords(variable)
                lats = lats.squeeze()
                lons = lons.squeeze()

                dx, dy = mpcalc.lat_lon_grid_deltas(to_np(lons), to_np(lats))

                divergence = mpcalc.divergence(u_wind, v_wind, dx, dy, dim_order='yx')
                divergence = divergence*1e3


            # Define cart projection
            lats, lons = latlon_coords(variable)
            cart_proj = ccrs.LambertConformal(central_longitude=8.722206, 
                                    central_latitude=46.73585)

            bounds = geo_bounds(wrfin=ncfile)

            # Create figure
            fig = plt.figure(figsize=(15, 10))

            if variable_name == 'slp':
                fig.patch.set_facecolor('k')

            ax = plt.axes(projection=cart_proj)

            ### Set map extent ###
            domain_extent = [3.701088, 13.814863, 43.85472,49.49499]

            if subset == True:
                ax.set_extent([subset_extent[0],subset_extent[1],
                               subset_extent[2],subset_extent[3]],
                                 ccrs.PlateCarree())
                
            else: 
                ax.set_extent([domain_extent[0]+0.7,domain_extent[1]-0.7,
                               domain_extent[2]+0.1,domain_extent[3]-0.1],
                                 ccrs.PlateCarree())

            # Plot contour of variables
            levels_num = 11
            levels = np.linspace(variable_min, variable_max, levels_num)
            
            # Creating new colormap for diverging colormaps
            def truncate_colormap(cmap, minval=0.0, maxval=1.0, n=100):
                    new_cmap = LinearSegmentedColormap.from_list(
                        'trunc({n},{a:.2f},{b:.2f})'.format(n=cmap.name, a=minval, 
                                                            b=maxval),
                        cmap(np.linspace(minval, maxval, n)))
                    return new_cmap
            
            cmap = plt.get_cmap('RdYlBu')
            
            if title_name == 'CIN':
                cmap = ListedColormap(sns.cubehelix_palette(levels_num-1, 
                                        start=.5, rot=-.75, reverse=True))
                variable_plot = plt.contourf(to_np(lons), to_np(lats), to_np(variable), 
                                 levels=levels, transform=ccrs.PlateCarree(), extend='max', 
                                 cmap=cmap)
                initiation_color = 'r*'
                
            elif variable_name == 'ctt':
                cmap = ListedColormap(sns.cubehelix_palette(levels_num-1, 
                                        start=.5, rot=-.75, reverse=True))
                variable_plot = plt.contourf(to_np(lons), to_np(lats), to_np(variable), 
                                 levels=levels, transform=ccrs.PlateCarree(), extend='both', 
                                 cmap=cmap)
                initiation_color = 'r*'
                
            elif variable_name == 'pvo':
                cmap = plt.get_cmap('RdYlBu_r')
                new_cmap = truncate_colormap(cmap, 0.05, 0.9)
                new_norm = DivergingNorm(vmin=-1., vcenter=2., vmax=10)
                
                variable_plot = plt.contourf(to_np(lons), to_np(lats), to_np(variable), 
                                 levels=levels, transform=ccrs.PlateCarree(), 
                                 cmap=new_cmap, extend='both', norm=new_norm)
                initiation_color = 'k*'
                
            elif variable_name == 'avo':
                cmap = plt.get_cmap('RdYlBu_r')
                new_cmap = truncate_colormap(cmap, 0.05, 0.9)
                new_norm = DivergingNorm(vmin=variable_min, vcenter=0, vmax=variable_max)
                
                variable_plot = plt.contourf(to_np(lons), to_np(lats), to_np(variable), 
                                 levels=levels, transform=ccrs.PlateCarree(), 
                                 cmap=new_cmap, extend='both', norm=new_norm)
                initiation_color = 'k*'
                
            elif variable_name == 'omega':
                new_cmap = truncate_colormap(cmap, 0.05, 0.9)
                new_norm = DivergingNorm(vmin=variable_min, vcenter=0, vmax=variable_max)

                variable_plot = plt.contourf(to_np(lons), to_np(lats), to_np(variable), 
                                 levels=levels, transform=ccrs.PlateCarree(), 
                                 cmap=new_cmap, extend='both', norm=new_norm)
                initiation_color = 'k*'
                
            elif variable_name == 'ua':
                new_cmap = truncate_colormap(cmap, 0.05, 0.9)
                new_norm = DivergingNorm(vmin=variable_min, vcenter=0, vmax=variable_max)

                variable_plot = plt.contourf(to_np(lons), to_np(lats), divergence, 
                                 levels=levels, transform=ccrs.PlateCarree(), 
                                 cmap=new_cmap, extend='both', norm=new_norm)
                initiation_color = 'k*'
                
            elif variable_name == 'UP_HELI_MAX' or variable_name == 'W_UP_MAX' or variable_name == 'QVAPOR':
                cmap = ListedColormap(sns.cubehelix_palette(levels_num-1, 
                                        start=.5, rot=-.75))
                variable_plot = plt.contourf(to_np(lons), to_np(lats), 
                                to_np(variable), levels=levels, extend='max',
                                transform=ccrs.PlateCarree(),cmap=cmap)
                initiation_color = 'r*'
                
            elif variable_name == 'theta_e' or variable_name == 't2':
                cmap = ListedColormap(sns.cubehelix_palette(levels_num-1, 
                                        start=.5, rot=-.75))
                variable_plot = plt.contourf(to_np(lons), to_np(lats), 
                                to_np(variable), levels=levels, extend='both',
                                transform=ccrs.PlateCarree(),cmap=cmap)
                initiation_color = 'r*'

                
            elif variable_name == 'REFD_MAX':
                levels = np.arange(5., 75., 5.)
                dbz_rgb = np.array([[4,233,231],
                                    [1,159,244], [3,0,244],
                                    [2,253,2], [1,197,1],
                                    [0,142,0], [253,248,2],
                                    [229,188,0], [253,149,0],
                                    [253,0,0], [212,0,0],
                                    [188,0,0],[248,0,253],
                                    [152,84,198]], np.float32) / 255.0
                dbz_cmap, dbz_norm = from_levels_and_colors(levels, dbz_rgb,
                                                           extend='max')
                
                variable_plot = plt.contourf(to_np(lons), to_np(lats), 
                                 to_np(variable), levels=levels, extend='max',
                                 transform=ccrs.PlateCarree(), cmap=dbz_cmap,
                                            norm=dbz_norm)
                initiation_color = 'r*'
                
            elif variable_name == 'slp':
                ax.background_patch.set_fill(False)
                    
                wslice = slice(1, None, 12)
                # Plot 850-hPa wind vectors
                vectors850 = ax.quiver(to_np(lons)[wslice, wslice], 
                                       to_np(lats)[wslice, wslice],
                                       to_np(u_wind850)[wslice, wslice], 
                                       to_np(v_wind850)[wslice, wslice],
                                       headlength=4, headwidth=3, scale=400, color='gold', 
                                       label='850mb wind', transform=ccrs.PlateCarree(), 
                                       zorder=2)

                # Plot 500-hPa wind vectors
                vectors500 = ax.quiver(to_np(lons)[wslice, wslice], 
                                       to_np(lats)[wslice, wslice],
                                       to_np(u_wind500)[wslice, wslice], 
                                       to_np(v_wind500)[wslice, wslice],
                                       headlength=4, headwidth=3, scale=400, 
                                       color='cornflowerblue', zorder=2,
                                       label='500mb wind', transform=ccrs.PlateCarree())

                # Plot 500-850 shear
                shear = ax.quiver(to_np(lons[wslice, wslice]), 
                                  to_np(lats[wslice, wslice]),
                                  to_np(u_wind500[wslice, wslice]) - 
                                  to_np(u_wind850[wslice, wslice]),
                                  to_np(v_wind500[wslice, wslice]) - 
                                  to_np(v_wind850[wslice, wslice]),
                                  headlength=4, headwidth=3, scale=400, 
                                  color='deeppink', zorder=2,
                                  label='500-850mb shear', transform=ccrs.PlateCarree())

                contour = ax.contour(to_np(lons), to_np(lats), slp, levels=levels, 
                                     colors='lime', linewidths=2, alpha=0.5, zorder=1,
                                     transform=ccrs.PlateCarree())
                ax.clabel(contour, fontsize=12, inline=1, inline_spacing=4, fmt='%i')
                
                # Add a legend
                ax.legend(('850mb wind', '500mb wind', '500-850mb shear'), loc=4)

                # Manually set colors for legend
                legend = ax.get_legend()
                legend.legendHandles[0].set_color('gold')
                legend.legendHandles[1].set_color('cornflowerblue')
                legend.legendHandles[2].set_color('deeppink')
                
                initiation_color = 'w*'
            
            else:
                cmap = ListedColormap(sns.cubehelix_palette(10, 
                                        start=.5, rot=-.75))
                variable_plot = plt.contourf(to_np(lons), to_np(lats), 
                                to_np(variable), levels=levels,
                                transform=ccrs.PlateCarree(),cmap=cmap)
                initiation_color = 'r*'
                         
            # Plot reflectivity contours with colorbar 
            if title_name == 'Updraft and Reflectivity':
                dbz_levels = np.arange(35., 75., 5.)
                dbz_rgb = np.array([[253,248,2],
                        [229,188,0], [253,149,0],
                        [253,0,0], [212,0,0],
                        [188,0,0],[248,0,253],
                        [152,84,198]], np.float32) / 255.0
                dbz_cmap, dbz_norm = from_levels_and_colors(dbz_levels, dbz_rgb,
                                               extend='max')                

                contours = plt.contour(to_np(lons), to_np(lats), 
                                           to_np(reflectivity), 
                                           levels=dbz_levels, 
                                           transform=ccrs.PlateCarree(), 
                                           cmap=dbz_cmap, norm=dbz_norm, 
                                           linewidths=1)

                cbar_refl = mpu.colorbar(contours, ax, orientation='horizontal', aspect=10, 
                                         shrink=.5, pad=0.05)
                cbar_refl.set_label('Maximum Derived Radar Reflectivity'                                         '[$dBZ$]', fontsize=12.5)
                colorbar_lines = cbar_refl.ax.get_children()
                colorbar_lines[0].set_linewidths([10]*5)
            
            # Add wind quivers for every 10th data point
            if variable_name == 'wspd_wdir':
                plt.quiver(to_np(lons[::10,::10]), to_np(lats[::10,::10]),
                            to_np(u_pressure[::10, ::10]), 
                            to_np(v_pressure[::10, ::10]),
                            transform=ccrs.PlateCarree())
            
            # Plot colorbar
            if variable_name == 'slp':
                pass
            else:
                cbar = mpu.colorbar(variable_plot, ax, orientation='vertical', aspect=40, 
                                    shrink=.05, pad=0.05)
                cbar.set_label(colorbar_label, fontsize=15)
                cbar.set_ticks(levels)
            
            # Add borders and coastlines
            if variable_name == 'slp':
                ax.add_feature(cfeature.BORDERS.with_scale('10m'), 
                           edgecolor='white', linewidth=2)
                ax.add_feature(cfeature.COASTLINE.with_scale('10m'), 
                           edgecolor='white', linewidth=2)
            else:
                ax.add_feature(cfeature.BORDERS.with_scale('10m'), 
                               linewidth=0.8)
                ax.add_feature(cfeature.COASTLINE.with_scale('10m'), 
                               linewidth=0.8)
            
            ### Add initiation location ###
            if initiation == True:
                ax.plot(initiation_location.lon, initiation_location.lat, 
                        initiation_color, markersize=20, transform=ccrs.PlateCarree())
            
            # Add gridlines
            lon = np.arange(0, 20, 1)
            lat = np.arange(40, 60, 1)

            gl = ax.gridlines(xlocs=lon, ylocs=lat, zorder=3)
            
            # Add tick labels
            mpu.yticklabels(lat, ax=ax, fontsize=12.5)
            mpu.xticklabels(lon, ax=ax, fontsize=12.5)
            
            # Make nicetime
            file_name = '{}wrfout_d02_{}_{}:{}:00'.format(data_dir, 
                                                          date, time, minutes)
            xr_file = xr.open_dataset(file_name)
            nicetime = pd.to_datetime(xr_file.QVAPOR.isel(Time=0).XTIME.values)
            nicetime = nicetime.strftime('%Y-%m-%d %H:%M')
            
            # Add plot title
            if pressure_level != False: 
                ax.set_title('{} @ {} hPa'.format(title_name, pressure_level), 
                             loc='left', fontsize=15)
                ax.set_title('Valid time: {} UTC'.format(nicetime), 
                             loc='right', fontsize=15)
            else:
                if variable_name == 'slp':
                    ax.set_title(title_name, loc='left', fontsize=15, color='white')
                    ax.set_title('Valid time: {} UTC'.format(nicetime), 
                                 loc='right', fontsize=15, color='white')
                else:
                    ax.set_title(title_name, loc='left', fontsize=20)
                    ax.set_title('Valid time: {} UTC'.format(nicetime), 
                                 loc='right', fontsize=15)

            plt.show()
            
            ### Save figure ###
            if save == True:
                if pressure_level != False: 
                    if subset == True:
                        fig.savefig('{}/{}/horizontal_map_{}_subset_{}_{}_{}:{}.png'.format(
                            save_dir, save_name, save_name, pressure_level, date, time, 
                            minutes), bbox_inches='tight', dpi=300)
                    else: 
                        fig.savefig('{}/{}/horizontal_map_{}_{}_{}_{}:{}.png'.format(
                            save_dir, save_name, save_name, pressure_level, date, time, 
                            minutes), bbox_inches='tight', dpi=300)
                
                else: 
                    if subset == True:
                        fig.savefig('{}/{}/horizontal_map_{}_subset_{}_{}:{}.png'.format(
                            save_dir, save_name, save_name, date, time, minutes),
                                    bbox_inches='tight', dpi=300, facecolor=fig.get_facecolor())
                    
                    else: 
                        fig.savefig('{}/{}/horizontal_map_{}_{}_{}:{}.png'.format(
                            save_dir, save_name, save_name, date, time, minutes), 
                                    bbox_inches='tight', dpi=300, facecolor=fig.get_facecolor())
        
    ### Make a GIF from the plots ###
    if gif == True: 
        # Predifine some variables
        gif_data_dir = save_dir + save_name
        gif_save_dir = '{}gifs/'.format(save_dir)
        gif_save_name = 'horizontal_map_{}.gif'.format(save_name)

        # GIF creating procedure
        os.chdir(gif_data_dir)

        image_folder = os.fsencode(gif_data_dir)

        filenames = []

        for file in os.listdir(image_folder):
            filename = os.fsdecode(file)
            if filename.endswith( ('.png') ):
                filenames.append(filename)

        filenames.sort()
        images = list(map(lambda filename: imageio.imread(filename), 
                          filenames))

        imageio.mimsave(os.path.join(gif_save_dir + gif_save_name), 
                        images, duration = 0.50)
h.add_grid(increment=20)

# Add wind speed colored line
cmap = ListedColormap(sns.cubehelix_palette(10, start=.5, rot=-.75))
levels = np.linspace(0, 20, 11)
wind_speed_h = h.plot_colormapped(u,
                                  v,
                                  wind_speed,
                                  intervals=levels,
                                  cmap=cmap)

# Add color bar for hodograph
cbar_h = mpu.colorbar(wind_speed_h,
                      ax_hod,
                      orientation='vertical',
                      aspect=30,
                      shrink=.05,
                      pad=0.1,
                      extend='max')
cbar_h.set_label('Wind Speed [$kn$]', fontsize=10)
cbar_h.set_ticks(levels)

# Set label of axes
skew.ax.set_ylabel('Pressure [$hPa$]', fontsize=12.5)
skew.ax.set_xlabel('Temperature [$°C$]', fontsize=12.5)

# Make nicetime
nicetime = pd.to_datetime(date)

# Add title
skew.ax.set_title('')
def cross_section(variable_name,
                  date,
                  time,
                  start_lat,
                  start_lon,
                  end_lat,
                  end_lon,
                  save=False):
    '''This function plots a vertical cross section of the chosen 
    variable. Supported variables for plotting procedure are 
    vertical_velocity, rh, omega, absolute_vorticity, theta_e and
    reflectivity.'''

    ### Predefine some variables ###
    # Define data filename
    data_dir = '/scratch3/thomasl/work/data/casestudy_baden/'
    filename = '{}wrfout_d02_{}_{}:00'.format(data_dir, date, time)

    # Define save directory
    save_dir = '/scratch3/thomasl/work/retrospective_part/' 'casestudy_baden/cross_section/'

    # Create the start point and end point for the cross section
    start_point = CoordPair(lat=start_lat, lon=start_lon)
    end_point = CoordPair(lat=end_lat, lon=end_lon)

    ### Start plotting procedure ###
    # Open NetCDF file
    ncfile = Dataset(filename)

    # Extract the model height, terrain height and variables
    ht = getvar(ncfile, 'z') / 1000  # change to km
    ter = getvar(ncfile, 'ter') / 1000

    if variable_name == 'vertical_velocity':
        variable = getvar(ncfile, 'wa', units='kt')
        title_name = 'Vertical Velocity'
        colorbar_label = 'Vertical Velocity [$kn$]'
        variable_min = -2
        variable_max = 2

    elif variable_name == 'rh':
        variable = getvar(ncfile, 'rh')
        title_name = 'Relative Humidity'
        colorbar_label = 'Relative Humidity [$pct$]'
        variable_min = 0
        variable_max = 100

    elif variable_name == 'omega':
        variable = getvar(ncfile, 'omega')
        title_name = 'Vertical Motion (Omega)'
        colorbar_label = 'Omega [$Pa$ $s^-$$^1$]'
        variable_min = -5
        variable_max = 5

    elif variable_name == 'absolute_vorticity':
        variable = getvar(ncfile, 'avo')
        title_name = 'Absolute Vorticity'
        colorbar_label = 'Absolute Vorticity [$10^{-5}$' '$s^{-1}$]'
        variable_min = -50
        variable_max = 100

    elif variable_name == 'theta_e':
        variable = getvar(ncfile, 'theta_e')
        title_name = 'Theta-E'
        colorbar_label = 'Theta-E [$K$]'
        variable_min = 315
        variable_max = 335

    elif variable_name == 'reflectivity':
        variable = getvar(ncfile, 'dbz')  #, timeidx=-1
        title_name = 'Reflectivity'
        colorbar_label = 'Reflectivity [$dBZ$]'
        variable_min = 5
        variable_max = 75

    # Linear Z for interpolation
    Z = 10**(variable / 10)

    # Compute the vertical cross-section interpolation
    z_cross = vertcross(Z,
                        ht,
                        wrfin=ncfile,
                        start_point=start_point,
                        end_point=end_point,
                        latlon=True,
                        meta=True)

    # Convert back after interpolation
    variable_cross = 10.0 * np.log10(z_cross)

    # Make a copy of the z cross data
    variable_cross_filled = np.ma.copy(to_np(variable_cross))

    # For each cross section column, find the first index with
    # non-missing values and copy these to the missing elements below
    for i in range(variable_cross_filled.shape[-1]):
        column_vals = variable_cross_filled[:, i]
        first_idx = int(np.transpose((column_vals > -200).nonzero())[0])
        variable_cross_filled[0:first_idx,
                              i] = variable_cross_filled[first_idx, i]

    ter_line = interpline(ter,
                          wrfin=ncfile,
                          start_point=start_point,
                          end_point=end_point)

    # Get latitude and longitude points
    lats, lons = latlon_coords(variable)

    # Create the figure
    fig = plt.figure(figsize=(15, 10))
    ax = plt.axes()

    ys = to_np(variable_cross.coords['vertical'])
    xs = np.arange(0, variable_cross.shape[-1], 1)

    # Make contour plot
    if variable_name == 'reflectivity':
        levels = np.arange(variable_min, variable_max, 5)

        # Create the dbz color table found on NWS pages.
        dbz_rgb = np.array(
            [[4, 233, 231], [1, 159, 244], [3, 0, 244], [2, 253, 2],
             [1, 197, 1], [0, 142, 0], [253, 248, 2], [229, 188, 0],
             [253, 149, 0], [253, 0, 0], [212, 0, 0], [188, 0, 0],
             [248, 0, 253], [152, 84, 198]], np.float32) / 255.0

        dbz_cmap, dbz_norm = from_levels_and_colors(levels,
                                                    dbz_rgb,
                                                    extend='max')

    else:
        levels = np.linspace(variable_min, variable_max, 11)

    if variable_name == 'omega' or variable_name == 'vertical_velocity':

        def truncate_colormap(cmap, minval=0.0, maxval=1.0, n=100):
            new_cmap = colors.LinearSegmentedColormap.from_list(
                'trunc({n},{a:.2f},{b:.2f})'.format(n=cmap.name,
                                                    a=minval,
                                                    b=maxval),
                cmap(np.linspace(minval, maxval, n)))
            return new_cmap

        old_cmap = plt.get_cmap('RdYlBu')
        cmap = truncate_colormap(old_cmap, 0.05, 0.9)

        norm = colors.DivergingNorm(vmin=variable_min,
                                    vcenter=0,
                                    vmax=variable_max)

    else:
        cmap = ListedColormap(sns.cubehelix_palette(20, start=.5, rot=-.75))

    if variable_name == 'omega' or variable_name == 'vertical_velocity':
        variable_contours = ax.contourf(xs,
                                        ys,
                                        to_np(variable_cross_filled),
                                        levels=levels,
                                        cmap=cmap,
                                        extend='both',
                                        norm=norm)

    elif variable_name == 'rh':
        variable_contours = ax.contourf(xs,
                                        ys,
                                        to_np(variable_cross_filled),
                                        levels=levels,
                                        cmap=cmap,
                                        extend='max')
    elif variable_name == 'reflectivity':
        variable_contours = ax.contourf(xs,
                                        ys,
                                        to_np(variable_cross_filled),
                                        levels=levels,
                                        cmap=dbz_cmap,
                                        norm=dbz_norm,
                                        extend='both')

    else:
        variable_contours = ax.contourf(xs,
                                        ys,
                                        to_np(variable_cross_filled),
                                        levels=levels,
                                        cmap=cmap,
                                        extend='both')
    # Plot wind barbs
    if variable_name == 'vertical_velocity':
        u = getvar(ncfile, 'ua', units='kt')

        U = 10**(u / 10)

        u_cross = vertcross(U,
                            ht,
                            wrfin=ncfile,
                            start_point=start_point,
                            end_point=end_point,
                            latlon=True,
                            meta=True)

        u_cross = 10.0 * np.log10(u_cross)

        u_cross_filled = np.ma.copy(to_np(u_cross))

        for i in range(u_cross_filled.shape[-1]):
            column_vals = u_cross_filled[:, i]
            first_idx = int(np.transpose((column_vals > -200).nonzero())[0])
            u_cross_filled[0:first_idx, i] = u_cross_filled[first_idx, i]

        ax.barbs(xs[::3],
                 ys[::3],
                 to_np(u_cross_filled[::3, ::3]),
                 to_np(variable_cross_filled[::3, ::3]),
                 length=7,
                 zorder=1)

    if variable_name == 'omega':
        u = getvar(ncfile, 'ua', units='kt')

        U = 10**(u / 10)

        u_cross = vertcross(U,
                            ht,
                            wrfin=ncfile,
                            start_point=start_point,
                            end_point=end_point,
                            latlon=True,
                            meta=True)

        u_cross = 10.0 * np.log10(u_cross)

        u_cross_filled = np.ma.copy(to_np(u_cross))

        for i in range(u_cross_filled.shape[-1]):
            column_vals = u_cross_filled[:, i]
            first_idx = int(np.transpose((column_vals > -200).nonzero())[0])
            u_cross_filled[0:first_idx, i] = u_cross_filled[first_idx, i]

        w = getvar(ncfile, 'wa', units='kt')

        W = 10**(w / 10)

        w_cross = vertcross(W,
                            ht,
                            wrfin=ncfile,
                            start_point=start_point,
                            end_point=end_point,
                            latlon=True,
                            meta=True)

        w_cross = 10.0 * np.log10(w_cross)

        w_cross_filled = np.ma.copy(to_np(w_cross))

        for i in range(w_cross_filled.shape[-1]):
            column_vals = w_cross_filled[:, i]
            first_idx = int(np.transpose((column_vals > -200).nonzero())[0])
            w_cross_filled[0:first_idx, i] = w_cross_filled[first_idx, i]

        ax.barbs(xs[::3],
                 ys[::3],
                 to_np(u_cross_filled[::3, ::3]),
                 to_np(w_cross_filled[::3, ::3]),
                 length=7,
                 zorder=1,
                 color='grey')

    # Add color bar
    cbar = mpu.colorbar(variable_contours,
                        ax,
                        orientation='vertical',
                        aspect=40,
                        shrink=.05,
                        pad=0.05)
    cbar.set_label(colorbar_label, fontsize=15)
    cbar.set_ticks(levels)

    # Set x-ticks to use latitude and longitude labels
    coord_pairs = to_np(variable_cross.coords['xy_loc'])
    x_ticks = np.arange(coord_pairs.shape[0])
    x_labels = [
        pair.latlon_str(fmt='{:.2f}, {:.2f}') for pair in to_np(coord_pairs)
    ]

    # Set desired number of x ticks below
    num_ticks = 5
    thin = int((len(x_ticks) / num_ticks) + .5)
    ax.set_xticks(x_ticks[::thin])
    ax.set_xticklabels(x_labels[::thin], rotation=45, fontsize=10)
    ax.set_xlim(x_ticks[0], x_ticks[-1])

    # Set y-ticks and limit the height
    ax.set_yticks(np.linspace(0, 12, 13))
    ax.set_ylim(0, 12)

    # Set x-axis and y-axis labels
    ax.set_xlabel('Latitude, Longitude', fontsize=12.5)
    ax.set_ylabel('Height [$km$]', fontsize=12.5)

    # Fill in mountian area
    ht_fill = ax.fill_between(xs,
                              0,
                              to_np(ter_line),
                              facecolor='saddlebrown',
                              zorder=2)

    # Make nicetime
    xr_file = xr.open_dataset(filename)
    nicetime = pd.to_datetime(xr_file.QVAPOR.isel(Time=0).XTIME.values)

    # Add title
    ax.set_title('Vertical Cross-Section of {}'.format(title_name),
                 fontsize=20,
                 loc='left')
    ax.set_title('Valid time: {} {}'.format(
        nicetime.strftime('%Y-%m-%d %H:%M'), 'UTC'),
                 fontsize=15,
                 loc='right')

    # Add grid for y axis
    ax.grid(axis='y', linestyle='--', color='grey')

    plt.show()

    ### Save figure ###
    if save == True:
        fig.savefig('{}cross_section_{}.png'.format(save_dir, variable_name),
                    bbox_inches='tight',
                    dpi=300)
def lagranto_plotting(traj_variable_name,
                      start_time,
                      end_time,
                      trajs_bunch_level='all',
                      subset=False,
                      save=False):
    '''This function plots the chosen variables for the trajectories 
    calculated with Lagranto. Supported variables for plotting procedure 
    are water_vapor, updraft and height.'''

    ### Predefine some variables ###
    traj_data_dir = '/scratch3/thomasl/work/retrospective_part/lagranto/' 'traj_baden_10000_every1000_area_1200.ll'

    save_dir = '/scratch3/thomasl/work/retrospective_part' '/casestudy_baden/lagranto/'

    start_locations = 'area'  # distinction between single and multiple
    # starting points of trajectories
    number_trajs_plot = 1

    # Location of Initiation
    lat = 47.25
    lon = 7.85
    initiation = CoordPair(lat, lon)

    # Change extent of plot
    subset_extent = [7, 9, 47, 48]

    # Variables for getting PBL height of WRF model data
    date = '2018-05-30'
    time = '16:10'
    wrf_filename = '/scratch3/thomasl/work/data/casestudy_baden/' 'wrfout_d02_{}_{}:00'.format(
        date, time)

    # Variables:
    if traj_variable_name == 'water_vapor':
        traj_variable_name = 'QVAPOR'
        title_name = 'Trajectories of Water Vapor'
        colorbar_label_trajs = 'Water Vapor Mixing Ratio [$g$ $kg^{-1}$]'
        save_name = 'trajectory_water_vapor_{}_{}'.format(start_time, end_time)
        traj_variable_min = 0
        traj_variable_max = 15

    elif traj_variable_name == 'updraft':
        traj_variable_name = 'W_UP_MAX'
        title_name = 'Trajectories of Updraft'
        colorbar_label_trajs = 'Max Z-Wind Updraft [$m$ $s^-$$^1$]'
        save_name = 'trajectory_updraft_{}_{}'.format(start_time, end_time)
        traj_variable_min = 0
        traj_variable_max = 10

    elif traj_variable_name == 'height':
        traj_variable_name = 'z'
        title_name = 'Height of Trajectories'
        colorbar_label_trajs = 'Height of Trajectories [$m$]'
        save_name = 'trajectory_height_{}_{}'.format(start_time, end_time)
        traj_variable_min = 0
        traj_variable_max = 10000

    ### Plotting procedure ###
    trajs = Tra()
    trajs.load_ascii(traj_data_dir)

    # Get PBL out of WRF model data
    ncfile = Dataset(wrf_filename)
    wrf_file = xr.open_dataset(wrf_filename)
    data = wrf_file.PBLH

    location = ll_to_xy(ncfile, lat, lon)
    data_point = data.sel(west_east=location[0], south_north=location[1])
    pbl = data_point.values

    # Separate trajectories in 3 vertical bunches
    # Trajectories of pbl (according to pbl height of WRF model data)
    trajspbl = []
    for t in trajs:
        if (t['z'][0] <= pbl):
            trajspbl.append(t)

    # Trajectories between pbl and 5000 m
    trajs5 = []
    for t in trajs:
        if (t['z'][0] > pbl and t['z'][0] < 5000):
            trajs5.append(t)

    # Trajectories between 5000 m and 10000 m
    trajs10 = []
    for t in trajs:
        if (t['z'][0] > 5000 and t['z'][0] <= 10000):
            trajs10.append(t)

    if trajs_bunch_level == 'pbl':
        trajs_bunch = trajspbl

    elif trajs_bunch_level == '5':
        trajs_bunch = trajs5

    elif trajs_bunch_level == '10':
        trajs_bunch = trajs10

    elif trajs_bunch_level == 'all':
        trajs_bunch = trajs

    # Get terrain height
    terrain_height = getvar(ncfile, 'HGT') / 1000  # change to km

    # Define cart projection
    lats, lons = latlon_coords(terrain_height)
    cart_proj = ccrs.LambertConformal(central_longitude=8.722206,
                                      central_latitude=46.73585)

    # Create figure
    fig = plt.figure(figsize=(15, 10))
    ax = plt.axes(projection=cart_proj)

    ### Set map extent ###
    domain_extent = [3.701088, 13.814863, 43.85472, 49.49499]

    if subset == True:
        ax.set_extent([
            subset_extent[0], subset_extent[1], subset_extent[2],
            subset_extent[3]
        ], ccrs.PlateCarree())

    else:
        ax.set_extent([
            domain_extent[0] + 0.7, domain_extent[1] - 0.7,
            domain_extent[2] + 0.1, domain_extent[3] - 0.1
        ], ccrs.PlateCarree())

    # Plot trajectories
    levels_trajs = np.linspace(traj_variable_min, traj_variable_max, 11)
    rounded_levels_trajs = [round(elem, 1) for elem in levels_trajs]

    cmap = ListedColormap(sns.cubehelix_palette(
        10,
        start=.5,
        rot=-.75,
    ))

    plt_trajs = plot_trajs(ax,
                           trajs_bunch[0::number_trajs_plot],
                           traj_variable_name,
                           linewidth=2,
                           levels=rounded_levels_trajs,
                           cmap=cmap)

    # Plot the terrain height with colorbar
    levels = np.linspace(0, 4, 21)
    terrain = plt.contourf(to_np(lons),
                           to_np(lats),
                           to_np(terrain_height),
                           levels=levels,
                           transform=ccrs.PlateCarree(),
                           cmap=get_cmap('Greys'),
                           alpha=0.75)

    cbar = mpu.colorbar(terrain,
                        ax,
                        orientation='horizontal',
                        aspect=40,
                        shrink=.05,
                        pad=0.075)
    cbar.set_label('Terrain Height [$km$]', fontsize=15)
    cbar.set_ticks(levels)

    # Make only every second color bar tick label visible
    for label in cbar.ax.xaxis.get_ticklabels()[1::2]:
        label.set_visible(False)

    # Add color bar for trajectory variable
    if traj_variable_name == 'QVAPOR':
        extend = 'both'
    else:
        extend = 'max'
    cbar_trajs = mpu.colorbar(plt_trajs,
                              ax,
                              orientation='vertical',
                              aspect=40,
                              shrink=.05,
                              pad=0.05,
                              extend=extend)
    cbar_trajs.set_label(colorbar_label_trajs, fontsize=15)
    cbar_trajs.set_ticks(rounded_levels_trajs)

    # Add borders and coastlines
    ax.add_feature(cfeature.BORDERS.with_scale('10m'), linewidth=0.8)
    ax.add_feature(cfeature.COASTLINE.with_scale('10m'), linewidth=0.8)

    # Add cross for initiation location
    for t in trajs:
        ax.plot(t['lon'][0], t['lat'][0], 'kx', transform=ccrs.PlateCarree())

    # Add gridlines
    lon = np.arange(0, 20, 1)
    lat = np.arange(40, 60, 1)

    gl = ax.gridlines(xlocs=lon, ylocs=lat, zorder=3)

    # Add tick labels
    mpu.yticklabels(lat, ax=ax, fontsize=12.5)
    mpu.xticklabels(lon, ax=ax, fontsize=12.5)

    # Set title
    ax.set_title(title_name, loc='left', fontsize=20)
    ax.set_title('Time Range: {} - {} UTC'.format(start_time, end_time),
                 loc='right',
                 fontsize=15)

    plt.show()

    ### Save figure ###
    if save == True:
        if subset == True:
            if trajs_bunch_level == 'all':
                fig.savefig('{}{}_subset_{}.png'.format(
                    save_dir, save_name, start_locations),
                            bbox_inches='tight',
                            dpi=300)
            else:
                fig.savefig('{}{}_subset_{}_{}.png'.format(
                    save_dir, save_name, trajs_bunch_level, start_locations),
                            bbox_inches='tight',
                            dpi=300)

        else:
            if trajs_bunch_level == 'all':
                fig.savefig('{}{}_{}.png'.format(save_dir, save_name,
                                                 start_locations),
                            bbox_inches='tight',
                            dpi=300)
            else:
                fig.savefig('{}{}_{}_{}.png'.format(save_dir, save_name,
                                                    trajs_bunch_level,
                                                    start_locations),
                            bbox_inches='tight',
                            dpi=300)