Пример #1
0
def points_on_great_circle(p_orig, p_dest, n):
    x_array = []; # long
    y_array = []; # lat
    for i in range(n):
        point = gcc.intermediate_point(p_orig, p_dest, fraction=i/(n-1))
        x_array.append(point[0])
        y_array.append(point[1])
    return [x_array, y_array];
Пример #2
0
def getInterpolatedArray(endPairs, steps):
    interpolatedArray = []

    for i in range(0, steps):
        point = intermediate_point((endPairs[0][1], endPairs[0][0]),
                                   (endPairs[1][1], endPairs[1][0]),
                                   float(i) / (float(steps) - 1.0))
        interpolatedArray.append([point[1], point[0]])
    return interpolatedArray
Пример #3
0
def calc_intermediate(origin_point, destination_point, num_of_points):
    """Takes an origin/destination lat/lon pair and generates intermediate points.

        Args:
            origin_point: a list-like item where the 0th index is lat and 1 index is lon
            destination_point: a list-like item where 0th index is lat, and 1 index is lon
            num_of_points: integer that specifies how many intermediate points to calculate
        Returns:
            List of lat/lon tuples of length num_of_points
    """

    origin_point = tuple([origin_point[1], origin_point[0]])
    destination_point = tuple([destination_point[1], destination_point[0]])
    i_points = []

    for frac in np.linspace(1 / num_of_points,
                            1,
                            num_of_points,
                            endpoint=False):
        new_ipoint = gcc.intermediate_point(origin_point, destination_point,
                                            frac)
        i_points.append(new_ipoint)

    return i_points
Пример #4
0
                    destination[1],
                    linestyle="dashdot",
                    linewidth=0.6,
                    color='b',
                    label='Alone flight A1')
map.drawgreatcircle(aircraft_2[0],
                    aircraft_2[1],
                    destination[0],
                    destination[1],
                    linestyle="dashdot",
                    linewidth=0.6,
                    color='r',
                    label='Alone flight A2')

# Add arrows
midpoint_flight_1 = gcc.intermediate_point(p1, p_RDV, fraction=0.5)
midpoint_flight_2 = gcc.intermediate_point(p2, p_RDV, fraction=0.5)
midpoint_flight_form = gcc.intermediate_point(p_RDV, p_d, fraction=0.5)
add_arrow(line_1[0], position=midpoint_flight_1)
add_arrow(line_2[0], position=midpoint_flight_2)
add_arrow(line_formation[0], position=midpoint_flight_form)

# Legend
plt.legend(frameon=True,
           loc='upper right',
           edgecolor='1',
           ncol=2,
           borderpad=1,
           markerscale=1.2,
           labelspacing=2,
           facecolor='white')
Пример #5
0
def pick_transect(option='coord',
                  lat=[-76, -76],
                  lon=[360 - 32, 360 - 32],
                  run='ISMF',
                  vartype='velocity',
                  transect_name='',
                  scope_name='frisEAcoast',
                  overwrite=False,
                  savepath=savepath_nersc,
                  append=False):

    fmesh = netCDF4.Dataset(meshpath[runname.index(run)])

    # import variables from file
    latcell = fmesh.variables['latCell'][:]
    loncell = fmesh.variables['lonCell'][:]
    xcell = fmesh.variables['xCell'][:]
    ycell = fmesh.variables['yCell'][:]
    zbottom = np.multiply(-1, fmesh.variables['bottomDepth'][:])
    #if vartype == 'scalar':
    #latpt = fmesh.variables['latCell'][:]
    #lonpt = fmesh.variables['lonCell'][:]
    if vartype == 'velocity':
        latpt = fmesh.variables['latEdge'][:]
        lonpt = fmesh.variables['lonEdge'][:]
        #idxpt = fmesh.variables['indexToEdgeID'][:]
        xpt = fmesh.variables['xEdge'][:]
        ypt = fmesh.variables['yEdge'][:]

    # the outcome of all these options is a list of x,y points with varying spacing and number
    if option == 'coord':
        geod = pyproj.Geod(ellps='WGS84')
        dlat = 0.3  # at 30km resolution, distance between cells in deg
        dlon = 0.98

        if transect_name != '':
            #TODO edit using region_name,region_xybounds, region_coordbounds
            lat = [
                region_coordbounds[region_name.index(transect_name), 1, 0],
                region_coordbounds[region_name.index(transect_name), 1, 1]
            ]
            lon = [
                region_coordbounds[region_name.index(transect_name), 0, 0],
                region_coordbounds[region_name.index(transect_name), 0, 1]
            ]
            zmax = region_zbounds[region_name.index(transect_name), 1]
            zmin = region_zbounds[region_name.index(transect_name), 0]
        else:
            transect_name = (str(int(abs(lat[0]))) + 'S' +
                             str(int(abs(lon[0] - 360))) + 'W-' +
                             str(int(abs(lat[1]))) + 'S' +
                             str(int(abs(lon[1] - 360))) + 'W')
            zmax = 0.
            zmin = -9999.

        p1, p2 = (lon[0] - 360, lat[0]), (lon[1] - 360, lat[1])
        frac_along_route = 0.05
        lat_interp = np.zeros((int(1 / frac_along_route)))
        lon_interp = np.zeros((int(1 / frac_along_route)))
        transect_idx = np.zeros((int(1 / frac_along_route)), dtype=int)

        for i, frac in enumerate(np.arange(0, 1, frac_along_route)):
            lon_interp[i], lat_interp[i] = great_circle.intermediate_point(
                p1, p2, frac)
            if lon_interp[i] < 0:
                lon_interp[i] += 360
            logical_trans = ((latcell > (lat_interp[i] - dlat) * deg2rad) &
                             (latcell < (lat_interp[i] + dlat) * deg2rad) &
                             (loncell > (lon_interp[i] - dlon) * deg2rad) &
                             (loncell < (lon_interp[i] + dlon) * deg2rad))
            candidate_idx = np.asarray(logical_trans.nonzero(),
                                       dtype=int)[0, :]
            distance_from_point = np.zeros((np.shape(candidate_idx)))
            _, _, distance_from_point = geod.inv(
                [lon_interp[i] for j in candidate_idx],
                [lat_interp[i]
                 for j in candidate_idx], loncell[candidate_idx] / deg2rad,
                latcell[candidate_idx] / deg2rad)
            transect_idx[i] = int(
                candidate_idx[np.argmin(distance_from_point)])
        _, temp_idx = np.unique(transect_idx, return_index=True)
        cellidx = transect_idx[np.sort(temp_idx)]
        zbool = (zbottom[cellidx] < zmax) & (zbottom[cellidx] > zmin)
        cellidx = cellidx[zbool]
        edgeidx = []
        dist = np.sqrt(
            np.square(fmesh.variables['yCell'][cellidx] -
                      fmesh.variables['yCell'][cellidx[0]]) +
            np.square(fmesh.variables['xCell'][cellidx] -
                      fmesh.variables['xCell'][cellidx[0]]))
        #elif select_cell == 'connecting':
        #    # NOT FUNCTIONAL

    elif option == 'zcontour':
        print('option ', option, ' is not yet enabled')

    elif option == 'by_index':
        datestr = '{0:04d}-{1:02d}'.format(98, 1)
        #filename = ('{0}/mpaso.hist.am.timeSeriesStatsMonthly.'
        #            .format(runpath[runname.index(run)])
        #            + datestr + '-01.nc')
        #f = netCDF4.Dataset(filename, 'r')

        if transect_name == 'trough_shelf':
            cellidx = np.subtract(cells_trough_shelf_lat, 1)
        elif transect_name == 'trough_ice':
            cellidx = np.subtract(cells_trough_ice_lat, 1)
        else:
            print('transect name not matched')

        #uCell = f.variables['timeMonthly_avg_velocityZonal'][0,idx,:]
        #vCell = f.variables['timeMonthly_avg_velocityMeridional'][0,idx,:]

    x_transect = fmesh.variables['xCell'][cellidx]
    y_transect = fmesh.variables['yCell'][cellidx]
    edgesOnCell = np.subtract(fmesh.variables['edgesOnCell'][cellidx, :], 1)
    verticesOnCell = np.subtract(fmesh.variables['verticesOnCell'][cellidx, :],
                                 1)
    verticesOnEdge = np.zeros((len(cellidx), 7, 2))
    for i in range(len(cellidx)):
        for j in range(7):
            verticesOnEdge[i, j, :] = (
                fmesh.variables['verticesOnEdge'][edgesOnCell[i, j], :])

    # Select edges based on their orientation with respect to the transect line
    edgeidx = []
    x0 = xcell[cellidx[0]]
    y0 = ycell[cellidx[0]]
    x1 = xcell[cellidx[-1]]
    y1 = ycell[cellidx[-1]]
    m = (y1 - y0) / (x1 - x0)
    b = (x1 * y0 - x0 * y1) / (x1 - x0)
    angle = atan(1 / m)
    if vartype == 'velocity':
        #transect_angle = angle/deg2rad
        #if transect_angle>=180:
        #   transect_angle += -360
        #elif transect_angle<-180:
        #   transect_angle += 360
        #if transect_angle < 0:
        #   transect_angle += 180
        #print('transect_angle = ',transect_angle)
        #print('x0,y0 = ',x0,y0)
        #print('x1,y1 = ',x1,y1)
        idx = []
        dxy = 1e3
        #dxy = 5e3
        for i, celli in enumerate(cellidx):
            for j, edge in enumerate(edgesOnCell[i, :]):
                angleEdge = fmesh.variables['angleEdge'][
                    edge]  #edgesOnCell[i,j]]
                ye = fmesh.variables['yEdge'][edge]
                xe = fmesh.variables['xEdge'][edge]
                if abs(x0 - x1) > (y0 - y1):  #only restrictions on y
                    ym = m * xe + b
                    xlim = xe  #xcell[celli]
                    ylim = ym - dxy
                    #print('xe,ym = ',xe,ym)
                else:  #only restrictions on x
                    xm = (ye - b) / m
                    xlim = xm - dxy
                    ylim = ye  #ycell[celli]
                    #print('xm,ye = ',xm,ye)
                #if i == 1:
                #    print('xcell,ycell = ',xcell[celli],ycell[celli])
                #    print('xe,ye = ',xe,ye)
                #    print('xlim,ylim = ',xlim,ylim)
                if ((xe <= xlim) and (ye <= ylim)
                        #and abs(xe-xcell[celli])>1e3 and abs(ye-ycell[celli])>1e3
                    ):
                    #edge not in edgesOnCell[i+1,:]) ):
                    edgeidx.append(edgesOnCell[i, j])
                    idx.append(celli)
                    #edge_angle = angleEdge/deg2rad
                    #if edge_angle>=180:
                    #   edge_angle += -360
                    #elif edge_angle<-180:
                    #   edge_angle += 360
                    #if edge_angle < 0:
                    #   edge_angle += 180
                    #dangle = edge_angle-transect_angle
                    #print('edge_angle = ',edge_angle)
                    #print('dangle = ',dangle)
        cellidx = idx
    if vartype == 'velocity':
        dist = np.sqrt(
            np.square(fmesh.variables['yEdge'][edgeidx] -
                      fmesh.variables['yEdge'][edgeidx[0]]) +
            np.square(fmesh.variables['xEdge'][edgeidx] -
                      fmesh.variables['xEdge'][edgeidx[0]]))
    else:
        dist = np.sqrt(
            np.square(fmesh.variables['yCell'][cellidx] -
                      fmesh.variables['yCell'][cellidx[0]]) +
            np.square(fmesh.variables['xCell'][cellidx] -
                      fmesh.variables['xCell'][cellidx[0]]))

        # TODO replace above method with that below
        # include all edges whose vertices have y-coordinates above or on a line
        # connecting neighboring cell centers


#        for i,cell in enumerate(cellidx):
#            if cell == cellidx[-1]:
#                m = ( (y_transect[i] - y_transect[i-1]) /
#                      (x_transect[i] - x_transect[i-1]) )
#                b = ( (x_transect[i] * y_transect[i-1] -
#                       x_transect[i-1] * y_transect[i]) /
#                      (x_transect[i] - x_transect[i-1]) )
#            else:
#                m = ( (y_transect[i+1] - y_transect[i]) /
#                      (x_transect[i+1] - x_transect[i]) )
#                b = ( (x_transect[i+1] * y_transect[i] -
#                       x_transect[i] * y_transect[i+1]) /
#                      (x_transect[i+1] - x_transect[i]) )
#            for j,edge in enumerate(edgesOnCell[i,:]):
#                x2 = fmesh.variables['xVertex'][verticesOnEdge[i,j,:]
#                y2 = fmesh.variables['yVertex'][verticesOnEdge[i,j,:]
#                if ( ( y2[0] >= m*x2[0] + b) and
#                     ( y2[1] >= m*x2[1] + b) and
#                     ( x2[1] >= m*x2[1] + b) and
#                     ( edge not in edgesOnCell[i+1,:]) ):
#                    edgeidx.append(edge)

#    print('idxcell',str(i),':',str(ycell[i]),',',str(xcell[i]))
#    shared_edges = []
#    shared_verts = []
#    xEdge = fmesh.variables['xEdge'][edgesOnCell[i,:]]))
#    edge1 = np.argmin(xEdge)
#       fmesh.variables[]verticesOnCell[i,:] = (
#    vert1 = verticesOnCell[i,:]
#    vert2 = verticesOnCell[i+1,:]
#    edges1 = edgesOnCell[i,:]
#    print('xedge:',str(fmesh.variables['xEdge'][edges1-1]))
#    edges2 = fmesh.variables['edgesOnCell'][i+1,:]
#    for j in vert1:
#       if j in vert2:
#          np.append(shared_verts,j)
#    print('len(shared_edges) idx=',str(i),'=',str(len(shared_edges)))
#    for j in edges1:
#       if j in edges2:
#          np.append(shared_edges,j)
#    print('len(shared_verts) idx=',str(i),'=',str(len(shared_verts)))
#for i in idx:
#    print('idxcell',str(i),':',str(ycell[i]),',',str(xcell[i]))
#    ii = fmesh.variables['indexToCellID'][:].index(i)
#    for j,jj in enumerate(fmesh.variables['edgesOnCell'][ii,:]):
#        print('edge ',str(j),':',str(fmesh.variables['yEdge'][jj]),',',str(fmesh.variables['xEdge'][jj]))
#        plt.plot(fmesh.variables['yEdge'][jj],
#                 fmesh.variables['xEdge'][jj],'r.',markersize=ms)
#        k = fmesh.variables['cellsOnCell'][i,j]
#        print('cell ',str(k),':',str(fmesh.variables['yCell'][k]),',',str(fmesh.variables['xEdge'][k]))
#if (edges[1] in idx) and (edges[10] in idx):
#   print('found duplicate')
#   idx[idx.index(edges[10])] = nan
#if (edges[6] in idx) and (edges[5] in idx):
#   print('found duplicate')
#   idx[idx.index(edges[5])] = nan

#idx1 = np.argsort(fmesh.variables['yEdge'][edgeidx])
#edgeidx = edgeidx[np.argsort(fmesh.variables['xEdge'][edgeidx])]
#dist = np.sqrt( np.square(fmesh.variables['yEdge'][edgeidx] - fmesh.variables['yEdge'][edgeidx[0]]) +
#                np.square(fmesh.variables['xEdge'][edgeidx] - fmesh.variables['xEdge'][edgeidx[0]]) )

# show profile line across cells
#if not os.path.exists(savepath + 'bathy_' + placename + '.png'):
#    fig1 = plt.figure()
#    plt.plot(yCell[logical_N],     xCell[logical_N], 'k.')
#    plt.plot(yCell[logical_trans], xCell[logical_trans], 'r.')
#    plt.axis('equal')
#    plt.savefig('grid_' + placename + '_' + datestr + '.png',dpi=set_dpi)
#    plt.close()
#
#    fig = plt.figure()
#    cntr1 = plt.tricontourf(yCell[logical_N].flatten(), xCell[logical_N].flatten(),
#                            zmax[logical_N].flatten(), 20, cmap="viridis")
#    plt.plot(yCell[logical_N],     xCell[logical_N], 'o', color = 'white',
#             markersize = 4, fillstyle = 'none')#, alpha = 0.5)
#    cntr = plt.tricontour(yCell[logical_N].flatten(), xCell[logical_N].flatten(),
#                           zice[logical_N].flatten(), [-10], colors = 'k')
#    plt.plot(yCell[idxsort_trans], xCell[idxsort_trans], 'k-')
#    plt.axis('equal')
#    cbar = plt.colorbar(cntr1)
#    cbar.set_label('Depth (m)')
#    plt.savefig(savepath + 'bathy_' + placename + '.png',dpi=set_dpi)
#    plt.close()

# show profile line across cells
    if (not os.path.exists(savepath + 'bathy_' + transect_name +
                           '.png')) or overwrite:
        # northern limit for subplots
        ms = 1
        #xcell = fmesh.variables['xCell'][:]
        #ycell = fmesh.variables['yCell'][:]
        #latcell = fmesh.variables['latCell'][:]
        idx_scope = pick_from_region(region=scope_name,
                                     run=run,
                                     plot_map=False)
        zmax_scope = np.multiply(-1.,
                                 fmesh.variables['bottomDepth'][idx_scope])
        icemask_scope = fmesh.variables['landIceMask'][0, idx_scope]
        #zice_scope     = fmesh.variables['landIceDraft'][idx_scope]
        ycell_scope = ycell[idx_scope]
        xcell_scope = xcell[idx_scope]

        fig = plt.figure()
        ax = fig.add_subplot(111)
        cntr1 = plt.scatter(ycell_scope,
                            xcell_scope,
                            s=loc_ptsize[region_name.index(scope_name)],
                            c=zmax_scope)
        #cntr1 = plt.tricontourf(ycell[idx_scope],xcell[idx_scope],zmax, 20, cmap="viridis")
        #plt.plot(ycell[idx_scope],xcell[idx_scope], 'o', color = 'white',
        #         markersize = ms, fillstyle = 'none', alpha = 0.5)
        #cntr = plt.tricontour(ycell_scope,xcell_scope,
        #                      zice, [-10], colors = 'k',linewidth=lw1)
        plt.plot(ycell_scope[icemask_scope == 1],
                 xcell_scope[icemask_scope == 1],
                 'o',
                 color='white',
                 markersize=5 * ms,
                 fillstyle='none')
        plt.plot(ycell[cellidx],
                 xcell[cellidx],
                 'o',
                 color='black',
                 markersize=ms,
                 fillstyle='none')
        #plt.plot([y0,y1],[x0,x1], 'k-')

        cNorm = Normalize(vmin=-1 * pi, vmax=1 * pi)
        scalarMap = cmx.ScalarMappable(norm=cNorm, cmap='jet')
        #for i in range(len(idx)):
        #    for j in range(6):
        #        colorVal = scalarMap.to_rgba(fmesh.variables['angleEdge'][edgesOnCell[i,j]])
        #        sc = plt.scatter(fmesh.variables['yEdge'][edgesOnCell[i,j]],
        #                    fmesh.variables['xEdge'][edgesOnCell[i,j]],s=ms/2,c=colorVal)
        for k in edgeidx:
            colorVal = scalarMap.to_rgba(
                fmesh.variables['angleEdge'][edgesOnCell[i, j]])
            sc = plt.plot([
                fmesh.variables['yVertex'][
                    fmesh.variables['verticesOnEdge'][k, 0] - 1],
                fmesh.variables['yVertex'][
                    fmesh.variables['verticesOnEdge'][k, 1] - 1]
            ], [
                fmesh.variables['xVertex'][
                    fmesh.variables['verticesOnEdge'][k, 0] - 1],
                fmesh.variables['xVertex'][
                    fmesh.variables['verticesOnEdge'][k, 1] - 1]
            ],
                          'b-',
                          linewidth=lw1)  #marker='None',linestyle='-','k')
            #print(fmesh.variables['yVertex'][verticesOnEdge[i,j,1]])
            #print(fmesh.variables['xVertex'][verticesOnEdge[i,j,1]])
            #xv = [fmesh.variables['yVertex'][verticesOnEdge[i,j,0]],
            #      fmesh.variables['yVertex'][verticesOnEdge[i,j,1]]]
            #yv = [fmesh.variables['xVertex'][verticesOnEdge[i,j,0]],
            #      fmesh.variables['xVertex'][verticesOnEdge[i,j,1]]]
            #plt.plot(xv,yv,'b-',linewidth=0.5)
    #plt.plot(ypt[idx], xpt[idx], 'k.',markersize=ms)
    #    for i,j in enumerate(idx):
    #        plt.plot([yv1[i],yv2[i]],[xv1[i],xv2[i]], 'k-')
    #ax.set_xlabel('y (m)')
    #ax.set_ylabel('x (m)')
        plt.axis('equal')
        plt.ylim([
            region_xybounds[region_name.index(scope_name)][0, 0],
            region_xybounds[region_name.index(scope_name)][0, 1]
        ])
        plt.xlim([
            region_xybounds[region_name.index(scope_name)][1, 0],
            region_xybounds[region_name.index(scope_name)][1, 1]
        ])
        cbar = plt.colorbar(cntr1)
        #cbar = plt.colorbar(sc)
        cbar.set_label(r'Depth (m)')
        print('save ', 'bathy_' + transect_name)
        plt.savefig(savepath + 'bathy_' + transect_name)
        plt.close()

    return cellidx, edgeidx, dist, angle
Пример #6
0
def plot_basemap_results(**kwargs):

    # Retrieving the arguments
    show = kwargs.get('show', True)
    RDV = kwargs.get('rdv', None)
    BYE = kwargs.get('bye', None);
    A1_orig = kwargs.get('A1_orig', None);
    A1_dest = kwargs.get('A1_dest', None);
    A2_orig = kwargs.get('A2_orig', None);
    A2_dest = kwargs.get('A2_dest', None);
    bounds = kwargs.get('Bounds', None);
    output_file = kwargs.get('out_file', None);
    region = kwargs.get('Region', None);
    
    # Setting the map
    fig = plt.figure(num=1, figsize=(12,12)) 
    map=Basemap(llcrnrlon=region[0],llcrnrlat=region[1],urcrnrlon=region[2],urcrnrlat=region[3])
    map.fillcontinents(color='grey', alpha=0.3, lake_color='grey')
    
    # Plots the position, destination and RDV & BYE points
    Airc_1 = map.plot(A1_orig[0], A1_orig[1], 'b4', markersize=18, label='Aircraft 1')
    Airc_2 = map.plot(A2_orig[0], A2_orig[1], 'r4', markersize=18, label='Aircraft 2')
    Dest_1 = map.plot(A1_dest[0], A1_dest[1], 'bs', markersize=10, label='Destination 1')
    Dest_2 = map.plot(A2_dest[0], A2_dest[1], 'rs', markersize=10, label='Destination 2')
    RDV_point = map.plot(RDV[0], RDV[1], 'ko', markersize=10, label='RDV')
    BYE_point = map.plot(BYE[0], BYE[1], 'kx', markersize=10, label='BYE')
    
    # Draw the boundaries
    p1, p2, p_RDV, p_BYE, d1, d2 = (A1_orig[0],A1_orig[1]), (A2_orig[0],A2_orig[1]), (RDV[0], RDV[1]), (BYE[0], BYE[1]), (A1_dest[0], A1_dest[1]), (A2_dest[0], A2_dest[1])
    plt.fill_between([bounds[0][0],bounds[0][1]], bounds[1][0],bounds[1][1], color='#163A6B', alpha=0.15, label='Boundaries', linewidth=0)
    #[point_set, y_1, y_2] = compute_boundaries_great_circle(p1, p2, p_d, 30)
    #plt.fill_between(point_set, y_1,y_2, color='#163A6B', alpha=0.15, label='Boundaries', linewidth=0)
    
    # Add connections
    line_1_start = map.drawgreatcircle(A1_orig[0],A1_orig[1],RDV[0],RDV[1], linestyle="solid", linewidth=0.6, color='b', label='A1: Cruise alone 1')
    line_2_start = map.drawgreatcircle(A2_orig[0],A2_orig[1],RDV[0],RDV[1], linestyle="solid", linewidth=0.6, color='r', label='A2: Cruise alone 1')
    line_formation = map.drawgreatcircle(RDV[0],RDV[1],BYE[0],BYE[1], linestyle="solid", linewidth=1, color='k', label='Formation flight')
    line_1_end = map.drawgreatcircle(BYE[0],BYE[1],A1_dest[0],A1_dest[1], linestyle="dashdot", linewidth=1, color='b', label='A1: Cruise alone 2')
    line_2_end = map.drawgreatcircle(BYE[0],BYE[1],A2_dest[0],A2_dest[1], linestyle="dashdot", linewidth=1, color='r', label='A2: Cruise alone 2')
    map.drawgreatcircle(A1_orig[0],A1_orig[1],A1_dest[0],A1_dest[1], linestyle="dashdot", linewidth=0.6, alpha=0.5, color='b', label='A1: Alone flight')
    map.drawgreatcircle(A2_orig[0],A2_orig[1],A2_dest[0],A2_dest[1], linestyle="dashdot", linewidth=0.6, alpha=0.5, color='r', label='A2: Alone flight')
    
    # Add arrows
    midpoint_1_start = gcc.intermediate_point(p1, p_RDV, fraction=0.5)
    midpoint_2_start = gcc.intermediate_point(p2, p_RDV, fraction=0.5)
    midpoint_form = gcc.intermediate_point(p_RDV, p_BYE, fraction=0.5)
    midpoint_1_end = gcc.intermediate_point(p_BYE, d1, fraction=0.5)
    midpoint_2_end = gcc.intermediate_point(p_BYE, d2, fraction=0.5)
    add_arrow(line_1_start[0], position=midpoint_1_start)
    add_arrow(line_2_start[0], position=midpoint_2_start)
    add_arrow(line_formation[0], position=midpoint_form)
    add_arrow(line_1_end[0], position=midpoint_1_end)
    add_arrow(line_2_end[0], position=midpoint_2_end)
    
    # Legend
    plt.legend(frameon = True, loc='upper right', edgecolor='1', ncol = 2, borderpad = 1, markerscale = 1.2, labelspacing = 2, facecolor='white')
    
    # Show/hide figure
    if not show: 
        plt.close();
    
    # Saving the file and parameters
    plt.gca().set_axis_off()
    plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, 
                hspace = 0, wspace = 0)
    plt.margins(0,0)
    plt.gca().xaxis.set_major_locator(plt.NullLocator())
    plt.gca().yaxis.set_major_locator(plt.NullLocator())
    fig.savefig(output_file, dpi=900, bbox_inches = 'tight',
        pad_inches = 0, facecolor='w', edgecolor='w', transparent=True, optimize = True, quality=95)