示例#1
0
def plotTile_patches(lonc, latc, lonv, latv, data):
    """
    plot the tile using matplotlib patcheCollection
    """
    from matplotlib.patches import Polygon
    from matplotlib.collections import PatchCollection

    # need to flip the raster upside down
    data = np.flipud(data)

    ## delta for calculating cell vertices from cell center
    dlon = lonc[0] - lonc[1] / 2.
    dlat = latc[0] - latc[1] / 2.

    #lonp = np.zeros([len(lon), 4])
    #latp = np.zeros([len(lat), 4])
    patches = []
    for i, llon in enumerate(lonc):
        for j, llat in enumerate(latc):
            lon_w = llon - dlon
            lon_e = llon + dlon
            lat_n = llat + dlat
            lat_s = llat - dlat
            ## counter-clockwise vertices for each cell
            xp = np.asarray([lon_w, lon_e, lon_e, lon_w])
            yp = np.asarray([lat_s, lat_n, lat_n, lat_s])
            patches.append(Polygon(np.vstack([xp, yp]).T))

    pdb.set_trace()
    cmap = 'viridis'
    pc = PatchCollection(patches, cmap=cmap)
    pc.set_array(data.flatten())
    pc.set_lw(0.1)

    plt.rcParams.update({'font.size': 18})
    fig = plt.figure(figsize=(12, 6))
    ax = fig.add_subplot(111)
    ax.add_collection(pc)
    ax.set_xlim([lonv.min(), lonv.max()])
    ax.set_ylim([latv.min(), latv.max()])
    ax.set_aspect('equal')
    plt.show()
示例#2
0
def plot_poly(colors,
              cells,
              nvertices,
              x,
              y,
              xc=None,
              yc=None,
              xperiod=None,
              yperiod=None,
              colorbar=True,
              cmap='viridis'):
    """ from https://gist.github.com/pwolfram/2745eaccaf33f222fed6"""
    patches = []
    for ii, (ac, nv) in enumerate(zip(cells, nvertices)):
        ac = np.asarray(ac[:nv], dtype='int')
        xp = x[ac]
        yp = y[ac]
        if xc is not None:
            xp = fix_periodicity(xp, xc[ii], xperiod)
        if yc is not None:
            yp = fix_periodicity(yp, yc[ii], yperiod)
        patches.append(Polygon(zip(xp, yp)))

    pc = PatchCollection(patches, cmap=cmap, alpha=1.0)
    pc.set_array(colors)
    pc.set_edgecolor('face')
    pc.set_lw(0.1)

    plt.figure()
    ax = plt.gca()
    ax.add_collection(pc)
    ax.set_aspect('equal')
    ax.autoscale_view()
    if colorbar:
        plt.colorbar(pc)
    return pc
示例#3
0
def plot_target(data_temp, var_temp, start_indices_temp, end_indices_temp,
                out_dir_temp):

    #Set some strings
    if var_temp == 'rad_continuum_o2':
        var_string = 'o2_radiance'
        var_cbar_string = 'Radiance [Ph s' + r'$^{-1}$' + ' m' + r'$^{-2}$' + ' sr' + r'$^{-1}$' + r'$\mu$' + 'm' + r'$^{-1}$' + ']'
        var_title_string = "O" + r'$_2$' + ' A-Band Radiance'
        var_cbar = plt.cm.Purples_r

    elif var_temp == 'xco2':
        var_string = 'xco2'
        var_cbar_string = r'$X_{CO_2}$' + ' [ppm]'
        var_title_string = r'$X_{CO_2}$'
        var_cbar = plt.cm.viridis

    elif var_temp == 'dp':
        var_string = 'dp'
        var_cbar_string = 'dp [hPa]'
        var_title_string = 'dp'
        var_cbar = plt.cm.RdBu_r

    elif var_temp == 'aod_total':
        var_string = 'aod'
        var_cbar_string = 'AOD'
        var_title_string = 'AOD'
        var_cbar = plt.cm.magma

    else:
        print("Please select an appropriate variable...")

    ############################################
    #Plot all the individual TG/AMs!
    for i in range(len(start_indices_temp)):
        print(
            "---------------------------------------------------------------")
        print("Plotting TG/AM ", str(i + 1), " of ", len(start_indices_temp))
        data_temp2 = data_temp[start_indices_temp[i]:end_indices_temp[i]]
        print(data_temp2['target_id'][0], int(data_temp2['orbit'][0]),
              data_temp2['sounding_id'][0])

        #Remove weird outliers that are far from the actual TG/AM
        cluster_input = np.array(
            [data_temp2['longitude'], data_temp2['latitude']]).T
        try:
            clusters = hcluster.fclusterdata(cluster_input,
                                             1.,
                                             criterion='distance')
            print("Cluster #s = ", np.bincount(clusters))

            #Grab the largest cluster, or any/all clusters greater than 30 soundings
            cluster_mask = (clusters == np.argmax(
                np.bincount(clusters))) | np.isin(
                    clusters,
                    np.where(np.bincount(clusters) > 30)[0])

        except:
            #If there's exactly one sounding, fclusterdata doesn't work
            cluster_mask = np.ones(len(data_temp2), dtype=bool)

        #Determine plotting box
        N,S,E,W = np.round(max(data_temp2['target_lat'][cluster_mask][0],data_temp2['latitude'][cluster_mask].max())+.25,1),\
                  np.round(min(data_temp2['target_lat'][cluster_mask][0],data_temp2['latitude'][cluster_mask].min())-.25,1),\
                  np.round(max(data_temp2['target_lon'][cluster_mask][0],data_temp2['longitude'][cluster_mask].max())+(.25/np.cos(np.deg2rad(max(data_temp2['target_lat'][cluster_mask][0],data_temp2['latitude'][cluster_mask].max())))),1),\
                  np.round(min(data_temp2['target_lon'][cluster_mask][0],data_temp2['longitude'][cluster_mask].min())-(.25/np.cos(np.deg2rad(min(data_temp2['target_lat'][cluster_mask][0],data_temp2['latitude'][cluster_mask].min())))),1)

        #And keep anything within the plotting box
        data_temp2 = data_temp2[(data_temp2['latitude'] < N)
                                & (data_temp2['latitude'] > S) &
                                (data_temp2['longitude'] < E) &
                                (data_temp2['longitude'] > W)]

        #Get some datetime info from the sounding_id
        month_str = calendar.month_abbr[int(
            data_temp2['sounding_id'][0].astype(str)[4:6].lstrip("0"))]
        day_str, year_str = data_temp2['sounding_id'][0].astype(
            str)[6:8].lstrip("0"), data_temp2['sounding_id'][0].astype(
                str)[:4].lstrip("0")
        hour_str, minute_str = data_temp2['sounding_id'][0].astype(
            str)[8:10], data_temp2['sounding_id'][0].astype(str)[10:12]

        #Check if the .png exists already. If not, make it!
        if os.path.isfile(out_dir_temp + '/' +
                          data_temp2['production_string'][0].astype(str) +
                          '/' + var_string + '/OCO3_' +
                          data_temp2['production_string'][0].astype(str) +
                          "_" + var_string + '_' +
                          str(data_temp2['sounding_id'][0])[:8] + '_' +
                          str(int(data_temp2['orbit'][0])) + "_" +
                          data_temp2['target_id'][0].astype(str) + '.png'):
            print(out_dir_temp + '/' +
                  data_temp2['production_string'][0].astype(str) + '/' +
                  var_string + '/OCO3_' +
                  data_temp2['production_string'][0].astype(str) + "_" +
                  var_string + '_' + str(data_temp2['sounding_id'][0])[:8] +
                  '_' + str(int(data_temp2['orbit'][0])) + "_" +
                  data_temp2['target_id'][0].astype(str) +
                  '.png already exists!')

        else:
            fig, ax1 = plt.subplots(figsize=[20, 20])
            m1 = Basemap(llcrnrlon=W,
                         llcrnrlat=S,
                         urcrnrlon=E,
                         urcrnrlat=N,
                         epsg=3857,
                         resolution='h')
            try:
                m1.arcgisimage(service='World_Imagery',
                               xpixels=2000,
                               verbose=True)
            except:
                #Sometimes this fails randomly, so try again
                time.sleep(20)
                m1.arcgisimage(service='World_Imagery',
                               xpixels=2000,
                               verbose=True)
            m1.drawmeridians(np.linspace(W, E, 6)[1:-1],
                             labels=[0, 0, 0, 1],
                             size=24,
                             color='0.75')
            m1.drawparallels(np.linspace(N, S, 6)[1:-1],
                             labels=[1, 0, 0, 0],
                             size=24,
                             color='0.75')
            m1.drawcoastlines()

            #Map Scale. Have to hack because the Basemap drawmapscale function is broken, but this should work. Cartopy doesn't even have a map scale function.
            lat0 = S + (N - S) * 0.04 + 0.02  #0.04
            lon0 = W + (E - W) * 0.04
            distance = 40. / np.cos(lat0 * np.pi / 180.)
            corner_buffered_m1 = m1(lon0, lat0)
            corner_buffered_lon, corner_buffered_lat = m1(
                corner_buffered_m1[0] + (distance / 2 * 1000),
                corner_buffered_m1[1],
                inverse=True)
            scale = m1.drawmapscale(corner_buffered_lon,
                                    corner_buffered_lat,
                                    corner_buffered_lon,
                                    corner_buffered_lat,
                                    distance,
                                    units='km',
                                    fontcolor='w',
                                    fontsize=16,
                                    yoffset=2000)
            scale[3].set_text(40)

            #Plot footprints
            x1, y1 = m1(data_temp2['vertex_longitude_1'],
                        data_temp2['vertex_latitude_1'])
            x2, y2 = m1(data_temp2['vertex_longitude_2'],
                        data_temp2['vertex_latitude_2'])
            x3, y3 = m1(data_temp2['vertex_longitude_3'],
                        data_temp2['vertex_latitude_3'])
            x4, y4 = m1(data_temp2['vertex_longitude_4'],
                        data_temp2['vertex_latitude_4'])
            patches = []
            for i in range(len(x1)):
                if (x1[i] == 0.0) | (x2[i] == 0.0) | (x3[i] == 0.0) | (x4[i]
                                                                       == 0.0):
                    print("Bad vertex...")
                else:
                    patches += [
                        Polygon([(x1[i], y1[i]), (x2[i], y2[i]),
                                 (x3[i], y3[i]), (x4[i], y4[i])])
                    ]
            p = PatchCollection(patches, alpha=1.)

            p.set_array(data_temp2[var_temp])
            if var_temp == 'dp':
                p.set_clim(
                    -1 * max(np.abs(np.percentile(data_temp2[var_temp], 10)),
                             np.abs(np.percentile(data_temp2[var_temp], 90))),
                    max(np.abs(np.percentile(data_temp2[var_temp], 10)),
                        np.abs(np.percentile(data_temp2[var_temp], 90))))
            elif var_temp == 'aod_total':
                p.set_clim(0, max(0.3, np.percentile(data_temp2[var_temp],
                                                     90)))
            else:
                p.set_clim(np.percentile(data_temp2[var_temp], 10),
                           np.percentile(data_temp2[var_temp], 90))
            p.set_lw(1.0)
            p.set_cmap(var_cbar)
            ax1.add_collection(p)

            #Colorbar
            divider = make_axes_locatable(ax1)
            cax = divider.append_axes("right", size=0.4, pad=0.25)
            if var_temp == 'aod_total':
                cbar = fig.colorbar(p, extend='max', cax=cax)
            else:
                cbar = fig.colorbar(p, extend='both', cax=cax)
            cbar.set_label(var_cbar_string, size=28, rotation=270, labelpad=35)
            cbar.ax.tick_params(labelsize=22)
            cbar.ax.yaxis.get_offset_text().set_fontsize(22)

            #Title
            title = ax1.set_title(
                'OCO-3 ' + var_title_string + '\n' +
                data_temp2['sounding_operation_mode_string'][0].astype(str) +
                ' Mode (' +
                data_temp2['sounding_pcs_data_source_string'][0].astype(str) +
                '), ' + data_temp2['target_id'][0].astype(str) + ', "' +
                data_temp2['target_name'][0].astype(str) + '"\n' +
                data_temp2['production_string'][0].astype(str) + '\n' +
                hour_str + ':' + minute_str + ' UTC ' + day_str + ' ' +
                month_str + ' ' + year_str + ', Orbit ' +
                str(int(data_temp2['orbit'][0])),
                size=30,
                y=1.01)

            #Time stamp
            plt.text(0.99,
                     0.01,
                     "Created " + str(datetime.datetime.now().day) + ' ' +
                     calendar.month_abbr[datetime.datetime.now().month] + ' ' +
                     str(datetime.datetime.now().year) +
                     "\nCourtesy NASA/JPL-Caltech (R. R. Nelson)",
                     ha='right',
                     va='bottom',
                     transform=ax1.transAxes,
                     color='1.0',
                     size=18)

            #Preliminary data stamp
            plt.text(0.01,
                     0.99,
                     "PRELIMINARY (vEarly)",
                     ha='left',
                     va='top',
                     transform=ax1.transAxes,
                     color='r',
                     size=18)

            #Globe inset
            ax2 = inset_axes(ax1, width=2., height=2.)
            m2 = Basemap(projection='ortho',
                         lat_0=((N + S) / 2.),
                         lon_0=((E + W) / 2.),
                         resolution='l')
            m2.bluemarble()
            x1_globe, y1_globe = m2(((W + E) / 2.), ((N + S) / 2.))
            m2.scatter(x1_globe, y1_globe, c='r', s=100, marker='*')

            #Mark the target
            x1_target, y1_target = m1(data_temp2['target_lon'][0],
                                      data_temp2['target_lat'][0])
            ax1.scatter(x1_target, y1_target, c='r', marker="*", s=600)

            #Create save directory if it doesn't exist
            if not os.path.exists(
                    out_dir_temp + '/' +
                    data_temp2['production_string'][0].astype(str) + '/' +
                    var_string):
                os.makedirs(out_dir_temp + '/' +
                            data_temp2['production_string'][0].astype(str) +
                            '/' + var_string)

            #Save figure
            print("Saving as " + out_dir_temp + '/' +
                  data_temp2['production_string'][0].astype(str) + '/' +
                  var_string + '/OCO3_' +
                  data_temp2['production_string'][0].astype(str) + "_" +
                  var_string + '_' + str(data_temp2['sounding_id'][0])[:8] +
                  '_' + str(int(data_temp2['orbit'][0])) + "_" +
                  data_temp2['target_id'][0].astype(str) + '.png')
示例#4
0
def plotSparseMatrix(matrix, chrom, vmin, vmax, RF_dict, output_filepath):
    "Plots HIFI sparse matrix using Python's Matplotlib module"
    plt.ioff()  #prevent view window from openning over ssh connection
    fig, ax = plt.subplots(figsize=(8, 8))
    #create heat map using 'PatchCollection' rectangles and associated coordinates
    x = 0.0
    patches, colours = [], []
    y = sum(RF_dict["y"]["sizes"])
    for i, row_height in enumerate(RF_dict["y"]["sizes"]):
        y -= row_height
        for j, col_width in enumerate(RF_dict["x"]["sizes"]):
            colours.append(matrix[i][j])
            patch = Rectangle((x, y), col_width, row_height)
            patches.append(patch)
            x += col_width
        x = 0.0
    #plot 'PatchCollection' of rectangles
    pc = PatchCollection(patches, cmap=cmap)
    pc.set_clim([vmin, vmax])
    pc.set_array(np.array(colours))
    pc.set_edgecolor("face")
    pc.set_lw(0.1)
    ax.add_collection(pc)
    #remove outline from color bar
    cbar = plt.colorbar(pc, fraction=0.04575, pad=0.04)
    cbar.outline.set_visible(False)
    cbar.ax.tick_params(labelsize=16, length=4, width=0.5, color="grey")
    ax.tick_params(axis="x",
                   which="both",
                   bottom=False,
                   top=False,
                   direction="out",
                   length=4,
                   width=0.5,
                   pad=10,
                   color="grey",
                   labelsize=16)
    ax.xaxis.set_label_position("top")
    ax.set_xlabel(RF_dict["x"]["label"], fontsize=16, labelpad=8.25)
    ax.xaxis.tick_top()
    ax.tick_params(axis="y",
                   which="both",
                   left=False,
                   right=False,
                   direction="out",
                   length=4,
                   width=0.5,
                   color="grey",
                   labelsize=16)
    ax.set_ylabel(RF_dict["y"]["label"], fontsize=16, labelpad=None)
    ax.grid(False)
    #   remove x and y ticks
    plt.xticks([], [])
    plt.yticks([], [])
    #   remove axis edges
    for axis in ["bottom", "top", "left", "right"]:
        plt.gca().spines[axis].set_visible(False)
    ax.set_aspect("equal")
    plt.tight_layout()
    plt.savefig(output_filepath + ".png",
                format="png",
                dpi=600,
                transparent=False,
                bbox_inches="tight")
    plt.savefig(output_filepath + ".pdf",
                format="pdf",
                transparent=False,
                bbox_inches="tight")
    plt.close()

    #save matrix
    np.savetxt(output_filepath + ".csv", matrix, delimiter=",")