Exemple #1
0
        name = sys.argv[1]
    f = Level3File(name)

    # Pull the data out of the file object
    datadict = f.sym_block[0][0]

    # Turn into an array, then mask
    data = np.ma.array(datadict['data'])
    data[data == 0] = np.ma.masked

    # Grab azimuths and calculate a range based on number of gates
    az = np.array(datadict['start_az'] + [datadict['end_az'][-1]])
    rng = np.linspace(0, f.max_range, data.shape[-1] + 1)

    # Convert az,range to x,y
    xlocs = rng * np.sin(np.deg2rad(az[:, np.newaxis]))
    ylocs = rng * np.cos(np.deg2rad(az[:, np.newaxis]))

    # Plot the data
    norm, cmap = colortables.get_with_steps(ctable, 16, 16)
    ax.pcolormesh(xlocs, ylocs, data, norm=norm, cmap=cmap)
    ax.set_aspect('equal', 'datalim')
    ax.set_xlim(xmin, xmax)
    ax.set_ylim(xmin, xmax)
    add_timestamp(ax, f.metadata['prod_time'], y=0.02, high_contrast=True)

if len(sys.argv) < 3 or sys.argv[2] == 'plot':
    plt.show()
else:
    plt.savefig(sys.argv[1] + '.png')
    ('NWS8bitVel', -100, 1.0))  # m/s
for v, ctable, ax in zip(('N0Q', 'N0U'), ctables, axes):
    # Open the file
    name = get_test_data('nids/KOUN_SDUS54_{}TLX_201305202016'.format(v),
                         as_file_obj=False)
    f = Level3File(name)

    # Pull the data out of the file object
    datadict = f.sym_block[0][0]

    # Turn into an array using the scale specified by the file
    data = f.map_data(datadict['data'])

    # Grab azimuths and calculate a range based on number of gates
    az = np.array(datadict['start_az'] + [datadict['end_az'][-1]])
    rng = np.linspace(0, f.max_range, data.shape[-1] + 1)

    # Convert az,range to x,y
    xlocs = rng * np.sin(np.deg2rad(az[:, np.newaxis]))
    ylocs = rng * np.cos(np.deg2rad(az[:, np.newaxis]))

    # Plot the data
    norm, cmap = colortables.get_with_steps(*ctable)
    ax.pcolormesh(xlocs, ylocs, data, norm=norm, cmap=cmap)
    ax.set_aspect('equal', 'datalim')
    ax.set_xlim(-40, 20)
    ax.set_ylim(-30, 30)
    add_timestamp(ax, f.metadata['prod_time'], y=0.02, high_contrast=True)

plt.show()
def main():
    manager = mp.Manager()
    results = manager.dict()
    pool = mp.Pool(12)

    jobs = []

    for filepath in glob.glob(join(args["NEXRADL3"], '*')):
        job = pool.apply_async(calculate_radar_stats, (results, filepath))
        jobs.append(job)

    for job in tqdm(jobs, desc="Bounding & Searching Data"):
        job.get()

    pool.close()
    pool.join()

    print('Sorting...')
    columns = [
        'datetime', 'metadata', 'sensorData', 'indices', 'xlocs', 'ylocs',
        'data', 'polyVerts', 'offset', 'areaValue', 'refValue', 'varRefValue'
    ]
    resultsDF = pd.DataFrame.from_dict(results,
                                       orient='index',
                                       columns=columns)
    resultsDF['datetime'] = pd.to_datetime(resultsDF.datetime)
    resultsDF.sort_values(by='datetime', inplace=True)
    #resultsDF.to_csv(args["output"] + '.csv', index = False)
    print(resultsDF[['areaValue', 'refValue']].head(5))

    # --- Plot time series---
    print('Plotting Slices...')
    fig, axes = plt.subplots(8, 8, figsize=(30, 30))
    date_format = mpl_dates.DateFormatter('%H:%Mz')

    for i, (dt, record) in tqdm(enumerate(resultsDF.iterrows()),
                                desc='Plotting Slices'):
        plotx = i % 8
        ploty = int(i / 8)

        negXLim = -.5
        posXLim = 1.5
        negYLim = -1.0
        posYLim = 1.0
        norm, cmap = colortables.get_with_steps('NWSReflectivity', 18, 16)
        tempdata = record[
            'data']  # create a deep copy of data to maipulate for plotting
        tempdata[tempdata == 0] = np.ma.masked  # mask out 0s for plotting

        axes[ploty][plotx].pcolormesh(record['xlocs'],
                                      record['ylocs'],
                                      tempdata,
                                      norm=norm,
                                      cmap=cmap)
        axes[ploty][plotx].set_aspect('equal', 'datalim')
        axes[ploty][plotx].set_xlim(negXLim, posXLim)
        axes[ploty][plotx].set_ylim(negYLim, posYLim)
        pVXs, pVYs = zip(
            *record['polyVerts']
        )  # create lists of x and y values for transformed polyVerts
        axes[ploty][plotx].plot(pVXs, pVYs)
        if negXLim < record['offset'][1] < posXLim and negYLim < record[
                'offset'][0] < posYLim:
            axes[ploty][plotx].plot(record['offset'][1], record['offset'][0],
                                    'o')  # Location of the radar
            axes[ploty][plotx].text(
                record['offset'][1], record['offset'][0],
                record['sensorData']['siteID']
            )  # will plot outside limits of subplot if site falls outside range

        axes[ploty][plotx].plot(0.0, 0.0, 'bx')  # Location of the convection
        axes[ploty][plotx].text(0.0, 0.0, str(args["convLatLon"]))
        add_timestamp(axes[ploty][plotx],
                      record['datetime'],
                      y=0.02,
                      high_contrast=True)
        axes[ploty][plotx].tick_params(axis='both', which='both')

    print('Calculating Statistics...')

    # pull data out of DF to make code cleaner
    datetimes = resultsDF['datetime'].tolist()
    #elapsedtimes = list(map(lambda x: x - min(datetimes), datetimes))						# not currently used, need to get this working
    areaValues = resultsDF['areaValue'].tolist()  # area ≥ 35dbz within ROI
    refValues = (
        np.array(resultsDF['refValue'].tolist()) - 65
    ) * 0.5  # mean reflectivity ≥ 35dbz within ROI (conversion: (val-65)*0.5) [https://mesonet.agron.iastate.edu/GIS/rasters.php?rid=2]
    if np.nan in refValues:
        warnings.warn(
            "Radar inputs contains instance with no ref values >= thresh",
            UserWarning)
    #areaRefValues = np.multiply(areaValues, refValues)										# product of area and reflectivity
    varValues = resultsDF['varRefValue'].tolist(
    )  # variance of mean reflectivity ≥ 35dbz within ROI
    cvValues = np.array([
        a / b for a, b in zip(varValues, refValues)
    ]) * 0.5  # coeff. of variation for mean reflectivity ≥ 35dbz within ROI

    # Frequency
    N = len(refValues)
    T = 1.0 / N
    yf = fft(refValues)
    w = blackman(N)
    ywf = fft(refValues * w)

    # Normalization
    areaNorm = areaValues / np.max(areaValues)
    xf = np.linspace(0, 1.0 / (2.0 * T), N // 2)
    cvNorm = cvValues / np.max(cvValues)
    areaCVValuesNormalized = np.multiply(areaNorm, cvNorm)

    # Curve Smoothing
    window = len(
        resultsDF.index
    ) // 8  # ~2 hours/8 = ~15 mins ----> number of samples in moving average ( helps counteract more visible noise in higher temporal resolution data)
    yAreaAvg = movingaverage(
        areaValues, window)[window // 2:-window //
                            2]  # create moving averages for time series'
    yRefAvg = movingaverage(refValues, window)[window // 2:-window // 2]
    yCVAvg = movingaverage(cvValues, window)[window // 2:-window // 2]
    yAreaCVNormAvg = movingaverage(areaCVValuesNormalized,
                                   window)[window // 2:-window // 2]

    # local minima & maxima on smoothed curves
    minTemporalwindow = window * 2

    areaLocalMax = argrelmax(yAreaAvg)
    areaLocalMin = argrelmin(yAreaAvg)
    endpoints = []
    if yAreaAvg[0] <= np.all(yAreaAvg[1:window]) or yAreaAvg[0] >= np.all(
            yAreaAvg[1:window]):
        endpoints.append(0)
    if yAreaAvg[-1] <= np.all(
            yAreaAvg[len(yAreaAvg - 1) - window:-2]) or yAreaAvg[-1] >= np.all(
                yAreaAvg[len(yAreaAvg - 1) - window:-2]):
        endpoints.append(len(yAreaAvg) - 1)
    areaExtremaRaw = sorted(
        areaLocalMax[0].tolist() + areaLocalMin[0].tolist() + endpoints
    )  # combine mins, maxes, and endpoints (if endpoints are an extreme) then sort
    areaExtrema = [
        x for x in areaExtremaRaw[1:]
        if x - areaExtremaRaw[0] >= minTemporalwindow
    ]  # remove maxima that are within threshold of first one
    areaExtrema = [areaExtremaRaw[0]
                   ] + areaExtrema  # add back in forst one to begining
    print(f'Area Extrema: {areaExtrema}')

    refLocalMax = argrelmax(yRefAvg)
    refLocalMin = argrelmin(yRefAvg)
    endpoints = []
    if yRefAvg[0] <= np.all(yRefAvg[1:window]) or yRefAvg[0] >= np.all(
            yRefAvg[1:window]):
        endpoints.append(0)
    if yRefAvg[-1] <= np.all(
            yRefAvg[len(yRefAvg - 1) - window:-2]) or yRefAvg[-1] >= np.all(
                yRefAvg[len(yRefAvg - 1) - window:-2]):
        endpoints.append(len(yRefAvg) - 1)
    refExtremaRaw = sorted(refLocalMax[0].tolist() + refLocalMin[0].tolist() +
                           endpoints)
    refExtrema = [
        x for x in refExtremaRaw[1:]
        if x - refExtremaRaw[0] >= minTemporalwindow
    ]
    refExtrema = [refExtremaRaw[0]] + refExtrema
    print(f'Ref Extrema: {refExtrema}')

    #cvLocalMax = argrelmax(yCVAvg)
    #cvLocalMin = argrelmin(yCVAvg)
    #endpoints = []
    #if yCVAvg[0] <= np.all(yCVAvg[1:window]) or yCVAvg[0] >= np.all(yCVAvg[1:window]):
    #	endpoints.append(0)
    #if yCVAvg[-1] <= np.all(yCVAvg[len(yCVAvg-1)-window:-2]) or yCVAvg[-1] >= np.all(yCVAvg[len(yCVAvg-1)-window:-2]):
    #	endpoints.append(len(yCVAvg)-1)
    #cvExtremaRaw = sorted(cvLocalMax[0].tolist()+cvLocalMin[0].tolist()+endpoints)
    #cvExtrema = [x for x in cvExtremaRaw[1:] if x-cvExtremaRaw[0]>=minTemporalwindow]
    #cvExtrema = [cvExtremaRaw[0]]+cvExtrema
    #print(f'CV Extrema: {cvExtrema}')

    yAreaCVNormLocalMax = argrelmax(yAreaCVNormAvg)
    yAreaCVNormLocalMin = argrelmin(yAreaCVNormAvg)
    endpoints = []
    if yAreaCVNormAvg[0] <= np.all(
            yAreaCVNormAvg[1:window]) or yAreaCVNormAvg[0] >= np.all(
                yAreaCVNormAvg[1:window]):
        endpoints.append(0)
    if yAreaCVNormAvg[-1] <= np.all(
            yAreaCVNormAvg[len(yAreaCVNormAvg - 1) -
                           window:-2]) or yAreaCVNormAvg[-1] >= np.all(
                               yAreaCVNormAvg[len(yAreaCVNormAvg - 1) -
                                              window:-2]):
        endpoints.append(len(yAreaCVNormAvg) - 1)
    yAreaCVNormExtremaRaw = sorted(yAreaCVNormLocalMax[0].tolist() +
                                   yAreaCVNormLocalMin[0].tolist() + endpoints)
    yAreaCVNormExtrema = [
        x for x in yAreaCVNormExtremaRaw[1:]
        if x - yAreaCVNormExtremaRaw[0] >= minTemporalwindow
    ]
    yAreaCVNormExtrema = [yAreaCVNormExtremaRaw[0]] + yAreaCVNormExtrema
    print(f'AreaCVNorm Extrema: {yAreaCVNormExtrema}')

    # Find slopes of Build-up Lines
    # 	Area
    xArea = np.array(datetimes[window // 2:-window // 2])[np.array(
        [areaExtrema[0], areaExtrema[1]]
    )]  # grab datetime (x component) of the leftmost bounds (determined by window size), and the first extreme on the smoothed curve (sm curve is already bound by window, we need to apply bounds to datetimes)
    xAreaDiff = xArea[1] - xArea[
        0]  # subtract the later value from the former to get our delta x
    yArea = yAreaAvg[np.array(
        [areaExtrema[0], areaExtrema[1]]
    )]  # grab the values (y component) of the sm curve at the begining and at the first extreme
    yAreaDiff = yArea[1] - yArea[0]  # subtract to find delta y
    slopeArea = np.arctan(yAreaDiff /
                          xAreaDiff.seconds)  # calc the slope angle
    print(f'Slope Area: {slopeArea}')

    #   Reflectivity
    xRef = np.array(datetimes[window // 2:-window // 2])[np.array(
        [refExtrema[0], refExtrema[1]])]
    xRefDiff = xRef[1] - xRef[0]
    yRef = yRefAvg[np.array([refExtrema[0], refExtrema[1]])]
    yRefDiff = yRef[1] - yRef[0]
    slopeRef = np.arctan(yRefDiff / xRefDiff.seconds)
    print(f'Slope Reflectivity: {slopeRef}')

    # 	Product of Area and CV of ref
    xProduct = np.array(datetimes[window // 2:-window // 2])[np.array(
        [yAreaCVNormExtrema[0], yAreaCVNormExtrema[1]])]
    XProductDiff = xProduct[1] - xProduct[0]
    yProduct = yAreaCVNormAvg[np.array(
        [yAreaCVNormExtrema[0], yAreaCVNormExtrema[1]])]
    yProductDiff = yProduct[1] - yProduct[0]
    slopeProduct = np.arctan(yProductDiff / XProductDiff.seconds)
    print(f'Slope Product: {slopeProduct}')

    print('Plotting Additional Data and Saving Output...')
    # Area for Reflectivity ≥ 35dbz
    axes[-1][-5].plot_date(datetimes, areaValues, linestyle='solid', ms=2)
    axes[-1][-5].plot_date(datetimes[window // 2:-window // 2],
                           yAreaAvg,
                           linestyle='solid',
                           ms=2)
    axes[-1][-5].plot_date(
        np.array(datetimes[window // 2:-window // 2])[np.array(
            [areaExtrema[0], areaExtrema[1]])],
        yAreaAvg[np.array([areaExtrema[0], areaExtrema[1]])],
        linestyle="solid",
        ms=2)
    axes[-1][-5].legend(['Area Delta', 'Sm. Area Delta', 'Build-up Rate'])
    axes[-1][-5].xaxis.set_major_formatter(date_format)
    plt.setp(axes[-1][-5].xaxis.get_majorticklabels(),
             rotation=45,
             ha="right",
             rotation_mode="anchor")
    axes[-1][-5].set_title('Area of Reflectivity ≥ 35dbz (km^2)')

    # TODO: map y axis to dbz for output
    # Mean of Reflectivity ≥ 35dbz
    axes[-1][-4].plot_date(datetimes, refValues, linestyle='solid', ms=2)
    #axes[-1][-4].plot_date(datetimes[window//2:-window//2], yRefAvg, linestyle='solid', ms=2)
    #axes[-1][-4].plot_date(np.array(datetimes[window//2:-window//2])[np.array([0,refLocalMax[0][0]])], yRefAvg[np.array([0,refLocalMax[0][0]])], linestyle="solid", ms=2)
    axes[-1][-4].plot_date(datetimes[window // 2:-window // 2],
                           yRefAvg,
                           linestyle='solid',
                           ms=2)
    axes[-1][-4].plot_date(np.array(
        datetimes[window // 2:-window // 2])[np.array(
            [refExtrema[0], refExtrema[1]])],
                           yRefAvg[np.array([refExtrema[0], refExtrema[1]])],
                           linestyle="solid",
                           ms=2)
    axes[-1][-4].legend(['Ref Delta', 'Sm. Ref Delta', 'Build-up Rate'])
    axes[-1][-4].xaxis.set_major_formatter(date_format)
    plt.setp(axes[-1][-4].xaxis.get_majorticklabels(),
             rotation=45,
             ha="right",
             rotation_mode="anchor")
    axes[-1][-4].set_title('Mean of Reflectivity ≥ 35dbz')

    # Product of cv reflectivity and area
    axes[-1][-3].plot_date(datetimes,
                           areaCVValuesNormalized,
                           linestyle='solid',
                           ms=2)
    axes[-1][-3].plot_date(datetimes[window // 2:-window // 2],
                           yAreaCVNormAvg,
                           linestyle='solid',
                           ms=2)
    axes[-1][-3].plot_date(
        np.array(datetimes[window // 2:-window // 2])[np.array(
            [yAreaCVNormExtrema[0], yAreaCVNormExtrema[1]])],
        yAreaCVNormAvg[np.array([yAreaCVNormExtrema[0],
                                 yAreaCVNormExtrema[1]])],
        linestyle="solid",
        ms=2)
    axes[-1][-3].legend(
        ['Area*cv_Ref Delta', 'Sm. Area*cv_Ref Delta', 'Build-up Rate'])
    axes[-1][-3].xaxis.set_major_formatter(date_format)
    plt.setp(axes[-1][-3].xaxis.get_majorticklabels(),
             rotation=45,
             ha="right",
             rotation_mode="anchor")
    axes[-1][-3].set_title('Norm Product: CV Reflectivity * Area ≥ 35dbz')

    # Coeff. of Variance of Reflectivity ≥ 35dbz
    axes[-1][-2].plot_date(datetimes, cvValues, linestyle='solid', ms=2)
    axes[-1][-2].plot_date(datetimes[window // 2:-window // 2],
                           yCVAvg,
                           linestyle='solid',
                           ms=2)
    axes[-1][-2].legend(['CV Delta', 'Sm. CV Delta'])
    axes[-1][-2].xaxis.set_major_formatter(date_format)
    plt.setp(axes[-1][-2].xaxis.get_majorticklabels(),
             rotation=45,
             ha="right",
             rotation_mode="anchor")
    axes[-1][-2].set_title('CV of Reflectivity ≥ 35dbz')

    # Testing plot
    axes[-1][-1].semilogy(xf[1:N // 2], 2.0 / N * np.abs(yf[1:N // 2]), '-b')
    axes[-1][-1].semilogy(xf[1:N // 2], 2.0 / N * np.abs(ywf[1:N // 2]), '-r')
    axes[-1][-1].legend(['FFT', 'FFT w. Window'])
    #axes[-1][-1].plot(xf, 2.0/N * np.abs(yf[0:N//2]),linestyle='solid', ms=2)
    #axes[-1][-1].plot_date(datetimes, yCVAvg, linestyle='solid')
    #axes[-1][-1].xaxis.set_major_formatter(date_format)
    plt.setp(axes[-1][-1].xaxis.get_majorticklabels(),
             rotation=45,
             ha="right",
             rotation_mode="anchor")
    axes[-1][-1].set_title('Testing Plot (Frequency)')

    plt.tight_layout()
    plt.savefig(args["output"] + 'Nexrad.png')  # Set the output file name
    #plt.show()

    f_o = open(args["output"] + 'log_stats_area_nexrad.txt', 'a')
    f_o.write(datetimes[0].strftime("%Y%m%d%H%M%S") + '\t' +
              str(args["convLatLon"]) + '\t' + str(args["convBearing"]) +
              '\t' + str(args["scaleFactor"]) + '\t' +
              str(np.max(areaValues)) + '\t' + str(np.max(refValues)) + '\t' +
              str(slopeArea)  # std dev of LIS aligned data
              + '\t' + str(slopeRef) + '\t' + str(slopeProduct) + '\n')
    f_o.close()
Exemple #4
0
add_metpy_logo(fig, 190, 85, size='large')
for v, ctable, ax in zip(('N0Q', 'N0U'), ('NWSReflectivity', 'NWSVelocity'), axes):
    # Open the file
    name = get_test_data('nids/KOUN_SDUS54_{}TLX_201305202016'.format(v), as_file_obj=False)
    f = Level3File(name)

    # Pull the data out of the file object
    datadict = f.sym_block[0][0]

    # Turn into an array, then mask
    data = np.ma.array(datadict['data'])
    data[data == 0] = np.ma.masked

    # Grab azimuths and calculate a range based on number of gates
    az = np.array(datadict['start_az'] + [datadict['end_az'][-1]])
    rng = np.linspace(0, f.max_range, data.shape[-1] + 1)

    # Convert az,range to x,y
    xlocs = rng * np.sin(np.deg2rad(az[:, np.newaxis]))
    ylocs = rng * np.cos(np.deg2rad(az[:, np.newaxis]))

    # Plot the data
    norm, cmap = colortables.get_with_steps(ctable, 16, 16)
    ax.pcolormesh(xlocs, ylocs, data, norm=norm, cmap=cmap)
    ax.set_aspect('equal', 'datalim')
    ax.set_xlim(-40, 20)
    ax.set_ylim(-30, 30)
    add_timestamp(ax, f.metadata['prod_time'], y=0.02, high_contrast=True)

plt.show()
Exemple #5
0
def plot_U_W_P_T(u, w, p, t, time, x, y, plot_prefix="workshop"):

    plot_filename = "%s.%s" % (plot_prefix, output_format)

    fig, ((ax1, ax2, ax3, ax4)) = P.subplots(4,
                                             1,
                                             sharey=True,
                                             sharex=True,
                                             figsize=(6, 8))

    yy, xx = N.meshgrid(y, x)
    yy = yy / 1000.
    xx = xx / 1000.

    clevels = N.arange(-35., 40., 5.)
    norm, cmap = colortables.get_with_steps('viridis', clevels.shape[0], 5.)
    plot = ax1.contourf(xx, yy, u, clevels, cmap=cmap)
    #   cbar    = ax1.colorbar(plot,location='right',pad="5%")
    #   cbar.set_label("U")
    plot = ax1.contour(xx, yy, u, clevels[::2], colors='k', linewidths=0.5)
    title = ("U-Wind (m/s)")
    ax1.set_title(title, loc='left', fontsize=8)
    start, end = ax1.get_xlim()
    #   ax1.xaxis.set_ticks(N.arange(start, end+6, 6))
    ax1.xaxis.set_ticks(N.arange(start, end + 11, 10))
    ax1.xaxis.set_major_formatter(ticker.FormatStrFormatter('%d'))
    start, end = ax1.get_ylim()
    ax1.yaxis.set_ticks(N.arange(start, end, 2))
    ax1.yaxis.set_major_formatter(ticker.FormatStrFormatter('%d'))

    at = AnchoredText(
        "Max U: %4.1f \n Min U: %4.1f" % (u.max(), u.min()),
        loc=1,
        prop=dict(size=10),
        frameon=True,
    )
    at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
    ax1.add_artist(at)

    if N.abs(t).max() > 5.0:
        clevels = N.arange(-30., 32., 2.)
    else:
        clevels = N.arange(-1., 1.1, 0.1) / 10.
    norm, cmap = colortables.get_with_steps('viridis', clevels.shape[0],
                                            clevels[1] - clevels[0])
    wmask = N.ma.masked_array(w, mask=[N.abs(w) <= _min_w])
    plot = ax2.contourf(xx, yy, wmask, clevels, cmap=cmap)
    #   cbar    = plot.colorbar(plot,location='right',pad="5%")
    plot = ax2.contour(xx, yy, wmask, clevels[::2], colors='k', linewidths=0.5)
    #   cbar.set_label('%s' % ("$m s^{-1}$"))
    title = ("Vertical Velocity (m/s)")
    ax2.set_title(title, loc='left', fontsize=8)

    at = AnchoredText(
        "Max W: %4.1f \n Min W: %4.1f" % (w.max(), w.min()),
        loc=1,
        prop=dict(size=10),
        frameon=True,
    )
    at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
    ax2.add_artist(at)

    if N.abs(t).max() > 5.0:
        clevels = N.arange(-16., 10., 1.)
    else:
        clevels = N.arange(-100, 105, 5)
        clevels = 0.01 * clevels[clevels != 0]
    norm, cmap = colortables.get_with_steps('viridis', clevels.shape[0],
                                            clevels[1] - clevels[0])
    tmask = N.ma.masked_array(t, mask=[N.abs(t) <= 0.00001])
    plot = ax3.contourf(xx, yy, tmask, clevels, cmap=cmap)
    #   cbar    = ax3.colorbar(plot,location='right',pad="5%")
    plot = ax3.contour(xx, yy, tmask, clevels, colors='k', linewidths=0.5)
    #   cbar.set_label('%s' % ("K"))
    title = ("Pert. Potential Temperature (K)")
    ax3.set_title(title, loc='left', fontsize=8)

    at = AnchoredText(
        "Max TH: %5.3f \n Min TH: %5.3f" % (t.max(), t.min()),
        loc=1,
        prop=dict(size=10),
        frameon=True,
    )
    at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
    ax3.add_artist(at)

    if N.abs(t).max() > 5.0:
        clevels = N.arange(-1000., 1000., 100.0)
#       clevels = N.arange(-3.,3.,0.1)
    else:
        clevels = N.arange(-15., 15.5, 0.5)

    norm, cmap = colortables.get_with_steps('viridis', clevels.shape[0],
                                            clevels[1] - clevels[0])
    plot = ax4.contourf(xx, yy, p, clevels, cmap=cmap)
    #   cbar    = ax4.colorbar(plot,location='right',pad="5%")
    plot = ax4.contour(xx, yy, p, clevels[::2], colors='k', linewidths=0.5)
    #   cbar.set_label('%s' % ("mb"))
    title = ("Pressure (mb)")
    ax4.set_title(title, fontsize=8)
    ax4.set_xlabel('X km', fontsize=8)

    at = AnchoredText(
        "Max P: %4.1f \n Min P: %4.1f" % (p.max(), p.min()),
        loc=1,
        prop=dict(size=10),
        frameon=True,
    )
    at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
    ax4.add_artist(at)

    if int(time) < 1000:
        title = ("Time = %3d sec" % (int(time)))
    else:
        title = ("Time = %4d sec" % (int(time)))

    fig.suptitle(title, y=1.0, fontsize=10)

    P.tight_layout(h_pad=0.5)

    if output_format == "pdf":
        print("\n Saving file %s" % (plot_filename))
        fig.savefig(plot_filename, format="pdf", dpi=300)

    if output_format == "png":
        print("\n Saving file %s" % (plot_filename))
        fig.savefig(plot_filename, format="png", dpi=300)

    if interactive:
        print(plot_filename)
        os.system("open %s" % plot_filename)

    return plot_filename
Exemple #6
0
def cref_uv850(initial_time, fhour=0, model='ShangHai',
               map_center=(117, 39), map_width=12, draw_wind=False):
    """
    Analysis composite reflectivity and 850hPa wind.
    
    Arguments:
        initial_time {string or datetime}} -- 
            initial time, string or datetime ojbect.
            like '18042008' or datetime(2018, 4, 20, 8).
    
    Keyword Arguments:
        fhour {int} -- forecast hour (default: {0})
        model {str} -- model name (default: {'ShangHai'})
        map_center {tuple} -- map center (default: {(117, 39)})
        map_width {int} -- map width (default: {12})
        draw_wind {bool} -- draw 850hPa wind or not (default: {False})
    
    Raises:
        ValueError -- [description]
    """

    # micaps data directory
    data_dirs = {
        'SHANGHAI': ['SHANGHAI_HR/COMPOSITE_REFLECTIVITY/ENTIRE_ATMOSPHERE',
                     'SHANGHAI_HR/UGRD/850', 'SHANGHAI_HR/VGRD/850'],
        'BEIJING': ['BEIJING_MR/COMPOSITE_REFLECTIVITY/ENTIRE_ATMOSPHERE',
                    'BEIJING_MR/UGRD/850', 'BEIJING_MR/VGRD/850'],
        'GRAPES_MESO': ['GRAPES_MESO_HR/RADAR_COMBINATION_REFLECTIVITY',
                        'GRAPES_MESO_HR/UGRD/850', 'GRAPES_MESO_HR/VGRD/850'],
        'GRAPES_3KM': ['GRAPES_3KM/RADAR_COMBINATION_REFLECTIVITY',
                       'GRAPES_3KM/UGRD/850', 'GRAPES_3KM/VGRD/850']}
    try:
        data_dir = data_dirs[model.strip().upper()]
    except KeyError:
        raise ValueError('Unknown model, choose ShangHai, BeiJing, Grapes_meso of Grapes_3km.')
        
    # get filename
    filename = model_filename(initial_time, fhour)
    
    # retrieve data from micaps server
    cref = get_model_grid(data_dir[0], filename=filename)
    if cref is None:
        return
    init_time = cref.coords['init_time'].values[0]
    if draw_wind:
        u850 = get_model_grid(data_dir[1], filename=filename)
        if u850 is None:
            return
        v850 = get_model_grid(data_dir[2], filename=filename)
        if v850 is None:
            return
    
    # prepare data
    data = np.ma.masked_array(cref.values)
    data[data == 9999] = np.ma.masked
    data[data < 10] = np.ma.masked
    cref_data = {'lon':cref.coords['lon'].values, 
                 'lat':cref.coords['lat'].values, 
                 'data':np.squeeze(data)}
    if draw_wind:
        uv850 = {'lon': u850.coords['lon'].values,
                 'lat': u850.coords['lat'].values,
                 'udata': np.squeeze(u850.values),
                 'vdata': np.squeeze(v850.values)}
    
    # set up map projection
    datacrs = ccrs.PlateCarree()
    plotcrs = ccrs.AlbersEqualArea(
        central_latitude=map_center[1], central_longitude=map_center[0],
        standard_parallels=[30., 60.])
    
    # set up figure
    fig = plt.figure(figsize=(12, 9))
    gs = mpl.gridspec.GridSpec(
        1, 2, width_ratios=[1, .03], 
        bottom=.01, top=.99, hspace=0.01, wspace=0.01)
    ax = plt.subplot(gs[0], projection=plotcrs)
    
    # add model title
    add_model_title(
        'CREF (dBz), 850-hPa Winds', init_time, model=model,
        fhour=fhour, fontsize=18, multilines=True)
    
    # add map background
    map_extent = (
        map_center[0] - map_width/2.0, map_center[0] + map_width/2.0,
        map_center[1] - map_width/3.0, map_center[1] + map_width/3.0)
    ax.set_extent(map_extent, crs=datacrs)
    add_china_map_2cartopy(
        ax, name='province', edgecolor='black',
        lw=2, zorder=100)
    
    # draw composite reflectivity
    x, y = np.meshgrid(cref_data['lon'], cref_data['lat'])
    norm, cmap = colortables.get_with_steps('NWSReflectivity', 12, 4)
    pm = ax.pcolormesh(x, y, cref_data['data'], norm=norm, cmap=cmap, transform=datacrs)
    cax = plt.subplot(gs[1])
    cb = plt.colorbar(pm, cax=cax, orientation='vertical', extendrect='True')
    cb.set_label('Composite reflectivity', size=12)

    # draw wind vector
    if draw_wind:
        x, y = np.meshgrid(uv850['lon'], uv850['lat'])
        ax.quiver(x, y, uv850['udata'], uv850['vdata'],
                  transform=datacrs, regrid_shape=25)
    
    # show figure
    gs.tight_layout(fig)
    plt.show()
Exemple #7
0
def cref_uv850_compare(initial_time, fhour=0, map_center=(117, 39), map_width=12, draw_wind=False):
    """
    Compare mesoscale model's composite reflectivity.
    
    Arguments:
        initial_time {string or datetime}} -- 
            initial time, string or datetime ojbect.
            like '18042008' or datetime(2018, 4, 20, 8).
    
    Keyword Arguments:
        fhour {int} -- forecast hour (default: {0})
        map_center {tuple} -- map center (default: {(117, 39)})
        map_width {int} -- map width (default: {12})
        draw_wind {bool} -- draw 850hPa wind or not (default: {False})
    """

    # micaps data directory
    data_dirs = {'SHANGHAI': ['SHANGHAI_HR/COMPOSITE_REFLECTIVITY/ENTIRE_ATMOSPHERE',
                              'SHANGHAI_HR/UGRD/850', 'SHANGHAI_HR/VGRD/850'],
                 'BEIJING': ['BEIJING_MR/COMPOSITE_REFLECTIVITY/ENTIRE_ATMOSPHERE',
                             'BEIJING_MR/UGRD/850', 'BEIJING_MR/VGRD/850'],
                 'GRAPES_MESO': ['GRAPES_MESO_HR/RADAR_COMBINATION_REFLECTIVITY',
                                 'GRAPES_MESO_HR/UGRD/850', 'GRAPES_MESO_HR/VGRD/850'],
                 'GRAPES_3KM': ['GRAPES_3KM/RADAR_COMBINATION_REFLECTIVITY',
                                'GRAPES_3KM/UGRD/850', 'GRAPES_3KM/VGRD/850']}
    
    # get filename
    filename = model_filename(initial_time, fhour)
    
    # set up map projection
    datacrs = ccrs.PlateCarree()
    plotcrs = ccrs.AlbersEqualArea(
        central_latitude=map_center[1], central_longitude=map_center[0],
        standard_parallels=[30., 60.])
    
    # set up figure
    fig = plt.figure(figsize=(16, 12))
    axes_class = (GeoAxes, dict(map_projection=plotcrs))
    grid = AxesGrid(fig, 111, axes_class=axes_class, nrows_ncols=(2, 2),
                    axes_pad=0.05, cbar_location='right', cbar_mode='single',
                    cbar_pad=0.05, label_mode='')
    
    # loop every data directory
    for index, key in enumerate(data_dirs):
        # get axis and data directory
        ax = grid[index]
        data_dir = data_dirs[key]
        
        # retrieve data from micaps server
        cref = get_model_grid(data_dir[0], filename=filename)
        if cref is None:
            return
        init_time = cref.coords['init_time'].values[0]
        if draw_wind:
            u850 = get_model_grid(data_dir[1], filename=filename)
            if u850 is None:
                return
            v850 = get_model_grid(data_dir[2], filename=filename)
            if v850 is None:
                return
            
        # add title
        if index == 0:
            initial_str, fhour_str, valid_str = get_model_time_stamp(init_time, fhour)
            fig.suptitle('CREF (dBz), 850-hPa Winds    ' + initial_str + '; ' + fhour_str + '; ' + valid_str,
                         x=0.5, y=0.9, fontsize=16)
    
        # prepare data
        data = np.ma.masked_array(cref.values)
        data[data == 9999] = np.ma.masked
        data[data < 10] = np.ma.masked
        cref_data = {'lon':cref.coords['lon'].values, 
                     'lat':cref.coords['lat'].values, 
                     'data':np.squeeze(data)}
        if draw_wind:
            uv850 = {'lon': u850.coords['lon'].values,
                     'lat': u850.coords['lat'].values,
                     'udata': np.squeeze(u850.values),
                     'vdata': np.squeeze(v850.values)}
    
        # add map background
        map_extent = (
            map_center[0] - map_width/2.0, map_center[0] + map_width/2.0,
            map_center[1] - map_width/3.0, map_center[1] + map_width/3.0)
        ax.set_extent(map_extent, crs=datacrs)
        add_china_map_2cartopy(
            ax, name='province', edgecolor='black',
            lw=2, zorder=100)
    
        # draw composite reflectivity
        x, y = np.meshgrid(cref_data['lon'], cref_data['lat'])
        norm, cmap = colortables.get_with_steps('NWSReflectivity', 12, 4)
        pm = ax.pcolormesh(x, y, cref_data['data'], norm=norm, cmap=cmap, transform=datacrs)

        # draw wind vector
        if draw_wind:
            x, y = np.meshgrid(uv850['lon'], uv850['lat'])
            ax.quiver(x, y, uv850['udata'], uv850['vdata'],
                      transform=datacrs, regrid_shape=25)
            
        # add title
        add_titlebox(ax, key)
            
    # add color bar
    cbar = grid.cbar_axes[0].colorbar(pm)
    
    # show figure
    plt.show()