KURT PETERS wrote: > Thanks, that's exactly what I would like to do. I'll take a look. > Regards, > Kurt >
Kurt: I just added a "tissot" method to Basemap that does this (so you won't have to extend the Basemap class in the next version). The plot_tissot.py example has been updated to do this. Here's the method: def tissot(self,lon_0,lat_0,radius_deg,npts): """ create list of ``npts`` x,y pairs that are equidistant on the surface of the earth from central point ``lon_0,lat_0`` and form an ellipse with radius of ``radius_deg`` degrees of latitude along longitude ``lon_0``. The ellipse represents a Tissot's indicatrix (http://en.wikipedia.org/wiki/Tissot%27s_Indicatrix), which when drawn on a map shows the distortion inherent in the map projection.""" g = pyproj.Geod(a=self.rmajor,b=self.rminor) az12,az21,dist = g.inv(lon_0,lat_0,lon_0,lat_0+radius_deg) seg = [self(lon_0,lat_0+radius_deg)] delaz = 360./npts az = az12 for n in range(npts): az = az+delaz # skip segments along equator (Geod can't handle equatorial arcs) if np.allclose(0.,lat_0) and (np.allclose(90.,az) or np.allclose(270.,az)): continue else: lon, lat, az21 = g.fwd(lon_0, lat_0, az, dist) x,y = self(lon,lat) # add segment if it is in the map projection region. if x < 1.e20 and y < 1.e20: seg.append((x,y)) return seg -Jeff > ----Original Message Follows---- > From: Jeff Whitaker <[EMAIL PROTECTED]> > To: KURT PETERS <[EMAIL PROTECTED]> > CC: matplotlib-users@lists.sourceforge.net > Subject: Re: [Matplotlib-users] scale a circle properly (not from shapefile) > Date: Fri, 11 Jul 2008 06:22:08 -0600 > > KURT PETERS wrote: > >> I am trying to do something similar to the plot_tissot.py example, but am >> having some problems. >> >> I would like to project a group of circles onto a map projection. Below >> is the code I developed, which doesn't work because I get the error: >> ==========ERROR ==== >> File "C:\Python25\Lib\site-packages\matplotlib\path.py", line 127, in >> __init__ >> assert vertices.ndim == 2 >> AssertionError >> ========== >> >> ====CODE ========= >> m = Basemap(llcrnrlon=-180,llcrnrlat=-80,urcrnrlon=180,urcrnrlat=80, >> projection='cyl') >> shp_info = m.readshapefile(r'C:\Documents and Settings\kpeters\My >> Documents\basemap-0.99\examples\tissot','tissot',drawbounds=True) >> ax = plt.gca() >> coords = >> [(116,45),(104,41),(98,37),(88,30),(78,25),(116,-45),(104,-41),(98,-37),(88,-30),(78,-25)] >> >> for lon1,lat1 in coords: >> newverts = [] >> circle = Circle((lon1,lat1),radius=10, facecolor='green') >> # trans = circle.get_patch_transform() >> path = circle.get_path() >> #for jj in path.iter_segments(): #looks like the iterator is >> broken??? >> for jj in path.vertices: >> verts1, verts2 = jj; >> newverts.append(m(verts1,verts2)) >> print newverts >> p = PolyCollection(newverts, facecolor='green', zorder = 10) >> ax.add_collection(p) >> ==END CODE== >> >> Is this a logical/best way to get circles properly projected, or is there a >> better way? >> >> I looked at "transform_vector" but I'm not too sure what the uin and vin >> do. Is there a transform in basemaps that could be passed to a path like >> in this thread: "Re: [Matplotlib-users] Drawing filled circles (discs)": >> "circle = CirclePolygon((x1,y1), r, resolution) >> trans = circle.get_patch_transform() >> path = circle.get_path() >> transpath = path.transformed(trans)" >> >> It should be noted that I also tried: >> ===code dif=== >> for lon1,lat1 in coords: >> newverts = [] >> circle = Circle((lon1,lat1),radius=10, facecolor='green') >> path = circle.get_path() >> #for jj in path.iter_segments(): #looks like the iterator is >> broken??? >> for jj in path.vertices: >> verts1, verts2 = jj; >> newverts.append(m(verts1,verts2)) >> print newverts >> # newcircle = Circle(m(lon1,lat1),radius=10, facecolor='green') >> p = Polygon(newverts, facecolor='green', zorder = 10) >> ax.add_patch(p) >> =========== >> but that doesn't seem to display anything (I suspect the right radius isn't >> being used). Note, that the "newcircle" line that is commented out, puts >> circles on the map, they're just not transformed right. >> >> Regards, >> Kurt >> >> >> > > Kurt: Sounds like what you want is to create a set of points that is > equidistant on the surface of the earth from a given central point. I've > cobbled something together to do this using the Geod class that is part of > the pyproj module (http://code.google.com/p/pyproj) used by basemap. Here > it is: > > import numpy as np > import matplotlib.pyplot as plt > from mpl_toolkits.basemap import Basemap > from mpl_toolkits.basemap import pyproj > from matplotlib.patches import Polygon > > # Tissot's Indicatrix (http://en.wikipedia.org/wiki/Tissot's_Indicatrix). > # These diagrams illustrate the distortion inherent in all map projections. > # In conformal projections, where angles are conserved around every > location, > # the Tissot's indicatrix are all circles, with varying sizes. In equal-area > # projections, where area proportions between objects are conserved, the > # Tissot's indicatrix have all unit area, although their shapes and > # orientations vary with location. > > class Basemap2(Basemap): > def circle(self,lon_0,lat_0,radius_deg,npts): > # create list of npts lon,lat pairs that are equidistant on the > # surface of the earth from central point lon_0,lat_0 > # and has radius along lon_0 of radius_deg degrees of latitude. > # uses the WGS84 ellipsoid (a=6378137.0,b=6356752.3142). > # points are transformed to map projection coordinates. > g = pyproj.Geod(ellps='WGS84') > az12,az21,dist = g.inv(lon_0,lat_0,lon_0,lat_0+radius_deg) > seg = [] > delaz = 360./npts > az = az12 > for n in range(npts): > az = az+delaz > lon, lat, az21 = g.fwd(lon_0, lat_0, az, dist) > seg.append(m(lon,lat)) > return seg > > # create mercator Basemap instance with WGS84 ellipsoid. > m = Basemap2(llcrnrlon=-180,llcrnrlat=-70,urcrnrlon=180,urcrnrlat=70, > projection='merc',lat_ts=20,rsphere=(6378137.0,6356752.3142)) > ax = plt.gca() > # draw "circles" at specified longitudes and latitudes. > for parallel in range(-60,61,30): > for meridian in range(-165,166,30): > seg = m.circle(meridian,parallel,6,101) > poly = Polygon(seg,facecolor='green',zorder=10) > ax.add_patch(poly) > # draw meridians and parallels. > m.drawparallels(np.arange(-90,91,30),labels=[1,0,0,0]) > m.drawmeridians(np.arange(-180,180,60),labels=[0,0,0,1]) > m.drawcoastlines() > m.fillcontinents() > plt.title('Tissot Diagram - Mercator') > plt.show() > > Let us know if you have questions about what is going on here. > > -Jeff > > > > -- > Jeffrey S. Whitaker Phone : (303)497-6313 > NOAA/OAR/CDC R/PSD1 FAX : (303)497-6449 > 325 Broadway Boulder, CO, USA 80305-3328 > > > > ------------------------------------------------------------------------- > Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW! > Studies have shown that voting for your favorite open source project, > along with a healthy diet, reduces your potential for chronic lameness > and boredom. Vote Now at http://www.sourceforge.net/community/cca08 > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > -- Jeffrey S. Whitaker Phone : (303)497-6313 Meteorologist FAX : (303)497-6449 NOAA/OAR/PSD R/PSD1 Email : [EMAIL PROTECTED] 325 Broadway Office : Skaggs Research Cntr 1D-113 Boulder, CO, USA 80303-3328 Web : http://tinyurl.com/5telg -- Jeffrey S. Whitaker Phone : (303)497-6313 Meteorologist FAX : (303)497-6449 NOAA/OAR/PSD R/PSD1 Email : [EMAIL PROTECTED] 325 Broadway Office : Skaggs Research Cntr 1D-113 Boulder, CO, USA 80303-3328 Web : http://tinyurl.com/5telg ------------------------------------------------------------------------- Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW! Studies have shown that voting for your favorite open source project, along with a healthy diet, reduces your potential for chronic lameness and boredom. Vote Now at http://www.sourceforge.net/community/cca08 _______________________________________________ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users