def _get_plot_dimensions(self, plots, res): """Get the dimensions of the plots to be panelled.""" # Select the index of the plot to get the size from. base_plot = getattr(res, 'nglPanelScalePlotIndex', 0) pwidth = Ngl.get_float(plots[base_plot], 'vpWidthF') pheight = Ngl.get_float(plots[base_plot], 'vpHeightF') return pwidth, pheight
def draw_vp_box(wks, plot): # Retrieve the viewport values of the drawable object. vpx = Ngl.get_float(plot, "vpXF") vpy = Ngl.get_float(plot, "vpYF") vpw = Ngl.get_float(plot, "vpWidthF") vph = Ngl.get_float(plot, "vpHeightF") print("Viewport x,y,width,height =", vpx, vpy, vpw, vph) # Make a box with the viewport values. xbox = [vpx, vpx + vpw, vpx + vpw, vpx, vpx] ybox = [vpy, vpy, vpy - vph, vpy - vph, vpy] # Set up some marker resources. mkres = Ngl.Resources() mkres.gsMarkerIndex = 16 # filled dot mkres.gsMarkerSizeF = 0.02 # larger than default mkres.gsMarkerColor = "ForestGreen" # Draw a single marker at the vpXF/vpYF location. Ngl.polymarker_ndc(wks, vpx, vpy, mkres) # Set up some line resources. lnres = Ngl.Resources() lnres.gsLineColor = "NavyBlue" # line color lnres.gsLineThicknessF = 3.5 # 3.5 times as thick # Draw a box around the viewport. Ngl.polyline_ndc(wks, xbox, ybox, lnres) # Set up some text resources. txres = Ngl.Resources() txres.txJust = "CenterLeft" txres.txFontHeightF = 0.015 txres.txFontColor = "ForestGreen" txres.txBackgroundFillColor = "white" # Draw a text string labeling the marker Ngl.text_ndc(wks, "(vpXF,vpYF)", vpx + 0.03, vpy, txres) # Draw text strings labeling the viewport box. txres.txFontColor = "black" txres.txJust = "CenterLeft" Ngl.text_ndc(wks, "viewport", vpx + vpw / 2., vpy - vph, txres) Ngl.text_ndc(wks, "viewport", vpx + vpw / 2., vpy, txres) txres.txAngleF = 90. Ngl.text_ndc(wks, "viewport", vpx, vpy - vph / 2., txres) Ngl.text_ndc(wks, "viewport", vpx + vpw, vpy - vph / 2., txres) return
def ngl_Strings(wks, plot, title='', left='', center='', right='', xtitle='', ytitle=''): vpx = Ngl.get_float(plot,"vpXF") #-- retrieve value of res.vpXF from plot vpy = Ngl.get_float(plot,"vpYF") #-- retrieve value of res.vpYF from plot vpw = Ngl.get_float(plot,"vpWidthF") #-- retrieve value of res.vpWidthF from plot vph = Ngl.get_float(plot,"vpHeightF") #-- retrieve value of res.vpHeightF from plot ymax = vpy+0.08 #-- we need space for the title and strings if(ymax > 0.98): print("--> if you can't see the title use res.nglMaximize = False and/or set res.vpYF") #-- add title if(title != ""): tires = Ngl.Resources() tires.txFontHeightF = 0.016 tires.txJust = "CenterCenter" tires.txFont = 22 #-- Font 22: Helvetica bold if(left != "" or center != "" or right != ""): y = vpy + 0.075 else: y = vpy + 0.05 Ngl.text_ndc(wks, title, 0.5, y, tires) #-- add left, center and/or right string txres = Ngl.Resources() txres.txFontHeightF = 0.020 #-- font size for left, center and right string y = vpy + 0.035 #-- y-position if(left != ""): txres.txJust = "CenterLeft" #-- text justification x = vpx #-- x-position Ngl.text_ndc(wks, left, x, y, txres) #-- add text to wks if(center != ""): txres.txJust = "CenterCenter" #-- text justification Ngl.text_ndc(wks, center, 0.5, y, txres) #-- add text to wks if(right != ""): txres.txJust = "CenterRight" #-- text justification x = vpx+vpw #-- x-position Ngl.text_ndc(wks, right, x, y, txres) #-- add text to wks #-- add y-axis title string txtires = Ngl.Resources() txtires.txFontHeightF = 0.024 #-- font size for x-axis title string txtires.txAngleF = 90.0 txtires.txJust = "CenterCenter" #-- text justification y = vpy - vph/2 #-- y-position x = vpx - 0.12 Ngl.text_ndc(wks, ytitle, x, y, txtires) #-- add text to wks
def right_axis(wks, plot, yaxis_string, tres): ttres = tres # Copy resources ttres.nglDraw = False # Make sure string is just created, not drawn. ttres.txAngleF = -90. # Use 90 to rotate other direction. # # Retrieve font height of left axis string and use to calculate size of # right axis string # if not hasattr(ttres, "txFontHeightF"): ttres.txFontHeightF = Ngl.get_float(plot.base, "tiYAxisFontHeightF") # # Set up variable to hold annotation resources. # amres = Ngl.Resources() # # Create string to put at right of plot, like a Y axis title. # if yaxis_string != "": txid = Ngl.text(wks, plot, yaxis_string, 0., 0., ttres) amres.amJust = "CenterCenter" amres.amParallelPosF = 0.55 # Move towards plot. annoid = Ngl.add_annotation(plot, txid, amres) return
def add_panel_label(wks, plot, panLabel="", factor=.05, placement="ul", axfunc=min, rlist=None): ''' Adds a label to a plot similar to the result from the nglPanelFigureString resource. The box around the perimenter of the label is drawn by the text_ndc function and controlled by txPerim* attributes. add_panel_label(wks, plot, panLabel="", factor=(1., 1.), placement="ul", axfunc=min, rlist=None) wks : workstation Id as returned by open_wks() plot : plot Id of the panel to add the label panLabel : String containing the panel label factor : ratio of margin to reference axis length placement : One of "ul", "ur", "ll" or "lr" to specify the corner where the label should be placed axfunct : function which is used to give the reference axis length based on the viewport width and height. This function should accept one list or tupel as argument. rlist : Resouce object that can be used to customize the label and its perimeter box. It can contain any resource that is accepted by text_ndc as a valid resource. ''' vpXF, vpYF, vpWidthF, vpHeightF = [ngl.get_float(plot, name) for name in ["vpXF", "vpYF", "vpWidthF", "vpHeightF"]] margin = factor * axfunc([vpWidthF, vpHeightF]) ul_edge = [vpXF + .5 * vpWidthF, vpYF + .5 * vpHeightF] if placement[0] == "u": ul_edge[1] = vpYF - margin tx_just = "Top" elif placement[0] == "l": ul_edge[1] = vpYF - vpHeightF + margin tx_just = "Bottom" if placement[1] == "l": ul_edge[0] = vpXF + margin tx_just = tx_just + "Left" elif placement[1] == "r": ul_edge[0] = vpXF + vpWidthF - margin tx_just = tx_just + "Right" if len(ul_edge) != 2: raise ValueError("placement is not in ['ul', 'ur', 'll', 'lr']") tx_res = {"txFontHeightF": .02, "txPerimOn": True, "txBackgroundFillColor": 0, "txJust": tx_just} if rlist: tx_res.update(rlist.__dict__) ngl.text_ndc(wks, panLabel, *ul_edge, rlistc=_dict2Resource(tx_res))
def ngl_Strings(wks, plot, left='', center='', right=''): ''' *Reference: https://github.com/NCAR/pyngl/issues/11 ngl_Strings(wks, plot, left='', center='', right='') Add annotations - left, right or center string above plot Correspond to NCL's gsnLeftString, gsnCenterString, gsnRightString' ''' assert str(getattr(wks, '__class__') == "<class 'int'>"), 'ERROR - 1st parameter is not a Ngl wks' assert str(getattr(plot, '__class__') == "<class 'ngl.PlotIds'>" ), 'ERROR - 2nd parameter is not a Ngl plot' vpx = Ngl.get_float(plot, "vpXF") #-- retrieve value of res.vpXF from plot vpy = Ngl.get_float(plot, "vpYF") #-- retrieve value of res.vpYF from plot vpw = Ngl.get_float( plot, "vpWidthF") #-- retrieve value of res.vpWidthF from plot txres = Ngl.Resources() txres.txFontHeightF = 0.018 #-- font size for left, center and right string txres.txFont = 26 y = vpy + 0.025 #-- y-position if (left != ''): txres.txJust = "CenterLeft" #-- text justification x = vpx #-- x-position Ngl.text_ndc(wks, left, x, y, txres) #-- add text to wks if (center != ''): txres.txJust = "CenterCenter" #-- text justification x = vpx + vpw/2 x = vpx + vpw / 2 Ngl.text_ndc(wks, center, x, y, txres) #-- add text to wks if (right != ''): txres.txJust = "CenterRight" #-- text justification x = vpx + vpw #-- x-position Ngl.text_ndc(wks, right, x, y, txres) #-- add text to wks
def subtitles(wks, plot, left_string, center_string, right_string, tres): ttres = tres # Copy resources ttres.nglDraw = False # Make sure string is just created, not drawn. # # Retrieve font height of left axis string and use this to calculate # size of subtitles. # if not hasattr(ttres, "txFontHeightF"): font_height = Ngl.get_float(plot.base, "tiXAxisFontHeightF") ttres.txFontHeightF = font_height * 0.8 # Slightly smaller # # Set some some annotation resources to describe how close text # is to be attached to plot. # amres = Ngl.Resources() if not hasattr(ttres, "amOrthogonalPosF"): amres.amOrthogonalPosF = -0.51 # Top of plot plus a little extra # to stay off the border. else: amres.amOrthogonalPosF = ttres.amOrthogonalPosF # # Create three strings to put at the top, using a slightly # smaller font height than the axis titles. # if left_string != "": txidl = Ngl.text(wks, plot, left_string, 0., 0., ttres) amres.amJust = "BottomLeft" amres.amParallelPosF = -0.5 # Left-justified annoidl = Ngl.add_annotation(plot, txidl, amres) if center_string != "": txidc = Ngl.text(wks, plot, center_string, 0., 0., ttres) amres.amJust = "BottomCenter" amres.amParallelPosF = 0.0 # Centered annoidc = Ngl.add_annotation(plot, txidc, amres) if right_string != "": txidr = Ngl.text(wks, plot, right_string, 0., 0., ttres) amres.amJust = "BottomRight" amres.amParallelPosF = 0.5 # Right-justifed annoidr = Ngl.add_annotation(plot, txidr, amres) return
def add_axis(wks, plot, ax="XB", offset=0., res=None): val_ax = ("XT", "XB", "YL", "YR") if not res: res = {} else: res = _resource2dict(res) resp = {} keys = ["vpXF", "vpYF", "vpWidthF", "vpHeightF", "trXMinF", "trXMaxF", "trYMinF", "trYMaxF"] for a in val_ax: for k in ("LabelFontHeight", "MajorOutwardLength", "MinorOutwardLength"): keys.append("tm{}{}F".format(a, k)) for k in keys: resp[k] = ngl.get_float(plot, k) for k in ("tm" + a + k for a in val_ax for k in ("Values", "MinorValues")): resp[k] = ngl.get_float_array(plot, k) for k in ("tm{}MinorPerMajor".format(a) for a in val_ax): resp[k] = ngl.get_integer(plot, k) for k in ("tm{}MinorOn".format(a) for a in val_ax): resp[k] = (ngl.get_integer(plot, k) == 1) for k in ("tm" + a + "Labels".format(a) for a in val_ax): resp[k] = ngl.get_string_array(plot, k) resp.update(res) for a in ("XT", "XB", "YL", "YR"): resp["tm{}Mode".format(a)] = "Explicit" resp["tm{}On".format(a)] = (a == ax) resp["tm{}BorderOn".format(a)] = (a == ax) resp["nglDraw"] = False resp["nglFrame"] = False blank_plot = ngl.blank_plot(wks, _dict2Resource(resp)) amres = {"amJust": "CenterCenter"} if ax[1].lower() in "lt": ampos_sig = -1. else: ampos_sig = 1. if ax[0].lower() == "x": amres["amOrthogonalPosF"] = ampos_sig * offset else: amres["amParallelPosF"] = ampos_sig * offset return ngl.add_annotation(plot, blank_plot, _dict2Resource(amres))
def set_plot_position(plot, vpXY=None, vpWH=None): '''Change the viewport location and width. If one is omitted, the value will be retained. set_plot_position(plot, vpXY=None, vpWH=None) plot : plot Id of the plot to modify vpXY : tupel of the coordinates of the upper left corner of the viewport in NDC space vpWH : tupel of viewports width and height in NDC space ''' attrib = ["vpXF", "vpYF", "vpWidthF", "vpHeightF"] rlist = dict(zip(attrib, [ngl.get_float(plot, name) for name in attrib])) if vpXY: rlist["vpXF"], rlist["vpYF"] = vpXY if vpWH: rlist["vpWidthF"], rlist["vpHeightF"] = vpWH _set_values(plot, rlist)
lon_labels.append("{:g}W".format(abs(l))) elif l > 0: lon_labels.append("{:g}E".format(l)) else: lon_labels.append("{:g}".format(l)) #---------------------------------------------------------------------- # This section creates a blank plot, for the purpose of customizing # its tickmarks. #---------------------------------------------------------------------- #---Resource list for blank plot bres = Ngl.Resources() #---Retrieve viewport coordinates and set them for blank plot. bres.vpXF = Ngl.get_float(map, "vpXF") bres.vpYF = Ngl.get_float(map, "vpYF") bres.vpHeightF = Ngl.get_float(map, "vpHeightF") bres.vpWidthF = Ngl.get_float(map, "vpWidthF") #---Retrieve min/max values of map and set them for blank plot. bres.trXMinF = Ngl.get_float(map, "trXMinF") bres.trXMaxF = Ngl.get_float(map, "trXMaxF") bres.trYMinF = Ngl.get_float(map, "trYMinF") bres.trYMaxF = Ngl.get_float(map, "trYMaxF") #---Default is inward. bres.nglPointTickmarksOutward = True #---Set the values and labels for the X axis of blank plot. bres.tmXBMode = "Explicit"
resMP.nglFrame = False resMP.sfXArray = Tlons.values resMP.sfYArray = Tlats.values resMP.cnLineLabelsOn = False resMP.cnLinesOn = False resMP.cnLevelSelectionMode = "ManualLevels" contour = Ngl.contour(wks, varM, resMP) resMP.mpProjection = "CylindricalEquidistant" # Change the map projection. resMP.mpCenterLonF = 0. # Rotate the projection. #resMP.mpFillOn = True # Turn on map fill. resMP.mpLimitMode = "LatLon" # Limit the map view. resMP.mpMinLonF = Ngl.get_float(contour.sffield, "sfXCActualStartF") resMP.mpMaxLonF = Ngl.get_float(contour.sffield, "sfXCActualEndF") resMP.mpMinLatF = Ngl.get_float(contour.sffield, "sfYCActualStartF") resMP.mpMaxLatF = Ngl.get_float(contour.sffield, "sfYCActualEndF") #resMP.mpOutlineBoundarySets = "AllBoundaries" #resMP.sfYArray = Tlats.values #resMP.sfXArray = Tlons.values setplotrange(resMP, a1, a2, adiff) plot.append(Ngl.contour_map(wks, varM, resMP)) plot.append(Ngl.contour_map(wks, varN, resMP)) setplotrange(resMP, b1, b2, bdiff) plot.append(Ngl.contour_map(wks, varM - varN, resMP)) textres = Ngl.Resources()
# # Turn on the right Y labels and tickmarks and move the axis string to # the right. # res2.tmYRLabelsOn = True res2.tmYROn = True res2.tmYUseLeft = False res2.tmYRFormat = "f" # Gets rid of unnecessary trailing zeros # # Move the Y axis string to the right. # res2.tiYAxisString = "U component of wind (m/s)" res2.tiYAxisSide = "Right" res2.tiYAxisFontColor = "purple" res2.tiXAxisFontHeightF = Ngl.get_float(plot1, "tiXAxisFontHeightF") # # Make sure the font heights and tickmark lengths are the same as # the first plot. # res2.tmYRLabelFontHeightF = Ngl.get_float(plot1, "tmYLLabelFontHeightF") res2.tmYRMajorLengthF = Ngl.get_float(plot1, "tmYLMajorLengthF") # # Change line pattern, color and thickness. # pattern = "$_____$_____$$_____$$_____$$_____$$_____$$___" res2.xyDashPattern = Ngl.new_dash_pattern(wks, pattern) res2.xyLineColor = "purple" res2.xyLineThicknessF = 3.0
1750.,2000.,2250.,2500.,2750.,3000.,3250., 3500.,3750.,4000.,4250.,4500.,4750.,5000.] resources.tiMainString = "North Carolina Coast (depth in meters)" resources.tiMainFontHeightF = 0.015 resources.nglDraw = False resources.nglFrame = False contour = Ngl.contour(wks,depth,resources) # # Retrieve the actual lat/lon end points of the scalar array so # we know where to overlay on map. # xs = Ngl.get_float(contour.sffield,"sfXCActualStartF") xe = Ngl.get_float(contour.sffield,"sfXCActualEndF") ys = Ngl.get_float(contour.sffield,"sfYCActualStartF") ye = Ngl.get_float(contour.sffield,"sfYCActualEndF") # # The next set of resources will apply to the map plot. # resources.mpProjection = "CylindricalEquidistant" # # Once the high resolution coastline data files have been # downloaded (see the Notes section above for details), to # access them you need to change the following resource # to "HighRes". #
if hasattr(uvar,"_FillValue"): resources.vfMissingUValueV = uvar._FillValue if hasattr(vvar,"_FillValue"): resources.vfMissingVValueV = vvar._FillValue resources.tiXAxisFont = "Times-Roman" # Change the default font used. resources.tmXBLabelFont = "Times-Roman" resources.tmYLLabelFont = "Times-Roman" resources.stLineColor = "green" # Change streamlines to green. plot = Ngl.streamline(wks,uvar[::2,::2],vvar[::2,::2],resources) #----------- Begin third plot ----------------------------------------- arrowlength = Ngl.get_float(plot,"stArrowLengthF") spacing = Ngl.get_float(plot,"stMinLineSpacingF") resources.stMinLineSpacingF = spacing * 2.0 # Set some resources based resources.stArrowLengthF = arrowlength * 2.0 # on resources you retrieved. resources.stLineColor = "red" # Change line color to red resources.stLineThicknessF = 1.5 uvar = file.variables["U_GRD_6_GPML"] vvar = file.variables["V_GRD_6_GPML"] # # Set resources and plot. # if hasattr(uvar,"units"): resources.tiMainString = "GRD_6_GPML (u,v " + uvar.units + ")"
def plot_Robinson_pyngl(var, lon, lat, wks_name='plot', clim=None, cspace=None, cmap=None): # # Select a colormap and open a workstation. # rlist = Ngl.Resources() wks_type = "png" wks = Ngl.open_wks(wks_type, wks_name, rlist) if cmap is None: mycmap = 'BlAqGrYeOrReVi200' Ngl.define_colormap(wks, mycmap) else: try: mycmap = '/Users/frederic/python/cmap/' + cmap mycmap = np.loadtxt(mycmap) except: mycmap = cmap try: Ngl.define_colormap(wks, mycmap) except: raise Warning('Unknown colormap') # # The next set of resources will apply to the contour plot and the labelbar. # resources = Ngl.Resources() resources.sfXArray = lon resources.sfYArray = lat resources.gsnMaximize = True # use full page resources.cnFillOn = True resources.cnFillMode = "RasterFill" resources.cnMaxLevelCount = 255 resources.cnLinesOn = False resources.cnLineLabelsOn = False if clim is not None: resources.cnLevelSelectionMode = "ManualLevels" # set manual contour levels resources.cnMinLevelValF = clim[0] # set min contour level resources.cnMaxLevelValF = clim[1] # set max contour level if cspace is None: LevelSpacing = (clim[1] - clim[0]) / 100. resources.cnLevelSpacingF = LevelSpacing # set contour spacing else: resources.cnLevelSpacingF = cspace # set contour spacing resources.lbOrientation = "Horizontal" # Default is vertical. resources.lbBoxLinesOn = False resources.lbLabelFontHeightF = 0.01 # label font height resources.lbBoxMinorExtentF = 0.15 # # The contour plot is not very interesting, so don't draw it. # resources.nglDraw = False resources.nglFrame = False contour = Ngl.contour(wks, var, resources) # # Retrieve the actual lat/lon end points of the scalar array so # we know where to overlay on map. # xs = Ngl.get_float(contour.sffield, "sfXCActualStartF") xe = Ngl.get_float(contour.sffield, "sfXCActualEndF") ys = Ngl.get_float(contour.sffield, "sfYCActualStartF") ye = Ngl.get_float(contour.sffield, "sfYCActualEndF") resources.nglDraw = True # Turn these resources back on. resources.nglFrame = True resources.mpProjection = "Robinson" resources.mpCenterLonF = 270 resources.mpCenterLatF = 0 resources.mpGeophysicalLineThicknessF = 2 map = Ngl.contour_map(wks, var, resources) Ngl.end()
lon_labels.append("%gW" % abs(l)) elif l > 0: lon_labels.append("%gE" % l) else: lon_labels.append("%g" % l) #---------------------------------------------------------------------- # This section creates a blank plot, for the purpose of customizing # its tickmarks. #---------------------------------------------------------------------- #---Resource list for blank plot bres = Ngl.Resources() #---Retrieve viewport coordinates and set them for blank plot. bres.vpXF = Ngl.get_float(map,"vpXF") bres.vpYF = Ngl.get_float(map,"vpYF") bres.vpHeightF = Ngl.get_float(map,"vpHeightF") bres.vpWidthF = Ngl.get_float(map,"vpWidthF" ) #---Retrieve min/max values of map and set them for blank plot. bres.trXMinF = Ngl.get_float(map,"trXMinF") bres.trXMaxF = Ngl.get_float(map,"trXMaxF") bres.trYMinF = Ngl.get_float(map,"trYMinF") bres.trYMaxF = Ngl.get_float(map,"trYMaxF") #---Default is inward. bres.nglPointTickmarksOutward = True #---Set the values and labels for the X axis of blank plot. bres.tmXBMode = "Explicit"
cnres.sfYArray = lat # # The data is ordered lon x lat; you must reorder before plotting # using transpose. # contour_map_plot = Ngl.contour_map(wks, precip[:].transpose(),cnres) # ------------------------------------------------------------------- # Code for creating map only plot. # ------------------------------------------------------------------- # Get size of contour/map plot # Retrieve size of contour/map plot bres = Ngl.Resources() bres.vpx = Ngl.get_float(contour_map_plot,"vpXF") bres.vpy = Ngl.get_float(contour_map_plot,"vpYF") bres.vph = Ngl.get_float(contour_map_plot,"vpHeightF") bres.vpw = Ngl.get_float(contour_map_plot,"vpWidthF" ) mpres = set_map_resources() # Make sure map plot is same size as contour/map plot. mpres.nglMaximize = False # this must be turned off otherwise plot will be resized! mpres.vpXF = bres.vpx mpres.vpYF = bres.vpy mpres.vpWidthF = bres.vpw mpres.vpHeightF = bres.vph # Turn off since they are already drawn in contour/map plot. mpres.pmTickMarkDisplayMode = "Never"
#-- generate plot2, but don't draw it yet print("-- rplot --") rplot = Ngl.contour(wks, rhum, rres) #-- overlay rplot on tplot print("-- overlay tplot --") Ngl.overlay(map, tplot) print("-- overlay rplot --") Ngl.overlay(map, rplot) #-- draw the plot Ngl.draw(map) #-- Retrieve some resources from map for adding labels vpx = Ngl.get_float(map, 'vpXF') vpy = Ngl.get_float(map, 'vpYF') vpw = Ngl.get_float(map, 'vpWidthF') fnth = Ngl.get_float(map, 'tmXBLabelFontHeightF') #-- write variable long_name and units to the plot txres = Ngl.Resources() txres.txFontHeightF = fnth txres.txJust = "CenterLeft" Ngl.text_ndc(wks, f.t.long_name, vpx, vpy + 0.02, txres) txres.txJust = "CenterRight" Ngl.text_ndc(wks, f.t.units, vpx + vpw, vpy + 0.02, txres) ###Ngl.text_ndc(wks,f.variables["t"].attributes['long_name'],0.17,0.88,txres)
def plot_Robinson_pyngl(var,lon,lat,wks_name='plot', clim=None, cspace=None, cmap=None): # # Select a colormap and open a workstation. # rlist = Ngl.Resources() wks_type = "png" wks = Ngl.open_wks(wks_type,wks_name,rlist) if cmap is None: mycmap = 'BlAqGrYeOrReVi200' Ngl.define_colormap(wks,mycmap) else: try: mycmap = '/Users/frederic/python/cmap/' + cmap mycmap = np.loadtxt(mycmap) except: mycmap = cmap try: Ngl.define_colormap(wks,mycmap) except: raise Warning, 'Unknown colormap' # # The next set of resources will apply to the contour plot and the labelbar. # resources = Ngl.Resources() resources.sfXArray = lon resources.sfYArray = lat resources.gsnMaximize = True # use full page resources.cnFillOn = True resources.cnFillMode = "RasterFill" resources.cnMaxLevelCount = 255 resources.cnLinesOn = False resources.cnLineLabelsOn = False if clim is not None: resources.cnLevelSelectionMode = "ManualLevels" # set manual contour levels resources.cnMinLevelValF = clim[0] # set min contour level resources.cnMaxLevelValF = clim[1] # set max contour level if cspace is None: LevelSpacing = (clim[1] - clim[0]) / 100. resources.cnLevelSpacingF = LevelSpacing # set contour spacing else: resources.cnLevelSpacingF = cspace # set contour spacing resources.lbOrientation = "Horizontal" # Default is vertical. resources.lbBoxLinesOn = False resources.lbLabelFontHeightF = 0.01 # label font height resources.lbBoxMinorExtentF = 0.15 # # The contour plot is not very interesting, so don't draw it. # resources.nglDraw = False resources.nglFrame = False contour = Ngl.contour(wks,var,resources) # # Retrieve the actual lat/lon end points of the scalar array so # we know where to overlay on map. # xs = Ngl.get_float(contour.sffield,"sfXCActualStartF") xe = Ngl.get_float(contour.sffield,"sfXCActualEndF") ys = Ngl.get_float(contour.sffield,"sfYCActualStartF") ye = Ngl.get_float(contour.sffield,"sfYCActualEndF") resources.nglDraw = True # Turn these resources back on. resources.nglFrame = True resources.mpProjection = "Robinson" resources.mpCenterLonF = 270 resources.mpCenterLatF = 0 resources.mpGeophysicalLineThicknessF = 2 map = Ngl.contour_map(wks,var,resources) Ngl.end()
resources.tiMainString = "2562 Element Geodesic grid" resources.lbBoxLinesOn = False resources.lbTitleString = "kinetic energy" resources.nglDraw = False # Just create the plot. Don't resources.nglFrame = False # draw it or advance the frame. contour = Ngl.contour(wks,ke,resources) # # Retrieve the actual lat/lon end points of the scalar array so # we know where to overlay on map. # xs = Ngl.get_float(contour.sffield,"sfXCActualStartF") xe = Ngl.get_float(contour.sffield,"sfXCActualEndF") ys = Ngl.get_float(contour.sffield,"sfYCActualStartF") ye = Ngl.get_float(contour.sffield,"sfYCActualEndF") resources.nglDraw = True # Now we want to draw the plot resources.nglFrame = True # and advance the frame. resources.mpGridAndLimbOn = False resources.mpProjection = "Orthographic" resources.mpDataBaseVersion = "MediumRes" resources.mpLimitMode = "LatLon" resources.mpMinLonF = xs resources.mpMaxLonF = xe resources.mpMinLatF = ys resources.mpMaxLatF = ye
def add_map_tickmarks(wks,map,lat_spc,lon_spc): bres = Ngl.Resources() bres.nglMaximize = False #---Set some resources based on map plot already created. bres.vpXF = Ngl.get_float(map, "vpXF") bres.vpYF = Ngl.get_float(map, "vpYF") bres.vpWidthF = Ngl.get_float(map, "vpWidthF") bres.vpHeightF = Ngl.get_float(map, "vpHeightF") bres.trXMinF = Ngl.get_float(map, "trXMinF") bres.trXMaxF = Ngl.get_float(map, "trXMaxF") bres.trYMinF = Ngl.get_float(map, "trYMinF") bres.trYMaxF = Ngl.get_float(map, "trYMaxF") bres.tmEqualizeXYSizes = True # make sure labels same size #---Create longitude labels based on longitude spacing given. lon_values = np.arange(-180,181,lon_spc) lon_labels = [] for l in lon_values: if l < 0: lon_labels.append("{}~S~o~N~W".format(np.fabs(l))) elif l > 0: lon_labels.append("{}~S~o~N~E".format(l)) else: lon_labels.append("0") #---Create latitude labels based on latitude spacing given. lat_values = np.arange(-90,91,lat_spc) lat_labels = [] for l in lat_values: if l < 0: lat_labels.append("{}~S~o~N~S".format(np.fabs(l))) elif l > 0: lat_labels.append("{}~S~o~N~N".format(l)) else: lat_labels.append("EQ") #---Set tickmark resources bres.tmXBMode = "Explicit" bres.tmXBValues = lon_values bres.tmXBLabels = lon_labels bres.tmYLMode = "Explicit" bres.tmYLValues = lat_values bres.tmYLLabels = lat_labels bres.tmYLLabelFontHeightF = 0.009 # Make these labels smaller. bres.tmXBLabelFontHeightF = 0.009 # Ditto #---To urn on tickmark lines, change these values to something like 0.01 #---Turn off tickmark lines bres.tmXBMajorLengthF = 0. bres.tmYLMajorLengthF = 0. bres.tmXBMajorOutwardLengthF = 0. bres.tmYLMajorOutwardLengthF = 0. #---Create the blank plot with the special labels blank = Ngl.blank_plot(wks,bres) #---Attach blank plot with special labels to map plot, and return sres = Ngl.Resources() sres.amZone = 0 # '0' means centered over base plot. sres.amResizeNotify = True return Ngl.add_annotation(map,blank,sres)
def _plot_trj_marker(wks, plot, x, y, angle, res): ''' Plots a single arrow head onto the a trajectory plot pgon = _plot_trj_marker(wks, plot, x, y, angle, res) wks : The identifier returned from calling Ngl.open_wks. x,y : The X and Y coordinates of the arrow heads centre. xMarker, yMarker : X and Y coordinates in data coordinates of the marker polygon angle: angle relative to the x axis of the marker res: Resource list using following special resources: Special resources: trjArrowDirection : can be 'pos' or 'neg' to select direction of the arrows trjArrowXShapeF : Array containing the x coordinates of the arrow head relative to the heads centre. trjArrowYShapeF : Array containing the y coordinates of the arrow head relative to the heads centre. ''' # get plot centre in data coordinates xMid, yMid = [(ngl.get_float(plot, "tr" + ax + "MaxF") + ngl.get_float(plot, "tr" + ax + "MinF")) / 2. for ax in "XY"] # rotate arrow if res.trjArrowDirection == "neg": angle = angle - np.pi xMarker = copy.deepcopy(res.trjArrowXShapeF) yMarker = copy.deepcopy(res.trjArrowYShapeF) # scale marker xMarker = xMarker * res.trjArrowXScaleF * res.trjArrowSizeF + xMid yMarker = yMarker * res.trjArrowYScaleF * res.trjArrowSizeF + yMid xMarker_ndc, yMarker_ndc = ngl.datatondc(plot, xMarker, yMarker) # move centre of mass to origin xMarker_ndc, yMarker_ndc = [xMarker_ndc - np.mean(xMarker_ndc), yMarker_ndc - np.mean(yMarker_ndc)] # rotate marker xMarker_ndc, yMarker_ndc = [ np.cos(angle) * xMarker_ndc - np.sin(angle) * yMarker_ndc, np.sin(angle) * xMarker_ndc + np.cos(angle) * yMarker_ndc] # shift to final position xOffset_ndc, yOffset_ndc = ngl.datatondc(plot, x, y) xMarker_ndc += xOffset_ndc yMarker_ndc += yOffset_ndc # convert back to coordinates xMarker, yMarker = ngl.ndctodata(plot, xMarker_ndc, yMarker_ndc) # filter attributes from res for attr in dir(res): if not attr[0:2] in ["gs", "__"] or attr[0:3] == "gsn": delattr(res, attr) return ngl.add_polygon(wks, plot, xMarker, yMarker, res)
# # Turn on the right Y labels and tickmarks and move the axis string to # the right. # res2.tmYRLabelsOn = True res2.tmYROn = True res2.tmYUseLeft = False res2.tmYRFormat = "f" # Gets rid of unnecessary trailing zeros # # Move the Y axis string to the right. # res2.tiYAxisString = "U component of wind (m/s)" res2.tiYAxisSide = "Right" res2.tiYAxisFontColor = "purple" res2.tiXAxisFontHeightF = Ngl.get_float(plot1,"tiXAxisFontHeightF") # # Make sure the font heights and tickmark lengths are the same as # the first plot. # res2.tmYRLabelFontHeightF = Ngl.get_float(plot1,"tmYLLabelFontHeightF") res2.tmYRMajorLengthF = Ngl.get_float(plot1,"tmYLMajorLengthF") # # Change line pattern, color and thickness. # pattern = "$_____$_____$$_____$$_____$$_____$$_____$$___" res2.xyDashPattern = Ngl.new_dash_pattern(wks,pattern) res2.xyLineColor = "purple" res2.xyLineThicknessF = 3.0
def trj(wks, x, y, time, res=None): ''' Plots trajectories with arrow heads attached. plot = trj(wks, x, y, time, res=None) wks : The identifier returned from calling Ngl.open_wks. x,y : The X and Y coordinates of the curve(s). These values can be one-dimensional NumPy arrays, NumPy masked arrays or two-dimensional NumPy arrays. If x and/or y are two-dimensional, then the leftmost dimension determines the number of curves. time : Time coordinates of the trajectories. These values can be one-dimensional NumPy arrays, NumPy masked arrays res: Resource list using following special resources: Special resources: trjArrowStep : Number of samples between arrow heads. Default: 10 trjArrowOffsetF : Shift the position of the arrows along the curve. Should be between 0. and 1. Default: 0.5 trjArrowDirection : can be 'pos' or 'neg' to select direction of the arrows. Default: 'pos' trjArrowXShapeF : Array containing the x NDC coordinates of the arrow head relative to the heads centre. Default: Equiliteral triangle trjArrowYShapeF : Array containing the y NDC coordinates of the arrow head relative to the heads centre. Default: Equiliteral triangle trjArrowXScaleF : Scales arrow head in X direction, befor rotation is applied. Default: 1. trjArrowYScaleF : Scales arrow head in y direction, befor rotation is applied. Default: 1. trjArrowSizeF : Scales the size of an arrow head. Default: 0.02 The arrow heads are plotted with add_polygon, so all gs* attributes of the resource list are applied to the arrow heads polygon. ''' if not res: res = ngl.Resources() # set default values: if not hasattr(res, 'trjArrowStep'): res.trjArrowStep = 10 if not hasattr(res, 'trjArrowOffsetF'): res.trjArrowOffsetF = .5 else: res.trjArrowOffsetF -= np.floor(res.trjArrowOffsetF) if not hasattr(res, 'trjArrowDirection'): res.trjArrowDirection = 'pos' if not hasattr(res, 'trjArrowXShapeF'): res.trjArrowXShapeF = [np.sqrt(3) / 3., -np.sqrt(3) / 6., -np.sqrt(3) / 6.] res.trjArrowXShapeF = np.asarray(res.trjArrowXShapeF) if not hasattr(res, 'trjArrowYShapeF'): res.trjArrowYShapeF = [0., .5, -.5] res.trjArrowYShapeF = np.asarray(res.trjArrowYShapeF) if not hasattr(res, 'trjArrowXScaleF'): res.trjArrowXScaleF = 1. if not hasattr(res, 'trjArrowYScaleF'): res.trjArrowYScaleF = 1. if not hasattr(res, 'trjArrowSizeF'): res.trjArrowSizeF = .02 # check for draw and frame if hasattr(res, "nglDraw"): doDraw = res.nglDraw else: doDraw = True res.nglDraw = False if hasattr(res, "nglFrame"): doFrame = res.nglFrame else: doFrame = True res.nglFrame = False # Convert to mask array x = np.ma.asarray(x) y = np.ma.asarray(y) time = np.ma.asarray(time) # check input data if x.shape != y.shape: raise ValueError("Inconsistend shape. x, y and time must have the " + "same shape.") if x.ndim < 1 or x.ndim > 2: raise ValueError("Input arrays x and y must be of rank 1 or 2.") if np.rank(x) == 1: # add singleton dimension to the begining x = x[np.newaxis, ...] y = y[np.newaxis, ...] # Dimension of trajectories dim = 0 # mask all missig values np.ma.masked_where(y.mask, x, copy=False) np.ma.masked_where(x.mask, y, copy=False) # create line plot resource res_lines = copy.deepcopy(res) # remove trj* attributes from res_lines for attr in dir(res_lines): if attr[0:3] == "trj" or (attr[0:2] == "gs" and attr[2] != "n"): delattr(res_lines, attr) # create line plot plot = ngl.xy(wks, x, y, res_lines) # get axes length in data coordinates xAxisLen, yAxisLen = [ngl.get_float(plot, "tr" + ax + "MaxF") - ngl.get_float(plot, "tr" + ax + "MinF") for ax in "XY"] # get marker color # to be implemented # place Marker marker_id = [] for t in xrange(x.shape[dim]): xt = x[t, ...].compressed() yt = y[t, ...].compressed() tt = time[::res.trjArrowStep] # shift time by offset if res.trjArrowOffsetF != 0.: tt = tt[:-1] + res.trjArrowOffsetF * (tt[1:] - tt[:-1]) # itterate over markers for tm in tt: # find nearest indices in time array idx = (np.abs(time - tm)).argmin().min() if time[idx] < tm: idx1 = idx idx2 = idx + 1 elif time[idx] > tm: idx1 = idx - 1 idx2 = idx else: if idx == 0: idx1 = idx idx2 = idx + 1 else: idx1 = idx - 1 idx2 = idx if idx >= len(xt) - 1: continue # interpolate linearly to get coordinates ds = (tm - time[idx1]) / (time[idx2] - time[idx1]) xm, ym = [coord[idx1] + ds * (coord[idx2] - coord[idx1]) for coord in [xt, yt]] x1, y1 = ngl.datatondc(plot, xt[idx1], yt[idx1]) x2, y2 = ngl.datatondc(plot, xt[idx2], yt[idx2]) angle = np.arctan2(y2 - y1, x2 - x1) # create marker resource res_marker = copy.deepcopy(res) # scale adjust marker scale res_marker.trjArrowXScaleF = res.trjArrowXScaleF * xAxisLen res_marker.trjArrowYScaleF = res.trjArrowYScaleF * yAxisLen marker_id.append( _plot_trj_marker(wks, plot, xm, ym, angle, res_marker)) if doDraw: ngl.draw(plot) res.nglDraw = True if doFrame: ngl.frame(wks) res.nglFrame = True return plot
res.tmXBLabelFontHeightF = 0.012 #-- change XB label font size res.tmYLLabelFontHeightF = 0.012 #-- change YL label font size res.tmXBMajorLengthF = 0.008 #-- change XB the tickmark length res.tmYLMajorLengthF = 0.008 #-- change YL the tickmark length res.tiMainString = "Counts per country" #-- title string res.tiMainFont = "helvetica" #-- title string font res.tiMainFontHeightF = 0.025 #-- set title string font size #-- create the map map = Ngl.map(wks, res) #----------------------------------------------------------------------------------- #-- add custom label bar to the plot #----------------------------------------------------------------------------------- vpx = Ngl.get_float(map, "vpXF") #-- retrieve viewport x-position vpy = Ngl.get_float(map, "vpYF") #-- retrieve viewport y-position vpw = Ngl.get_float(map, "vpWidthF") #-- retrieve viewport width vph = Ngl.get_float(map, "vpHeightF") #-- retrieve viewport height lbx, lby = vpx, vpy - vph - 0.04 lbres = Ngl.Resources() lbres.vpWidthF = vpw #-- width of labelbar lbres.vpHeightF = 0.08 #-- height of labelbar lbres.lbOrientation = "horizontal" #-- labelbar orientation lbres.lbLabelFontHeightF = 0.012 #-- labelbar label font size lbres.lbAutoManage = False #-- we control label bar lbres.lbFillColors = colors #-- box fill colors lbres.lbPerimOn = False #-- turn off labelbar perimeter lbres.lbMonoFillPattern = True #-- turn on solid pattern
res.nglDraw = False # Don't draw plot or advance frame. res.nglFrame = False plot = Ngl.xy(wks, years, y1, res) # # Create a blank plot with the special labels that we want. This # plot will be overlaid on the original XY plot. # # Make sure the blank plot is drawn in same location, by setting # the viewport coordinates to the same values. # #---Retrieve viewport coordinates and set them for blank plot. bres = Ngl.Resources() bres.vpXF = Ngl.get_float(plot, "vpXF") bres.vpYF = Ngl.get_float(plot, "vpYF") bres.vpHeightF = Ngl.get_float(plot, "vpHeightF") bres.vpWidthF = Ngl.get_float(plot, "vpWidthF") # # Create the values that represent the locations of the minor tickmarks # in the previous plot. # values = numpy.arange(1950, 2005, 2) # # Create an array of labels for these locations. Since we already # have labels at 1950, 1960, etc, set these to "". #
if hasattr(uvar, "units"): resources.tiMainString = "GRD_6_TRO (u,v {})".format(uvar.units) else: resources.tiMainString = "GRD_6_TRO" resources.tiXAxisFont = "Times-Roman" # Change the default font used. resources.tmXBLabelFont = "Times-Roman" resources.tmYLLabelFont = "Times-Roman" resources.stLineColor = "green" # Change streamlines to green. plot = Ngl.streamline(wks, uvar[::2, ::2], vvar[::2, ::2], resources) #----------- Begin third plot ----------------------------------------- arrowlength = Ngl.get_float(plot, "stArrowLengthF") spacing = Ngl.get_float(plot, "stMinLineSpacingF") resources.stMinLineSpacingF = spacing * 2.0 # Set some resources based resources.stArrowLengthF = arrowlength * 2.0 # on resources you retrieved. resources.stLineColor = "red" # Change line color to red resources.stLineThicknessF = 1.5 uvar = file.variables["U_GRD_6_GPML"] vvar = file.variables["V_GRD_6_GPML"] # # Set resources and plot. # if hasattr(uvar, "units"): resources.tiMainString = "GRD_6_GPML (u,v {})".format(uvar.units)