Beispiel #1
0
def print_cape_for_timestamp(wrf_data, timestamp, filepath):
    slp = pressure_lib.get_sea_level_pressure(wrf_data)
    cinfo = getvar(wrf_data, "cape_2d", missing=0.0)
    cape = cinfo[0, :, :].fillna(0)

    lat, lon = latlon_coords(slp)
    lat_normal = to_np(lat)
    lon_normal = to_np(lon)

    # rain sum
    cape_res = get_pyngl(cinfo)
    cape_res.nglDraw = False  # don't draw plot
    cape_res.nglFrame = False  # don't advance frame

    cape_res.cnFillOn = True  # turn on contour fill
    cape_res.cnLinesOn = False  # turn off contour lines
    cape_res.cnLineLabelsOn = False  # turn off line labels
    cape_res.cnFillMode = "RasterFill"  # These two resources
    cape_res.cnLevelSelectionMode = "ExplicitLevels"
    cape_res.cnFillColors        = numpy.array([ [255,255,255], [  0,255,  0], [  0,128,  0], \
                                                 [240,230,140], [255,255,  0], [255,140,  0], \
                                                 [255,  0,  0], [139,  0,  0], [186, 85,211],\
                                                 [153, 50,204], [139,  0,139], ],'f') / 255.
    cape_res.cnLevels = numpy.array(
        [.1, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500])

    cape_res = geography_lib.initialize_geography(cape_res, "gray50")

    cape_res.lbTitleString = "Convective available potential energy [CAPE] in (J/kg)"
    cape_res.lbOrientation = "horizontal"
    cape_res.lbTitleFontHeightF = 0.015
    cape_res.lbLabelFontHeightF = 0.015

    cape_res.tiMainString = "Thunderstorm probability (%s)" % timestamp.strftime(
        "%b %d %Y %HUTC")
    cape_res.trGridType = "TriangularMesh"  # can speed up plotting.
    cape_res.tfDoNDCOverlay = True  # required for native projection

    # pressure
    p_res = pressure_lib.get_pressure_resource(lat_normal, lon_normal)

    wk_res = Ngl.Resources()
    wk_res.wkWidth = 2500
    wk_res.wkHeight = 2500
    output_path = "%scape_%s" % (filepath, timestamp.strftime("%Y_%m_%d_%H"))
    wks_comp = Ngl.open_wks("png", output_path, wk_res)

    # creating plots for the measurands
    capeplot = Ngl.contour_map(wks_comp, cape, cape_res)
    pplot = Ngl.contour(wks_comp, slp, p_res)

    Ngl.overlay(capeplot, pplot)
    Ngl.maximize_plot(wks_comp, capeplot)
    Ngl.draw(capeplot)
    Ngl.frame(wks_comp)
    Ngl.delete_wks(wks_comp)  # delete currently used workstation
Beispiel #2
0
def get_3h_rainsum(previous_data, current_data, timestamp, filepath):
    slp = pressure_lib.get_sea_level_pressure(current_data)
    previous_sum, rain_con = get_cumulated_rain_sum(previous_data)
    current_sum, rain_con = get_cumulated_rain_sum(current_data)
    rain_sum = current_sum - previous_sum

    lat, lon = latlon_coords(rain_con)
    lat_normal = to_np(lat)
    lon_normal = to_np(lon)

    # rain sum
    rr_res = initialize_rain_resource(rain_con)

    rr_res.lbTitleString = "3h rainsum in (mm)"
    rr_res.lbOrientation = "horizontal"
    rr_res.lbTitleFontHeightF = 0.015
    rr_res.lbLabelFontHeightF = 0.015

    rr_res.tiMainString = "3h rainsum (%s)" % timestamp.strftime(
        "%b %d %Y %HUTC")
    rr_res.trGridType = "TriangularMesh"  # can speed up plotting.
    rr_res.tfDoNDCOverlay = True  # required for native projection

    # pressure
    p_res = pressure_lib.get_pressure_resource(lat_normal, lon_normal)

    wk_res = Ngl.Resources()
    wk_res.wkWidth = 2500
    wk_res.wkHeight = 2500
    output_path = "%srain_3h_%s" % (filepath,
                                    timestamp.strftime("%Y_%m_%d_%H"))
    wks_comp = Ngl.open_wks("png", output_path, wk_res)

    # creating plots for the measurands
    rrplot = Ngl.contour_map(wks_comp, rain_sum, rr_res)
    pplot = Ngl.contour(wks_comp, slp, p_res)

    Ngl.overlay(rrplot, pplot)
    Ngl.maximize_plot(wks_comp, rrplot)
    Ngl.draw(rrplot)
    Ngl.frame(wks_comp)
    Ngl.delete_wks(wks_comp)  # delete currently used workstation
def plot_power(Pow, symmetry=("symm"), source="", var1="", plotpath="./", flim=0.5, nWavePlt=20, cmin=0.05, cmax=0.55,
               cspc=0.05, plotxy=[1, 1], N=[1, 2]):

    dims = Pow.shape
    nplot = dims[0]

    FillMode = "AreaFill"

    # text labels
    abc = list(string.ascii_lowercase)

    # plot resources
    wkstype = "png"
    wks = ngl.open_wks(wkstype, plotpath + "SpaceTimePower_" + source + var1)
    plots = []

    # coherence2 plot resources
    res = coh_resources(cmin, cmax, cspc, FillMode, flim, nWavePlt)
    # phase arrow resources
    resA = phase_resources(flim, nWavePlt)

    # dispersion curve resources
    dcres = ngl.Resources()
    dcres.gsLineThicknessF = 2.0
    dcres.gsLineDashPattern = 0

    # text box resources
    txres = ngl.Resources()
    txres.txPerimOn = True
    txres.txFontHeightF = 0.013
    txres.txBackgroundFillColor = "Background"

    # panel plot resources
    resP = panel_resources(nplot, abc)

    # plot contours and phase arrows
    pp = 0
    while pp < nplot:
        if nplot == 1:
            coh2 = Pow
        else:
            coh2 = Pow[pp, :, :]
        if len(symmetry) == nplot:
            Symmetry = symmetry[pp]
        else:
            Symmetry = symmetry

        res.tiMainString = source + "    log10( Power(" + var1 + "))           " + Symmetry
        plot = ngl.contour(wks, coh2, res)

        (matsuno_names, textlabels, textlocsX, textlocsY) = text_labels(Symmetry)
        nlabel = len(textlocsX)

        # generate matsuno mode dispersion curves
        if Symmetry == "midlat":
            He = [3000, 7000, 10000]
            matsuno_modes = mp.matsuno_modes_wk_bg(he=He, n=N, latitude=0., max_wn=nWavePlt, n_wn=500, u=25)
        else:
            He = [12, 25, 50]
            matsuno_modes = mp.matsuno_modes_wk(he=He, n=N, latitude=0., max_wn=nWavePlt, n_wn=500)

        # add polylines for dispersion curves
        for he in matsuno_modes:
            df = matsuno_modes[he]
            wn = df.index.values
            for wavename in df:
                for matsuno_name in matsuno_names:
                    if wavename == (matsuno_name + str(he) + "m)"):
                        wave = df[wavename].values
                        wnwave = wn[~np.isnan(wave)]
                        wave = wave[~np.isnan(wave)]
                        ngl.add_polyline(wks, plot, wnwave, wave, dcres)

        # add text boxes
        ll = 0
        while ll < nlabel:
            ngl.add_text(wks, plot, textlabels[ll], textlocsX[ll], textlocsY[ll], txres)
            ll += 1

        plots.append(plot)
        pp += 1

        # panel plots
    ngl.panel(wks, plots, plotxy, resP)
    ngl.delete_wks(wks)
    #ngl.end()

    return
Beispiel #4
0
res.cnMinLevelValF     = -0.1#0.45#-0.1             #-- contour min. value
res.cnMaxLevelValF     = 2.0#1.5#2.0          #-- contour max. value
res.cnLevelSpacingF    = 0.1#0.05#0.1             #-- contour interval
colors00 = Ngl.read_colormap_file("MPL_RdBu")
ncolors00= colors00.shape[0]
colors0 = colors00[np.linspace(2,ncolors00-1,int((res.cnMaxLevelValF-res.cnMinLevelValF)/res.cnLevelSpacingF),dtype=int),:] 
grey_color = np.expand_dims(np.array([0.85, 0.85, 0.85, 1]), axis=0)
colors = np.append(grey_color,colors0[::-1,:],axis=0)

res.cnFillPalette      = colors#'BlWhRe' #'MPL_YlOrRd'         #-- choose color map
plot = []
title = 'CESM all forcing vs '+sf+' foricng~C~FWI >= p'+str(pxx)+' risk ratio'
for pp in range(2,nperiods,1):
 print('period '+str(pp+1))
 res.tiMainString = str(pyear0[pp])+'-'+str(pyear1[pp]) 
 riskratio_cyc, lon_cyc = Ngl.add_cyclic(riskratio_ens_agree_masked[pp,:,:], lon)
 res.sfXArray           =  lon_cyc
 p = Ngl.contour_map(wks,riskratio_cyc,res)
 if pp==(nperiods-1):
  for rr in range(0,n_reg,1):
   poly_y = [df_reg['reg_N'][rr],df_reg['reg_S'][rr],df_reg['reg_S'][rr],df_reg['reg_N'][rr],df_reg['reg_N'][rr]]
   poly_x = [df_reg['reg_E'][rr],df_reg['reg_E'][rr],df_reg['reg_W'][rr],df_reg['reg_W'][rr],df_reg['reg_E'][rr]]
   poly_reg = Ngl.add_polygon(wks,p,poly_x,poly_y,gsres)
 plot.append(p)

Ngl.panel(wks,plot,[4,1],pres)
Ngl.text_ndc(wks,title,0.5,0.92,txres)
Ngl.frame(wks)

Ngl.delete_wks(wks)
Beispiel #5
0
def make_test(wrf_file=None, fixed_case=None):
    if wrf_file is not None:
        ncfile = NetCDF(wrf_file)
        lats, lons, proj_params = get_proj_params(ncfile)
        proj = getproj(lats=lats, lons=lons, **proj_params)
        name_suffix = basename(wrf_file)
    elif fixed_case is not None:
        name_suffix = fixed_case
        if fixed_case == "south_rot":
            lats, lons, proj = nz_proj()
        elif fixed_case == "arg_rot":
            lats, lons, proj = argentina_proj()
        elif fixed_case == "south_polar":
            lats, lons, proj = south_polar_proj()
        elif fixed_case == "north_polar":
            lats, lons, proj = north_polar_proj()
        elif fixed_case == "dateline_rot":
            lats, lons, proj = dateline_rot_proj()

    print("wrf proj4: {}".format(proj.proj4()))
    if PYNGL:
        # PyNGL plotting
        wks_type = bytes("png")
        wks = Ngl.open_wks(wks_type, bytes("pyngl_{}".format(name_suffix)))
        mpres = proj.pyngl()
        map = Ngl.map(wks, mpres)

        Ngl.delete_wks(wks)

    if BASEMAP:
        # Basemap plotting
        fig = plt.figure(figsize=(10, 10))
        ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])

        # Define and plot the meridians and parallels
        min_lat = np.amin(lats)
        max_lat = np.amax(lats)
        min_lon = np.amin(lons)
        max_lon = np.amax(lons)

        parallels = np.arange(np.floor(min_lat), np.ceil(max_lat),
                              (max_lat - min_lat) / 5.0)
        meridians = np.arange(np.floor(min_lon), np.ceil(max_lon),
                              (max_lon - min_lon) / 5.0)

        bm = proj.basemap()
        bm.drawcoastlines(linewidth=.5)
        #bm.drawparallels(parallels,labels=[1,1,1,1],fontsize=10)
        #bm.drawmeridians(meridians,labels=[1,1,1,1],fontsize=10)
        print("basemap proj4: {}".format(bm.proj4string))
        plt.savefig("basemap_{}.png".format(name_suffix))
        plt.close(fig)

    if CARTOPY:
        # Cartopy plotting
        fig = plt.figure(figsize=(10, 10))
        ax = plt.axes([0.1, 0.1, 0.8, 0.8], projection=proj.cartopy())
        print("cartopy proj4: {}".format(proj.cartopy().proj4_params))

        ax.coastlines('50m', linewidth=0.8)
        #print proj.x_extents()
        #print proj.y_extents()
        ax.set_xlim(proj.cartopy_xlim())
        ax.set_ylim(proj.cartopy_ylim())
        ax.gridlines()
        plt.savefig("cartopy_{}.png".format(name_suffix))
        plt.close(fig)
def create_meteogram_for(filepath, filename, timestamp):
    with open(filepath + filename) as f:
        head, input = read_file(f)

    # Create numpy 2D array
    cdf = numpy.array(input)

    # Collect meteorological data
    pressure = cdf[:, 9] / 100
    rain_cum = cdf[:, 16]
    rain_expl = cdf[:, 17]
    tempht = cdf[:, 5] - 273.15
    hum = cdf[:, 6]
    taus = cdf[:, 1]
    u = cdf[:, 7]
    v = cdf[:, 8]
    rain_sum = numpy.add(rain_cum, rain_expl)

    # set up a color map and open an output workstation.
    colors = numpy.array([                                                \
                             [255,255,255], [255,255,255], [255,255,255], \
                             [240,255,240], [220,255,220], [190,255,190], \
                             [120,255,120], [ 80,255, 80], [ 50,200, 50], \
                             [ 20,150, 20]                                \
                           ],'f') / 255.
    wks_type = "png"
    output_file = filepath + timestamp.strftime(
        "%m_%d_%H") + "_meteogram_" + filename.split(".")[0]
    wks = Ngl.open_wks(wks_type, output_file)

    # calculate secondary data
    count_xdata = taus[-1]
    main_hours, sec_hours, labels = generate_xlegend(timestamp, count_xdata)
    # dew points data and relative humidity
    rel_hum = humidity_lib.calculate_relative_humidity(hum, tempht, pressure,
                                                       len(taus))
    dew_point = temperature_lib.calculate_dewpoint(tempht, rel_hum, len(taus))

    # 3 hour rain sums
    rain3h_sum, rain3h_time = rain_lib.calculate_3hrain_data(rain_sum, taus)

    # wind speed
    wind_speed = wind_lib.calculate_windspeed(u, v, len(taus))

    # wind direction
    wind_direction = wind_lib.calculate_winddirection(u, v, len(taus))

    # generate measurand resources
    # pressure resource
    sealevel_pressure = pressure_lib.reduce_pressure_to_sealevel(
        pressure, cdf[:, 5], float(head[13]))
    pres_res = pressure_lib.get_pressure_resource(count_xdata,
                                                  sealevel_pressure)
    pres_res.tiMainString = format_title(head[0], timestamp)
    pres_res = config_xaxis_legend(pres_res, main_hours, sec_hours, labels)

    # relative humidity
    relhum_res = humidity_lib.get_relhumidity_resource(count_xdata)
    relhum_res = config_xaxis_legend(relhum_res, main_hours, sec_hours, labels)

    # wind speed recource
    wind_res = wind_lib.get_windspeed_resource(count_xdata, wind_speed)
    wind_res = config_xaxis_legend(wind_res, main_hours, sec_hours, labels)

    # wind direction recource
    direction_res = wind_lib.get_winddirection_resource(
        count_xdata, wind_speed)
    direction_res = config_xaxis_legend(direction_res, main_hours, sec_hours,
                                        labels)

    # rain sum resources
    rainsum_res = rain_lib.get_rainsum_resource(count_xdata)
    rainsum_res = config_xaxis_legend(rainsum_res, main_hours, sec_hours,
                                      labels)

    # 3 hour rain sum bar charts
    rain3h_res = rain_lib.get_3hrain_resource(rain3h_time)
    rainhist = create_rain_bar_plot(wks, rain3h_time, rain3h_sum, rain3h_res)

    # ground temperature resource
    tempsfc_res = temperature_lib.get_temperature_resource(
        count_xdata, tempht, dew_point)
    tempsfc_res = config_xaxis_legend(tempsfc_res, main_hours, sec_hours,
                                      labels)

    # generate plot results
    pressmsz = Ngl.xy(wks, taus, sealevel_pressure, pres_res)
    relhummsz = Ngl.xy(wks, taus, rel_hum, relhum_res)
    windmsz = Ngl.xy(wks, taus, wind_speed, wind_res)
    dirmsz = Ngl.xy(wks, taus, wind_direction, direction_res)
    rainsum = Ngl.xy(wks, taus, rain_sum, rainsum_res)
    temptmsz = Ngl.xy(wks, taus, tempht, tempsfc_res)
    tempsfc_res.xyLineColor = "blue"  # line color for dew point
    dewpmsz = Ngl.xy(wks, taus, dew_point, tempsfc_res)

    Ngl.draw(pressmsz)
    Ngl.draw(relhummsz)
    Ngl.overlay(rainsum, rainhist)
    Ngl.draw(rainsum)
    Ngl.draw(windmsz)
    Ngl.draw(dirmsz)
    Ngl.overlay(temptmsz, dewpmsz)
    Ngl.draw(temptmsz)
    Ngl.frame(wks)
    Ngl.delete_wks(wks)  # delete currently used workstation
Beispiel #7
0
def ens_spread_map(var1var2):

    recoverpath = dict(base = '/',
                       temp = 'data/additional_data/temp/{}/'.format(ex_op_str))

    # load all dictionaries and strings from json file #

    json_filename = 'ensemble_spread_maps_{}_dicts_strings.json'.format(var1var2)
    with open(recoverpath['base'] + recoverpath['temp'] + json_filename, 'r') as f:
        path, domain, variable1, variable2, model, run, hour = json.load(f)


    # load numpy arrays #

    numpyarrays_filename = 'ensemble_spread_maps_{}_ndarrays_outofloop.npz'.format(var1var2)
    with open(path['base'] + path['temp'] + numpyarrays_filename, 'rb') as f:
        with np.load(f) as loadedfile:
            clat = loadedfile['clat']
            clon = loadedfile['clon']
            vlat = loadedfile['vlat']
            vlon = loadedfile['vlon']
            ll_lat = loadedfile['ll_lat']
            ll_lon = loadedfile['ll_lon']

    numpyarrays_filename = 'ensemble_spread_maps_{}_ndarrays_withinloop.npz'.format(var1var2)
    with open(recoverpath['base'] + recoverpath['temp'] + numpyarrays_filename, 'rb') as f:
        with np.load(f) as loadedfile:
            data_array1 = loadedfile['data_array1']
            data_array2 = loadedfile['data_array2']

    #print('loaded all vars')


    # example plot_name: icon-eu-eps_2020070512_mslp_mean_spread_europe_000h
    plot_name = '{}_{:4d}{:02d}{:02d}{:02d}_{}_{}_{:03d}h'.format(
                 model, run['year'], run['month'], run['day'], run['hour'],
                 var1var2, domain['name'], hour)


    # plot basic map with borders #

    wks_res          = Ngl.Resources()
    wks_res.wkWidth  = domain['plot_width']
    wks_res.wkHeight = domain['plot_width']     # the whitespace above and below the plot will be cut afterwards

    filename_colorpalette = 'colormap_WhiteBeigeGreenBlue_12.txt'
    with open(path['base'] + path['colorpalette'] + filename_colorpalette, 'r') as f:
        lines = f.readlines()
    rgb_colors = []
    rgb_colors.append([1, 1, 1])
    rgb_colors.append([0, 0, 0])
    rgb_colors.append([.5, .5, .5])
    for line in lines:
        rgb_colors.append([float(line[0:3])/255, float(line[4:7])/255, float(line[8:11])/255])
    rgb_colors.append(rgb_colors[-1])
    wks_res.wkColorMap = np.array(rgb_colors)

    if variable1['name'] == 'gph_500hPa' :
        levels1 = np.arange(0, 12.1, 1)
    elif variable1['name'] == 'mslp' :
        levels1 = np.arange(0, 12.1, 1)
    elif variable1['name'] == 't_850hPa' :
        levels1 = np.arange(0, 6.1, 0.5)


    wks_type = 'png'
    wks = Ngl.open_wks(wks_type, path['base'] + path['plots'] + plot_name, wks_res)

    mpres   = Ngl.Resources()
    mpres.mpProjection = domain['projection']

    if domain['limits_type'] == 'radius':
        mpres.mpLimitMode  = 'LatLon'
        mpres.mpCenterLonF = domain['centerlon']
        mpres.mpCenterLatF = domain['centerlat']
        cutout_plot = dict(
                            lat_min = float(np.where(domain['centerlat'] - domain['radius'] / 111.2 < -90,
                                               -90, domain['centerlat'] - domain['radius'] / 111.2)),
                            lat_max = float(np.where(domain['centerlat'] + domain['radius'] / 111.2 > 90,
                                               90, domain['centerlat'] + domain['radius'] / 111.2)),
                           )
        cutout_plot['lon_min'] = float(np.where(cutout_plot['lat_min'] <= -90 or cutout_plot['lat_max'] >= 90,
                                       0,
                                       domain['centerlon'] - domain['radius'] \
                                        / (111.2 * np.cos(domain['centerlat']*np.pi/180))))
        cutout_plot['lon_max'] = float(np.where(cutout_plot['lat_min'] <= -90 or cutout_plot['lat_max'] >= 90,
                                       360,
                                       domain['centerlon'] + domain['radius'] \
                                        / (111.2 * np.cos(domain['centerlat']*np.pi/180))))
        mpres.mpMinLonF     = cutout_plot['lon_min']
        mpres.mpMaxLonF     = cutout_plot['lon_max']
        mpres.mpMinLatF     = cutout_plot['lat_min']
        mpres.mpMaxLatF     = cutout_plot['lat_max']

    elif domain['limits_type'] == 'deltalatlon':
        mpres.mpLimitMode  = 'LatLon'
        mpres.mpCenterLonF = 0
        mpres.mpCenterLatF = 0
        mpres.mpMinLonF    = domain['centerlon'] - domain['deltalon_deg']
        mpres.mpMaxLonF    = domain['centerlon'] + domain['deltalon_deg']
        mpres.mpMinLatF    = domain['centerlat'] - domain['deltalat_deg']
        mpres.mpMaxLatF    = domain['centerlat'] + domain['deltalat_deg']

    elif domain['limits_type'] == 'angle':
        mpres.mpLimitMode    = 'Angles'
        mpres.mpCenterLonF   = domain['centerlon']
        mpres.mpCenterLatF   = domain['centerlat']
        mpres.mpLeftAngleF   = domain['angle']
        mpres.mpRightAngleF  = domain['angle']
        mpres.mpTopAngleF    = domain['angle']
        mpres.mpBottomAngleF = domain['angle']

    mpres.nglMaximize   = False
    mpres.vpXF          = 0.001
    mpres.vpYF          = 1.00
    mpres.vpWidthF      = 0.88
    mpres.vpHeightF     = 1.00
    mpres.mpMonoFillColor = 'True'
    mpres.mpFillColor = -1
    mpres.mpFillOn = True
    mpres.mpGridAndLimbOn = False
    mpres.mpGreatCircleLinesOn = False

    mpres.mpDataBaseVersion         = 'MediumRes'
    mpres.mpDataSetName             = 'Earth..4'
    mpres.mpOutlineBoundarySets     = 'national'
    mpres.mpGeophysicalLineColor        = 'black'
    mpres.mpNationalLineColor           = 'black'
    mpres.mpGeophysicalLineThicknessF   = 1.0 * domain['plot_width'] / 1000
    mpres.mpNationalLineThicknessF      = 1.0 * domain['plot_width'] / 1000

    mpres.mpPerimOn                     = True
    mpres.mpPerimLineColor              = 'black'
    mpres.mpPerimLineThicknessF         = 6.0 * domain['plot_width'] / 1000
    mpres.tmXBOn = False
    mpres.tmXTOn = False
    mpres.tmYLOn = False
    mpres.tmYROn = False

    mpres.nglDraw        =  False              # don't draw plot
    mpres.nglFrame       =  False              # don't advance frame


    # settings for variable1 / shading #

    v1res = Ngl.Resources()
    v1res.sfDataArray       = data_array1
    v1res.sfXArray          = clon             
    v1res.sfYArray          = clat
    v1res.sfXCellBounds     = vlon
    v1res.sfYCellBounds     = vlat
    v1res.sfMissingValueV   = 9999
    v1res.cnMissingValFillColor = 'Gray80'

    v1res.cnLinesOn         = False   # Turn off contour lines.
    v1res.cnFillOn          = True
    v1res.cnFillMode        = 'CellFill'
    #v1res.cnFillOpacityF    = 0.5   
    #v1res.cnFillDrawOrder   = 'Predraw'
    v1res.cnLevelSelectionMode = 'ExplicitLevels' 
    v1res.cnLevels          = levels1


    # set resources for a nice label bar #

    v1res.lbLabelBarOn          = True
    v1res.lbAutoManage          = False
    v1res.lbOrientation         = 'vertical'
    v1res.lbLabelOffsetF        = 0.04      # minor axis fraction: the distance between colorbar and numbers
    v1res.lbBoxMinorExtentF     = 0.20      # minor axis fraction: width of the color boxes when labelbar down
    v1res.lbTopMarginF          = 0.14      # make a little more space at top for the unit label
    v1res.lbRightMarginF        = 0.0
    v1res.lbBottomMarginF       = 0.0
    v1res.lbLeftMarginF         = -0.35

    v1res.cnLabelBarEndStyle    = 'ExcludeOuterBoxes'
    #if variable1['name'] == 'prec_rate' :
    #    v1res.cnLabelBarEndStyle    = 'IncludeOuterBoxes'
    #v1res.cnExplicitLabelBarLabelsOn = True
    #v1res.pmLabelBarDisplayMode =  'Always'
    v1res.pmLabelBarWidthF      = 0.10
    #v1res.lbLabelStrings        = label_str_list
    v1res.lbLabelFontHeightF    = 0.010
    #v1res.lbBoxCount            = 40
    v1res.lbBoxSeparatorLinesOn = False
    v1res.lbBoxLineThicknessF   = 4
    #v1res.lbBoxEndCapStyle     = 'TriangleBothEnds'
    v1res.lbLabelAlignment      = 'ExternalEdges'
    if variable2['name'] == 'mslp':
        v1res.lbLabelStride = 1
    elif variable2['name'] == 'gph_500hPa':
        v1res.lbLabelStride = 1
    elif variable2['name'] == 't_850hPa':
        v1res.lbLabelStride = 2

    v1res.nglFrame = False
    v1res.nglDraw  = False


    # settings for variable2 / thin contourlines #

    v2res = Ngl.Resources()
    v2res.sfDataArray       = data_array2
    v2res.sfXArray          = ll_lon
    v2res.sfYArray          = ll_lat
    v2res.sfMissingValueV   = 9999  
    #v2res.trGridType        = 'TriangularMesh'
    v2res.cnFillOn       = False
    v2res.cnLinesOn      = True
    v2res.cnLineLabelsOn = True
    v2res.cnLineLabelInterval = 1
    v2res.cnLineLabelPlacementMode = 'Constant'
    v2res.cnLineDashSegLenF = 0.25
    v2res.cnLabelDrawOrder = 'PostDraw' # necessary to make everything visible
    v2res.cnLineThicknessF = 3.0 * domain['plot_width'] / 1000
    v2res.cnInfoLabelOn = False
 
    v2res.cnSmoothingOn = False
    v2res.cnSmoothingDistanceF = 0.01
    v2res.cnSmoothingTensionF = 0.1            
    if variable2['name'] == 'mslp':
        v2res.cnLevelSpacingF = 2
        v2res.cnLineLabelFontHeightF = 0.008
        v2res.cnLineDashSegLenF = 0.18
        v2res.cnLineLabelInterval = 2
    elif variable2['name'] == 'gph_500hPa':
        v2res.cnLevelSpacingF = 4
        v2res.cnLineLabelFontHeightF = 0.008
    elif variable2['name'] == 't_850hPa':
        v2res.cnLevelSpacingF = 2
        v2res.cnLineLabelFontHeightF = 0.009
        v2res.cnLineDashSegLenF = 0.18

    v2res.cnLevelSelectionMode = 'ManualLevels' 
    #v2res.cnLevels = levels2
    #v2res.cnRasterSmoothingOn = True

    v2res.nglFrame = False
    v2res.nglDraw  = False


    # settings for variable2 / thick contourlines #

    v3res = Ngl.Resources()
    v3res.sfDataArray       = data_array2
    v3res.sfXArray          = ll_lon
    v3res.sfYArray          = ll_lat
    v3res.sfMissingValueV   = 9999  
    #v3res.trGridType        = 'TriangularMesh'
    v3res.cnFillOn       = False
    v3res.cnLinesOn      = True
    v3res.cnLineLabelsOn = True
    v3res.cnLineLabelInterval = 1
    v3res.cnLineLabelPlacementMode = 'Constant'
    v3res.cnLineDashSegLenF = 0.25
    v3res.cnLabelDrawOrder = 'PostDraw' # necessary to make everything visible
    v3res.cnLineThicknessF = 5.0 * domain['plot_width'] / 1000
    v3res.cnLineLabelFontHeightF = 0.010
    v3res.cnInfoLabelOn = False
 
    v3res.cnSmoothingOn = False
    #v3res.cnSmoothingDistanceF = 0.01
    #v3res.cnSmoothingTensionF = 0.1            
    v3res.cnLevelSelectionMode = 'ManualLevels' 
    #v3res.cnLevels = levels2
    #v3res.cnRasterSmoothingOn = True

    if variable2['name'] == 'mslp':
        v3res.cnLevelSpacingF = 10
        v3res.cnLineLabelFontHeightF = 0.008
        v3res.cnLineDashSegLenF = 0.18
        v3res.cnLineLabelInterval = 2
    elif variable2['name'] == 'gph_500hPa':
        v3res.cnLevelSpacingF = 16
        v3res.cnLineLabelFontHeightF = 0.008
        v3res.cnLevelSelectionMode = 'ExplicitLevels' 
        v3res.cnLevels = np.arange(520, 600, 16)
    elif variable2['name'] == 't_850hPa':
        v3res.cnLevelSpacingF = 6
        v3res.cnLineLabelFontHeightF = 0.009
        v3res.cnLineDashSegLenF = 0.18

    v3res.nglFrame = False
    v3res.nglDraw  = False


    # settings for unit text #

    text_str = variable1['unit']
    text_res_1 = Ngl.Resources()
    text_res_1.txFontColor      = 'black'
    text_res_1.txFontHeightF = 0.013
    #text_x = 0.965
    text_x = 0.972
    text_y = 0.837 #0.865


    # put everything together # 

    basic_map = Ngl.map(wks, mpres)
    v1plot = Ngl.contour(wks, data_array1, v1res)
    v2plot = Ngl.contour(wks, data_array2, v2res)
    v3plot = Ngl.contour(wks, data_array2, v3res)
    Ngl.overlay(basic_map, v1plot)
    Ngl.overlay(basic_map, v2plot)
    Ngl.overlay(basic_map, v3plot)

    Ngl.draw(basic_map)
    Ngl.text_ndc(wks, text_str, text_x, text_y, text_res_1)
    Ngl.frame(wks)
    Ngl.delete_wks(wks)


    # cut top and bottom whitespace of plot #

    im = Image.open(path['base'] + path['plots'] + plot_name + '.png')
    image_array = np.asarray(im.convert('L'))
    image_array = np.where(image_array < 255, 1, 0)
    image_filter = np.amax(image_array, axis=1)
    vmargins = [np.nonzero(image_filter)[0][0], np.nonzero(image_filter[::-1])[0][0]]
    #print(vmargins)
    #print(im.size)

    im_cropped = Image.new('RGB',(im.size[0], im.size[1] - vmargins[0] - vmargins[1]), (255,255,255))
    im_cropped.paste(im.crop((0, vmargins[0], im.size[0], im.size[1] - vmargins[1])), (0, 0))
    #print(im_cropped.size)
    im.close()
    im_cropped.save(path['base'] + path['plots'] + plot_name + '.png', 'png')
    im_cropped.close()

    return
Beispiel #8
0
def double_contourplot(var1var2, model):

    recoverpath = dict(base='/',
                       temp='data/additional_data/temp/{}/'.format(ex_op_str))

    # load all dictionaries and strings from json file #

    json_filename = 'deterministic_overview_maps_{}_{}_dicts_strings.json'.format(
        model, var1var2)
    with open(recoverpath['base'] + recoverpath['temp'] + json_filename,
              'r') as f:
        path, domain, variable1, variable2, run, hour = json.load(f)

    # load numpy arrays #

    if variable1['load_global_field']:
        numpyarrays_filename = 'deterministic_overview_maps_{}_{}_ndarrays_outofloop.npz'.format(
            model, var1var2)

        if model == 'icon-eu-det':
            with open(path['base'] + path['temp'] + numpyarrays_filename,
                      'rb') as f:
                with np.load(f) as loadedfile:
                    clat = loadedfile['clat']
                    clon = loadedfile['clon']

        elif model == 'icon-global-det':
            if not variable1['load_global_field']:
                with open(path['base'] + path['temp'] + numpyarrays_filename,
                          'rb') as f:
                    with np.load(f) as loadedfile:
                        ll_lat = loadedfile['ll_lat']
                        ll_lon = loadedfile['ll_lon']
            elif variable2['name'] == '':
                with open(path['base'] + path['temp'] + numpyarrays_filename,
                          'rb') as f:
                    with np.load(f) as loadedfile:
                        clat = loadedfile['clat']
                        clon = loadedfile['clon']
                        vlat = loadedfile['vlat']
                        vlon = loadedfile['vlon']
            else:
                with open(path['base'] + path['temp'] + numpyarrays_filename,
                          'rb') as f:
                    with np.load(f) as loadedfile:
                        clat = loadedfile['clat']
                        clon = loadedfile['clon']
                        vlat = loadedfile['vlat']
                        vlon = loadedfile['vlon']
                        ll_lat = loadedfile['ll_lat']
                        ll_lon = loadedfile['ll_lon']

        numpyarrays_filename = 'deterministic_overview_maps_{}_{}_ndarrays_withinloop.npz'.format(
            model, var1var2)
        with open(
                recoverpath['base'] + recoverpath['temp'] +
                numpyarrays_filename, 'rb') as f:
            with np.load(f) as loadedfile:
                data_array1 = loadedfile['data_array1']
                if variable2['name'] != '':
                    data_array2 = loadedfile['data_array2']

        #print('loaded all vars')

        if domain['limits_type'] == 'radius':
            margin_deg = 20
        elif domain['limits_type'] == 'deltalatlon' or domain[
                'limits_type'] == 'angle':
            margin_deg = 20

        if model == 'icon-eu-det':
            data_array1_cut, clat_cut, clon_cut, vlat_cut, vlon_cut = data_array1, clat, clon, None, None
        elif model == 'icon-global-det':
            data_array_dims = '2d'
            [data_array1_cut], clat_cut, clon_cut, vlat_cut, vlon_cut = \
              cut_by_domain(domain, variable1['grid'], data_array_dims,
                            [data_array1], clat, clon, vlat, vlon, margin_deg)
            if variable2['name'] != '':
                [data_array2_cut], ll_lat_cut, ll_lon_cut = \
                  cut_by_domain(domain, variable2['grid'], data_array_dims,
                                [data_array2], ll_lat, ll_lon, None, None, margin_deg)
                #data_array2_cut, ll_lat_cut, ll_lon_cut = data_array2, ll_lat, ll_lon
    else:
        # if load_global_field == False
        if variable1['name'][:2] == 'pv'\
         and variable1['name'][-1:] == 'K':
            iso_theta_value = float(variable1['name'][3:6])
            data_array1_cut, clat_cut, clon_cut \
             = calc_pv_on_theta(model, domain, variable1['grid'], run, hour, iso_theta_value)
        elif variable1['name'][:5] == 'theta'\
         and variable1['name'][-3:] == 'PVU':
            iso_pv_value = float(variable1['name'][6:9])
            data_array1_cut, clat_cut, clon_cut \
             = calc_theta_on_pv(model, domain, variable1['grid'], run, hour, iso_pv_value)

    # example plot_name: icon-global-det_2020070512_prec_rate_mslp_europe_000h.png
    plot_name = '{}_{:4d}{:02d}{:02d}{:02d}_{}_{}_{:03d}h'.format(
        model, run['year'], run['month'], run['day'], run['hour'], var1var2,
        domain['name'], hour)

    # plot basic map with borders #

    if variable1['name'] == 'prec_rate'\
     or variable1['name'] == 'prec_6h':
        filename_colorpalette = 'colorscale_prec_rate.txt'
        with open(path['base'] + path['colorpalette'] + filename_colorpalette,
                  'r') as f:
            lines = f.readlines()
        rgb_colors = []
        rgb_colors.append([0, 0, 0,
                           0])  # color for under the lowest value, transparent
        for i, line in enumerate(lines):
            rgb_colors.append([
                float(line[0:3]) / 255,
                float(line[4:7]) / 255,
                float(line[8:11]) / 255, 1
            ])
        rgb_colors.append(
            rgb_colors[-1]
        )  # add highest loaded color to color for over the highest value
        levels1 = ([0.1, 0.2, 0.3, 0.5, 1, 2, 3, 5, 10, 20, 30, 50])
        lbStride_value = 1

    elif variable1['name'] == 't_850hPa':
        rgb_colors = []
        rgb_colors.append(
            [0, 0, 0])  # placeholder for color for under the lowest value
        for i in range(10):
            rgb_colors.append(
                list(
                    cmasher.take_cmap_colors('cmr.flamingo',
                                             10,
                                             cmap_range=(0.45, 0.88))[i]))
        for i in range(2, 12):
            rgb_colors.append(
                list(
                    palettable.colorbrewer.sequential.Purples_9.
                    get_mpl_colormap(N=14)(i)[:3]))
        rgb_colors.append(list(np.array([60, 53, 139]) / 255))
        rgb_colors.append(list(np.array([65, 69, 171]) / 255))
        rgb_colors.append(list(np.array([68, 86, 199]) / 255))
        for i in range(2, 19):
            rgb_colors.append(
                list(
                    palettable.colorbrewer.diverging.Spectral_10.
                    get_mpl_colormap(N=19).reversed()(i)[:3]))
        for i in range(1, 11):
            rgb_colors.append(
                list(
                    palettable.cartocolors.sequential.Burg_7.get_mpl_colormap(
                        N=11).reversed()(i)[:3]))
        rgb_colors[0] = rgb_colors[
            1]  # copy lowest loaded color to color for under the lowest value
        rgb_colors.append(
            rgb_colors[-1]
        )  # add highest loaded color to color for over the highest value
        rgb_colors[31] = list(np.array([255, 255, 160]) / 255)
        rgb_colors[32] = list(np.array([247, 230, 128]) / 255)
        levels1 = np.arange(-25, 25 + 1, 1)
        lbStride_value = 5

    elif variable1['name'] == 'theta_e_850hPa':
        rgb_colors = []
        rgb_colors.append(
            [0, 0, 0])  # placeholder for color for under the lowest value
        for i in range(5):
            rgb_colors.append(
                list(
                    cmasher.take_cmap_colors('cmr.flamingo',
                                             5,
                                             cmap_range=(0.65, 0.93))[i]))
        for i in range(4, 13):
            rgb_colors.append(
                list(
                    palettable.colorbrewer.sequential.Purples_9.
                    get_mpl_colormap(N=16)(i)[:3]))
        for i in range(26):
            rgb_colors.append(
                list(
                    palettable.colorbrewer.diverging.Spectral_10.
                    get_mpl_colormap(N=26).reversed()(i)[:3]))
        for i in range(1, 11):
            rgb_colors.append(
                list(
                    palettable.cartocolors.sequential.Burg_7.get_mpl_colormap(
                        N=11).reversed()(i)[:3]))
        for i in range(2, 2 + 5):
            rgb_colors.append(
                list(
                    palettable.scientific.sequential.Turku_10.get_mpl_colormap(
                        N=12).reversed()(i)[:3]))
        rgb_colors[0] = rgb_colors[
            1]  # copy lowest loaded color to color for under the lowest value
        rgb_colors.append(
            rgb_colors[-1]
        )  # add highest loaded color to color for over the highest value
        rgb_colors[27] = list(np.array([255, 255, 160]) / 255)
        rgb_colors[28] = list(np.array([247, 237, 128]) / 255)
        levels1 = np.arange(-20, 90 + 1, 2)
        lbStride_value = 5

    elif variable1['name'] == 'wind_300hPa':
        rgb_colors = []
        rgb_colors.append([0, 0, 0,
                           0])  # color for under the lowest value, transparent
        for i in range(1, 8):
            rgb_colors.append(
                list(
                    palettable.cmocean.sequential.Ice_10.get_mpl_colormap(
                        N=10).reversed()(i)[:3]) + [1])
        rgb_colors.append(
            rgb_colors[-1]
        )  # add highest loaded color to color for over the highest value
        levels1 = (list(range(120, 330 + 1, 30)))
        lbStride_value = 1

    elif variable1['name'] == 'cape_ml':
        rgb_colors = []
        rgb_colors.append([0, 0, 0,
                           0])  # color for under the lowest value, transparent
        for i in range(2, 7):
            rgb_colors.append(
                list(
                    palettable.scientific.sequential.Tokyo_7.get_mpl_colormap(
                        N=7)(i)[:3]) + [1])
        for i in range(1, 17, 3):
            rgb_colors.append(
                list(
                    palettable.cmocean.sequential.Thermal_20.get_mpl_colormap(
                        N=22).reversed()(i)[:3]) + [1])
        for i in range(9, 18, 4):
            rgb_colors.append(
                list(
                    palettable.cmocean.sequential.Ice_20.get_mpl_colormap(
                        N=20)(i)[:3]) + [1])
        rgb_colors.append(
            rgb_colors[-1]
        )  # add highest loaded color to color for over the highest value
        rgb_colors[1] = list(np.array([138, 98, 110]) / 255) + [1]
        rgb_colors[10] = list(np.array([142, 69, 139]) / 255) + [1]
        #levels1 = ([0,100,200,350,530,750,1000,1300,1630,2000,2400,2850,3330,3850,4400,5000])  # follows (wmax)**2
        levels1 = ([
            100, 200, 350, 500, 750, 1000, 1300, 1600, 2000, 2400, 2800, 3300,
            3800, 4400, 5000
        ])  # rounded to be pretty
        lbStride_value = 1

        #rgb_arr = np.array(rgb_colors)
        #np.savetxt("colorpalette_marco_cape_ml.txt", np.around(rgb_arr[3:-1]*255,0), fmt='%2d', delimiter = ",")

    elif variable1['name'] == 'synth_bt_ir10.8':
        filename_colorpalette = 'rainbowIRsummer.txt'
        with open(path['base'] + path['colorpalette'] + filename_colorpalette,
                  'r') as f:
            lines = f.readlines()
        rgb_colors = []
        rgb_colors.append(list(np.array([118, 39, 118]) / 255))
        for i, line in enumerate(lines):
            if i % 14 == 0 and i > 70:
                rgb_colors.append(
                    [float(line[:10]),
                     float(line[11:21]),
                     float(line[22:32])])
        rgb_colors.append(list(np.array([35, 244, 255]) / 255))
        num_bw_colors = 30
        for i in range(num_bw_colors + 1):
            rgb_colors.append([
                1 - i / num_bw_colors, 1 - i / num_bw_colors,
                1 - i / num_bw_colors
            ])
        rgb_colors.append(
            rgb_colors[-1]
        )  # add highest loaded color to color for over the highest value
        levels1 = (list(range(-90, -20, 1)) + list(range(-20, 40 + 1, 2)))
        lbStride_value = 10

    elif variable1['name'] == 'prec_24h'\
     or variable1['name'] == 'prec_sum':
        filename_colorpalette = 'colorscale_prec24h.txt'
        with open(path['base'] + path['colorpalette'] + filename_colorpalette,
                  'r') as f:
            lines = f.readlines()
        rgb_colors = []
        rgb_colors.append([0, 0, 0,
                           0])  # color for under the lowest value, transparent
        for i, line in enumerate(lines):
            rgb_colors.append([
                float(line[0:3]) / 255,
                float(line[4:7]) / 255,
                float(line[8:11]) / 255, 1
            ])
        rgb_colors.append(
            rgb_colors[-1]
        )  # add highest loaded color to color for over the highest value

        levels1 = ([
            1, 10, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 250, 300, 400
        ])
        lbStride_value = 1

    elif variable1['name'] == 'vmax_10m':
        filename_colorpalette = 'colorscale_vmax.txt'
        with open(path['base'] + path['colorpalette'] + filename_colorpalette,
                  'r') as f:
            lines = f.readlines()
        rgb_colors = []
        rgb_colors.append(
            [0, 0, 0])  # placeholder for color for under the lowest value
        for i in range(0, 11):  # load colors from palettable
            rgb_colors.append(
                list(
                    cmasher.take_cmap_colors('cmr.chroma',
                                             11,
                                             cmap_range=(0.20,
                                                         0.95))[::-1][i]))
        for i in range(0, 3):  # load colors from palettable
            rgb_colors.append(
                list(
                    cmasher.take_cmap_colors('cmr.freeze',
                                             3,
                                             cmap_range=(0.40, 0.90))[i]))
        for i in range(0, 2):  # load colors from palettable
            rgb_colors.append(
                list(
                    cmasher.take_cmap_colors('cmr.flamingo',
                                             2,
                                             cmap_range=(0.55,
                                                         0.80))[::-1][i]))
        rgb_colors[0] = rgb_colors[
            1]  # copy lowest loaded color to color for under the lowest value
        rgb_colors.append(
            rgb_colors[-1]
        )  # add highest loaded color to color for over the highest value
        levels1 = ([
            0, 6, 12, 20, 29, 39, 50, 62, 75, 89, 103, 118, 154, 178, 209, 251,
            300
        ])
        lbStride_value = 1

    elif variable1['name'] == 'shear_200-850hPa':
        filename_colorpalette = 'colorscale_shear_200-850hPa.txt'
        with open(path['base'] + path['colorpalette'] + filename_colorpalette,
                  'r') as f:
            lines = f.readlines()
        rgb_colors = []
        rgb_colors.append([1, 1, 1])
        for i, line in enumerate(lines):
            rgb_colors.append([
                float(line[0:3]) / 255,
                float(line[4:7]) / 255,
                float(line[8:11]) / 255
            ])
        rgb_colors.append([0, 0, 1])
        levels1 = (list(np.arange(0, 30, 2.5)) + list(range(30, 50 + 1, 5)) +
                   [99])
        lbStride_value = 1

    elif variable1['name'][:2] == 'pv'\
     and variable1['name'][-1:] == 'K':
        filename_colorpalette = 'colorscale_ipv_eth.txt'
        with open(path['base'] + path['colorpalette'] + filename_colorpalette,
                  'r') as f:
            lines = f.readlines()
        rgb_colors = []
        rgb_colors.append(
            [0, 0, 0])  # placeholder for color for under the lowest value
        for i, line in enumerate(lines):
            rgb_colors.append([
                float(line[0:3]) / 255,
                float(line[4:7]) / 255,
                float(line[8:11]) / 255
            ])
        rgb_colors[0] = rgb_colors[
            1]  # copy lowest loaded color to color for under the lowest value
        rgb_colors.append(
            rgb_colors[-1]
        )  # add highest loaded color to color for over the highest value
        levels1 = ([-1, -0.5, 0.2, 0.7, 1, 1.5, 2, 3, 4, 5, 6, 7, 8, 9, 10])
        lbStride_value = 1

    elif variable1['name'][:5] == 'theta'\
     and variable1['name'][-3:] == 'PVU':
        rgb_colors = []
        rgb_colors.append(
            [0, 0, 0])  # placeholder for color for under the lowest value
        for i in range(30):
            rgb_colors.append(
                list(
                    palettable.colorbrewer.diverging.RdYlBu_10.
                    get_mpl_colormap(N=30)(i)[:3]))
        rgb_colors[0] = rgb_colors[
            1]  # copy lowest loaded color to color for under the lowest value
        rgb_colors.append(
            rgb_colors[-1]
        )  # add highest loaded color to color for over the highest value
        levels1 = np.arange(270, 420 + 1, 5)
        #levels1 = np.arange(300, 360+1, 20)
        lbStride_value = 2

    mpres = Ngl.Resources()
    mpres.mpProjection = domain['projection']

    if domain['limits_type'] == 'radius':
        mpres.mpLimitMode = 'LatLon'
        mpres.mpCenterLonF = domain['centerlon']
        mpres.mpCenterLatF = domain['centerlat']
        cutout_plot = dict(
            lat_min=float(
                np.where(domain['centerlat'] - domain['radius'] / 111.2 < -90,
                         -90, domain['centerlat'] - domain['radius'] / 111.2)),
            lat_max=float(
                np.where(domain['centerlat'] + domain['radius'] / 111.2 > 90,
                         90, domain['centerlat'] + domain['radius'] / 111.2)),
        )
        cutout_plot['lon_min'] = float(np.where(cutout_plot['lat_min'] <= -90 or cutout_plot['lat_max'] >= 90,
                                       0,
                                       domain['centerlon'] - domain['radius'] \
                                        / (111.2 * np.cos(domain['centerlat']*np.pi/180))))
        cutout_plot['lon_max'] = float(np.where(cutout_plot['lat_min'] <= -90 or cutout_plot['lat_max'] >= 90,
                                       360,
                                       domain['centerlon'] + domain['radius'] \
                                        / (111.2 * np.cos(domain['centerlat']*np.pi/180))))
        mpres.mpMinLonF = cutout_plot['lon_min']
        mpres.mpMaxLonF = cutout_plot['lon_max']
        mpres.mpMinLatF = cutout_plot['lat_min']
        mpres.mpMaxLatF = cutout_plot['lat_max']

    elif domain['limits_type'] == 'deltalatlon':
        mpres.mpLimitMode = 'LatLon'
        mpres.mpCenterLonF = 0
        mpres.mpCenterLatF = 0
        mpres.mpMinLonF = domain['centerlon'] - domain['deltalon_deg']
        mpres.mpMaxLonF = domain['centerlon'] + domain['deltalon_deg']
        mpres.mpMinLatF = domain['centerlat'] - domain['deltalat_deg']
        mpres.mpMaxLatF = domain['centerlat'] + domain['deltalat_deg']

    elif domain['limits_type'] == 'angle':
        mpres.mpLimitMode = 'Angles'
        mpres.mpCenterLonF = domain['centerlon']
        mpres.mpCenterLatF = domain['centerlat']
        mpres.mpLeftAngleF = domain['angle']
        mpres.mpRightAngleF = domain['angle']
        mpres.mpTopAngleF = domain['angle']
        mpres.mpBottomAngleF = domain['angle']

    mpres.nglMaximize = False
    mpres.vpXF = 0.001
    mpres.vpYF = 1.00
    mpres.vpWidthF = 0.88
    mpres.vpHeightF = 1.00

    mpres.mpLandFillColor = list(np.array([255, 225, 171]) / 255)
    mpres.mpOceanFillColor = [1, 1, 1]
    mpres.mpInlandWaterFillColor = [1, 1, 1]

    mpres.mpFillOn = True
    mpres.mpGridAndLimbOn = False
    mpres.mpGreatCircleLinesOn = False

    mpres.mpDataBaseVersion = 'MediumRes'
    mpres.mpDataSetName = 'Earth..4'
    mpres.mpOutlineBoundarySets = 'national'
    mpres.mpGeophysicalLineColor = 'black'
    mpres.mpNationalLineColor = 'black'
    mpres.mpGeophysicalLineThicknessF = 1.5 * domain['plot_width'] / 1000
    mpres.mpNationalLineThicknessF = 1.5 * domain['plot_width'] / 1000

    mpres.mpPerimOn = True
    mpres.mpPerimLineColor = 'black'
    mpres.mpPerimLineThicknessF = 8.0 * domain['plot_width'] / 1000
    mpres.tmXBOn = False
    mpres.tmXTOn = False
    mpres.tmYLOn = False
    mpres.tmYROn = False

    mpres.nglDraw = False  #-- don't draw plot
    mpres.nglFrame = False  #-- don't advance frame

    # settings for variable1 / shading #

    v1res = Ngl.Resources()
    v1res.nglFrame = False
    v1res.nglDraw = False
    v1res.sfDataArray = data_array1_cut
    v1res.sfXArray = clon_cut
    v1res.sfYArray = clat_cut
    v1res.sfMissingValueV = 9999
    #v1res.cnFillBackgroundColor = 'transparent'
    v1res.cnMissingValFillColor = 'Gray80'
    v1res.cnFillColors = np.array(rgb_colors)

    v1res.cnLinesOn = False
    v1res.cnFillOn = True
    v1res.cnLineLabelsOn = False
    if not variable1['load_global_field']:
        v1res.cnFillMode = 'RasterFill'
    elif model == 'icon-eu-det':
        v1res.cnFillMode = 'RasterFill'
    elif model == 'icon-global-det':
        v1res.cnFillMode = 'CellFill'
        v1res.sfXCellBounds = vlon_cut
        v1res.sfYCellBounds = vlat_cut
    #v1res.cnFillOpacityF        = 0.5
    #v1res.cnFillDrawOrder       = 'Predraw'
    v1res.cnLevelSelectionMode = 'ExplicitLevels'
    v1res.cnLevels = levels1

    v1res.lbLabelBarOn = True
    v1res.lbAutoManage = False
    v1res.lbOrientation = 'vertical'
    v1res.lbLabelOffsetF = 0.04  # minor axis fraction: the distance between colorbar and numbers
    v1res.lbBoxMinorExtentF = 0.20  # minor axis fraction: width of the color boxes when labelbar down
    v1res.lbTopMarginF = 0.2  # make a little more space at top for the unit label
    v1res.lbRightMarginF = 0.0
    v1res.lbBottomMarginF = 0.05
    v1res.lbLeftMarginF = -0.35

    v1res.cnLabelBarEndStyle = 'ExcludeOuterBoxes'
    #if variable1['name'] == 'prec_rate' :
    #    v1res.cnLabelBarEndStyle    = 'IncludeOuterBoxes'
    #v1res.cnExplicitLabelBarLabelsOn = True
    #v1res.pmLabelBarDisplayMode =  'Always'
    v1res.pmLabelBarWidthF = 0.10
    #v1res.lbLabelStrings        = label_str_list
    v1res.lbLabelFontHeightF = 0.010
    #v1res.lbBoxCount            = 40
    v1res.lbBoxSeparatorLinesOn = False
    v1res.lbBoxLineThicknessF = 4
    #v1res.lbBoxEndCapStyle     = 'TriangleBothEnds'
    v1res.lbLabelAlignment = 'ExternalEdges'
    v1res.lbLabelStride = lbStride_value

    # settings for variable2 / contourlines #

    if variable2['name'] != '':
        v2res = Ngl.Resources()
        v2res.nglFrame = False
        v2res.nglDraw = False
        v2res.sfDataArray = data_array2_cut
        v2res.sfXArray = ll_lon_cut  #ll_lon_cyclic
        v2res.sfYArray = ll_lat_cut
        v2res.sfMissingValueV = 9999
        #v2res.trGridType        = 'TriangularMesh'
        v2res.cnFillOn = False
        v2res.cnLinesOn = True
        v2res.cnLineLabelsOn = True
        v2res.cnLineLabelPlacementMode = 'Constant'
        v2res.cnLabelDrawOrder = 'PostDraw'
        v2res.cnInfoLabelOn = False
        v2res.cnSmoothingOn = False
        v2res.cnLevelSelectionMode = 'ExplicitLevels'
        v2res.cnLineThicknessF = 3.0 * domain['plot_width'] / 1000
        v2res.cnLineLabelFontHeightF = 0.008
        v2res.cnLineDashSegLenF = 0.25

        v3res = Ngl.Resources()
        v3res.nglFrame = False
        v3res.nglDraw = False
        v3res.sfDataArray = data_array2_cut
        v3res.sfXArray = ll_lon_cut  #ll_lon_cyclic
        v3res.sfYArray = ll_lat_cut
        v3res.sfMissingValueV = 9999
        #v3res.trGridType        = 'TriangularMesh'
        v3res.cnFillOn = False
        v3res.cnLinesOn = True
        v3res.cnLineLabelsOn = True
        v3res.cnLineLabelPlacementMode = 'Constant'
        v3res.cnLabelDrawOrder = 'PostDraw'
        v3res.cnInfoLabelOn = False
        v3res.cnSmoothingOn = False
        v3res.cnLevelSelectionMode = 'ExplicitLevels'
        v3res.cnLineThicknessF = 5.0 * domain['plot_width'] / 1000
        v3res.cnLineLabelFontHeightF = 0.008
        v3res.cnLineDashSegLenF = 0.25

        if variable2['name'] == 'mslp':
            v2res.cnLevels = np.arange(900, 1100, 2)
            v2res.cnLineLabelInterval = 1
            v3res.cnLevels = np.arange(900, 1100, 10)
            v3res.cnLineLabelInterval = 1

        elif variable2['name'] == 'gph_300hPa':
            v2res.cnLevels = np.arange(780, 1000, 6)
            v2res.cnLineLabelInterval = 1
            v3res.cnLevels = np.arange(780, 1000, 24)
            v3res.cnLineLabelInterval = 1

        elif variable2['name'] == 'gph_850hPa':
            v2res.cnLevels = np.arange(100, 180, 2)
            v2res.cnLineLabelInterval = 2
            v3res.cnLevels = np.arange(100, 180, 10)
            v3res.cnLineLabelInterval = 2

        elif variable2['name'] == 'gph_700hPa':
            v2res.cnLevels = np.arange(472, 633, 2)
            v2res.cnLineLabelInterval = 1
            v3res.cnLevels = np.arange(472, 633, 8)
            v3res.cnLineLabelInterval = 1

        elif variable2['name'] == 'gph_500hPa':
            v2res.cnLevels = np.arange(472, 633, 4)
            v2res.cnLineLabelInterval = 1
            v3res.cnLevels = np.arange(472, 633, 16)
            v3res.cnLineLabelInterval = 1

        elif variable2['name'] == 'shear_0-6km':
            v4res = Ngl.Resources()
            v4res.nglFrame = False
            v4res.nglDraw = False
            v4res.sfDataArray = data_array2_cut
            v4res.sfXArray = ll_lon_cut  #ll_lon_cyclic
            v4res.sfYArray = ll_lat_cut
            v4res.sfMissingValueV = 9999
            #v4res.trGridType        = 'TriangularMesh'
            v4res.cnFillOn = False
            v4res.cnLinesOn = True
            v4res.cnLineLabelsOn = True
            v4res.cnLineLabelPlacementMode = 'Constant'
            v4res.cnLabelDrawOrder = 'PostDraw'
            v4res.cnInfoLabelOn = False
            v4res.cnSmoothingOn = False
            v4res.cnLevelSelectionMode = 'ExplicitLevels'
            v4res.cnLineLabelFontHeightF = 0.008
            v4res.cnLineDashSegLenF = 0.25
            v5res = Ngl.Resources()
            v5res.nglFrame = False
            v5res.nglDraw = False
            v5res.sfDataArray = data_array2_cut
            v5res.sfXArray = ll_lon_cut  #ll_lon_cyclic
            v5res.sfYArray = ll_lat_cut
            v5res.sfMissingValueV = 9999
            #54res.trGridType        = 'TriangularMesh'
            v5res.cnFillOn = False
            v5res.cnLinesOn = True
            v5res.cnLineLabelsOn = True
            v5res.cnLineLabelPlacementMode = 'Constant'
            v5res.cnLabelDrawOrder = 'PostDraw'
            v5res.cnInfoLabelOn = False
            v5res.cnSmoothingOn = False
            v5res.cnLevelSelectionMode = 'ExplicitLevels'
            v5res.cnLineLabelFontHeightF = 0.008
            v5res.cnLineDashSegLenF = 0.25

            v2res.cnLevels = [10]
            v2res.cnLineLabelInterval = 1
            v2res.cnLineDashSegLenF = 0.15
            v2res.cnLineThicknessF = 2.4 * domain['plot_width'] / 1000
            v3res.cnLevels = [15]
            v3res.cnLineLabelInterval = 1
            v3res.cnLineThicknessF = 4.5 * domain['plot_width'] / 1000
            v3res.cnLineDashSegLenF = 0.15
            v3res.cnLineThicknessF = 3.6 * domain['plot_width'] / 1000
            v4res.cnLevels = [20]
            v4res.cnLineLabelInterval = 1
            v4res.cnLineDashSegLenF = 0.15
            v4res.cnLineThicknessF = 5.4 * domain['plot_width'] / 1000
            v5res.cnLevels = [25]
            v5res.cnLineLabelInterval = 1
            v5res.cnLineDashSegLenF = 0.15
            v5res.cnLineThicknessF = 8.0 * domain['plot_width'] / 1000
    ''' these are settings for some experiment with lows/highs min/max pressure labels:
    v2res.cnLineLabelsOn = True
    v2res.cnLabelDrawOrder = 'PostDraw'
    v2res.cnLineLabelPerimOn = False
    v2res.cnLineLabelBackgroundColor = 'transparent'
    v2res.cnLineLabelPlacementMode = 'Computed'
    v2res.cnLineLabelDensityF = 0.2
    v2res.cnLineLabelFontHeightF = 0.010
    #v2res.cnLineDashSegLenF = 0.25

    v2res.cnLowLabelsOn = True
    #v2res.cnLowLabelPerimOn = False
    v2res.cnLowLabelString = '$ZDV$hPa'
    #v2res.cnLowLabelFontColor = 'black'
    v2res.cnLowLabelBackgroundColor = 'white'''

    # settings for unit text #

    if variable1['name'][:2] == 'pv'\
    and (domain['name'] == 'southern_south_america'\
          or domain['name'] == 'south_pole'):
        text_str = variable1['unit'] + ' * -1'
    else:
        text_str = variable1['unit']
    text_res_1 = Ngl.Resources()
    text_res_1.txFontColor = 'black'
    text_res_1.txFontHeightF = 0.013
    text_x = 0.965
    text_y = domain['text_y']

    # settings for description label #

    res_text_descr = Ngl.Resources()
    res_text_descr.txJust = 'CenterLeft'
    res_text_descr.txFontHeightF = 0.01
    res_text_descr.txFontColor = 'black'
    res_text_descr.txBackgroundFillColor = 'white'
    res_text_descr.txPerimOn = True
    res_text_descr.txPerimColor = 'black'

    text_descr_str1 = 'ICON-Global-Deterministic from {:02d}.{:02d}.{:4d} {:02d}UTC +{:d}h, '.format(
        run['day'], run['month'], run['year'], run['hour'], hour)
    if variable2['name'] == '':
        text_descr_str2 = 'Contours: {} in {}'.format(variable1['name'],
                                                      variable1['unit'])
    else:
        text_descr_str2 = 'Contours: {} in {}, Lines: {} in {}'.format(
            variable1['name'], variable1['unit'], variable2['name'],
            variable2['unit'])
    text_descr_x = 0.02
    text_descr_y = domain['text_y'] - 0.005

    # override settings for specific cases #

    if domain['name'] == 'mediterranean':
        mpres.mpPerimLineThicknessF /= 1.5
        mpres.mpGeophysicalLineThicknessF /= 1.5
        mpres.mpNationalLineThicknessF /= 1.5
        mpres.vpWidthF = 0.94
        v1res.lbLabelFontHeightF = 0.005
        v1res.pmLabelBarWidthF = 0.04
        v1res.lbLeftMarginF = -0.50
        if variable2['name'] != '':
            v2res.cnLineThicknessF /= 1.5
            v2res.cnLineLabelFontHeightF /= 1.5
            v3res.cnLineThicknessF /= 1.5
            v3res.cnLineLabelFontHeightF /= 1.5
            v2res.cnLineDashSegLenF = 0.12
            v3res.cnLineDashSegLenF = 0.12
        text_res_1.txFontHeightF = 0.007
        text_x = 0.980
        res_text_descr.txFontHeightF = 0.007
        text_descr_x = 0.005

    elif domain['name'] == 'north_pole' or domain['name'] == 'south_pole':
        if variable2['name'] == 'mslp':
            v2res.cnLevels = np.arange(900, 1100, 4)
            v3res.cnLevels = np.arange(900, 1100, 20)
        elif variable2['name'] == 'gph_300hPa':
            v2res.cnLevels = np.arange(780, 1000, 12)
            v3res.cnLevels = np.arange(780, 1000, 48)
        elif variable2['name'] == 'gph_500hPa':
            v2res.cnLevels = np.arange(472, 633, 8)
            v3res.cnLevels = np.arange(472, 633, 32)
        elif variable2['name'] == 'gph_700hPa':
            v2res.cnLevels = np.arange(472, 633, 8)
            v3res.cnLevels = np.arange(472, 633, 32)
        elif variable2['name'] == 'gph_850hPa':
            v2res.cnLevels = np.arange(102, 180, 4)
            v3res.cnLevels = np.arange(102, 180, 20)
    elif domain['name'] == 'Argentina_Central' or domain[
            'name'] == 'Argentina_Central_cerca':
        if variable2['name'] == 'gph_850hPa':
            v2res.cnLevels = np.arange(100, 180, 1)
            v3res.cnLevels = np.arange(100, 180, 5)
            v2res.cnLineLabelInterval = 1

    wks_res = Ngl.Resources()
    wks_res.wkWidth = domain['plot_width']
    wks_res.wkHeight = domain[
        'plot_width']  # the whitespace above and below the plot will be cut afterwards
    #wks_res.wkColorMap = np.array(rgb_colors)
    wks_type = 'png'
    wks = Ngl.open_wks(wks_type, path['base'] + path['plots'] + plot_name,
                       wks_res)

    basic_map = Ngl.map(wks, mpres)

    # plot subnational borders for some domains #
    '''shp_filenames = []
    if domain['name'] == 'southern_south_america'\
     or domain['name'] == 'arg_uru_braz'\
     or domain['name'] == 'argentina_central'\
     or domain['name'] == 'argentina_central_cerca':
        shp_filenames.append(['gadm36_ARG_1.shp', 0.3])
        shp_filenames.append(['gadm36_BRA_1.shp', 0.3])
        shp_filenames.append(['gadm36_CHL_1.shp', 0.3])
    elif domain['name'] == 'north_america':
        shp_filenames.append(['gadm36_USA_1.shp', 0.3])
        shp_filenames.append(['gadm36_CAN_1.shp', 0.3])
        shp_filenames.append(['gadm36_MEX_1.shp', 0.3])
    elif domain['name'] == 'eastern_asia':
        shp_filenames.append(['gadm36_CHN_1.shp', 0.3])

    for shp_filename, lineThickness in shp_filenames:
        shpf = Nio.open_file(path['base'] + path['shapefiles'] + shp_filename, 'r')
        shpf_lon = np.ravel(shpf.variables['x'][:])
        shpf_lat = np.ravel(shpf.variables['y'][:])
        shpf_segments = shpf.variables['segments'][:, 0]

        plres = Ngl.Resources()
        plres.gsLineColor = 'black'
        plres.gsLineThicknessF = lineThickness
        plres.gsSegments = shpf_segments
        Ngl.add_polyline(wks, basic_map, shpf_lon, shpf_lat, plres)'''

    # put everything together #

    contourshades_plot = Ngl.contour(wks, data_array1_cut, v1res)
    if variable2['name'] != '':
        contourlines_minor_plot = Ngl.contour(wks, data_array2_cut, v2res)
        contourlines_major_plot = Ngl.contour(wks, data_array2_cut, v3res)
        if variable2['name'] == 'shear_0-6km':
            contourlines_major2_plot = Ngl.contour(wks, data_array2_cut, v4res)
            contourlines_major3_plot = Ngl.contour(wks, data_array2_cut, v5res)

    Ngl.overlay(basic_map, contourshades_plot)
    if variable2['name'] != '':
        Ngl.overlay(basic_map, contourlines_minor_plot)
        Ngl.overlay(basic_map, contourlines_major_plot)
        if variable2['name'] == 'shear_0-6km':
            Ngl.overlay(basic_map, contourlines_major2_plot)
            Ngl.overlay(basic_map, contourlines_major3_plot)

    Ngl.draw(basic_map)
    Ngl.text_ndc(wks, text_str, text_x, text_y, text_res_1)
    #Ngl.text_ndc(wks, text_descr_str1 + text_descr_str2, text_descr_x, text_descr_y, res_text_descr)

    Ngl.frame(wks)
    Ngl.delete_wks(wks)

    # cut top and bottom whitespace of plot #

    im = Image.open(path['base'] + path['plots'] + plot_name + '.png')
    image_array = np.asarray(im.convert('L'))
    image_array = np.where(image_array < 255, 1, 0)
    image_filter = np.amax(image_array, axis=1)
    vmargins = [
        np.nonzero(image_filter)[0][0],
        np.nonzero(image_filter[::-1])[0][0]
    ]
    #print(vmargins)
    #print(im.size)

    im_cropped = Image.new(
        'RGB', (im.size[0], im.size[1] - vmargins[0] - vmargins[1]),
        (255, 255, 255))
    im_cropped.paste(
        im.crop((0, vmargins[0], im.size[0], im.size[1] - vmargins[1])),
        (0, 0))
    #print(im_cropped.size)
    im.close()
    im_cropped.save(path['base'] + path['plots'] + plot_name + '.png', 'png')
    im_cropped.close()

    return
Beispiel #9
0
def popsicle_diagram(restartfile, param_file, pftcolors, stemcolor=159, file=None, title=None, xtitle=None, ytitle=None, yrange=None, colormap=None, title_charsize=0.75, aspect_ratio=None, makepng=False, png_dens=pngdens, use_wks=None, showjupyter=False):

    if use_wks == None:
        plot_type = get_workstation_type(file)
        
        wks_res = Ngl.Resources()
        if plot_type == 'x11':
            wks_res.wkPause = False
        elif plot_type == 'png':
            wks_res.wkWidth = page_width * 100
            wks_res.wkHeight = page_height * 100
        else:
            wks_res.wkPaperWidthF = page_width
            wks_res.wkPaperHeightF = page_height
            wks_res.wkOrientation = "portrait"
            
        if not colormap == None:
            colormap = parse_colormap(colormap)
            wks_res.wkColorMap = colormap
            
        wks = Ngl.open_wks(plot_type,file,wks_res)
        if wks < 0 and plot_type == "x11":
            clear_oldest_x11_window()
            wks = Ngl.open_wks(plot_type,file,wks_res)
    else:
        wks = use_wks

    resources = Ngl.Resources()

    #cdkif plot_type != 'png':
    resources.nglDraw = False

    #cdkif plot_type != 'png':
    resources.nglFrame = False


    if title != None:
        resources.tiMainString = title

    if xtitle != None:
        resources.tiXAxisString = xtitle

    if ytitle != None:
        resources.tiYAxisString = ytitle

    if yrange != None:
        resources.trYMinF = np.min(yrange)
        resources.trYMaxF = np.max(yrange)

    resources.trXMinF = 0.
    resources.trXMaxF = 1.

    resources.tiMainFontHeightF = 0.025 * title_charsize

    resources.tmXBMajorLengthF        = 0.01
    resources.tmXBMajorOutwardLengthF = 0.01
    resources.tmYLMajorLengthF        = 0.01    
    resources.tmYLMajorOutwardLengthF = 0.01

    resources.tmXBMinorOn    = False
    resources.tmYLMinorOn    = False

    resources.tmXTOn          = False
    resources.tmYROn          = False
    resources.tmXBOn          = False
    resources.tmXBLabelsOn    = False

    if aspect_ratio != None:
        if aspect_ratio > 1.:
            resources.vpHeightF =  0.6  / aspect_ratio
        else:
            resources.vpWidthF =  0.6  * aspect_ratio

    resources.trXMinF = 0.
    resources.trXMaxF = 1.
    if yrange == None:
        yrange = [0, np.ma.max(restartfile.variables['fates_height'][:])]
    resources.trYMinF = np.min(yrange)
    resources.trYMaxF = np.max(yrange)

    dummies = np.ma.masked_all(3)
    plot = Ngl.xy(wks, dummies, dummies, resources)

    #### the main logic all goes here.  ####

    # first calculate the crown areas of each cohort
    cohort_crownareas = carea_allom(restartfile, param_file)

    max_coh_per_patch = 100
    max_cohorts = len(restartfile.variables['fates_CohortsPerPatch'][:])
    max_patches = max_cohorts / max_coh_per_patch
    maxcanlev = restartfile.variables['fates_canopy_layer'][:].max()
    cohort_rhs = np.zeros(maxcanlev)
    ## iterate over patches
    patch_area_sofar = 0.
    vline_res = Ngl.Resources
    vline_res.gsLineThicknessF = .01
    #
    crown_res = Ngl.Resources()
    crown_res.gsLineColor            = "black"
    crown_res.gsLineThicknessF       = .01
    crown_res.gsEdgesOn              = True
    crown_res.gsFillOpacityF         = 0.5
    #
    shadow_res = Ngl.Resources()
    shadow_res.gsFillColor            = "black"
    shadow_res.gsEdgesOn              = False
    #
    stem_res1 = Ngl.Resources()
    stem_res1.gsLineThicknessF       = 1.
    stem_res1.gsEdgesOn              = True
    stem_res1.gsLineColor            = "black"
    #
    stem_res2 = Ngl.Resources()
    stem_res2.gsEdgesOn              = False
    stem_res2.gsFillOpacityF         = 1.
    #
    for i in range(max_patches):
        ## draw thin vertical line at patch lower boundary edge to delineate patches
        patch_lower_edge = 1.-patch_area_sofar - restartfile.variables['fates_area'][i*max_coh_per_patch]/1e4
        zlx = [patch_lower_edge, patch_lower_edge]
        zly = [0., 1000.]
        Ngl.add_polyline(wks,plot, zlx, zly, vline_res)
        #
        ## iterate over cohorts
        for l in range(maxcanlev-1,-1,-1):
            shadow_res.gsFillOpacity = l * 0.5
            cohort_rhs = 1. - patch_area_sofar
            if restartfile.variables['fates_CohortsPerPatch'][i*max_coh_per_patch] > 0:
                for j in range(restartfile.variables['fates_CohortsPerPatch'][i*max_coh_per_patch]-1,-1,-1):
                    cindx = i * max_coh_per_patch + j
                    if restartfile.variables['fates_canopy_layer'][cindx]-1 == l:
                        rhs = cohort_rhs
                        lhs = rhs - cohort_crownareas[cindx]/1e4
                        ctop = restartfile.variables['fates_height'][cindx]
                        cbot = ctop * 0.6
                        crown_res.gsFillColor = pftcolors[restartfile.variables['fates_pft'][cindx]-1]
                        px = [rhs,rhs,lhs,lhs,rhs]
                        py = [ctop,cbot,cbot,ctop,ctop]
                        #
                        stem_center = (lhs + rhs) /2.
                        stem_width = .00001 * restartfile.variables['fates_dbh'][cindx]
                        stem_res2.gsFillColor = stemcolor
                        sx = [stem_center+stem_width,stem_center+stem_width,stem_center-stem_width,stem_center-stem_width,stem_center+stem_width]
                        sy = [cbot,0.,0.,cbot,cbot]
                        Ngl.add_polyline(wks,plot,sx,sy,stem_res1)
                        Ngl.add_polygon(wks,plot,sx,sy,stem_res2)
                        #
                        if l > 0:
                            Ngl.add_polygon(wks,plot,px,py,shadow_res)
                        #
                        Ngl.add_polygon(wks,plot,px,py,crown_res)
                        #
                        cohort_rhs = lhs
                        #if lhs < patch_lower_edge:
                        #    raise Exception
        #
        ## get cohort properties: height, upper horizontal edge, crown area, pft, canopy layer
        #
        ## draw cohort as popsicle
        #
        patch_area_sofar = patch_area_sofar + restartfile.variables['fates_area'][i*max_coh_per_patch]/1e4
    if use_wks == None:
        Ngl.draw(plot)
        Ngl.frame(wks)
    
        if not file==None:
            Ngl.delete_wks(wks)
            #
            if makepng or showjupyter:
                pdf_to_png(file, density=png_dens)
            if jupyter_avail and showjupyter:
                print(' ')
                print('showing file '+file)
                display(Image(file+'.png'))
        else:
            x11_window_list.append(wks)
    else:
        return plot
def print_comp_for_timestamp(wrf_data, timestamp, filepath):
  slp = pressure_lib.get_sea_level_pressure(wrf_data)
  temperature = getvar(wrf_data,"tc")
  u = get_latitude_wind(wrf_data)
  v = get_longitude_wind(wrf_data)

  lat, lon = latlon_coords(temperature)
  lat_normal = to_np(lat)
  lon_normal = to_np(lon)
  
  # temperature
  t_res = get_pyngl(temperature)
  t_res.nglDraw             = False                  # don't draw plot
  t_res.nglFrame            = False                  # don't advance frame
  
  t_res.cnFillOn            = True                   # turn on contour fill
  t_res.cnLinesOn           = False                  # turn off contour lines
  t_res.cnLineLabelsOn      = False                  # turn off line labels
  t_res.cnFillMode          = "RasterFill"           # These two resources
  t_res.cnFillPalette       = "BlAqGrYeOrReVi200"
  t_res.cnLevelSelectionMode = "ManualLevels"
  t_res.cnMinLevelValF      = -25.0                  # min. temperature for composite
  t_res.cnMaxLevelValF      = 45.0                   # max. temperature for composite
  t_res.cnLevelSpacingF     = 1                      # increment
  
  t_res = geography_lib.initialize_geography(t_res, "gray25")
  
  t_res.lbTitleString       = "%s in (%s)" % (temperature.description,temperature.units)
  t_res.lbOrientation       = "horizontal"
  t_res.lbTitleFontHeightF  = 0.015
  t_res.lbLabelFontHeightF  = 0.015                  
  
  t_res.tiMainString        = "Composite (%s)" % timestamp.strftime("%b %d %Y %HUTC")
  t_res.trGridType          = "TriangularMesh"       # can speed up plotting.
  t_res.tfDoNDCOverlay      = True                   # required for native projection

  # pressure
  p_res = pressure_lib.get_pressure_resource(lat_normal, lon_normal)
  
  # wind
  uv_res = Ngl.Resources()
  uv_res.nglDraw            =  False                # don't draw plot
  uv_res.nglFrame           =  False                # don't advance frame
  
  uv_res.vcFillArrowsOn     = True
  uv_res.vcRefMagnitudeF    = 15.0
  uv_res.vcRefLengthF       = 0.03
  uv_res.vcMinDistanceF     = 0.02
  uv_res.vcRefAnnoFontHeightF = 0.01
  uv_res.vcRefAnnoString1 = "$VMG$ m/s"
  uv_res.vcRefAnnoString2 = "ground windspeed (m/s) reference"
  
  uv_res.vfXArray           =  lon_normal
  uv_res.vfYArray           =  lat_normal

  wk_res = Ngl.Resources()
  wk_res.wkWidth = 2500
  wk_res.wkHeight = 2500
  output_path = "%scomp_%s" % (filepath, timestamp.strftime("%Y_%m_%d_%H"))
  wks_comp = Ngl.open_wks("png", output_path, wk_res)

  # creating plots for the measurands
  tplot = Ngl.contour_map(wks_comp,temperature[0,:,:],t_res)
  pplot = Ngl.contour(wks_comp,slp,p_res)
  vector = Ngl.vector(wks_comp,u,v,uv_res)

  Ngl.overlay(tplot, vector)
  Ngl.overlay(tplot, pplot)
  Ngl.maximize_plot(wks_comp, tplot)
  Ngl.draw(tplot)
  Ngl.frame(wks_comp)
  Ngl.delete_wks(wks_comp) # delete currently used workstation