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)
npts = 400 x = Ngl.fspan(100., npts - 1, npts) y = 500. + x * numpy.sin(0.031415926535898 * x) wks = Ngl.open_wks("ps", "datandc") xy = Ngl.xy(wks, x, y) # # Test with all in-range values and no missing values present. # x_dat = x y_dat = numpy.absolute(y) x_ndc, y_ndc = Ngl.datatondc(xy, x_dat, y_dat) x_dat2, y_dat2 = Ngl.ndctodata(xy, x_ndc, y_ndc) check_type(x_ndc) check_type(y_ndc) check_type(x_dat2) check_type(y_dat2) test_values("no oor or msg data: datatondc/ndctodata", x_dat, x_dat2, delta=1e-4) test_values("no oor or msg data: datatondc/ndctodata", y_dat, y_dat2, delta=1e-4)
# # Then draw markers. # gsres = Ngl.Resources() gsres.gsMarkerColor = "Blue" gsres.gsMarkerIndex = 16 gsres.gsMarkerSizeF = 17.0 Ngl.polymarker_ndc(wks, x_out[::8], y_out[::8], gsres) gsres.gsMarkerColor = "Red" gsres.gsMarkerIndex = 12 gsres.gsMarkerSizeF = 22.0 Ngl.polymarker_ndc(wks, x_out[4::8], y_out[4::8], gsres) Ngl.frame(wks) # # Show that datatondc and ndctodata are inverse functions by # converting a data point to NDC and then converting that point # back to data space. # x_ndc, y_ndc = Ngl.datatondc(xy, 100., 600.) x_dat, y_dat = Ngl.ndctodata(xy, x_ndc, y_ndc) # # Optional print. # # print("Original data: (100.0000, 600.0000) \nNDC: (%06.4f, %06.4f) \nBack to original: (%6.4f, %6.4f)" % (x_ndc,y_ndc,x_dat,y_dat)) Ngl.end()